diff --git a/BUILD.gn b/BUILD.gn
index 4615fe0..fd1c723 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -69,6 +69,7 @@
     "//base/util:base_util_unittests",
     "//chrome/installer",
     "//chrome/updater",
+    "//components:components_unittests",
     "//components/gwp_asan:gwp_asan_unittests",
     "//net:net_unittests",
     "//services:services_unittests",
@@ -91,10 +92,6 @@
     ]
   }
 
-  if (!is_fuchsia) {
-    deps += [ "//components:components_unittests" ]
-  }
-
   if (closure_compile) {
     deps += [ ":webui_closure_compile" ]
   }
diff --git a/DEPS b/DEPS
index e7d7f9c..bb83e1d 100644
--- a/DEPS
+++ b/DEPS
@@ -162,11 +162,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': '86c48abc94f387fd2897bdfc87c7cedcf138ad44',
+  'skia_revision': 'c25802db30fa371d3984eeef6b04a605e7b7f51f',
   # 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': '2a8c719952225d7bd00967c16f1613e694e1ad49',
+  'v8_revision': '7720ac9d21ceeaa24715da66d11c0437010fbdee',
   # 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.
@@ -174,11 +174,11 @@
   # 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': '8f08fed925c54835c4faee4d7dd61d6ed2964ffd',
+  'angle_revision': 'b5560486ad224ec6de8a54e2f2a7e638bed17fe1',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling SwiftShader
   # and whatever else without interference from each other.
-  'swiftshader_revision': '30847688f05927c32855b8ecf20465fc91fa893d',
+  'swiftshader_revision': '7a7f630ffbad1044c65c06ec08e5b7fa236666e2',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling PDFium
   # and whatever else without interference from each other.
@@ -197,7 +197,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling googletest
   # and whatever else without interference from each other.
-  'googletest_revision': 'cad3bc46c2ba8ec0bd7bb252d7279fe791140fbf',
+  'googletest_revision': 'f2fb48c3b3d79a75a88a99fba6576b25d42ec528',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling lighttpd
   # and whatever else without interference from each other.
@@ -225,7 +225,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': '914862e8ec8a95b835c02d4dba5540dae61ac170',
+  'catapult_revision': 'd8359680722cfcfdb4840462780c0dca5a728fdc',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling libFuzzer
   # and whatever else without interference from each other.
@@ -301,7 +301,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling feed
   # and whatever else without interference from each other.
-  'quiche_revision': 'ec36d7cd5edefa0706705dbe6e26b5d52c17adc2',
+  'quiche_revision': '181e908c2a5335b7955d3eeb024f7e0b3b8e86d7',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling ios_webkit
   # and whatever else without interference from each other.
@@ -744,7 +744,7 @@
     Var('chromium_git') + '/angle/angle.git' + '@' +  Var('angle_revision'),
 
   'src/third_party/dav1d/libdav1d':
-    Var('chromium_git') + '/external/github.com/videolan/dav1d.git' + '@' + 'acad1a99eaaeefacadbd1756c80365665bc7570a',
+    Var('chromium_git') + '/external/github.com/videolan/dav1d.git' + '@' + '556890be42d8affef280188c1a5d22cf299b2197',
 
   'src/third_party/dawn':
     Var('dawn_git') + '/dawn.git' + '@' +  Var('dawn_revision'),
@@ -853,7 +853,7 @@
 
   # Build tools for Chrome OS. Note: This depends on third_party/pyelftools.
   'src/third_party/chromite': {
-      'url': Var('chromium_git') + '/chromiumos/chromite.git' + '@' + '51ac9ed8487b485c668258f07c26ccdc478be9a0',
+      'url': Var('chromium_git') + '/chromiumos/chromite.git' + '@' + '497d3d907b450e1d67e5fb65b004f27406b1b74d',
       'condition': 'checkout_linux',
   },
 
@@ -868,7 +868,7 @@
 
   # For Linux and Chromium OS.
   'src/third_party/cros_system_api': {
-      'url': Var('chromium_git') + '/chromiumos/platform2/system_api.git' + '@' + '2f0f741fd31bc05c7d157939eba994be4d3a526d',
+      'url': Var('chromium_git') + '/chromiumos/platform2/system_api.git' + '@' + '191a60616c6ba9510957b26eae500b3c2099487c',
       'condition': 'checkout_linux',
   },
 
@@ -878,7 +878,7 @@
   },
 
   'src/third_party/depot_tools':
-    Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + '73ec83f0febdf5015e18199abe42ee092b6e67ab',
+    Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + '4a60db4c3e62239e471dc69906353fcf0384920a',
 
   'src/third_party/devtools-node-modules':
     Var('chromium_git') + '/external/github.com/ChromeDevTools/devtools-node-modules' + '@' + Var('devtools_node_modules_revision'),
@@ -1257,7 +1257,7 @@
   },
 
   'src/third_party/perfetto':
-    Var('android_git') + '/platform/external/perfetto.git' + '@' + '88f90b40111e2c5274de49e8f30297af87961db9',
+    Var('android_git') + '/platform/external/perfetto.git' + '@' + 'cec6a1f798c47b299b8b88af0759b26489140519',
 
   'src/third_party/perl': {
       'url': Var('chromium_git') + '/chromium/deps/perl.git' + '@' + '6f3e5028eb65d0b4c5fdd792106ac4c84eee1eb3',
@@ -1425,7 +1425,7 @@
     Var('chromium_git') + '/external/khronosgroup/webgl.git' + '@' + 'abaae129d9a0c6e1e092067e0b105475df43352e',
 
   'src/third_party/webrtc':
-    Var('webrtc_git') + '/src.git' + '@' + '7bf7a427bfcc9f398d90632aad54dc32372d8578',
+    Var('webrtc_git') + '/src.git' + '@' + 'f5dec1c6af02647d669cf255527464ec58a8f03b',
 
   'src/third_party/xdg-utils': {
       'url': Var('chromium_git') + '/chromium/deps/xdg-utils.git' + '@' + 'd80274d5869b17b8c9067a1022e4416ee7ed5e0d',
@@ -1487,7 +1487,7 @@
     Var('chromium_git') + '/v8/v8.git' + '@' +  Var('v8_revision'),
 
   'src-internal': {
-    'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@717df7b6ee6aafd0086f339305017361f9b24f56',
+    'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@79e09388b11e22eaee47ef410fceb14c5b3e6162',
     'condition': 'checkout_src_internal',
   },
 
diff --git a/android_webview/apk/java/proguard.flags b/android_webview/apk/java/proguard.flags
index b6888be..a267472 100644
--- a/android_webview/apk/java/proguard.flags
+++ b/android_webview/apk/java/proguard.flags
@@ -39,27 +39,17 @@
 -keep class com.android.webview.chromium.DrawGLFunctor
 -keep class com.android.webview.chromium.GraphicsUtils
 
-# Don't note about the API 21 compatibility code which references various
-# hidden APIs via reflection.
--dontnote com.android.webview.chromium.WebViewDelegateFactory$Api21CompatibilityDelegate
-
-# DefaultAndroidKeyStore uses reflection to access internal OpenSSL state.
--dontnote org.chromium.net.DefaultAndroidKeyStore
-
-# MediaPlayerBridge uses reflection to access internal metadata.
--dontnote org.chromium.media.MediaPlayerBridge
-
-# ProxyChangeListener$ProxyReceiver uses reflection to access internal
-# android.net.ProxyProperties.
--dontnote org.chromium.net.ProxyChangeListener$ProxyReceiver
-
 -keep class org.chromium.android_webview.AwBrowserProcess {
     java.nio.channels.FileLock sExclusiveFileLock;
 }
 
-# We strip some unused resources when preprocessing the GMS client libs.
--dontwarn com.google.android.gms.R**
-
-# Trichrome builds don't include a native library list in the main APK; it's
-# picked up from the library APK at runtime.
--dontwarn org.chromium.base.library_loader.NativeLibraries
+# Workaround for crbug/1002847. Methods of BaseGmsClient are incorrectly
+# removed even though they are required for the derived class GmsClient
+# to correctly implement Api$Client.
+# TODO: remove once crbug/1002847 resolved.
+-keep public class com.google.android.gms.common.internal.BaseGmsClient {
+  public void disconnect();
+  public void dump(java.lang.String,java.io.FileDescriptor,java.io.PrintWriter,java.lang.String[]);
+  public int getMinApkVersion();
+  public boolean requiresSignIn();
+}
diff --git a/ash/app_list/views/app_list_view.cc b/ash/app_list/views/app_list_view.cc
index f9995bc9..64f9c96 100644
--- a/ash/app_list/views/app_list_view.cc
+++ b/ash/app_list/views/app_list_view.cc
@@ -109,6 +109,30 @@
 constexpr char kAppListDragInTabletMaxLatencyHistogram[] =
     "Apps.StateTransition.Drag.PresentationTime.MaxLatency.TabletMode";
 
+// Returns whether AppList's rounded corners should be hidden based on
+// the app list view state and app list view bounds.
+bool ShouldHideRoundedCorners(ash::AppListViewState app_list_state,
+                              const gfx::Rect& bounds) {
+  switch (app_list_state) {
+    case ash::AppListViewState::kClosed:
+      return false;
+    case ash::AppListViewState::kFullscreenAllApps:
+    case ash::AppListViewState::kFullscreenSearch:
+      // Hide rounded corners in fullscreen state.
+      return true;
+
+    case ash::AppListViewState::kPeeking:
+    case ash::AppListViewState::kHalf:
+      // When the virtual keyboard shows, the AppListView is moved upward to
+      // avoid the overlapping area with the virtual keyboard. As a result, its
+      // bottom side may be on the display edge. Stop showing the rounded
+      // corners under this circumstance.
+      return bounds.y() == 0;
+  }
+  NOTREACHED();
+  return false;
+}
+
 // This view forwards the focus to the search box widget by providing it as a
 // FocusTraversable when a focus search is provided.
 class SearchBoxFocusHost : public views::View {
@@ -791,7 +815,7 @@
 
   app_list_background_shield_->UpdateBounds(contents_bounds);
 
-  UpdateAppListBackgroundYPosition();
+  UpdateAppListBackgroundYPosition(app_list_state_);
 }
 
 ax::mojom::Role AppListView::GetAccessibleWindowRole() {
@@ -1517,7 +1541,6 @@
     // Layout is called on animation completion, which makes the child views
     // jump. Update y positions in advance here to avoid that.
     app_list_main_view_->contents_view()->UpdateYPositionAndOpacity();
-    UpdateAppListBackgroundYPosition();
   }
 
   if (GetWidget()->IsActive()) {
@@ -1576,6 +1599,7 @@
   if (is_side_shelf_) {
     // There is no animation in side shelf.
     OnBoundsAnimationCompleted();
+    UpdateAppListBackgroundYPosition(target_state);
     if (animation_observer)
       animation_observer->OnImplicitAnimationsCompleted();
     return;
@@ -1615,10 +1639,14 @@
   const int current_y_with_transform =
       current_bounds_y + GetRemainingBoundsAnimationDistance();
 
+  const gfx::Transform current_shield_transform =
+      app_list_background_shield_->layer()->transform();
+
   // Schedule the animation; set to the target bounds, and make the transform
   // to make this appear in the original location. Then set an empty transform
   // with the animation.
   layer->SetBounds(target_bounds);
+
   gfx::Transform transform;
   const int y_offset = current_y_with_transform - target_bounds.y();
   transform.Translate(0, y_offset);
@@ -1639,6 +1667,27 @@
     animation.AddObserver(animation_observer);
   }
 
+  // In fullscreen state, or peeking state with restricted vertical space, the
+  // background shield is translated upwards to ensure background radius is not
+  // visible.
+  // NOTE: layer->SetBounds() changes shield transform, so reset the transform
+  // to the value before the |layer| bounds are set before starting the
+  // animation.
+  app_list_background_shield_->SetTransform(current_shield_transform);
+  ui::ScopedLayerAnimationSettings shield_animation(
+      app_list_background_shield_->layer()->GetAnimator());
+  shield_animation.SetTransitionDuration(duration_ms);
+  shield_animation.SetTweenType(gfx::Tween::EASE_OUT);
+  shield_animation.SetPreemptionStrategy(
+      ui::LayerAnimator::IMMEDIATELY_SET_NEW_TARGET);
+
+  gfx::Transform shield_transform;
+  if (ShouldHideRoundedCorners(target_state, target_bounds)) {
+    shield_transform.Translate(0,
+                               -AppListConfig::instance().background_radius());
+  }
+  app_list_background_shield_->SetTransform(shield_transform);
+
   if (update_childview_each_frame_) {
     layer->GetAnimator()->StartAnimation(new ui::LayerAnimationSequence(
         std::make_unique<PeekingResetAnimation>(y_offset, duration_ms, this)));
@@ -1921,11 +1970,15 @@
   UpdateAppListConfig(window);
 
   gfx::Transform transform;
-  if (ShouldHideRoundedCorners(new_bounds))
+  if (ShouldHideRoundedCorners(app_list_state_, new_bounds))
     transform.Translate(0, -AppListConfig::instance().background_radius());
 
-  app_list_background_shield_->SetTransform(transform);
-  app_list_background_shield_->SchedulePaint();
+  // Avoid setting new transform if the shield is animating to (or already has)
+  // the target value.
+  if (app_list_background_shield_->layer()->GetTargetTransform() != transform) {
+    app_list_background_shield_->SetTransform(transform);
+    app_list_background_shield_->SchedulePaint();
+  }
 }
 
 void AppListView::OnBoundsAnimationCompleted() {
@@ -1961,7 +2014,7 @@
   if (app_list_state_ == ash::AppListViewState::kClosed)
     return;
 
-  UpdateAppListBackgroundYPosition();
+  UpdateAppListBackgroundYPosition(app_list_state_);
 
   // Update the opacity of the background shield.
   SetBackgroundShieldColor();
@@ -2166,7 +2219,8 @@
                 GetFullscreenStateHeight()));
 }
 
-void AppListView::UpdateAppListBackgroundYPosition() {
+void AppListView::UpdateAppListBackgroundYPosition(
+    ash::AppListViewState state) {
   // Update the y position of the background shield.
   gfx::Transform transform;
   if (is_in_drag_) {
@@ -2184,13 +2238,14 @@
       transform.Translate(0, -AppListConfig::instance().background_radius() *
                                  (app_list_transition_progress - 1));
     }
-  } else if (is_fullscreen() || ShouldHideRoundedCorners(GetBoundsInScreen())) {
-    // AppListView::Layout may be called after OnWindowBoundsChanged. It may
-    // reset the transform of |app_list_background_shield_|. So hide the rounded
-    // corners here when ShouldHideRoundedCorners returns true.
+  } else if (ShouldHideRoundedCorners(state, GetBoundsInScreen())) {
     transform.Translate(0, -AppListConfig::instance().background_radius());
   }
-  app_list_background_shield_->SetTransform(transform);
+
+  // Avoid setting new transform if the shield is animating to (or already has)
+  // the target value.
+  if (app_list_background_shield_->layer()->GetTargetTransform() != transform)
+    app_list_background_shield_->SetTransform(transform);
 }
 
 bool AppListView::ShouldUpdateChildViewsDuringAnimation(
@@ -2216,16 +2271,6 @@
          GetPreferredWidgetYForState(target_state);
 }
 
-bool AppListView::ShouldHideRoundedCorners(const gfx::Rect& bounds) const {
-  // When the virtual keyboard shows, the AppListView is moved upward to avoid
-  // the overlapping area with the virtual keyboard. As a result, its bottom
-  // side may be on the display edge. Stop showing the rounded corners under
-  // this circumstance.
-  return (app_list_state_ == ash::AppListViewState::kPeeking ||
-          app_list_state_ == ash::AppListViewState::kHalf) &&
-         bounds.y() == 0;
-}
-
 void AppListView::OnStateTransitionAnimationCompleted() {
   delegate_->OnStateTransitionAnimationCompleted(app_list_state_);
 }
diff --git a/ash/app_list/views/app_list_view.h b/ash/app_list/views/app_list_view.h
index 89f0c3a..0c411170 100644
--- a/ash/app_list/views/app_list_view.h
+++ b/ash/app_list/views/app_list_view.h
@@ -437,18 +437,14 @@
   gfx::Rect GetPreferredWidgetBoundsForState(ash::AppListViewState state);
 
   // Updates y position of |app_list_background_shield_| based on the
-  // |app_list_state_| and |is_in_drag_|.
-  void UpdateAppListBackgroundYPosition();
+  // |state| and |is_in_drag_|.
+  void UpdateAppListBackgroundYPosition(ash::AppListViewState state);
 
   // Returns whether it should update child views' position and opacity in each
   // animation frame.
   bool ShouldUpdateChildViewsDuringAnimation(
       ash::AppListViewState target_state) const;
 
-  // Returns whether AppList's rounded corners should be hidden based on
-  // |bounds|.
-  bool ShouldHideRoundedCorners(const gfx::Rect& bounds) const;
-
   AppListViewDelegate* delegate_;    // Weak. Owned by AppListService.
   AppListModel* const model_;        // Not Owned.
   SearchModel* const search_model_;  // Not Owned.
diff --git a/ash/assistant/assistant_ui_controller.cc b/ash/assistant/assistant_ui_controller.cc
index 5750697..be63e0b 100644
--- a/ash/assistant/assistant_ui_controller.cc
+++ b/ash/assistant/assistant_ui_controller.cc
@@ -426,11 +426,6 @@
     AssistantVisibility old_visibility,
     base::Optional<AssistantEntryPoint> entry_point,
     base::Optional<AssistantExitPoint> exit_point) {
-  AssistantState::Get()->NotifyStatusChanged(
-      new_visibility == AssistantVisibility::kVisible
-          ? mojom::AssistantState::VISIBLE
-          : mojom::AssistantState::READY);
-
   switch (new_visibility) {
     case AssistantVisibility::kClosed:
       // When the UI is closed, we stop the auto close timer as it may be
diff --git a/ash/public/cpp/app_list/app_list_config.cc b/ash/public/cpp/app_list/app_list_config.cc
index e483a10..b857a4d 100644
--- a/ash/public/cpp/app_list/app_list_config.cc
+++ b/ash/public/cpp/app_list/app_list_config.cc
@@ -246,6 +246,12 @@
   return ItemIconInFolderIconMarginForType(ash::AppListConfigType::kShared);
 }
 
+int SuggestionChipIconDimension() {
+  // This is needed because chrome uses default instance when generating icons
+  // for suggestion chip and needs to be done for all configs including kShared.
+  return app_list_features::IsScalableAppListEnabled() ? 20 : 16;
+}
+
 }  // namespace
 
 AppListConfig::AppListConfig(ash::AppListConfigType type)
@@ -272,7 +278,7 @@
       search_list_icon_dimension_(20),
       search_list_icon_vertical_bar_dimension_(48),
       search_list_badge_icon_dimension_(14),
-      suggestion_chip_icon_dimension_(16),
+      suggestion_chip_icon_dimension_(SuggestionChipIconDimension()),
       app_title_max_line_height_(AppTitleMaxLineHeightForType(type)),
       app_title_font_(AppTitleFontForType(type)),
       peeking_app_list_height_(284),
diff --git a/ash/public/mojom/assistant_state_controller.mojom b/ash/public/mojom/assistant_state_controller.mojom
index 89562b0..c52356b 100644
--- a/ash/public/mojom/assistant_state_controller.mojom
+++ b/ash/public/mojom/assistant_state_controller.mojom
@@ -11,8 +11,6 @@
   NOT_READY = 0,
   // The Assistant service is ready.
   READY,
-  // The Assistant UI is showing.
-  VISIBLE
 };
 
 enum AssistantAllowedState {
diff --git a/ash/shelf/assistant_overlay.cc b/ash/shelf/assistant_overlay.cc
index 8367cc0..21303ff 100644
--- a/ash/shelf/assistant_overlay.cc
+++ b/ash/shelf/assistant_overlay.cc
@@ -50,7 +50,6 @@
 
 namespace ash {
 namespace {
-constexpr int kFullExpandDurationMs = 450;
 constexpr int kFullRetractDurationMs = 300;
 constexpr int kFullBurstDurationMs = 200;
 
@@ -64,536 +63,13 @@
 constexpr int kRippleOpacityRetractDurationMs = 200;
 constexpr float kRippleOpacity = 0.2f;
 
-constexpr float kIconInitSizeDip = 48.f;
-constexpr float kIconStartSizeDip = 4.f;
-constexpr float kIconSizeDip = 24.f;
-constexpr float kIconEndSizeDip = 48.f;
-constexpr float kIconOffsetDip = 56.f;
-constexpr float kIconOpacity = 1.f;
-
-constexpr float kBackgroundInitSizeDip = 48.f;
-constexpr float kBackgroundStartSizeDip = 10.f;
-constexpr float kBackgroundSizeDip = 48.f;
-constexpr int kBackgroundOpacityDurationMs = 200;
-constexpr float kBackgroundShadowElevationDip = 24.f;
-// TODO(xiaohuic): this is 2x device size, 1x actually have a different size.
-// Need to figure out a way to dynamically change sizes.
-constexpr float kBackgroundLargeWidthDip = 352.5f;
-constexpr float kBackgroundLargeHeightDip = 540.0f;
-constexpr float kBackgroundCornerRadiusDip = 12.f;
-constexpr float kBackgroundPaddingDip = 6.f;
-constexpr int kBackgroundMorphDurationMs = 150;
-
 constexpr int kHideDurationMs = 200;
 
-// The minimum scale factor to use when scaling rectangle layers. Smaller values
-// were causing visual anomalies.
-constexpr float kMinimumRectScale = 0.0001f;
-
-// The minimum scale factor to use when scaling circle layers. Smaller values
-// were causing visual anomalies.
-constexpr float kMinimumCircleScale = 0.001f;
-
-// These are voice interaction logo specs.
-constexpr float kMoleculeOffsetXDip[] = {-10.f, 10.f, 10.f, 19.f};
-constexpr float kMoleculeOffsetYDip[] = {-8.f, -2.f, 13.f, -9.f};
-constexpr float kMoleculeRadiusDip[] = {12.f, 6.f, 7.f, 3.f};
-constexpr float kMoleculeAmplitude = 2.f;
-constexpr SkColor kMoleculeColors[] = {
-    static_cast<SkColor>(0xFF4184F3),  // Blue
-    static_cast<SkColor>(0xFFEA4335),  // Red
-    static_cast<SkColor>(0xFFFBBC05),  // Yellow
-    static_cast<SkColor>(0xFF34A853)   // Green
-};
-constexpr int kMoleculeAnimationDurationMs = 1200;
-constexpr int kMoleculeAnimationOffset = 50;
-constexpr int kMoleculeOrder[] = {0, 2, 3, 1};
-
 }  // namespace
 
-class AssistantIcon : public ui::Layer, public ui::CompositorAnimationObserver {
- public:
-  AssistantIcon() : Layer(ui::LAYER_NOT_DRAWN) {
-    set_name("AssistantOverlay:ICON_LAYER");
-    SetBounds(gfx::Rect(0, 0, kIconInitSizeDip, kIconInitSizeDip));
-    SetFillsBoundsOpaquely(false);
-    SetMasksToBounds(false);
-
-    InitMoleculeShape();
-  }
-
-  ~AssistantIcon() override { StopAnimation(); }
-
-  void StartAnimation() {
-    ui::Compositor* compositor = GetCompositor();
-    if (compositor && !compositor->HasAnimationObserver(this)) {
-      animating_compositor_ = compositor;
-      animating_compositor_->AddAnimationObserver(this);
-    }
-  }
-
-  void StopAnimation() {
-    if (animating_compositor_ &&
-        animating_compositor_->HasAnimationObserver(this)) {
-      animating_compositor_->RemoveAnimationObserver(this);
-    }
-    animating_compositor_ = nullptr;
-  }
-
-  // ui::CompositorAnimationObserver
-  void OnCompositingShuttingDown(ui::Compositor* compositor) override {
-    DCHECK(compositor);
-    if (animating_compositor_ == compositor) {
-      StopAnimation();
-    }
-  }
-
-  void OnAnimationStep(base::TimeTicks timestamp) override {
-    uint64_t elapsed = (timestamp - base::TimeTicks()).InMilliseconds();
-    for (int i = 0; i < DOT_COUNT; ++i) {
-      float normalizedTime =
-          ((elapsed - kMoleculeAnimationOffset * kMoleculeOrder[i]) %
-           kMoleculeAnimationDurationMs) /
-          static_cast<float>(kMoleculeAnimationDurationMs);
-
-      gfx::Transform transform;
-      transform.Translate(0,
-                          kMoleculeAmplitude * sin(normalizedTime * 2 * M_PI));
-
-      dot_layers_[i]->SetTransform(transform);
-    }
-  }
-
- private:
-  enum Dot {
-    BLUE_DOT = 0,
-    RED_DOT,
-    YELLOW_DOT,
-    GREEN_DOT,
-    // The total number of shapes, not an actual shape.
-    DOT_COUNT
-  };
-
-  std::string ToLayerName(Dot dot) {
-    switch (dot) {
-      case BLUE_DOT:
-        return "BLUE_DOT";
-      case RED_DOT:
-        return "RED_DOT";
-      case YELLOW_DOT:
-        return "YELLOW_DOT";
-      case GREEN_DOT:
-        return "GREEN_DOT";
-      case DOT_COUNT:
-        NOTREACHED() << "The DOT_COUNT value should never be used.";
-        return "DOT_COUNT";
-    }
-    return "UNKNOWN";
-  }
-
-  /**
-   * Convenience method to place dots to Molecule shape used by Molecule
-   * animations.
-   */
-  void InitMoleculeShape() {
-    for (int i = 0; i < DOT_COUNT; ++i) {
-      dot_layer_delegates_[i] = std::make_unique<views::CircleLayerDelegate>(
-          kMoleculeColors[i], kMoleculeRadiusDip[i]);
-      dot_layers_[i] = std::make_unique<ui::Layer>();
-
-      dot_layers_[i]->SetBounds(gfx::Rect(
-          kIconInitSizeDip / 2 + kMoleculeOffsetXDip[i] - kMoleculeRadiusDip[i],
-          kIconInitSizeDip / 2 + kMoleculeOffsetYDip[i] - kMoleculeRadiusDip[i],
-          kMoleculeRadiusDip[i] * 2, kMoleculeRadiusDip[i] * 2));
-      dot_layers_[i]->SetFillsBoundsOpaquely(false);
-      dot_layers_[i]->set_delegate(dot_layer_delegates_[i].get());
-      dot_layers_[i]->SetVisible(true);
-      dot_layers_[i]->SetOpacity(1.0);
-      dot_layers_[i]->SetMasksToBounds(false);
-      dot_layers_[i]->set_name("DOT:" + ToLayerName(static_cast<Dot>(i)));
-
-      Add(dot_layers_[i].get());
-    }
-  }
-
-  std::unique_ptr<ui::Layer> dot_layers_[DOT_COUNT];
-  std::unique_ptr<views::CircleLayerDelegate> dot_layer_delegates_[DOT_COUNT];
-
-  ui::Compositor* animating_compositor_ = nullptr;
-
-  DISALLOW_COPY_AND_ASSIGN(AssistantIcon);
-};
-
-class AssistantIconBackground : public ui::Layer, public ui::LayerDelegate {
- public:
-  AssistantIconBackground()
-      : Layer(ui::LAYER_NOT_DRAWN),
-        large_size_(
-            gfx::Size(kBackgroundLargeWidthDip, kBackgroundLargeHeightDip)),
-        small_size_(gfx::Size(kBackgroundSizeDip, kBackgroundSizeDip)),
-        center_point_(
-            gfx::PointF(kBackgroundSizeDip / 2, kBackgroundSizeDip / 2)),
-        circle_layer_delegate_(std::make_unique<views::CircleLayerDelegate>(
-            SK_ColorWHITE,
-            kBackgroundSizeDip / 2)),
-        rect_layer_delegate_(std::make_unique<views::RectangleLayerDelegate>(
-            SK_ColorWHITE,
-            gfx::SizeF(small_size_))) {
-    set_name("AssistantOverlay:BACKGROUND_LAYER");
-    SetBounds(gfx::Rect(0, 0, kBackgroundInitSizeDip, kBackgroundInitSizeDip));
-    SetFillsBoundsOpaquely(false);
-    SetMasksToBounds(false);
-
-    shadow_values_ =
-        gfx::ShadowValue::MakeMdShadowValues(kBackgroundShadowElevationDip);
-    const gfx::Insets shadow_margin =
-        gfx::ShadowValue::GetMargin(shadow_values_);
-
-    border_shadow_delegate_ =
-        std::make_unique<views::BorderShadowLayerDelegate>(
-            shadow_values_, gfx::Rect(large_size_), SK_ColorWHITE,
-            kBackgroundCornerRadiusDip);
-
-    large_shadow_layer_ = std::make_unique<ui::Layer>();
-    large_shadow_layer_->set_delegate(border_shadow_delegate_.get());
-    large_shadow_layer_->SetFillsBoundsOpaquely(false);
-    large_shadow_layer_->SetBounds(
-        gfx::Rect(shadow_margin.left(), shadow_margin.top(),
-                  kBackgroundLargeWidthDip - shadow_margin.width(),
-                  kBackgroundLargeHeightDip - shadow_margin.height()));
-    Add(large_shadow_layer_.get());
-
-    shadow_layer_ = std::make_unique<ui::Layer>();
-    shadow_layer_->set_delegate(this);
-    shadow_layer_->SetFillsBoundsOpaquely(false);
-    shadow_layer_->SetBounds(
-        gfx::Rect(shadow_margin.left(), shadow_margin.top(),
-                  kBackgroundInitSizeDip - shadow_margin.width(),
-                  kBackgroundInitSizeDip - shadow_margin.height()));
-    Add(shadow_layer_.get());
-
-    for (int i = 0; i < PAINTED_SHAPE_COUNT; ++i)
-      AddPaintLayer(static_cast<PaintedShape>(i));
-  }
-  ~AssistantIconBackground() override = default;
-
-  void MoveLargeShadow(const gfx::PointF& new_center) {
-    gfx::Transform transform;
-    transform.Translate(new_center.x() - kBackgroundLargeWidthDip / 2,
-                        new_center.y() - kBackgroundLargeHeightDip / 2);
-    large_shadow_layer_->SetTransform(transform);
-  }
-
-  void AnimateToLarge(const gfx::PointF& new_center,
-                      ui::LayerAnimationObserver* animation_observer) {
-    PaintedShapeTransforms transforms;
-    // Setup the painted layers to be the small round size and show it
-    CalculateCircleTransforms(small_size_, &transforms);
-    SetTransforms(transforms);
-    SetPaintedLayersVisible(true);
-
-    // Hide the shadow layer
-    shadow_layer_->SetVisible(false);
-    // Also hide the large shadow layer, it will be shown when animation ends.
-    large_shadow_layer_->SetVisible(false);
-    // Move the shadow to the right place.
-    MoveLargeShadow(new_center);
-
-    center_point_ = new_center;
-    // Animate the painted layers to the large rectangle size
-    CalculateRectTransforms(large_size_, kBackgroundCornerRadiusDip,
-                            &transforms);
-
-    AnimateToTransforms(
-        transforms,
-        base::TimeDelta::FromMilliseconds(kBackgroundMorphDurationMs),
-        ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET,
-        gfx::Tween::LINEAR_OUT_SLOW_IN, animation_observer);
-  }
-
-  void SetToLarge(const gfx::PointF& new_center) {
-    PaintedShapeTransforms transforms;
-    SetPaintedLayersVisible(true);
-    // Hide the shadow layer
-    shadow_layer_->SetVisible(false);
-    // Show the large shadow behind
-    large_shadow_layer_->SetVisible(true);
-    // Move the shadow to the right place.
-    MoveLargeShadow(new_center);
-
-    center_point_ = new_center;
-    // Set the painted layers to the large rectangle size
-    CalculateRectTransforms(large_size_, kBackgroundCornerRadiusDip,
-                            &transforms);
-    SetTransforms(transforms);
-  }
-
-  void ResetShape() {
-    // This reverts to the original small round shape.
-    shadow_layer_->SetVisible(true);
-    large_shadow_layer_->SetVisible(false);
-    SetPaintedLayersVisible(false);
-    center_point_.SetPoint(small_size_.width() / 2.f,
-                           small_size_.height() / 2.f);
-  }
-
- private:
-  // Enumeration of the different shapes that compose the background.
-  enum PaintedShape {
-    TOP_LEFT_CIRCLE = 0,
-    TOP_RIGHT_CIRCLE,
-    BOTTOM_RIGHT_CIRCLE,
-    BOTTOM_LEFT_CIRCLE,
-    HORIZONTAL_RECT,
-    VERTICAL_RECT,
-    // The total number of shapes, not an actual shape.
-    PAINTED_SHAPE_COUNT
-  };
-
-  typedef gfx::Transform PaintedShapeTransforms[PAINTED_SHAPE_COUNT];
-
-  void AddPaintLayer(PaintedShape painted_shape) {
-    ui::LayerDelegate* delegate = nullptr;
-    switch (painted_shape) {
-      case TOP_LEFT_CIRCLE:
-      case TOP_RIGHT_CIRCLE:
-      case BOTTOM_RIGHT_CIRCLE:
-      case BOTTOM_LEFT_CIRCLE:
-        delegate = circle_layer_delegate_.get();
-        break;
-      case HORIZONTAL_RECT:
-      case VERTICAL_RECT:
-        delegate = rect_layer_delegate_.get();
-        break;
-      case PAINTED_SHAPE_COUNT:
-        NOTREACHED() << "PAINTED_SHAPE_COUNT is not an actual shape type.";
-        break;
-    }
-
-    ui::Layer* layer = new ui::Layer();
-    Add(layer);
-
-    layer->SetBounds(gfx::Rect(small_size_));
-    layer->SetFillsBoundsOpaquely(false);
-    layer->set_delegate(delegate);
-    layer->SetVisible(true);
-    layer->SetOpacity(1.0);
-    layer->SetMasksToBounds(false);
-    layer->set_name("PAINTED_SHAPE_COUNT:" + ToLayerName(painted_shape));
-
-    painted_layers_[static_cast<int>(painted_shape)].reset(layer);
-  }
-
-  void SetTransforms(const PaintedShapeTransforms transforms) {
-    for (int i = 0; i < PAINTED_SHAPE_COUNT; ++i)
-      painted_layers_[i]->SetTransform(transforms[i]);
-  }
-
-  void SetPaintedLayersVisible(bool visible) {
-    for (int i = 0; i < PAINTED_SHAPE_COUNT; ++i)
-      painted_layers_[i]->SetVisible(visible);
-  }
-
-  void CalculateCircleTransforms(const gfx::Size& size,
-                                 PaintedShapeTransforms* transforms_out) const {
-    CalculateRectTransforms(size, std::min(size.width(), size.height()) / 2.0f,
-                            transforms_out);
-  }
-
-  void CalculateRectTransforms(const gfx::Size& desired_size,
-                               float corner_radius,
-                               PaintedShapeTransforms* transforms_out) const {
-    DCHECK_GE(desired_size.width() / 2.0f, corner_radius)
-        << "The circle's diameter should not be greater than the total width.";
-    DCHECK_GE(desired_size.height() / 2.0f, corner_radius)
-        << "The circle's diameter should not be greater than the total height.";
-
-    gfx::SizeF size(desired_size);
-    // This function can be called before the layer's been added to a view,
-    // either at construction time or in tests.
-    if (GetCompositor()) {
-      // Modify |desired_size| so that the ripple aligns to pixel bounds.
-      const float dsf = GetCompositor()->device_scale_factor();
-      gfx::RectF ripple_bounds((gfx::PointF(center_point_)), gfx::SizeF());
-      ripple_bounds.Inset(-gfx::InsetsF(desired_size.height() / 2.0f,
-                                        desired_size.width() / 2.0f));
-      ripple_bounds.Scale(dsf);
-      ripple_bounds = gfx::RectF(gfx::ToEnclosingRect(ripple_bounds));
-      ripple_bounds.Scale(1.0f / dsf);
-      size = ripple_bounds.size();
-    }
-
-    // The shapes are drawn such that their center points are not at the origin.
-    // Thus we use the CalculateCircleTransform() and CalculateRectTransform()
-    // methods to calculate the complex Transforms.
-
-    const float circle_scale = std::max(
-        kMinimumCircleScale,
-        corner_radius / static_cast<float>(circle_layer_delegate_->radius()));
-
-    const float circle_target_x_offset = size.width() / 2.0f - corner_radius;
-    const float circle_target_y_offset = size.height() / 2.0f - corner_radius;
-
-    (*transforms_out)[TOP_LEFT_CIRCLE] = CalculateCircleTransform(
-        circle_scale, -circle_target_x_offset, -circle_target_y_offset);
-    (*transforms_out)[TOP_RIGHT_CIRCLE] = CalculateCircleTransform(
-        circle_scale, circle_target_x_offset, -circle_target_y_offset);
-    (*transforms_out)[BOTTOM_RIGHT_CIRCLE] = CalculateCircleTransform(
-        circle_scale, circle_target_x_offset, circle_target_y_offset);
-    (*transforms_out)[BOTTOM_LEFT_CIRCLE] = CalculateCircleTransform(
-        circle_scale, -circle_target_x_offset, circle_target_y_offset);
-
-    const float rect_delegate_width = rect_layer_delegate_->size().width();
-    const float rect_delegate_height = rect_layer_delegate_->size().height();
-
-    (*transforms_out)[HORIZONTAL_RECT] = CalculateRectTransform(
-        std::max(kMinimumRectScale, size.width() / rect_delegate_width),
-        std::max(kMinimumRectScale, (size.height() - 2.0f * corner_radius) /
-                                        rect_delegate_height));
-
-    (*transforms_out)[VERTICAL_RECT] = CalculateRectTransform(
-        std::max(kMinimumRectScale,
-                 (size.width() - 2.0f * corner_radius) / rect_delegate_width),
-        std::max(kMinimumRectScale, size.height() / rect_delegate_height));
-  }
-
-  gfx::Transform CalculateCircleTransform(float scale,
-                                          float target_center_x,
-                                          float target_center_y) const {
-    gfx::Transform transform;
-    // Offset for the center point of the ripple.
-    transform.Translate(center_point_.x(), center_point_.y());
-    // Move circle to target.
-    transform.Translate(target_center_x, target_center_y);
-    transform.Scale(scale, scale);
-    // Align center point of the painted circle.
-    const gfx::Vector2dF circle_center_offset =
-        circle_layer_delegate_->GetCenteringOffset();
-    transform.Translate(-circle_center_offset.x(), -circle_center_offset.y());
-    return transform;
-  }
-
-  gfx::Transform CalculateRectTransform(float x_scale, float y_scale) const {
-    gfx::Transform transform;
-    transform.Translate(center_point_.x(), center_point_.y());
-    transform.Scale(x_scale, y_scale);
-    const gfx::Vector2dF rect_center_offset =
-        rect_layer_delegate_->GetCenteringOffset();
-    transform.Translate(-rect_center_offset.x(), -rect_center_offset.y());
-    return transform;
-  }
-
-  void AnimateToTransforms(
-      const PaintedShapeTransforms transforms,
-      base::TimeDelta duration,
-      ui::LayerAnimator::PreemptionStrategy preemption_strategy,
-      gfx::Tween::Type tween,
-      ui::LayerAnimationObserver* animation_observer) {
-    for (int i = 0; i < PAINTED_SHAPE_COUNT; ++i) {
-      ui::LayerAnimator* animator = painted_layers_[i]->GetAnimator();
-      ui::ScopedLayerAnimationSettings animation(animator);
-      animation.SetPreemptionStrategy(preemption_strategy);
-      animation.SetTweenType(tween);
-      std::unique_ptr<ui::LayerAnimationElement> element =
-          ui::LayerAnimationElement::CreateTransformElement(transforms[i],
-                                                            duration);
-      ui::LayerAnimationSequence* sequence =
-          new ui::LayerAnimationSequence(std::move(element));
-
-      if (animation_observer)
-        sequence->AddObserver(animation_observer);
-
-      animator->StartAnimation(sequence);
-    }
-
-    {
-      ui::ScopedLayerAnimationSettings animation(
-          large_shadow_layer_->GetAnimator());
-      animation.SetTweenType(tween);
-      animation.SetTransitionDuration(duration);
-
-      large_shadow_layer_->SetVisible(true);
-    }
-  }
-
-  std::string ToLayerName(PaintedShape painted_shape) {
-    switch (painted_shape) {
-      case TOP_LEFT_CIRCLE:
-        return "TOP_LEFT_CIRCLE";
-      case TOP_RIGHT_CIRCLE:
-        return "TOP_RIGHT_CIRCLE";
-      case BOTTOM_RIGHT_CIRCLE:
-        return "BOTTOM_RIGHT_CIRCLE";
-      case BOTTOM_LEFT_CIRCLE:
-        return "BOTTOM_LEFT_CIRCLE";
-      case HORIZONTAL_RECT:
-        return "HORIZONTAL_RECT";
-      case VERTICAL_RECT:
-        return "VERTICAL_RECT";
-      case PAINTED_SHAPE_COUNT:
-        NOTREACHED() << "The PAINTED_SHAPE_COUNT value should never be used.";
-        return "PAINTED_SHAPE_COUNT";
-    }
-    return "UNKNOWN";
-  }
-
-  void OnPaintLayer(const ui::PaintContext& context) override {
-    // Radius is based on the parent layer size, the shadow layer is expanded
-    // to make room for the shadow.
-    float radius = size().width() / 2.f;
-
-    ui::PaintRecorder recorder(context, shadow_layer_->size());
-    gfx::Canvas* canvas = recorder.canvas();
-
-    cc::PaintFlags flags;
-    flags.setColor(SK_ColorWHITE);
-    flags.setAntiAlias(true);
-    flags.setStyle(cc::PaintFlags::kFill_Style);
-    flags.setLooper(gfx::CreateShadowDrawLooper(shadow_values_));
-    gfx::Rect shadow_bounds = shadow_layer_->bounds();
-    canvas->DrawCircle(
-        gfx::PointF(radius - shadow_bounds.x(), radius - shadow_bounds.y()),
-        radius, flags);
-  }
-
-  void OnDeviceScaleFactorChanged(float old_device_scale_factor,
-                                  float new_device_scale_factor) override {}
-
-  // ui::Layers for all of the painted shape layers that compose the morphing
-  // shape.
-  std::unique_ptr<ui::Layer> painted_layers_[PAINTED_SHAPE_COUNT];
-
-  const gfx::Size large_size_;
-
-  const gfx::Size small_size_;
-
-  // The center point of the painted shape.
-  gfx::PointF center_point_;
-
-  // ui::LayerDelegate to paint circles for all the circle layers.
-  std::unique_ptr<views::CircleLayerDelegate> circle_layer_delegate_;
-
-  // ui::LayerDelegate to paint rectangles for all the rectangle layers.
-  std::unique_ptr<views::RectangleLayerDelegate> rect_layer_delegate_;
-
-  // ui::LayerDelegate to paint rounded rectangle with shadow.
-  std::unique_ptr<views::BorderShadowLayerDelegate> border_shadow_delegate_;
-
-  gfx::ShadowValues shadow_values_;
-
-  // This layer shows the small circle with shadow.
-  std::unique_ptr<ui::Layer> shadow_layer_;
-
-  // This layer shows the large rounded rectangle with shadow.
-  std::unique_ptr<ui::Layer> large_shadow_layer_;
-
-  DISALLOW_COPY_AND_ASSIGN(AssistantIconBackground);
-};
 
 AssistantOverlay::AssistantOverlay(HomeButton* host_view)
     : ripple_layer_(std::make_unique<ui::Layer>()),
-      icon_layer_(std::make_unique<AssistantIcon>()),
-      background_layer_(std::make_unique<AssistantIconBackground>()),
       host_view_(host_view),
       circle_layer_delegate_(kRippleColor, kRippleCircleInitRadiusDip) {
   SetPaintToLayer(ui::LAYER_NOT_DRAWN);
@@ -607,10 +83,6 @@
   ripple_layer_->SetMasksToBounds(true);
   ripple_layer_->set_name("AssistantOverlay:PAINTED_LAYER");
   layer()->Add(ripple_layer_.get());
-
-  layer()->Add(background_layer_.get());
-
-  layer()->Add(icon_layer_.get());
 }
 
 AssistantOverlay::~AssistantOverlay() = default;
@@ -652,78 +124,6 @@
         base::TimeDelta::FromMilliseconds(kRippleOpacityDurationMs));
     ripple_layer_->SetOpacity(kRippleOpacity);
   }
-
-  icon_layer_->SetOpacity(0);
-  background_layer_->SetOpacity(0);
-  if (!show_icon_)
-    return;
-
-  // Setup icon initial state.
-  transform.MakeIdentity();
-  transform.Translate(center.x() - kIconStartSizeDip / 2.f,
-                      center.y() - kIconStartSizeDip / 2.f);
-
-  scale_factor = kIconStartSizeDip / kIconInitSizeDip;
-  transform.Scale(scale_factor, scale_factor);
-  icon_layer_->SetTransform(transform);
-
-  const bool is_tablet_mode =
-      Shell::Get()->tablet_mode_controller()->InTabletMode();
-  const int icon_x_offset = is_tablet_mode ? 0 : kIconOffsetDip;
-  const int icon_y_offset =
-      is_tablet_mode ? -kRippleCircleRadiusDip : -kIconOffsetDip;
-  // Setup icon animation.
-  scale_factor = kIconSizeDip / kIconInitSizeDip;
-  transform.MakeIdentity();
-  transform.Translate(center.x() - kIconSizeDip / 2 + icon_x_offset,
-                      center.y() - kIconSizeDip / 2 + icon_y_offset);
-  transform.Scale(scale_factor, scale_factor);
-
-  {
-    ui::ScopedLayerAnimationSettings settings(icon_layer_->GetAnimator());
-    settings.SetTransitionDuration(
-        base::TimeDelta::FromMilliseconds(kFullExpandDurationMs));
-    settings.SetTweenType(gfx::Tween::FAST_OUT_SLOW_IN_2);
-
-    icon_layer_->SetTransform(transform);
-    icon_layer_->SetOpacity(kIconOpacity);
-  }
-
-  // Setup background initial state.
-  background_layer_->ResetShape();
-
-  transform.MakeIdentity();
-  transform.Translate(center.x() - kBackgroundStartSizeDip / 2.f,
-                      center.y() - kBackgroundStartSizeDip / 2.f);
-
-  scale_factor = kBackgroundStartSizeDip / kBackgroundInitSizeDip;
-  transform.Scale(scale_factor, scale_factor);
-  background_layer_->SetTransform(transform);
-
-  // Setup background animation.
-  scale_factor = kBackgroundSizeDip / kBackgroundInitSizeDip;
-  transform.MakeIdentity();
-  transform.Translate(center.x() - kBackgroundSizeDip / 2 + icon_x_offset,
-                      center.y() - kBackgroundSizeDip / 2 + icon_y_offset);
-  transform.Scale(scale_factor, scale_factor);
-
-  {
-    ui::ScopedLayerAnimationSettings settings(background_layer_->GetAnimator());
-    settings.SetTransitionDuration(
-        base::TimeDelta::FromMilliseconds(kFullExpandDurationMs));
-    settings.SetTweenType(gfx::Tween::FAST_OUT_SLOW_IN_2);
-
-    background_layer_->SetTransform(transform);
-  }
-
-  {
-    ui::ScopedLayerAnimationSettings settings(background_layer_->GetAnimator());
-    settings.SetTransitionDuration(
-        base::TimeDelta::FromMilliseconds(kBackgroundOpacityDurationMs));
-    settings.SetTweenType(gfx::Tween::FAST_OUT_SLOW_IN_2);
-
-    background_layer_->SetOpacity(1);
-  }
 }
 
 void AssistantOverlay::BurstAnimation() {
@@ -750,109 +150,6 @@
     ripple_layer_->SetTransform(transform);
     ripple_layer_->SetOpacity(0);
   }
-
-  if (!show_icon_)
-    return;
-
-  // Setup icon animation.
-  // TODO(xiaohuic): Currently the animation does not support RTL.
-  {
-    ui::ScopedLayerAnimationSettings settings(icon_layer_->GetAnimator());
-    settings.SetTransitionDuration(
-        base::TimeDelta::FromMilliseconds(kBackgroundMorphDurationMs));
-    settings.SetPreemptionStrategy(
-        ui::LayerAnimator::PreemptionStrategy::ENQUEUE_NEW_ANIMATION);
-    settings.SetTweenType(gfx::Tween::LINEAR_OUT_SLOW_IN);
-
-    transform.MakeIdentity();
-    transform.Translate(kBackgroundLargeWidthDip / 2 + kBackgroundPaddingDip -
-                            kIconEndSizeDip / 2,
-                        -kBackgroundLargeHeightDip / 2 - kBackgroundPaddingDip -
-                            kIconEndSizeDip / 2);
-    SkMScalar scale_factor = kIconEndSizeDip / kIconInitSizeDip;
-    transform.Scale(scale_factor, scale_factor);
-
-    icon_layer_->SetTransform(transform);
-    icon_layer_->StartAnimation();
-  }
-
-  // Setup background animation.
-  // Transform to new shape.
-  // We want to animate from the background's current position into a larger
-  // size. The animation moves the background's center point while morphing from
-  // circle to a rectangle.
-  const bool is_tablet_mode =
-      Shell::Get()->tablet_mode_controller()->InTabletMode();
-  const int icon_x_offset = is_tablet_mode ? 0 : kIconOffsetDip;
-  const int icon_y_offset =
-      is_tablet_mode ? -kRippleCircleRadiusDip : -kIconOffsetDip;
-  float x_offset = center.x() - kBackgroundSizeDip / 2 + icon_x_offset;
-  float y_offset = center.y() - kBackgroundSizeDip / 2 + icon_y_offset;
-
-  background_layer_->AnimateToLarge(
-      gfx::PointF(
-          kBackgroundLargeWidthDip / 2 + kBackgroundPaddingDip - x_offset,
-          -kBackgroundLargeHeightDip / 2 - kBackgroundPaddingDip - y_offset),
-      nullptr);
-}
-
-void AssistantOverlay::WaitingAnimation() {
-  // If we are already playing burst animation, it will end up at waiting state
-  // anyway.  No need to do anything.
-  if (IsBursting())
-    return;
-
-  animation_state_ = AnimationState::WAITING;
-
-  gfx::Point center = host_view_->GetCenterPoint();
-  gfx::Transform transform;
-
-  ripple_layer_->SetOpacity(0);
-  icon_layer_->SetOpacity(0);
-  background_layer_->SetOpacity(0);
-  SetVisible(true);
-
-  // Setup icon layer.
-  {
-    transform.Translate(kBackgroundLargeWidthDip / 2 + kBackgroundPaddingDip -
-                            kIconEndSizeDip / 2,
-                        -kBackgroundLargeHeightDip / 2 - kBackgroundPaddingDip -
-                            kIconEndSizeDip / 2);
-    SkMScalar scale_factor = kIconEndSizeDip / kIconInitSizeDip;
-    transform.Scale(scale_factor, scale_factor);
-    icon_layer_->SetTransform(transform);
-
-    ui::ScopedLayerAnimationSettings settings(icon_layer_->GetAnimator());
-    settings.SetTransitionDuration(
-        base::TimeDelta::FromMilliseconds(kBackgroundMorphDurationMs));
-    settings.SetPreemptionStrategy(
-        ui::LayerAnimator::PreemptionStrategy::ENQUEUE_NEW_ANIMATION);
-    settings.SetTweenType(gfx::Tween::LINEAR_OUT_SLOW_IN);
-
-    icon_layer_->SetOpacity(1);
-    icon_layer_->StartAnimation();
-  }
-
-  // Setup background layer.
-  {
-    float x_offset = center.x() - kBackgroundSizeDip / 2;
-    float y_offset = center.y() - kBackgroundSizeDip / 2;
-
-    transform.MakeIdentity();
-    background_layer_->SetTransform(transform);
-    background_layer_->SetToLarge(gfx::PointF(
-        kBackgroundLargeWidthDip / 2 + kBackgroundPaddingDip - x_offset,
-        -kBackgroundLargeHeightDip / 2 - kBackgroundPaddingDip - y_offset));
-
-    ui::ScopedLayerAnimationSettings settings(background_layer_->GetAnimator());
-    settings.SetTransitionDuration(
-        base::TimeDelta::FromMilliseconds(kBackgroundMorphDurationMs));
-    settings.SetPreemptionStrategy(
-        ui::LayerAnimator::PreemptionStrategy::ENQUEUE_NEW_ANIMATION);
-    settings.SetTweenType(gfx::Tween::LINEAR_OUT_SLOW_IN);
-
-    background_layer_->SetOpacity(1);
-  }
 }
 
 void AssistantOverlay::EndAnimation() {
@@ -887,51 +184,6 @@
         base::TimeDelta::FromMilliseconds(kRippleOpacityRetractDurationMs));
     ripple_layer_->SetOpacity(0);
   }
-
-  if (!show_icon_)
-    return;
-
-  // Setup icon animation.
-  transform.MakeIdentity();
-
-  transform.Translate(center.x() - kIconStartSizeDip / 2.f,
-                      center.y() - kIconStartSizeDip / 2.f);
-
-  scale_factor = kIconStartSizeDip / kIconInitSizeDip;
-  transform.Scale(scale_factor, scale_factor);
-
-  {
-    ui::ScopedLayerAnimationSettings settings(icon_layer_->GetAnimator());
-    settings.SetPreemptionStrategy(ui::LayerAnimator::PreemptionStrategy::
-                                       IMMEDIATELY_ANIMATE_TO_NEW_TARGET);
-    settings.SetTransitionDuration(
-        base::TimeDelta::FromMilliseconds(kFullRetractDurationMs));
-    settings.SetTweenType(gfx::Tween::SLOW_OUT_LINEAR_IN);
-
-    icon_layer_->SetTransform(transform);
-    icon_layer_->SetOpacity(0);
-  }
-
-  // Setup background animation.
-  transform.MakeIdentity();
-
-  transform.Translate(center.x() - kBackgroundStartSizeDip / 2.f,
-                      center.y() - kBackgroundStartSizeDip / 2.f);
-
-  scale_factor = kBackgroundStartSizeDip / kBackgroundInitSizeDip;
-  transform.Scale(scale_factor, scale_factor);
-
-  {
-    ui::ScopedLayerAnimationSettings settings(background_layer_->GetAnimator());
-    settings.SetPreemptionStrategy(ui::LayerAnimator::PreemptionStrategy::
-                                       IMMEDIATELY_ANIMATE_TO_NEW_TARGET);
-    settings.SetTransitionDuration(
-        base::TimeDelta::FromMilliseconds(kFullRetractDurationMs));
-    settings.SetTweenType(gfx::Tween::SLOW_OUT_LINEAR_IN);
-
-    background_layer_->SetTransform(transform);
-    background_layer_->SetOpacity(0);
-  }
 }
 
 void AssistantOverlay::HideAnimation() {
@@ -948,31 +200,6 @@
 
     ripple_layer_->SetOpacity(0);
   }
-
-  // Setup icon animation.
-  {
-    ui::ScopedLayerAnimationSettings settings(icon_layer_->GetAnimator());
-    settings.SetTransitionDuration(
-        base::TimeDelta::FromMilliseconds(kHideDurationMs));
-    settings.SetTweenType(gfx::Tween::LINEAR_OUT_SLOW_IN);
-    settings.SetPreemptionStrategy(
-        ui::LayerAnimator::PreemptionStrategy::ENQUEUE_NEW_ANIMATION);
-
-    icon_layer_->SetOpacity(0);
-    icon_layer_->StopAnimation();
-  }
-
-  // Setup background animation.
-  {
-    ui::ScopedLayerAnimationSettings settings(background_layer_->GetAnimator());
-    settings.SetTransitionDuration(
-        base::TimeDelta::FromMilliseconds(kHideDurationMs));
-    settings.SetTweenType(gfx::Tween::LINEAR_OUT_SLOW_IN);
-    settings.SetPreemptionStrategy(
-        ui::LayerAnimator::PreemptionStrategy::ENQUEUE_NEW_ANIMATION);
-
-    background_layer_->SetOpacity(0);
-  }
 }
 
 const char* AssistantOverlay::GetClassName() const {
diff --git a/ash/shelf/assistant_overlay.h b/ash/shelf/assistant_overlay.h
index c53d251..f244b92 100644
--- a/ash/shelf/assistant_overlay.h
+++ b/ash/shelf/assistant_overlay.h
@@ -16,8 +16,6 @@
 namespace ash {
 
 class HomeButton;
-class AssistantIconBackground;
-class AssistantIcon;
 
 class ASH_EXPORT AssistantOverlay : public views::View {
  public:
@@ -27,12 +25,10 @@
   void StartAnimation(bool show_icon);
   void EndAnimation();
   void BurstAnimation();
-  void WaitingAnimation();
   void HideAnimation();
   bool IsBursting() const {
     return AnimationState::BURSTING == animation_state_;
   }
-  bool IsWaiting() const { return AnimationState::WAITING == animation_state_; }
   bool IsHidden() const { return AnimationState::HIDDEN == animation_state_; }
 
   // views::View:
@@ -46,14 +42,10 @@
     STARTING,
     // Indicates the current animation is in the bursting phase, which means no
     // turning back.
-    BURSTING,
-    // Indicates currently playing the waiting animation.
-    WAITING
+    BURSTING
   };
 
   std::unique_ptr<ui::Layer> ripple_layer_;
-  std::unique_ptr<AssistantIcon> icon_layer_;
-  std::unique_ptr<AssistantIconBackground> background_layer_;
 
   HomeButton* host_view_;
 
diff --git a/ash/shelf/home_button.cc b/ash/shelf/home_button.cc
index 2f62ab7..91dc64d 100644
--- a/ash/shelf/home_button.cc
+++ b/ash/shelf/home_button.cc
@@ -28,8 +28,8 @@
 namespace ash {
 namespace {
 
-constexpr uint8_t kVoiceInteractionRunningAlpha = 255;     // 100% alpha
-constexpr uint8_t kVoiceInteractionNotRunningAlpha = 138;  // 54% alpha
+constexpr uint8_t kAssistantVisibleAlpha = 255;    // 100% alpha
+constexpr uint8_t kAssistantInvisibleAlpha = 138;  // 54% alpha
 
 }  // namespace
 
@@ -93,7 +93,7 @@
   OnPressed(show_source, event.time_stamp());
 }
 
-void HomeButton::OnVoiceInteractionAvailabilityChanged() {
+void HomeButton::OnAssistantAvailabilityChanged() {
   SchedulePaint();
 }
 
@@ -125,7 +125,7 @@
   // factors.
   float ring_outer_radius_dp = 7.f;
   float ring_thickness_dp = 1.5f;
-  if (controller_.IsVoiceInteractionAvailable()) {
+  if (controller_.IsAssistantAvailable()) {
     ring_outer_radius_dp = 8.f;
     ring_thickness_dp = 1.f;
   }
@@ -138,11 +138,11 @@
     fg_flags.setStyle(cc::PaintFlags::kStroke_Style);
     fg_flags.setColor(ShelfConfig::Get()->shelf_icon_color());
 
-    if (controller_.IsVoiceInteractionAvailable()) {
+    if (controller_.IsAssistantAvailable()) {
       // active: 100% alpha, inactive: 54% alpha
-      fg_flags.setAlpha(controller_.IsVoiceInteractionRunning()
-                            ? kVoiceInteractionRunningAlpha
-                            : kVoiceInteractionNotRunningAlpha);
+      fg_flags.setAlpha(controller_.IsAssistantVisible()
+                            ? kAssistantVisibleAlpha
+                            : kAssistantInvisibleAlpha);
     }
 
     const float thickness = std::ceil(ring_thickness_dp * dsf);
@@ -151,7 +151,7 @@
     // Make sure the center of the circle lands on pixel centers.
     canvas->DrawCircle(circle_center, radius, fg_flags);
 
-    if (controller_.IsVoiceInteractionAvailable()) {
+    if (controller_.IsAssistantAvailable()) {
       fg_flags.setAlpha(255);
       const float kCircleRadiusDp = 5.f;
       fg_flags.setStyle(cc::PaintFlags::kFill_Style);
diff --git a/ash/shelf/home_button.h b/ash/shelf/home_button.h
index a80f9b352..c7b4a66 100644
--- a/ash/shelf/home_button.h
+++ b/ash/shelf/home_button.h
@@ -49,7 +49,7 @@
 
   // Called when the availability of a long-press gesture may have changed, e.g.
   // when Assistant becomes enabled.
-  void OnVoiceInteractionAvailabilityChanged();
+  void OnAssistantAvailabilityChanged();
 
   // True if the app list is shown for the display containing this button.
   bool IsShowingAppList() const;
diff --git a/ash/shelf/home_button_controller.cc b/ash/shelf/home_button_controller.cc
index 5f45bd6..0163685a 100644
--- a/ash/shelf/home_button_controller.cc
+++ b/ash/shelf/home_button_controller.cc
@@ -20,7 +20,6 @@
 #include "base/metrics/histogram_macros.h"
 #include "base/metrics/user_metrics.h"
 #include "base/metrics/user_metrics_action.h"
-#include "base/timer/timer.h"
 #include "chromeos/constants/chromeos_features.h"
 #include "components/account_id/account_id.h"
 #include "ui/display/screen.h"
@@ -30,9 +29,6 @@
 namespace ash {
 namespace {
 
-constexpr int kVoiceInteractionAnimationDelayMs = 200;
-constexpr int kVoiceInteractionAnimationHideDelayMs = 500;
-
 // Returns true if the button should appear activatable.
 bool CanActivate() {
   return Shell::Get()->home_screen_controller()->IsHomeScreenAvailable() ||
@@ -50,11 +46,11 @@
   shell->tablet_mode_controller()->AddObserver(this);
   AssistantState::Get()->AddObserver(this);
 
-  // Initialize voice interaction overlay and sync the flags if active user
-  // session has already started. This could happen when an external monitor
-  // is plugged in.
+  // Initialize the Assistant overlay and sync the flags if active user session
+  // has already started. This could happen when an external monitor is plugged
+  // in.
   if (shell->session_controller()->IsActiveUserSessionStarted())
-    InitializeVoiceInteractionOverlay();
+    InitializeAssistantOverlay();
 }
 
 HomeButtonController::~HomeButtonController() {
@@ -75,9 +71,8 @@
   switch (event->type()) {
     case ui::ET_GESTURE_TAP:
     case ui::ET_GESTURE_TAP_CANCEL:
-      if (IsVoiceInteractionAvailable()) {
+      if (IsAssistantAvailable()) {
         assistant_overlay_->EndAnimation();
-        assistant_animation_delay_timer_->Stop();
       }
 
       if (CanActivate())
@@ -86,23 +81,13 @@
       // After animating the ripple, let the button handle the event.
       return false;
     case ui::ET_GESTURE_TAP_DOWN:
-      if (IsVoiceInteractionAvailable()) {
-        assistant_animation_delay_timer_->Start(
-            FROM_HERE,
-            base::TimeDelta::FromMilliseconds(
-                kVoiceInteractionAnimationDelayMs),
-            base::BindOnce(
-                &HomeButtonController::StartVoiceInteractionAnimation,
-                base::Unretained(this)));
-      }
-
       if (CanActivate())
         button_->AnimateInkDrop(views::InkDropState::ACTION_PENDING, event);
 
       return false;
     case ui::ET_GESTURE_LONG_PRESS:
-      // Only consume the long press event if voice interaction is available.
-      if (!IsVoiceInteractionAvailable())
+      // Only consume the long press event if the Assistant is available.
+      if (!IsAssistantAvailable())
         return false;
 
       base::RecordAction(base::UserMetricsAction(
@@ -115,8 +100,8 @@
           AssistantEntryPoint::kLongPressLauncher);
       return true;
     case ui::ET_GESTURE_LONG_TAP:
-      // Only consume the long tap event if voice interaction is available.
-      if (!IsVoiceInteractionAvailable())
+      // Only consume the long tap event if the Assistant is available.
+      if (!IsAssistantAvailable())
         return false;
 
       // This event happens after the user long presses and lifts the finger.
@@ -131,7 +116,7 @@
   }
 }
 
-bool HomeButtonController::IsVoiceInteractionAvailable() {
+bool HomeButtonController::IsAssistantAvailable() {
   AssistantStateBase* state = AssistantState::Get();
   bool settings_enabled = state->settings_enabled().value_or(false);
   bool feature_allowed =
@@ -140,11 +125,12 @@
   return assistant_overlay_ && feature_allowed && settings_enabled;
 }
 
-bool HomeButtonController::IsVoiceInteractionRunning() {
-  // TODO(b/140823590): Update the method name/description and use Assistant
-  // visibility state instead.
-  return AssistantState::Get()->assistant_state() ==
-         mojom::AssistantState::VISIBLE;
+bool HomeButtonController::IsAssistantVisible() {
+  return Shell::Get()
+             ->assistant_controller()
+             ->ui_controller()
+             ->model()
+             ->visibility() == AssistantVisibility::kVisible;
 }
 
 void HomeButtonController::OnAppListVisibilityChanged(bool shown,
@@ -159,12 +145,12 @@
 
 void HomeButtonController::OnActiveUserSessionChanged(
     const AccountId& account_id) {
-  button_->OnVoiceInteractionAvailabilityChanged();
-  // Initialize voice interaction overlay when primary user session becomes
+  button_->OnAssistantAvailabilityChanged();
+  // Initialize the Assistant overlay when primary user session becomes
   // active.
   if (Shell::Get()->session_controller()->IsUserPrimary() &&
       !assistant_overlay_) {
-    InitializeVoiceInteractionOverlay();
+    InitializeAssistantOverlay();
   }
 }
 
@@ -174,40 +160,14 @@
 
 void HomeButtonController::OnAssistantStatusChanged(
     mojom::AssistantState state) {
-  button_->OnVoiceInteractionAvailabilityChanged();
-
-  if (!assistant_overlay_)
-    return;
-
-  switch (state) {
-    case mojom::AssistantState::READY:
-      UMA_HISTOGRAM_TIMES(
-          "VoiceInteraction.OpenDuration",
-          base::TimeTicks::Now() - voice_interaction_start_timestamp_);
-      break;
-    case mojom::AssistantState::NOT_READY:
-      break;
-    case mojom::AssistantState::VISIBLE:
-      // we start hiding the animation if it is running.
-      if (assistant_overlay_->IsBursting() || assistant_overlay_->IsWaiting()) {
-        assistant_animation_hide_delay_timer_->Start(
-            FROM_HERE,
-            base::TimeDelta::FromMilliseconds(
-                kVoiceInteractionAnimationHideDelayMs),
-            base::BindOnce(&AssistantOverlay::HideAnimation,
-                           base::Unretained(assistant_overlay_)));
-      }
-
-      voice_interaction_start_timestamp_ = base::TimeTicks::Now();
-      break;
-  }
+  button_->OnAssistantAvailabilityChanged();
 }
 
 void HomeButtonController::OnAssistantSettingsEnabled(bool enabled) {
-  button_->OnVoiceInteractionAvailabilityChanged();
+  button_->OnAssistantAvailabilityChanged();
 }
 
-void HomeButtonController::StartVoiceInteractionAnimation() {
+void HomeButtonController::StartAssistantAnimation() {
   assistant_overlay_->StartAnimation(false);
 }
 
@@ -228,13 +188,10 @@
       ->UpdateShelfVisibility();
 }
 
-void HomeButtonController::InitializeVoiceInteractionOverlay() {
+void HomeButtonController::InitializeAssistantOverlay() {
   assistant_overlay_ = new AssistantOverlay(button_);
   button_->AddChildView(assistant_overlay_);
   assistant_overlay_->SetVisible(false);
-  assistant_animation_delay_timer_ = std::make_unique<base::OneShotTimer>();
-  assistant_animation_hide_delay_timer_ =
-      std::make_unique<base::OneShotTimer>();
 }
 
 }  // namespace ash
diff --git a/ash/shelf/home_button_controller.h b/ash/shelf/home_button_controller.h
index d54cb1d4..dd17a841 100644
--- a/ash/shelf/home_button_controller.h
+++ b/ash/shelf/home_button_controller.h
@@ -13,10 +13,6 @@
 #include "ash/session/session_observer.h"
 #include "base/macros.h"
 
-namespace base {
-class OneShotTimer;
-}  // namespace base
-
 namespace ui {
 class GestureEvent;
 }  // namespace ui
@@ -37,16 +33,16 @@
   explicit HomeButtonController(HomeButton* button);
   ~HomeButtonController() override;
 
-  // Maybe handles a gesture event based on the event and whether voice
-  // interaction is available. Returns true if the event is consumed; otherwise,
-  // HomeButton should pass the event along to Button to consume.
+  // Maybe handles a gesture event based on the event and whether the Assistant
+  // is available. Returns true if the event is consumed; otherwise, HomeButton
+  // should pass the event along to Button to consume.
   bool MaybeHandleGestureEvent(ui::GestureEvent* event);
 
-  // Whether voice interaction is available via long-press.
-  bool IsVoiceInteractionAvailable();
+  // Whether the Assistant is available via long-press.
+  bool IsAssistantAvailable();
 
-  // Whether voice interaction is currently running.
-  bool IsVoiceInteractionRunning();
+  // Whether the Assistant UI currently showing.
+  bool IsAssistantVisible();
 
   bool is_showing_app_list() const { return is_showing_app_list_; }
 
@@ -67,10 +63,10 @@
   void OnAppListShown();
   void OnAppListDismissed();
 
-  void StartVoiceInteractionAnimation();
+  void StartAssistantAnimation();
 
-  // Initialize the voice interaction overlay.
-  void InitializeVoiceInteractionOverlay();
+  // Initialize the Assistant overlay.
+  void InitializeAssistantOverlay();
 
   // True if the app list is currently showing for the button's display.
   // This is useful because other app_list_visible functions aren't per-display.
@@ -79,12 +75,9 @@
   // The button that owns this controller.
   HomeButton* const button_;
 
-  // Owned by the button's view hierarchy. Null if voice interaction is not
+  // Owned by the button's view hierarchy. Null if the Assistant is not
   // enabled.
   AssistantOverlay* assistant_overlay_ = nullptr;
-  std::unique_ptr<base::OneShotTimer> assistant_animation_delay_timer_;
-  std::unique_ptr<base::OneShotTimer> assistant_animation_hide_delay_timer_;
-  base::TimeTicks voice_interaction_start_timestamp_;
 
   DISALLOW_COPY_AND_ASSIGN(HomeButtonController);
 };
diff --git a/ash/system/palette/palette_tray_unittest.cc b/ash/system/palette/palette_tray_unittest.cc
index d8313cdd..51cdba3 100644
--- a/ash/system/palette/palette_tray_unittest.cc
+++ b/ash/system/palette/palette_tray_unittest.cc
@@ -337,7 +337,7 @@
 TEST_F(PaletteTrayTestWithAssistant, MetalayerToolActivatesHighlighter) {
   ui::ScopedAnimationDurationScaleMode animation_duration_mode(
       ui::ScopedAnimationDurationScaleMode::NON_ZERO_DURATION);
-  assistant_state()->NotifyStatusChanged(mojom::AssistantState::VISIBLE);
+  assistant_state()->NotifyStatusChanged(mojom::AssistantState::READY);
   prefs()->SetBoolean(chromeos::assistant::prefs::kAssistantEnabled, true);
   prefs()->SetBoolean(chromeos::assistant::prefs::kAssistantContextEnabled,
                       true);
@@ -452,7 +452,7 @@
                              false /* no highlighter on press */);
 
   // Once the service is ready, the button should start working.
-  assistant_state()->NotifyStatusChanged(mojom::AssistantState::VISIBLE);
+  assistant_state()->NotifyStatusChanged(mojom::AssistantState::READY);
 
   // Press and drag with no button, still no highlighter.
   WaitDragAndAssertMetalayer("all enabled, no button ", origin, ui::EF_NONE,
diff --git a/ash/system/palette/tools/metalayer_unittest.cc b/ash/system/palette/tools/metalayer_unittest.cc
index dcde9f70..b7aff2f 100644
--- a/ash/system/palette/tools/metalayer_unittest.cc
+++ b/ash/system/palette/tools/metalayer_unittest.cc
@@ -71,8 +71,7 @@
 // has enabled the metalayer AND the voice interaction framework is ready.
 TEST_F(MetalayerToolTest, PaletteMenuState) {
   const mojom::AssistantState kStates[] = {mojom::AssistantState::NOT_READY,
-                                           mojom::AssistantState::READY,
-                                           mojom::AssistantState::VISIBLE};
+                                           mojom::AssistantState::READY};
   const mojom::AssistantAllowedState kAllowedStates[] = {
       mojom::AssistantAllowedState::ALLOWED,
       mojom::AssistantAllowedState::DISALLOWED_BY_POLICY,
@@ -144,7 +143,6 @@
 
 // Verifies that disabling the metalayer support disables the tool.
 TEST_F(MetalayerToolTest, MetalayerUnsupportedDisablesPaletteTool) {
-  assistant_state()->NotifyStatusChanged(mojom::AssistantState::VISIBLE);
   prefs()->SetBoolean(chromeos::assistant::prefs::kAssistantEnabled, true);
   prefs()->SetBoolean(chromeos::assistant::prefs::kAssistantContextEnabled,
                       true);
@@ -175,7 +173,6 @@
               DisableTool(PaletteToolId::METALAYER))
       .Times(0);
   assistant_state()->NotifyStatusChanged(mojom::AssistantState::READY);
-  assistant_state()->NotifyStatusChanged(mojom::AssistantState::VISIBLE);
   testing::Mock::VerifyAndClearExpectations(palette_tool_delegate_.get());
 
   // Changing the state to NOT_READY should disable the tool.
diff --git a/base/android/proguard/chromium_apk.flags b/base/android/proguard/chromium_apk.flags
index 36052e1..9025bc8 100644
--- a/base/android/proguard/chromium_apk.flags
+++ b/base/android/proguard/chromium_apk.flags
@@ -65,11 +65,6 @@
 # ~1%, and reduces the method count by ~4%.
 -allowaccessmodification
 
-# The support library contains references to newer platform versions.
-# Don't warn about those in case this app is linking against an older
-# platform version.  We know about them, and they are safe.
--dontwarn android.support.**
-
 # Ensure @RemovableInRelease actually works.
 -checkdiscard class ** {
   @org.chromium.base.annotations.RemovableInRelease *;
diff --git a/base/android/proguard/chromium_code.flags b/base/android/proguard/chromium_code.flags
index 983dbd5..a9f4e38 100644
--- a/base/android/proguard/chromium_code.flags
+++ b/base/android/proguard/chromium_code.flags
@@ -50,9 +50,12 @@
 -assumenosideeffects class ** {
   # Remove @RemovableInRelease methods so long as return values are unused.
   @org.chromium.base.annotations.RemovableInRelease <methods>;
+}
+
+-assumevalues class ** {
   # Remove object @RemovableInRelease methods even when return value is used.
-  # Note: * in return type does not match primitives.
-  @org.chromium.base.annotations.RemovableInRelease * *(...) return null;
+  # Note: ** in return type does not match primitives.
+  @org.chromium.base.annotations.RemovableInRelease ** *(...) return null;
   # Remove boolean @RemovableInRelease methods even when return value is used.
   @org.chromium.base.annotations.RemovableInRelease boolean *(...) return false;
 }
diff --git a/base/task/post_job.cc b/base/task/post_job.cc
index e57b32e..3b4eedb 100644
--- a/base/task/post_job.cc
+++ b/base/task/post_job.cc
@@ -42,6 +42,7 @@
   AssertExpectedConcurrency(recorded_max_concurrency_);
 #endif  // DCHECK_IS_ON()
   const bool should_yield =
+      task_source_->ShouldYield() ||
       pooled_task_runner_delegate_->ShouldYield(task_source_);
 
 #if DCHECK_IS_ON()
diff --git a/base/task/thread_pool/job_task_source.cc b/base/task/thread_pool/job_task_source.cc
index c6e5f97..bac8130 100644
--- a/base/task/thread_pool/job_task_source.cc
+++ b/base/task/thread_pool/job_task_source.cc
@@ -19,6 +19,39 @@
 namespace base {
 namespace internal {
 
+JobTaskSource::State::State() = default;
+JobTaskSource::State::~State() = default;
+
+JobTaskSource::State::Value JobTaskSource::State::Cancel() {
+  return {value_.fetch_or(kCanceledMask, std::memory_order_relaxed)};
+}
+
+JobTaskSource::State::Value
+JobTaskSource::State::TryIncrementWorkerCountRelease(size_t max_concurrency) {
+  uint32_t value_before_add = value_.load(std::memory_order_relaxed);
+
+  // std::memory_order_release on success to establish Release-Acquire ordering
+  // with DecrementWorkerCountAcquire() (see WillRunTask()).
+  while (!(value_before_add & kCanceledMask) &&
+         (value_before_add >> kWorkerCountBitOffset) < max_concurrency &&
+         !value_.compare_exchange_weak(
+             value_before_add, value_before_add + kWorkerCountIncrement,
+             std::memory_order_release, std::memory_order_relaxed)) {
+  }
+  return {value_before_add};
+}
+
+JobTaskSource::State::Value
+JobTaskSource::State::DecrementWorkerCountAcquire() {
+  const size_t value_before_sub = value_.fetch_sub(kWorkerCountIncrement);
+  DCHECK((value_before_sub >> kWorkerCountBitOffset) > 0);
+  return {value_before_sub};
+}
+
+JobTaskSource::State::Value JobTaskSource::State::Load() const {
+  return {value_.load(std::memory_order_relaxed)};
+}
+
 JobTaskSource::JobTaskSource(
     const Location& from_here,
     const TaskTraits& traits,
@@ -44,48 +77,46 @@
 }
 
 JobTaskSource::~JobTaskSource() {
-#if DCHECK_IS_ON()
-  auto worker_count = worker_count_.load(std::memory_order_relaxed);
   // Make sure there's no outstanding active run operation left.
-  DCHECK(worker_count == 0U || worker_count == kInvalidWorkerCount)
-      << worker_count;
-#endif
+  DCHECK_EQ(state_.Load().worker_count(), 0U);
 }
 
 ExecutionEnvironment JobTaskSource::GetExecutionEnvironment() {
   return {SequenceToken::Create(), nullptr};
 }
 
+void JobTaskSource::Cancel(TaskSource::Transaction* transaction) {
+  // Sets the kCanceledMask bit on |state_| so that further calls to
+  // WillRunTask() never succeed. std::memory_order_relaxed is sufficient
+  // because this task source never needs to be re-enqueued after Cancel().
+  state_.Cancel();
+}
+
 TaskSource::RunStatus JobTaskSource::WillRunTask() {
   // When this call is caused by an increase of max concurrency followed by an
   // associated NotifyConcurrencyIncrease(), the priority queue lock guarantees
   // an happens-after relation with NotifyConcurrencyIncrease(). The memory
-  // operations on |worker_count| below and in DidProcessTask() use
+  // operations on |state| below and in DidProcessTask() use
   // std::memory_order_release and std::memory_order_acquire respectively to
   // establish a Release-Acquire ordering. This ensures that all memory
   // side-effects made before this point, including an increase of max
   // concurrency followed by NotifyConcurrencyIncrease() are visible to a
   // DidProcessTask() call which is ordered after this one.
   const size_t max_concurrency = GetMaxConcurrency();
-  size_t worker_count_before_add =
-      worker_count_.load(std::memory_order_relaxed);
+  const auto state_before_add =
+      state_.TryIncrementWorkerCountRelease(max_concurrency);
 
-  // std::memory_order_release on success to make the newest |max_concurrency|
-  // visible to a thread that calls DidProcessTask() containing a matching
-  // std::memory_order_acquire.
-  while (worker_count_before_add < max_concurrency &&
-         !worker_count_.compare_exchange_weak(
-             worker_count_before_add, worker_count_before_add + 1,
-             std::memory_order_release, std::memory_order_relaxed)) {
-  }
   // Don't allow this worker to run the task if either:
-  //   A) |worker_count_| is already at |max_concurrency|.
-  //   B) |max_concurrency| was lowered below or to |worker_count_|.
-  //   C) |worker_count_| was invalidated.
-  if (worker_count_before_add >= max_concurrency) {
-    // The caller is prevented from running a task from this TaskSource.
+  //   A) |state_| was canceled.
+  //   B) |worker_count| is already at |max_concurrency|.
+  //   C) |max_concurrency| was lowered below or to |worker_count|.
+  // Case A:
+  if (state_before_add.is_canceled())
     return RunStatus::kDisallowed;
-  }
+  const size_t worker_count_before_add = state_before_add.worker_count();
+  // Case B) or C):
+  if (worker_count_before_add >= max_concurrency)
+    return RunStatus::kDisallowed;
 
   DCHECK_LT(worker_count_before_add, max_concurrency);
   return max_concurrency == worker_count_before_add + 1
@@ -96,12 +127,12 @@
 size_t JobTaskSource::GetRemainingConcurrency() const {
   // std::memory_order_relaxed is sufficient because no other state is
   // synchronized with GetRemainingConcurrency().
-  const size_t worker_count = worker_count_.load(std::memory_order_relaxed);
+  const auto state = state_.Load();
   const size_t max_concurrency = GetMaxConcurrency();
   // Avoid underflows.
-  if (worker_count > max_concurrency)
+  if (state.is_canceled() || state.worker_count() > max_concurrency)
     return 0;
-  return max_concurrency - worker_count;
+  return max_concurrency - state.worker_count();
 }
 
 void JobTaskSource::NotifyConcurrencyIncrease() {
@@ -125,6 +156,10 @@
   return max_concurrency_callback_.Run();
 }
 
+bool JobTaskSource::ShouldYield() const {
+  return state_.Load().is_canceled();
+}
+
 #if DCHECK_IS_ON()
 
 size_t JobTaskSource::GetConcurrencyIncreaseVersion() const {
@@ -151,16 +186,15 @@
 #endif  // DCHECK_IS_ON()
 
 Optional<Task> JobTaskSource::TakeTask(TaskSource::Transaction* transaction) {
-  DCHECK_GT(worker_count_.load(std::memory_order_relaxed), 0U);
+  // JobTaskSource members are not lock-protected so no need to acquire a lock
+  // if |transaction| is nullptr.
+  DCHECK_GT(state_.Load().worker_count(), 0U);
   DCHECK(worker_task_);
   return base::make_optional<Task>(from_here_, worker_task_, TimeDelta());
 }
 
 bool JobTaskSource::DidProcessTask(TaskSource::Transaction* transaction) {
-  size_t worker_count_before_sub =
-      worker_count_.load(std::memory_order_relaxed);
-
-  // std::memory_order_acquire on |worker_count_| is necessary to establish
+  // std::memory_order_acquire on |state_| is necessary to establish
   // Release-Acquire ordering (see WillRunTask()).
   // When the task source needs to be queued, either because the current task
   // yielded or because of NotifyConcurrencyIncrease(), one of the following is
@@ -169,7 +203,7 @@
   //      extra work yet): Incorrectly returning false is fine and the memory
   //      barrier may be ineffective.
   //   B) The JobTaskSource() is no longer in the queue: The Release-Acquire
-  //      ordering with WillRunTask() established by |worker_count| ensures that
+  //      ordering with WillRunTask() established by |state_| ensures that
   //      the upcoming call for GetMaxConcurrency() happens-after any
   //      NotifyConcurrencyIncrease() that happened-before WillRunTask(). If
   //      this task completed because it yielded, this barrier guarantees that
@@ -177,19 +211,17 @@
   //
   // Note that stale values the other way around (incorrectly re-enqueuing) are
   // not an issue because the queues support empty task sources.
-  while (worker_count_before_sub != kInvalidWorkerCount &&
-         !worker_count_.compare_exchange_weak(
-             worker_count_before_sub, worker_count_before_sub - 1,
-             std::memory_order_acquire, std::memory_order_relaxed)) {
-  }
-  if (worker_count_before_sub == kInvalidWorkerCount)
+  const auto state_before_sub = state_.DecrementWorkerCountAcquire();
+
+  // A canceled task source should never get re-enqueued.
+  if (state_before_sub.is_canceled())
     return false;
 
-  DCHECK_GT(worker_count_before_sub, 0U);
+  DCHECK_GT(state_before_sub.worker_count(), 0U);
 
   // Re-enqueue the TaskSource if the task ran and the worker count is below the
   // max concurrency.
-  return worker_count_before_sub <= GetMaxConcurrency();
+  return state_before_sub.worker_count() <= GetMaxConcurrency();
 }
 
 SequenceSortKey JobTaskSource::GetSortKey() const {
@@ -197,12 +229,7 @@
 }
 
 Optional<Task> JobTaskSource::Clear(TaskSource::Transaction* transaction) {
-  // Invalidate |worker_count_| so that further calls to WillRunTask() never
-  // succeed. std::memory_order_relaxed is sufficient because this task source
-  // never needs to be re-enqueued after Clear().
-  size_t worker_count_before_store =
-      worker_count_.exchange(kInvalidWorkerCount, std::memory_order_relaxed);
-  DCHECK_GT(worker_count_before_store, 0U);
+  Cancel();
   // Nothing is cleared since other workers might still racily run tasks. For
   // simplicity, the destructor will take care of it once all references are
   // released.
diff --git a/base/task/thread_pool/job_task_source.h b/base/task/thread_pool/job_task_source.h
index ddaca19..501dbeb 100644
--- a/base/task/thread_pool/job_task_source.h
+++ b/base/task/thread_pool/job_task_source.h
@@ -42,6 +42,10 @@
   // number of worker should be adjusted.
   void NotifyConcurrencyIncrease();
 
+  // Cancels this JobTaskSource, causing all workers to yield and WillRunTask()
+  // to return RunStatus::kDisallowed.
+  void Cancel(TaskSource::Transaction* transaction = nullptr);
+
   // TaskSource:
   ExecutionEnvironment GetExecutionEnvironment() override;
   size_t GetRemainingConcurrency() const override;
@@ -50,6 +54,10 @@
   // concurrently.
   size_t GetMaxConcurrency() const;
 
+  // Returns true if a worker should return from the worker task on the current
+  // thread ASAP.
+  bool ShouldYield() const;
+
 #if DCHECK_IS_ON()
   size_t GetConcurrencyIncreaseVersion() const;
   // Returns true if the concurrency version was updated above
@@ -58,8 +66,44 @@
 #endif  // DCHECK_IS_ON()
 
  private:
-  static constexpr size_t kInvalidWorkerCount =
-      std::numeric_limits<size_t>::max();
+  // Atomic internal state to track the number of workers running a task from
+  // this JobTaskSource and whether this JobTaskSource is canceled.
+  class State {
+   public:
+    static constexpr size_t kCanceledMask = 1;
+    static constexpr size_t kWorkerCountBitOffset = 1;
+    static constexpr size_t kWorkerCountIncrement = 1 << kWorkerCountBitOffset;
+
+    struct Value {
+      size_t worker_count() const { return value >> kWorkerCountBitOffset; }
+      // Returns true if canceled.
+      bool is_canceled() const { return value & kCanceledMask; }
+
+      uint32_t value;
+    };
+
+    State();
+    ~State();
+
+    // Sets as canceled using std::memory_order_relaxed. Returns the state
+    // before the operation.
+    Value Cancel();
+
+    // Increments the worker count by 1 if smaller than |max_concurrency| and if
+    // |!is_canceled()|, using std::memory_order_release, and returns the state
+    // before the operation. Equivalent to Load() otherwise.
+    Value TryIncrementWorkerCountRelease(size_t max_concurrency);
+
+    // Decrements the worker count by 1 using std::memory_order_acquire. Returns
+    // the state before the operation.
+    Value DecrementWorkerCountAcquire();
+
+    // Loads and returns the state, using std::memory_order_relaxed.
+    Value Load() const;
+
+   private:
+    std::atomic<uint32_t> value_{0};
+  };
 
   ~JobTaskSource() override;
 
@@ -70,9 +114,8 @@
   bool DidProcessTask(TaskSource::Transaction* transaction) override;
   SequenceSortKey GetSortKey() const override;
 
-  // The current number of workers concurrently running tasks from this
-  // TaskSource.
-  std::atomic_size_t worker_count_{0U};
+  // Current atomic state.
+  State state_;
 
   const Location from_here_;
   base::RepeatingCallback<size_t()> max_concurrency_callback_;
diff --git a/base/task/thread_pool/job_task_source_unittest.cc b/base/task/thread_pool/job_task_source_unittest.cc
index 31dc2c0..b1a0ea8 100644
--- a/base/task/thread_pool/job_task_source_unittest.cc
+++ b/base/task/thread_pool/job_task_source_unittest.cc
@@ -108,6 +108,8 @@
   EXPECT_EQ(registered_task_source_d.WillRunTask(),
             TaskSource::RunStatus::kAllowedNotSaturated);
 
+  EXPECT_FALSE(task_source->ShouldYield());
+
   {
     EXPECT_EQ(1U, task_source->GetRemainingConcurrency());
     auto task = registered_task_source_c.Clear();
@@ -116,6 +118,7 @@
     EXPECT_EQ(0U, task_source->GetRemainingConcurrency());
   }
   // The task source shouldn't allow any further tasks after Clear.
+  EXPECT_TRUE(task_source->ShouldYield());
   EXPECT_EQ(RegisteredTaskSource::CreateForTesting(task_source).WillRunTask(),
             TaskSource::RunStatus::kDisallowed);
 
@@ -131,15 +134,53 @@
   std::move(task_a->task).Run();
   registered_task_source_a.DidProcessTask();
 
-  // A valid outstanding RunStatus can also take & run a task.
+  // A valid outstanding RunStatus can also take and run a task.
   {
     auto task = registered_task_source_b.TakeTask();
     std::move(task->task).Run();
     registered_task_source_b.DidProcessTask();
   }
-  // Sanity check.
+}
+
+// Verifies that a job task source doesn't return an "allowed" RunStatus after
+// Cancel() is called.
+TEST_F(ThreadPoolJobTaskSourceTest, Cancel) {
+  auto job_task = base::MakeRefCounted<test::MockJobTask>(
+      DoNothing(), /* num_tasks_to_run */ 3);
+  scoped_refptr<JobTaskSource> task_source = job_task->GetJobTaskSource(
+      FROM_HERE, {ThreadPool(), TaskPriority::BEST_EFFORT},
+      &pooled_task_runner_delegate_);
+
+  auto registered_task_source_a =
+      RegisteredTaskSource::CreateForTesting(task_source);
+  EXPECT_EQ(registered_task_source_a.WillRunTask(),
+            TaskSource::RunStatus::kAllowedNotSaturated);
+  auto task_a = registered_task_source_a.TakeTask();
+
+  auto registered_task_source_b =
+      RegisteredTaskSource::CreateForTesting(task_source);
+  EXPECT_EQ(registered_task_source_b.WillRunTask(),
+            TaskSource::RunStatus::kAllowedNotSaturated);
+
+  EXPECT_FALSE(task_source->ShouldYield());
+
+  task_source->Cancel();
+  EXPECT_TRUE(task_source->ShouldYield());
+
+  // The task source shouldn't allow any further tasks after Cancel.
   EXPECT_EQ(RegisteredTaskSource::CreateForTesting(task_source).WillRunTask(),
             TaskSource::RunStatus::kDisallowed);
+
+  // A task that was already acquired can still run.
+  std::move(task_a->task).Run();
+  registered_task_source_a.DidProcessTask();
+
+  // A RegisteredTaskSource that's ready can also take and run a task.
+  {
+    auto task = registered_task_source_b.TakeTask();
+    std::move(task->task).Run();
+    registered_task_source_b.DidProcessTask();
+  }
 }
 
 // Verifies that multiple tasks can run in parallel up to |max_concurrency|.
diff --git a/base/task/thread_pool/thread_group_unittest.cc b/base/task/thread_pool/thread_group_unittest.cc
index cb4481c3..2fc78ae 100644
--- a/base/task/thread_pool/thread_group_unittest.cc
+++ b/base/task/thread_pool/thread_group_unittest.cc
@@ -53,6 +53,7 @@
 #endif
 
 constexpr size_t kMaxTasks = 4;
+constexpr size_t kTooManyTasks = 1000;
 // By default, tests allow half of the thread group to be used by best-effort
 // tasks.
 constexpr size_t kMaxBestEffortTasks = kMaxTasks / 2;
@@ -654,6 +655,48 @@
   task_tracker_.FlushForTesting();
 }
 
+// Verify that Cancel() on a job stops running the worker task and causes
+// current workers to yield.
+TEST_P(ThreadGroupTest, CancelJobTaskSource) {
+  StartThreadGroup();
+
+  CheckedLock tasks_running_lock;
+  std::unique_ptr<ConditionVariable> tasks_running_cv =
+      tasks_running_lock.CreateConditionVariable();
+  bool tasks_running = false;
+
+  // Schedule a big number of tasks.
+  auto job_task = base::MakeRefCounted<test::MockJobTask>(
+      BindLambdaForTesting([&](experimental::JobDelegate* delegate) {
+        {
+          CheckedAutoLock auto_lock(tasks_running_lock);
+          tasks_running = true;
+        }
+        tasks_running_cv->Signal();
+
+        while (!delegate->ShouldYield()) {
+        }
+      }),
+      /* num_tasks_to_run */ kTooManyTasks);
+  scoped_refptr<JobTaskSource> task_source = job_task->GetJobTaskSource(
+      FROM_HERE, {ThreadPool()}, &mock_pooled_task_runner_delegate_);
+
+  mock_pooled_task_runner_delegate_.EnqueueJobTaskSource(task_source);
+
+  // Wait for at least 1 task to start running.
+  {
+    CheckedAutoLock auto_lock(tasks_running_lock);
+    while (!tasks_running)
+      tasks_running_cv->Wait();
+  }
+
+  // Cancels pending tasks and unblocks running ones.
+  task_source->Cancel();
+
+  // This should not block since the job got cancelled.
+  task_tracker_.FlushForTesting();
+}
+
 // Verify that calling JobTaskSource::NotifyConcurrencyIncrease() (re-)schedule
 // tasks with the intended concurrency.
 TEST_P(ThreadGroupTest, JobTaskSourceConcurrencyIncrease) {
diff --git a/base/test/launcher/test_launcher.cc b/base/test/launcher/test_launcher.cc
index ae4acad..6192ee64 100644
--- a/base/test/launcher/test_launcher.cc
+++ b/base/test/launcher/test_launcher.cc
@@ -1752,6 +1752,12 @@
   }
 
   // Default to the number of processor cores.
+#if defined(OS_WIN)
+  // Use processors in all groups (Windows splits more than 64 logical
+  // processors into groups).
+  return base::checked_cast<size_t>(
+      ::GetActiveProcessorCount(ALL_PROCESSOR_GROUPS));
+#endif
   return base::checked_cast<size_t>(SysInfo::NumberOfProcessors());
 }
 
diff --git a/base/threading/platform_thread_unittest.cc b/base/threading/platform_thread_unittest.cc
index 2ef69fe3..96ea662 100644
--- a/base/threading/platform_thread_unittest.cc
+++ b/base/threading/platform_thread_unittest.cc
@@ -289,9 +289,7 @@
 #if defined(OS_WIN)
 // Test changing a created thread's priority, with the
 // kWindowsThreadModeBackground feature enabled.
-// Flaky: https://crbug.com/931706
-TEST(PlatformThreadTest,
-     DISABLED_SetCurrentThreadPriorityWithThreadModeBackground) {
+TEST(PlatformThreadTest, SetCurrentThreadPriorityWithThreadModeBackground) {
   test::ScopedFeatureList scoped_feature_list;
   scoped_feature_list.InitAndEnableFeature(
       features::kWindowsThreadModeBackground);
@@ -301,9 +299,8 @@
 // Test changing a created thread's priority, with the
 // kWindowsThreadModeBackground feature enabled, in an IDLE_PRIORITY_CLASS
 // process (regression test for https://crbug.com/901483).
-// Flaky: https://crbug.com/931706
 TEST(PlatformThreadTest,
-     DISABLED_SetCurrentThreadPriorityWithThreadModeBackgroundIdleProcess) {
+     SetCurrentThreadPriorityWithThreadModeBackgroundIdleProcess) {
   ::SetPriorityClass(Process::Current().Handle(), IDLE_PRIORITY_CLASS);
 
   test::ScopedFeatureList scoped_feature_list;
diff --git a/base/threading/platform_thread_win_unittest.cc b/base/threading/platform_thread_win_unittest.cc
index 15c9939..4c798fa00 100644
--- a/base/threading/platform_thread_win_unittest.cc
+++ b/base/threading/platform_thread_win_unittest.cc
@@ -24,9 +24,7 @@
 // behavior which we suspect is a Windows kernel bug. If this test starts
 // failing, the mitigation for https://crbug.com/901483 in
 // PlatformThread::SetCurrentThreadPriority() should be revisited.
-// Fails on various windows bots: https://crbug.com/931720.
-TEST(PlatformThreadWinTest,
-     DISABLED_SetBackgroundThreadModeFailsInIdlePriorityProcess) {
+TEST(PlatformThreadWinTest, SetBackgroundThreadModeFailsInIdlePriorityProcess) {
   PlatformThreadHandle::Handle thread_handle =
       PlatformThread::CurrentHandle().platform_handle();
 
diff --git a/build/android/BUILD.gn b/build/android/BUILD.gn
index 957ebb8..3e1f77f 100644
--- a/build/android/BUILD.gn
+++ b/build/android/BUILD.gn
@@ -85,12 +85,14 @@
     "${android_sdk_build_tools}/lib64/libc++.so",
     "${android_sdk_build_tools}/split-select",
     "${android_sdk_root}/platform-tools/adb",
-    "//third_party/android_build_tools/bundletool/bundletool-all-0.10.3.jar",
   ]
   data_deps = [
     ":devil_chromium_py",
   ]
   if (build_with_chromium) {
+    data += [
+      "//third_party/android_build_tools/bundletool/bundletool-all-0.10.3.jar",
+    ]
     data_deps +=
         [ "//third_party/android_platform/development/scripts:stack_py" ]
   }
diff --git a/cc/layers/render_surface_impl.cc b/cc/layers/render_surface_impl.cc
index ca739ac..0e81947 100644
--- a/cc/layers/render_surface_impl.cc
+++ b/cc/layers/render_surface_impl.cc
@@ -452,9 +452,9 @@
     gfx::SizeF mask_uv_size;
     mask_layer->GetContentsResourceId(&mask_resource_id, &mask_texture_size,
                                       &mask_uv_size);
-    gfx::SizeF unclipped_mask_target_size = gfx::ScaleSize(
-        gfx::SizeF(OwningEffectNode()->unscaled_mask_target_size),
-        surface_contents_scale.x(), surface_contents_scale.y());
+    gfx::SizeF unclipped_mask_target_size =
+        gfx::ScaleSize(gfx::SizeF(mask_layer->bounds()),
+                       surface_contents_scale.x(), surface_contents_scale.y());
     // Convert content_rect from target space to normalized mask UV space.
     // Where |unclipped_mask_target_size| maps to |mask_uv_size|.
     mask_uv_rect = gfx::ScaleRect(
diff --git a/cc/paint/paint_canvas.h b/cc/paint/paint_canvas.h
index a8201032..ff5a69b 100644
--- a/cc/paint/paint_canvas.h
+++ b/cc/paint/paint_canvas.h
@@ -50,6 +50,10 @@
   // recording or not, so could be simplified or removed.
   virtual SkImageInfo imageInfo() const = 0;
 
+  virtual void* accessTopLayerPixels(SkImageInfo* info,
+                                     size_t* rowBytes,
+                                     SkIPoint* origin = nullptr) = 0;
+
   // TODO(enne): It would be nice to get rid of flush() entirely, as it
   // doesn't really make sense for recording.  However, this gets used by
   // PaintCanvasVideoRenderer which takes a PaintCanvas to paint both
diff --git a/cc/paint/record_paint_canvas.cc b/cc/paint/record_paint_canvas.cc
index 3b1c610..d53569f7 100644
--- a/cc/paint/record_paint_canvas.cc
+++ b/cc/paint/record_paint_canvas.cc
@@ -28,6 +28,13 @@
   return GetCanvas()->imageInfo();
 }
 
+void* RecordPaintCanvas::accessTopLayerPixels(SkImageInfo* info,
+                                              size_t* rowBytes,
+                                              SkIPoint* origin) {
+  // Modifications to the underlying pixels cannot be saved.
+  return nullptr;
+}
+
 void RecordPaintCanvas::flush() {
   // This is a noop when recording.
 }
diff --git a/cc/paint/record_paint_canvas.h b/cc/paint/record_paint_canvas.h
index 68ad78a..24fb177 100644
--- a/cc/paint/record_paint_canvas.h
+++ b/cc/paint/record_paint_canvas.h
@@ -31,6 +31,10 @@
 
   SkImageInfo imageInfo() const override;
 
+  void* accessTopLayerPixels(SkImageInfo* info,
+                             size_t* rowBytes,
+                             SkIPoint* origin = nullptr) override;
+
   void flush() override;
 
   int save() override;
diff --git a/cc/paint/skia_paint_canvas.cc b/cc/paint/skia_paint_canvas.cc
index 3a6dfbbf..d014d7e 100644
--- a/cc/paint/skia_paint_canvas.cc
+++ b/cc/paint/skia_paint_canvas.cc
@@ -24,12 +24,13 @@
 SkiaPaintCanvas::SkiaPaintCanvas(const SkBitmap& bitmap,
                                  ImageProvider* image_provider)
     : canvas_(new SkCanvas(bitmap)),
+      bitmap_(bitmap),
       owned_(canvas_),
       image_provider_(image_provider) {}
 
 SkiaPaintCanvas::SkiaPaintCanvas(const SkBitmap& bitmap,
                                  const SkSurfaceProps& props)
-    : canvas_(new SkCanvas(bitmap, props)), owned_(canvas_) {}
+    : canvas_(new SkCanvas(bitmap, props)), bitmap_(bitmap), owned_(canvas_) {}
 
 SkiaPaintCanvas::~SkiaPaintCanvas() = default;
 
@@ -37,6 +38,14 @@
   return canvas_->imageInfo();
 }
 
+void* SkiaPaintCanvas::accessTopLayerPixels(SkImageInfo* info,
+                                            size_t* rowBytes,
+                                            SkIPoint* origin) {
+  if (bitmap_.isNull() || bitmap_.isImmutable())
+    return nullptr;
+  return canvas_->accessTopLayerPixels(info, rowBytes, origin);
+}
+
 void SkiaPaintCanvas::flush() {
   canvas_->flush();
 }
diff --git a/cc/paint/skia_paint_canvas.h b/cc/paint/skia_paint_canvas.h
index 6ba29a6..6c567ce 100644
--- a/cc/paint/skia_paint_canvas.h
+++ b/cc/paint/skia_paint_canvas.h
@@ -53,6 +53,10 @@
 
   SkImageInfo imageInfo() const override;
 
+  void* accessTopLayerPixels(SkImageInfo* info,
+                             size_t* rowBytes,
+                             SkIPoint* origin = nullptr) override;
+
   void flush() override;
 
   int save() override;
@@ -130,9 +134,9 @@
                 sk_sp<SkData> data) override;
 
   // Don't shadow non-virtual helper functions.
+  using PaintCanvas::clipPath;
   using PaintCanvas::clipRect;
   using PaintCanvas::clipRRect;
-  using PaintCanvas::clipPath;
   using PaintCanvas::drawColor;
   using PaintCanvas::drawImage;
   using PaintCanvas::drawPicture;
@@ -152,6 +156,7 @@
   }
 
   SkCanvas* canvas_;
+  SkBitmap bitmap_;
   std::unique_ptr<SkCanvas> owned_;
   ImageProvider* image_provider_ = nullptr;
 
diff --git a/cc/test/layer_test_common.h b/cc/test/layer_test_common.h
index 54afb26..38ca9ec9 100644
--- a/cc/test/layer_test_common.h
+++ b/cc/test/layer_test_common.h
@@ -100,7 +100,6 @@
         origin_effect->render_surface_reason = RenderSurfaceReason::kMask;
         origin_effect->is_masked = true;
         origin_effect->mask_layer_id = ptr->id();
-        origin_effect->unscaled_mask_target_size = origin->bounds();
         ptr->SetOffsetToTransformParent(origin->offset_to_transform_parent());
         CopyProperties(origin, ptr);
       }
diff --git a/cc/test/property_tree_test_utils.cc b/cc/test/property_tree_test_utils.cc
index 1142eaa..0d5159a 100644
--- a/cc/test/property_tree_test_utils.cc
+++ b/cc/test/property_tree_test_utils.cc
@@ -141,6 +141,7 @@
   transform_node->should_be_snapped = true;
   transform_node->scrolls = true;
 
+  scroll_tree.SetScrollOffset(layer->element_id(), gfx::ScrollOffset());
   scroll_tree.set_needs_update(true);
   return *node;
 }
@@ -267,11 +268,11 @@
                    scoped_refptr<Layer> outer_viewport_scroll_layer,
                    const gfx::Size& outer_viewport_size) {
   DCHECK(root);
-  bool is_using_layer_lists = root->layer_tree_host()->IsUsingLayerLists();
+  DCHECK_EQ(root, root->layer_tree_host()->root_layer());
+  DCHECK(root->layer_tree_host()->IsUsingLayerLists());
+
   scoped_refptr<Layer> inner_viewport_container_layer = Layer::Create();
   scoped_refptr<Layer> overscroll_elasticity_layer;
-  if (!is_using_layer_lists)
-    overscroll_elasticity_layer = Layer::Create();
   scoped_refptr<Layer> page_scale_layer = Layer::Create();
   scoped_refptr<Layer> inner_viewport_scroll_layer = Layer::Create();
   scoped_refptr<Layer> outer_viewport_container_layer = Layer::Create();
@@ -285,25 +286,15 @@
   outer_viewport_scroll_layer->SetHitTestable(true);
 
   root->AddChild(inner_viewport_container_layer);
-  if (root->layer_tree_host()->IsUsingLayerLists()) {
-    root->AddChild(page_scale_layer);
-    root->AddChild(inner_viewport_scroll_layer);
-    root->AddChild(outer_viewport_container_layer);
-    root->AddChild(outer_viewport_scroll_layer);
-  } else {
-    inner_viewport_container_layer->AddChild(overscroll_elasticity_layer);
-    overscroll_elasticity_layer->AddChild(page_scale_layer);
-    page_scale_layer->AddChild(inner_viewport_scroll_layer);
-    inner_viewport_scroll_layer->AddChild(outer_viewport_container_layer);
-    outer_viewport_container_layer->AddChild(outer_viewport_scroll_layer);
-    root->layer_tree_host()->property_trees()->needs_rebuild = true;
-  }
+  root->AddChild(page_scale_layer);
+  root->AddChild(inner_viewport_scroll_layer);
+  root->AddChild(outer_viewport_container_layer);
+  root->AddChild(outer_viewport_scroll_layer);
 
   root->layer_tree_host()->SetElementIdsForTesting();
   ViewportLayers viewport_layers;
   viewport_layers.overscroll_elasticity_element_id =
-      is_using_layer_lists ? OverscrollElasticityElementId()
-                           : overscroll_elasticity_layer->element_id();
+      OverscrollElasticityElementId();
   viewport_layers.page_scale = page_scale_layer;
   viewport_layers.inner_viewport_container = inner_viewport_container_layer;
   viewport_layers.outer_viewport_container = outer_viewport_container_layer;
@@ -311,12 +302,10 @@
   viewport_layers.outer_viewport_scroll = outer_viewport_scroll_layer;
   root->layer_tree_host()->RegisterViewportLayers(viewport_layers);
 
-  if (root->layer_tree_host()->IsUsingLayerLists()) {
-    SetupViewportProperties(
-        root, page_scale_layer.get(), inner_viewport_container_layer.get(),
-        inner_viewport_scroll_layer.get(), outer_viewport_container_layer.get(),
-        outer_viewport_scroll_layer.get());
-  }
+  SetupViewportProperties(
+      root, page_scale_layer.get(), inner_viewport_container_layer.get(),
+      inner_viewport_scroll_layer.get(), outer_viewport_container_layer.get(),
+      outer_viewport_scroll_layer.get());
 }
 
 void SetupViewport(Layer* root,
@@ -337,6 +326,7 @@
   LayerTreeImpl* layer_tree_impl = root->layer_tree_impl();
   DCHECK(!layer_tree_impl->InnerViewportScrollLayer());
   DCHECK(layer_tree_impl->settings().use_layer_lists);
+  DCHECK_EQ(root, layer_tree_impl->root_layer_for_testing());
 
   std::unique_ptr<LayerImpl> inner_viewport_container_layer =
       LayerImpl::Create(layer_tree_impl, 10000);
diff --git a/cc/trees/effect_node.cc b/cc/trees/effect_node.cc
index 339be0b..0b0a525 100644
--- a/cc/trees/effect_node.cc
+++ b/cc/trees/effect_node.cc
@@ -66,7 +66,6 @@
          HasRenderSurface() == other.HasRenderSurface() &&
          blend_mode == other.blend_mode &&
          surface_contents_scale == other.surface_contents_scale &&
-         unscaled_mask_target_size == other.unscaled_mask_target_size &&
          hidden_by_backface_visibility == other.hidden_by_backface_visibility &&
          double_sided == other.double_sided &&
          trilinear_filtering == other.trilinear_filtering &&
diff --git a/cc/trees/effect_node.h b/cc/trees/effect_node.h
index 0f9d220..51cf4d34 100644
--- a/cc/trees/effect_node.h
+++ b/cc/trees/effect_node.h
@@ -88,8 +88,6 @@
 
   gfx::Vector2dF surface_contents_scale;
 
-  gfx::Size unscaled_mask_target_size;
-
   bool cache_render_surface : 1;
   bool has_copy_request : 1;
   bool hidden_by_backface_visibility : 1;
diff --git a/cc/trees/layer_tree_host.cc b/cc/trees/layer_tree_host.cc
index 30b2b7a5..a480efec 100644
--- a/cc/trees/layer_tree_host.cc
+++ b/cc/trees/layer_tree_host.cc
@@ -200,7 +200,8 @@
   mutator_host_->SetMutatorHostClient(nullptr);
 
   // We must clear any pointers into the layer tree prior to destroying it.
-  RegisterViewportLayers(ViewportLayers());
+  if (IsUsingLayerLists())
+    RegisterViewportLayers(ViewportLayers());
 
   if (root_layer_) {
     root_layer_->SetLayerTreeHost(nullptr);
@@ -801,13 +802,7 @@
   // need to be built here.
   if (!IsUsingLayerLists()) {
     TRACE_EVENT0("cc", "LayerTreeHost::UpdateLayers::BuildPropertyTrees");
-    Layer* page_scale_layer = viewport_layers_.page_scale.get();
-    gfx::Transform identity_transform;
-    PropertyTreeBuilder::BuildPropertyTrees(
-        root_layer_.get(), page_scale_layer, inner_viewport_scroll_layer(),
-        outer_viewport_scroll_layer(), overscroll_elasticity_element_id(),
-        elastic_overscroll_, page_scale_factor_, device_scale_factor_,
-        device_viewport_rect_, identity_transform, &property_trees_);
+    PropertyTreeBuilder::BuildPropertyTrees(this);
     TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("cc.debug"),
                          "LayerTreeHost::UpdateLayers_BuiltPropertyTrees",
                          TRACE_EVENT_SCOPE_THREAD, "property_trees",
@@ -1110,12 +1105,7 @@
   //     overscroll elasticity (optional)
   //       page scale
   //         inner viewport scroll
-  DCHECK(IsUsingLayerLists() || !layers.page_scale ||
-         layers.inner_viewport_scroll->parent() == layers.page_scale);
-  DCHECK(IsUsingLayerLists() || !layers.page_scale ||
-         layers.page_scale->parent()->element_id() ==
-             layers.overscroll_elasticity_element_id ||
-         layers.page_scale->parent() == layers.inner_viewport_container);
+  DCHECK(IsUsingLayerLists());
   viewport_layers_.overscroll_elasticity_element_id =
       layers.overscroll_elasticity_element_id;
   viewport_layers_.page_scale = layers.page_scale;
@@ -1693,12 +1683,7 @@
 }
 
 void LayerTreeHost::BuildPropertyTreesForTesting() {
-  gfx::Transform identity_transform;
-  PropertyTreeBuilder::BuildPropertyTrees(
-      root_layer(), page_scale_layer(), inner_viewport_scroll_layer(),
-      outer_viewport_scroll_layer(), overscroll_elasticity_element_id(),
-      elastic_overscroll(), page_scale_factor(), device_scale_factor(),
-      device_viewport_rect(), identity_transform, property_trees());
+  PropertyTreeBuilder::BuildPropertyTrees(this);
 }
 
 bool LayerTreeHost::IsElementInPropertyTrees(ElementId element_id,
diff --git a/cc/trees/layer_tree_host_common.cc b/cc/trees/layer_tree_host_common.cc
index a3a63ffd..86e02f9 100644
--- a/cc/trees/layer_tree_host_common.cc
+++ b/cc/trees/layer_tree_host_common.cc
@@ -31,7 +31,6 @@
 LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting::
     CalcDrawPropsMainInputsForTesting(Layer* root_layer,
                                       const gfx::Rect& device_viewport_rect,
-                                      const gfx::Transform& device_transform,
                                       float device_scale_factor,
                                       float page_scale_factor,
                                       const Layer* page_scale_layer,
@@ -39,7 +38,6 @@
                                       const Layer* outer_viewport_scroll_layer)
     : root_layer(root_layer),
       device_viewport_rect(device_viewport_rect),
-      device_transform(device_transform),
       device_scale_factor(device_scale_factor),
       page_scale_factor(page_scale_factor),
       page_scale_layer(page_scale_layer),
@@ -48,24 +46,15 @@
 
 LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting::
     CalcDrawPropsMainInputsForTesting(Layer* root_layer,
-                                      const gfx::Rect& device_viewport_rect,
-                                      const gfx::Transform& device_transform)
+                                      const gfx::Rect& device_viewport_rect)
     : CalcDrawPropsMainInputsForTesting(root_layer,
                                         device_viewport_rect,
-                                        device_transform,
                                         1.f,
                                         1.f,
                                         nullptr,
                                         nullptr,
                                         nullptr) {}
 
-LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting::
-    CalcDrawPropsMainInputsForTesting(Layer* root_layer,
-                                      const gfx::Rect& device_viewport_rect)
-    : CalcDrawPropsMainInputsForTesting(root_layer,
-                                        device_viewport_rect,
-                                        gfx::Transform()) {}
-
 LayerTreeHostCommon::CalcDrawPropsImplInputs::CalcDrawPropsImplInputs(
     LayerImpl* root_layer,
     const gfx::Rect& device_viewport_rect,
@@ -600,13 +589,18 @@
     // unnecessary setting of the flag in layer list mode.
     property_trees->needs_rebuild = false;
   } else {
-    gfx::Vector2dF elastic_overscroll;
+    DCHECK_EQ(1.f, inputs->page_scale_factor);
+    DCHECK(!inputs->page_scale_layer);
+    DCHECK(!inputs->inner_viewport_scroll_layer);
+    DCHECK(!inputs->outer_viewport_scroll_layer);
+    LayerTreeHost* layer_tree_host = inputs->root_layer->layer_tree_host();
+    // TODO(wangxianzhu): Cleanup LayerTreeHostCommon methods and let caller
+    // sets these inputs on LayerTreeHost directly.
+    layer_tree_host->SetViewportRectAndScale(inputs->device_viewport_rect,
+                                             inputs->device_scale_factor,
+                                             viz::LocalSurfaceIdAllocation());
     PropertyTreeBuilder::BuildPropertyTrees(
-        inputs->root_layer, inputs->page_scale_layer,
-        inputs->inner_viewport_scroll_layer,
-        inputs->outer_viewport_scroll_layer, ElementId(), elastic_overscroll,
-        inputs->page_scale_factor, inputs->device_scale_factor,
-        inputs->device_viewport_rect, inputs->device_transform, property_trees);
+        inputs->root_layer->layer_tree_host());
   }
   draw_property_utils::UpdatePropertyTrees(
       inputs->root_layer->layer_tree_host(), property_trees);
diff --git a/cc/trees/layer_tree_host_common.h b/cc/trees/layer_tree_host_common.h
index 6c9dfd5f..9657c46 100644
--- a/cc/trees/layer_tree_host_common.h
+++ b/cc/trees/layer_tree_host_common.h
@@ -38,20 +38,15 @@
    public:
     CalcDrawPropsMainInputsForTesting(Layer* root_layer,
                                       const gfx::Rect& device_viewport_rect,
-                                      const gfx::Transform& device_transform,
                                       float device_scale_factor,
                                       float page_scale_factor,
                                       const Layer* page_scale_layer,
                                       const Layer* inner_viewport_scroll_layer,
                                       const Layer* outer_viewport_scroll_layer);
     CalcDrawPropsMainInputsForTesting(Layer* root_layer,
-                                      const gfx::Rect& device_viewport_rect,
-                                      const gfx::Transform& device_transform);
-    CalcDrawPropsMainInputsForTesting(Layer* root_layer,
                                       const gfx::Rect& device_viewport_rect);
     Layer* root_layer;
     gfx::Rect device_viewport_rect;
-    gfx::Transform device_transform;
     float device_scale_factor;
     float page_scale_factor;
     const Layer* page_scale_layer;
diff --git a/cc/trees/layer_tree_host_common_unittest.cc b/cc/trees/layer_tree_host_common_unittest.cc
index b02852cd..b34f461 100644
--- a/cc/trees/layer_tree_host_common_unittest.cc
+++ b/cc/trees/layer_tree_host_common_unittest.cc
@@ -104,11 +104,11 @@
                                       float device_scale_factor = 1.0f,
                                       float page_scale_factor = 1.0f,
                                       Layer* page_scale_layer = nullptr) {
-    if (!host()->IsUsingLayerLists()) {
-      if (device_scale_factor != host()->device_scale_factor() ||
-          page_scale_factor != host()->page_scale_factor()) {
-        host()->property_trees()->needs_rebuild = true;
-      }
+    if (!host()->IsUsingLayerLists() &&
+        device_scale_factor != host()->device_scale_factor()) {
+      DCHECK_EQ(1.0f, page_scale_factor);
+      DCHECK(!page_scale_layer);
+      host()->property_trees()->needs_rebuild = true;
     }
 
     EXPECT_TRUE(page_scale_layer || (page_scale_factor == 1.f));
@@ -7034,9 +7034,8 @@
 }
 
 // Needs layer tree mode: mask layer.
-TEST_F(LayerTreeHostCommonTestWithLayerTree, DrawPropertyScales) {
+TEST_F(LayerTreeHostCommonTestWithLayerTree, DrawPropertyDeviceScale) {
   auto root = Layer::Create();
-  auto page_scale = Layer::Create();
   auto child1 = Layer::Create();
   auto child2 = Layer::Create();
 
@@ -7055,14 +7054,11 @@
   mask->SetBounds(child1->bounds());
   child1->SetMaskLayer(mask);
 
-  page_scale->AddChild(child1);
-  page_scale->AddChild(child2);
-  root->AddChild(page_scale);
+  root->AddChild(child1);
+  root->AddChild(child2);
   host()->SetRootLayer(root);
   host()->SetElementIdsForTesting();
 
-  CommitAndActivate();
-
   TransformOperations scale;
   scale.AppendScale(5.f, 8.f, 3.f);
 
@@ -7075,12 +7071,75 @@
   CommitAndActivate();
 
   EXPECT_FLOAT_EQ(1.f, ImplOf(root)->GetIdealContentsScale());
-  EXPECT_FLOAT_EQ(1.f, ImplOf(page_scale)->GetIdealContentsScale());
   EXPECT_FLOAT_EQ(3.f, ImplOf(child1)->GetIdealContentsScale());
   EXPECT_FLOAT_EQ(3.f, ImplOf(mask)->GetIdealContentsScale());
   EXPECT_FLOAT_EQ(5.f, ImplOf(child2)->GetIdealContentsScale());
 
   EXPECT_FLOAT_EQ(kNotScaled, GetMaximumAnimationScale(ImplOf(root)));
+  EXPECT_FLOAT_EQ(kNotScaled, GetMaximumAnimationScale(ImplOf(child1)));
+  EXPECT_FLOAT_EQ(8.f, GetMaximumAnimationScale(ImplOf(child2)));
+
+  // Changing device-scale would affect ideal_contents_scale and
+  // maximum_animation_contents_scale.
+
+  float device_scale_factor = 4.0f;
+  CommitAndActivate(device_scale_factor);
+
+  EXPECT_FLOAT_EQ(4.f, ImplOf(root)->GetIdealContentsScale());
+  EXPECT_FLOAT_EQ(12.f, ImplOf(child1)->GetIdealContentsScale());
+  EXPECT_FLOAT_EQ(12.f, ImplOf(mask)->GetIdealContentsScale());
+  EXPECT_FLOAT_EQ(20.f, ImplOf(child2)->GetIdealContentsScale());
+
+  EXPECT_FLOAT_EQ(kNotScaled, GetMaximumAnimationScale(ImplOf(root)));
+  EXPECT_FLOAT_EQ(kNotScaled, GetMaximumAnimationScale(ImplOf(child1)));
+  EXPECT_FLOAT_EQ(32.f, GetMaximumAnimationScale(ImplOf(child2)));
+}
+
+TEST_F(LayerTreeHostCommonTest, DrawPropertyScales) {
+  auto root = Layer::Create();
+  auto page_scale = Layer::Create();
+  auto child1 = Layer::Create();
+  auto child2 = Layer::Create();
+
+  gfx::Transform scale_transform_child1, scale_transform_child2;
+  scale_transform_child1.Scale(2, 3);
+  scale_transform_child2.Scale(4, 5);
+
+  root->SetBounds(gfx::Size(1, 1));
+  root->SetIsDrawable(true);
+  child1->SetBounds(gfx::Size(1, 1));
+  child1->SetIsDrawable(true);
+  child2->SetBounds(gfx::Size(1, 1));
+  child2->SetIsDrawable(true);
+
+  root->AddChild(child1);
+  root->AddChild(child2);
+  root->AddChild(page_scale);
+  host()->SetRootLayer(root);
+  host()->SetElementIdsForTesting();
+
+  SetupRootProperties(root.get());
+  CopyProperties(root.get(), page_scale.get());
+  CreateTransformNode(page_scale.get());
+  CopyProperties(page_scale.get(), child1.get());
+  CreateTransformNode(child1.get()).local = scale_transform_child1;
+  CopyProperties(page_scale.get(), child2.get());
+  CreateTransformNode(child2.get()).local = scale_transform_child2;
+
+  TransformOperations scale;
+  scale.AppendScale(5.f, 8.f, 3.f);
+
+  AddAnimatedTransformToElementWithAnimation(child2->element_id(), timeline(),
+                                             1.0, TransformOperations(), scale);
+
+  CommitAndActivate();
+
+  EXPECT_FLOAT_EQ(1.f, ImplOf(root)->GetIdealContentsScale());
+  EXPECT_FLOAT_EQ(1.f, ImplOf(page_scale)->GetIdealContentsScale());
+  EXPECT_FLOAT_EQ(3.f, ImplOf(child1)->GetIdealContentsScale());
+  EXPECT_FLOAT_EQ(5.f, ImplOf(child2)->GetIdealContentsScale());
+
+  EXPECT_FLOAT_EQ(kNotScaled, GetMaximumAnimationScale(ImplOf(root)));
   EXPECT_FLOAT_EQ(kNotScaled, GetMaximumAnimationScale(ImplOf(page_scale)));
   EXPECT_FLOAT_EQ(kNotScaled, GetMaximumAnimationScale(ImplOf(child1)));
   EXPECT_FLOAT_EQ(8.f, GetMaximumAnimationScale(ImplOf(child2)));
@@ -7095,7 +7154,6 @@
   EXPECT_FLOAT_EQ(1.f, ImplOf(root)->GetIdealContentsScale());
   EXPECT_FLOAT_EQ(3.f, ImplOf(page_scale)->GetIdealContentsScale());
   EXPECT_FLOAT_EQ(9.f, ImplOf(child1)->GetIdealContentsScale());
-  EXPECT_FLOAT_EQ(9.f, ImplOf(mask)->GetIdealContentsScale());
   EXPECT_FLOAT_EQ(15.f, ImplOf(child2)->GetIdealContentsScale());
 
   EXPECT_FLOAT_EQ(kNotScaled, GetMaximumAnimationScale(ImplOf(root)));
@@ -7112,7 +7170,6 @@
   EXPECT_FLOAT_EQ(4.f, ImplOf(root)->GetIdealContentsScale());
   EXPECT_FLOAT_EQ(12.f, ImplOf(page_scale)->GetIdealContentsScale());
   EXPECT_FLOAT_EQ(36.f, ImplOf(child1)->GetIdealContentsScale());
-  EXPECT_FLOAT_EQ(36.f, ImplOf(mask)->GetIdealContentsScale());
   EXPECT_FLOAT_EQ(60.f, ImplOf(child2)->GetIdealContentsScale());
 
   EXPECT_FLOAT_EQ(kNotScaled, GetMaximumAnimationScale(ImplOf(root)));
diff --git a/cc/trees/layer_tree_host_impl.cc b/cc/trees/layer_tree_host_impl.cc
index fd4e8b4..343e0ea 100644
--- a/cc/trees/layer_tree_host_impl.cc
+++ b/cc/trees/layer_tree_host_impl.cc
@@ -1027,11 +1027,13 @@
     base::trace_event::TracedValue* value) const {
   value->SetBoolean("has_no_damage", has_no_damage);
 
-  // Quad data can be quite large, so only dump render passes if we select
-  // viz.quads.
-  bool quads_enabled;
-  TRACE_EVENT_CATEGORY_GROUP_ENABLED(TRACE_DISABLED_BY_DEFAULT("viz.quads"),
-                                     &quads_enabled);
+  // Quad data can be quite large, so only dump render passes if we are
+  // logging verbosely or viz.quads tracing category is enabled.
+  bool quads_enabled = VLOG_IS_ON(3);
+  if (!quads_enabled) {
+    TRACE_EVENT_CATEGORY_GROUP_ENABLED(TRACE_DISABLED_BY_DEFAULT("viz.quads"),
+                                       &quads_enabled);
+  }
   if (quads_enabled) {
     value->BeginArray("render_passes");
     for (size_t i = 0; i < render_passes.size(); ++i) {
@@ -1043,6 +1045,18 @@
   }
 }
 
+std::string LayerTreeHostImpl::FrameData::ToString() const {
+  base::trace_event::TracedValue value;
+  AsValueInto(&value);
+  std::string str;
+  base::JSONWriter::WriteWithOptions(
+      *value.ToBaseValue(),
+      base::JSONWriter::OPTIONS_OMIT_DOUBLE_TYPE_PRESERVATION |
+          base::JSONWriter::OPTIONS_PRETTY_PRINT,
+      &str);
+  return str;
+}
+
 DrawMode LayerTreeHostImpl::GetDrawMode() const {
   if (resourceless_software_draw_) {
     return DRAW_MODE_RESOURCELESS_SOFTWARE;
@@ -1574,6 +1588,15 @@
   }
 
   DrawResult draw_result = CalculateRenderPasses(frame);
+
+  // Dump render passes and draw quads if run with:
+  //   --vmodule=layer_tree_host_impl=3
+  if (VLOG_IS_ON(3)) {
+    VLOG(3) << "Prepare to draw ("
+            << (client_name ? client_name : "<unknown client>") << ")\n"
+            << frame->ToString();
+  }
+
   if (draw_result != DRAW_SUCCESS) {
     DCHECK(!resourceless_software_draw_);
     return draw_result;
diff --git a/cc/trees/layer_tree_host_impl.h b/cc/trees/layer_tree_host_impl.h
index f85ee235..fbdc241 100644
--- a/cc/trees/layer_tree_host_impl.h
+++ b/cc/trees/layer_tree_host_impl.h
@@ -198,6 +198,7 @@
 
     FrameData& operator=(const FrameData&) = delete;
     void AsValueInto(base::trace_event::TracedValue* value) const;
+    std::string ToString() const;
 
     // frame_token is populated by the LayerTreeHostImpl when submitted.
     uint32_t frame_token = 0;
diff --git a/cc/trees/layer_tree_host_impl_unittest.cc b/cc/trees/layer_tree_host_impl_unittest.cc
index 400bb14..90bca1a0 100644
--- a/cc/trees/layer_tree_host_impl_unittest.cc
+++ b/cc/trees/layer_tree_host_impl_unittest.cc
@@ -945,11 +945,11 @@
   auto* root = SetupDefaultRootLayer(gfx::Size(110, 110));
   root->SetHitTestable(true);
   root->SetScrollable(gfx::Size(10, 10));
+  CreateScrollNode(root);
   root->layer_tree_impl()
       ->property_trees()
       ->scroll_tree.UpdateScrollOffsetBaseForTesting(root->element_id(),
                                                      scroll_offset);
-  CreateScrollNode(root);
   UpdateDrawProperties(host_impl_->active_tree());
 
   std::unique_ptr<ScrollAndScaleSet> scroll_info;
diff --git a/cc/trees/layer_tree_host_unittest.cc b/cc/trees/layer_tree_host_unittest.cc
index 5a10a10..81dc18b 100644
--- a/cc/trees/layer_tree_host_unittest.cc
+++ b/cc/trees/layer_tree_host_unittest.cc
@@ -3106,16 +3106,15 @@
 // from LayerTreeHost to LayerTreeHostImpl in the MT compositor.
 class LayerTreeHostTestStartPageScaleAnimation : public LayerTreeHostTest {
  public:
-  LayerTreeHostTestStartPageScaleAnimation() = default;
+  LayerTreeHostTestStartPageScaleAnimation() { SetUseLayerLists(); }
 
   void SetupTree() override {
     LayerTreeHostTest::SetupTree();
 
     Layer* root_layer = layer_tree_host()->root_layer();
 
-    scoped_refptr<FakePictureLayer> layer = FakePictureLayer::Create(&client_);
-    layer->set_always_update_resources(true);
-    scroll_layer_ = layer;
+    scroll_layer_ = FakePictureLayer::Create(&client_);
+    scroll_layer_->set_always_update_resources(true);
 
     scroll_layer_->SetBounds(gfx::Size(2 * root_layer->bounds().width(),
                                        2 * root_layer->bounds().height()));
@@ -3169,7 +3168,7 @@
   }
 
   FakeContentLayerClient client_;
-  scoped_refptr<Layer> scroll_layer_;
+  scoped_refptr<FakePictureLayer> scroll_layer_;
 };
 
 // Single thread proxy does not support impl-side page scale changes.
@@ -3177,28 +3176,16 @@
 
 class ViewportDeltasAppliedDuringPinch : public LayerTreeHostTest {
  protected:
-  ViewportDeltasAppliedDuringPinch() : sent_gesture_(false) {}
+  ViewportDeltasAppliedDuringPinch() : sent_gesture_(false) {
+    SetUseLayerLists();
+  }
 
   void SetupTree() override {
-    scoped_refptr<Layer> root_clip = Layer::Create();
-    root_clip->SetBounds(gfx::Size(500, 500));
-    scoped_refptr<Layer> page_scale_layer = Layer::Create();
-    page_scale_layer->SetBounds(gfx::Size(500, 500));
-
-    scoped_refptr<Layer> pinch = Layer::Create();
-    pinch->SetBounds(gfx::Size(500, 500));
-    pinch->SetScrollable(gfx::Size(200, 200));
-    page_scale_layer->AddChild(pinch);
-    root_clip->AddChild(page_scale_layer);
-
-    ViewportLayers viewport_layers;
-    viewport_layers.page_scale = page_scale_layer;
-    viewport_layers.inner_viewport_container = root_clip;
-    viewport_layers.inner_viewport_scroll = pinch;
-    layer_tree_host()->RegisterViewportLayers(viewport_layers);
-    layer_tree_host()->SetPageScaleFactorAndLimits(1.f, 1.f, 4.f);
-    layer_tree_host()->SetRootLayer(root_clip);
+    SetInitialRootBounds(gfx::Size(200, 200));
     LayerTreeHostTest::SetupTree();
+    Layer* root = layer_tree_host()->root_layer();
+    SetupViewport(root, gfx::Size(500, 500), gfx::Size(500, 500));
+    layer_tree_host()->SetPageScaleFactorAndLimits(1.f, 1.f, 4.f);
   }
 
   void BeginTest() override { PostSetNeedsCommitToMainThread(); }
@@ -5380,45 +5367,26 @@
 class LayerTreeHostTestElasticOverscroll : public LayerTreeHostTest {
  public:
   LayerTreeHostTestElasticOverscroll()
-      : scroll_elasticity_helper_(nullptr), num_draws_(0) {}
+      : scroll_elasticity_helper_(nullptr), num_draws_(0) {
+    SetUseLayerLists();
+  }
 
   void InitializeSettings(LayerTreeSettings* settings) override {
     settings->enable_elastic_overscroll = true;
   }
 
   void SetupTree() override {
-    root_layer_ = Layer::Create();
-    root_layer_->SetBounds(gfx::Size(10, 10));
-
-    scoped_refptr<Layer> inner_viewport_container_layer = Layer::Create();
-    inner_viewport_container_layer->SetBounds(gfx::Size(10, 10));
-    scoped_refptr<Layer> overscroll_elasticity_layer = Layer::Create();
-    overscroll_elasticity_layer->SetElementId(
-        LayerIdToElementIdForTesting(overscroll_elasticity_layer->id()));
-    scoped_refptr<Layer> page_scale_layer = Layer::Create();
-    scoped_refptr<Layer> inner_viewport_scroll_layer = Layer::Create();
-    inner_viewport_scroll_layer->SetScrollable(
-        inner_viewport_container_layer->bounds());
-
-    root_layer_->AddChild(inner_viewport_container_layer);
-    inner_viewport_container_layer->AddChild(overscroll_elasticity_layer);
-    overscroll_elasticity_layer->AddChild(page_scale_layer);
-    page_scale_layer->AddChild(inner_viewport_scroll_layer);
+    LayerTreeHostTest::SetupTree();
+    root_layer_ = layer_tree_host()->root_layer();
+    SetupViewport(root_layer_, root_layer_->bounds(), root_layer_->bounds());
 
     scoped_refptr<Layer> content_layer = FakePictureLayer::Create(&client_);
     content_layer_id_ = content_layer->id();
     content_layer->SetBounds(gfx::Size(10, 10));
-    inner_viewport_scroll_layer->AddChild(content_layer);
+    CopyProperties(layer_tree_host()->outer_viewport_scroll_layer(),
+                   content_layer.get());
+    root_layer_->AddChild(content_layer);
 
-    layer_tree_host()->SetRootLayer(root_layer_);
-    ViewportLayers viewport_layers;
-    viewport_layers.overscroll_elasticity_element_id =
-        overscroll_elasticity_layer->element_id();
-    viewport_layers.page_scale = page_scale_layer;
-    viewport_layers.inner_viewport_container = inner_viewport_container_layer;
-    viewport_layers.inner_viewport_scroll = inner_viewport_scroll_layer;
-    layer_tree_host()->RegisterViewportLayers(viewport_layers);
-    LayerTreeHostTest::SetupTree();
     client_.set_bounds(content_layer->bounds());
   }
 
@@ -5467,7 +5435,7 @@
 
  private:
   FakeContentLayerClient client_;
-  scoped_refptr<Layer> root_layer_;
+  Layer* root_layer_;
   ScrollElasticityHelper* scroll_elasticity_helper_;
   int content_layer_id_;
   int num_draws_;
@@ -6889,23 +6857,19 @@
  protected:
   LayerTreeHostTestCrispUpAfterPinchEnds()
       : playback_allowed_event_(base::WaitableEvent::ResetPolicy::MANUAL,
-                                base::WaitableEvent::InitialState::SIGNALED) {}
+                                base::WaitableEvent::InitialState::SIGNALED) {
+    SetUseLayerLists();
+  }
 
   void SetupTree() override {
     frame_ = 1;
     posted_ = false;
     client_.set_fill_with_nonsolid_color(true);
 
-    scoped_refptr<Layer> root_clip = Layer::Create();
-    root_clip->SetBounds(gfx::Size(500, 500));
-    scoped_refptr<Layer> page_scale_layer = Layer::Create();
-    page_scale_layer->SetBounds(gfx::Size(500, 500));
-
-    scoped_refptr<Layer> pinch = Layer::Create();
-    pinch->SetBounds(gfx::Size(500, 500));
-    pinch->SetScrollable(gfx::Size(500, 500));
-    page_scale_layer->AddChild(pinch);
-    root_clip->AddChild(page_scale_layer);
+    SetInitialRootBounds(gfx::Size(500, 500));
+    LayerTreeHostTest::SetupTree();
+    Layer* root = layer_tree_host()->root_layer();
+    SetupViewport(root, root->bounds(), root->bounds());
 
     std::unique_ptr<FakeRecordingSource> recording(new FakeRecordingSource);
     recording->SetPlaybackAllowedEvent(&playback_allowed_event_);
@@ -6916,17 +6880,12 @@
     layer->SetContentsOpaque(true);
     // Avoid LCD text on the layer so we don't cause extra commits when we
     // pinch.
-    pinch->AddChild(layer);
+    CopyProperties(layer_tree_host()->inner_viewport_scroll_layer(),
+                   layer.get());
+    root->AddChild(layer);
 
-    ViewportLayers viewport_layers;
-    viewport_layers.page_scale = page_scale_layer;
-    viewport_layers.inner_viewport_container = root_clip;
-    viewport_layers.inner_viewport_scroll = pinch;
-    layer_tree_host()->RegisterViewportLayers(viewport_layers);
     layer_tree_host()->SetPageScaleFactorAndLimits(1.f, 1.f, 4.f);
-    layer_tree_host()->SetRootLayer(root_clip);
-    LayerTreeHostTest::SetupTree();
-    client_.set_bounds(root_clip->bounds());
+    client_.set_bounds(root->bounds());
   }
 
   // Returns the delta scale of all quads in the frame's root pass from their
@@ -7193,23 +7152,20 @@
  protected:
   LayerTreeHostTestContinuousDrawWhenCreatingVisibleTiles()
       : playback_allowed_event_(base::WaitableEvent::ResetPolicy::MANUAL,
-                                base::WaitableEvent::InitialState::SIGNALED) {}
+                                base::WaitableEvent::InitialState::SIGNALED) {
+    SetUseLayerLists();
+  }
 
   void SetupTree() override {
     step_ = 1;
     continuous_draws_ = 0;
     client_.set_fill_with_nonsolid_color(true);
 
-    scoped_refptr<Layer> root_clip = Layer::Create();
-    root_clip->SetBounds(gfx::Size(500, 500));
-    scoped_refptr<Layer> page_scale_layer = Layer::Create();
-    page_scale_layer->SetBounds(gfx::Size(500, 500));
+    SetInitialRootBounds(gfx::Size(500, 500));
+    LayerTreeHostTest::SetupTree();
 
-    scoped_refptr<Layer> pinch = Layer::Create();
-    pinch->SetBounds(gfx::Size(500, 500));
-    pinch->SetScrollable(gfx::Size(500, 500));
-    page_scale_layer->AddChild(pinch);
-    root_clip->AddChild(page_scale_layer);
+    Layer* root = layer_tree_host()->root_layer();
+    SetupViewport(root, root->bounds(), root->bounds());
 
     std::unique_ptr<FakeRecordingSource> recording(new FakeRecordingSource);
     recording->SetPlaybackAllowedEvent(&playback_allowed_event_);
@@ -7218,19 +7174,12 @@
                                                     std::move(recording));
     layer->SetBounds(gfx::Size(500, 500));
     layer->SetContentsOpaque(true);
-    // Avoid LCD text on the layer so we don't cause extra commits when we
-    // pinch.
-    pinch->AddChild(layer);
+    CopyProperties(layer_tree_host()->inner_viewport_scroll_layer(),
+                   layer.get());
+    root->AddChild(layer);
 
-    ViewportLayers viewport_layers;
-    viewport_layers.page_scale = page_scale_layer;
-    viewport_layers.inner_viewport_container = root_clip;
-    viewport_layers.inner_viewport_scroll = pinch;
-    layer_tree_host()->RegisterViewportLayers(viewport_layers);
     layer_tree_host()->SetPageScaleFactorAndLimits(1.f, 1.f, 4.f);
-    layer_tree_host()->SetRootLayer(root_clip);
-    LayerTreeHostTest::SetupTree();
-    client_.set_bounds(root_clip->bounds());
+    client_.set_bounds(root->bounds());
   }
 
   // Returns the delta scale of all quads in the frame's root pass from their
@@ -7563,44 +7512,42 @@
 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestUpdateCopyRequests);
 
 class LayerTreeTestPageScaleFlags : public LayerTreeTest {
+ public:
+  LayerTreeTestPageScaleFlags() { SetUseLayerLists(); }
+
  protected:
   void SetupTree() override {
     // -root
     //   -pre page scale
-    //   -page scale
-    //     -inner viewport scroll
-    //       -page scale grandchild
+    //   -viewport layers
     //   -post page scale
 
-    scoped_refptr<Layer> root = Layer::Create();
-    scoped_refptr<Layer> pre_page_scale = Layer::Create();
-    scoped_refptr<Layer> page_scale = Layer::Create();
-    scoped_refptr<Layer> inner_viewport_scroll = Layer::Create();
-    scoped_refptr<Layer> page_scale_grandchild = Layer::Create();
-    scoped_refptr<Layer> post_page_scale = Layer::Create();
+    LayerTreeTest::SetupTree();
+    Layer* root = layer_tree_host()->root_layer();
 
+    scoped_refptr<Layer> pre_page_scale = Layer::Create();
+    CopyProperties(root, pre_page_scale.get());
     root->AddChild(pre_page_scale);
-    root->AddChild(page_scale);
+
+    SetupViewport(root, root->bounds(), root->bounds());
+
+    scoped_refptr<Layer> post_page_scale = Layer::Create();
+    CopyProperties(root, post_page_scale.get());
     root->AddChild(post_page_scale);
 
-    page_scale->AddChild(inner_viewport_scroll);
-    inner_viewport_scroll->AddChild(page_scale_grandchild);
-
-    layer_tree_host()->SetRootLayer(root);
-    LayerTreeTest::SetupTree();
-
-    ViewportLayers viewport_layers;
-    viewport_layers.inner_viewport_container = root;
-    viewport_layers.page_scale = page_scale;
-    viewport_layers.inner_viewport_scroll = inner_viewport_scroll;
-    layer_tree_host()->RegisterViewportLayers(viewport_layers);
-
-    affected_by_page_scale_.push_back(page_scale->id());
-    affected_by_page_scale_.push_back(inner_viewport_scroll->id());
-    affected_by_page_scale_.push_back(page_scale_grandchild->id());
+    affected_by_page_scale_.push_back(
+        layer_tree_host()->page_scale_layer()->id());
+    affected_by_page_scale_.push_back(
+        layer_tree_host()->inner_viewport_scroll_layer()->id());
+    affected_by_page_scale_.push_back(
+        layer_tree_host()->outer_viewport_container_layer()->id());
+    affected_by_page_scale_.push_back(
+        layer_tree_host()->outer_viewport_scroll_layer()->id());
 
     not_affected_by_page_scale_.push_back(root->id());
     not_affected_by_page_scale_.push_back(pre_page_scale->id());
+    not_affected_by_page_scale_.push_back(
+        layer_tree_host()->inner_viewport_container_layer()->id());
     not_affected_by_page_scale_.push_back(post_page_scale->id());
   }
 
@@ -8815,6 +8762,8 @@
 class LayerTreeHostTopControlsDeltaTriggersViewportUpdate
     : public LayerTreeHostTest {
  public:
+  LayerTreeHostTopControlsDeltaTriggersViewportUpdate() { SetUseLayerLists(); }
+
   void BeginTest() override { PostSetNeedsCommitToMainThread(); }
 
   void SetupTree() override {
diff --git a/cc/trees/layer_tree_host_unittest_masks.cc b/cc/trees/layer_tree_host_unittest_masks.cc
index d81d3c3..41a9958 100644
--- a/cc/trees/layer_tree_host_unittest_masks.cc
+++ b/cc/trees/layer_tree_host_unittest_masks.cc
@@ -22,7 +22,9 @@
     // the surface bounds to be larger. It also has a parent that clips the
     // masked layer and its surface.
 
-    scoped_refptr<Layer> root = Layer::Create();
+    SetInitialRootBounds(gfx::Size(100, 100));
+    LayerTreeTest::SetupTree();
+    Layer* root = layer_tree_host()->root_layer();
 
     scoped_refptr<FakePictureLayer> content_layer =
         FakePictureLayer::Create(&client_);
@@ -42,9 +44,6 @@
             &client_, std::move(recording_source));
     content_layer->SetMaskLayer(mask_layer);
 
-    gfx::Size root_size(100, 100);
-    root->SetBounds(root_size);
-
     gfx::Size layer_size(100, 100);
     content_layer->SetBounds(layer_size);
 
@@ -52,16 +51,23 @@
     mask_layer->SetBounds(mask_size);
     mask_layer_id_ = mask_layer->id();
 
-    layer_tree_host()->SetRootLayer(root);
-    LayerTreeTest::SetupTree();
-    scoped_refptr<Layer> outer_viewport_scroll_layer = Layer::Create();
-    outer_viewport_scroll_layer->SetBounds(layer_size);
-    SetupViewport(root.get(), outer_viewport_scroll_layer, gfx::Size(50, 50));
-    layer_tree_host()->outer_viewport_container_layer()->SetMasksToBounds(true);
-    outer_viewport_scroll_layer->AddChild(content_layer);
+    scoped_refptr<Layer> clip_layer = Layer::Create();
+    clip_layer->SetBounds(gfx::Size(50, 50));
+    clip_layer->SetMasksToBounds(true);
+
+    scoped_refptr<Layer> scroll_layer = Layer::Create();
+    scroll_layer->SetBounds(layer_size);
+    scroll_layer->SetScrollable(gfx::Size(50, 50));
+    scroll_layer->SetMasksToBounds(true);
+    scroll_layer->SetElementId(
+        LayerIdToElementIdForTesting(scroll_layer->id()));
+
+    root->AddChild(clip_layer);
+    clip_layer->AddChild(scroll_layer);
+    scroll_layer->AddChild(content_layer);
 
     client_.set_bounds(root->bounds());
-    outer_viewport_scroll_layer->SetScrollOffset(gfx::ScrollOffset(50, 50));
+    scroll_layer->SetScrollOffset(gfx::ScrollOffset(50, 50));
   }
 
   void BeginTest() override { PostSetNeedsCommitToMainThread(); }
diff --git a/cc/trees/layer_tree_host_unittest_scroll.cc b/cc/trees/layer_tree_host_unittest_scroll.cc
index c1063631..fb7a1dcd 100644
--- a/cc/trees/layer_tree_host_unittest_scroll.cc
+++ b/cc/trees/layer_tree_host_unittest_scroll.cc
@@ -75,6 +75,8 @@
 
 class LayerTreeHostScrollTest : public LayerTreeTest {
  protected:
+  LayerTreeHostScrollTest() { SetUseLayerLists(); }
+
   void SetupTree() override {
     LayerTreeTest::SetupTree();
     Layer* root_layer = layer_tree_host()->root_layer();
@@ -84,26 +86,39 @@
                                   root_layer->bounds().height() + 100);
 
     SetupViewport(root_layer, root_layer->bounds(), scroll_layer_bounds);
+    layer_tree_host()->outer_viewport_scroll_layer()->set_did_scroll_callback(
+        base::BindRepeating(&LayerTreeHostScrollTest::DidScrollOuterViewport,
+                            base::Unretained(this)));
   }
+
+  // This is set as did_scroll_callback of scroll layers to automatically
+  // synchronize scroll delta from impl-side, which simulates cc client (e.g.
+  // Blink) behavior when handling impl-side scrolls.
+  void SyncScrollFromImpl(const gfx::ScrollOffset& scroll_offset,
+                          const ElementId& element_id) {
+    SetScrollOffset(layer_tree_host()->LayerByElementId(element_id),
+                    scroll_offset);
+  }
+
+  virtual void DidScrollOuterViewport(const gfx::ScrollOffset& scroll_offset,
+                                      const ElementId& element_id) {
+    SyncScrollFromImpl(scroll_offset, element_id);
+    num_outer_viewport_scrolls_++;
+  }
+
+  int num_outer_viewport_scrolls_ = 0;
 };
 
 class LayerTreeHostScrollTestScrollSimple : public LayerTreeHostScrollTest {
  public:
   LayerTreeHostScrollTestScrollSimple()
-      : initial_scroll_(10, 20),
-        second_scroll_(40, 5),
-        scroll_amount_(2, -1),
-        num_scrolls_(0) {}
+      : initial_scroll_(10, 20), second_scroll_(40, 5), scroll_amount_(2, -1) {}
 
   void BeginTest() override {
     outer_viewport_container_layer_id_ =
         layer_tree_host()->outer_viewport_container_layer()->id();
-    layer_tree_host()->outer_viewport_scroll_layer()->SetScrollOffset(
-        initial_scroll_);
-    layer_tree_host()->outer_viewport_scroll_layer()->set_did_scroll_callback(
-        base::BindRepeating(
-            &LayerTreeHostScrollTestScrollSimple::DidScrollOuterViewport,
-            base::Unretained(this)));
+    SetScrollOffset(layer_tree_host()->outer_viewport_scroll_layer(),
+                    initial_scroll_);
     PostSetNeedsCommitToMainThread();
   }
 
@@ -117,7 +132,7 @@
           scroll_layer->CurrentScrollOffset());
 
       // Pretend like Javascript updated the scroll position itself.
-      scroll_layer->SetScrollOffset(second_scroll_);
+      SetScrollOffset(scroll_layer, second_scroll_);
     }
   }
 
@@ -148,17 +163,12 @@
     }
   }
 
-  void DidScrollOuterViewport(const gfx::ScrollOffset&, const ElementId&) {
-    num_scrolls_++;
-  }
-
-  void AfterTest() override { EXPECT_EQ(1, num_scrolls_); }
+  void AfterTest() override { EXPECT_EQ(1, num_outer_viewport_scrolls_); }
 
  private:
   gfx::ScrollOffset initial_scroll_;
   gfx::ScrollOffset second_scroll_;
   gfx::Vector2dF scroll_amount_;
-  int num_scrolls_;
   int outer_viewport_container_layer_id_;
 };
 
@@ -168,14 +178,11 @@
     : public LayerTreeHostScrollTest {
  public:
   LayerTreeHostScrollTestScrollMultipleRedraw()
-      : initial_scroll_(40, 10), scroll_amount_(-3, 17), num_scrolls_(0) {}
+      : initial_scroll_(40, 10), scroll_amount_(-3, 17) {}
 
   void BeginTest() override {
     scroll_layer_ = layer_tree_host()->outer_viewport_scroll_layer();
-    scroll_layer_->SetScrollOffset(initial_scroll_);
-    scroll_layer_->set_did_scroll_callback(base::BindRepeating(
-        &LayerTreeHostScrollTestScrollMultipleRedraw::DidScrollOuterViewport,
-        base::Unretained(this)));
+    SetScrollOffset(scroll_layer_.get(), initial_scroll_);
     PostSetNeedsCommitToMainThread();
   }
 
@@ -227,16 +234,11 @@
     }
   }
 
-  void DidScrollOuterViewport(const gfx::ScrollOffset&, const ElementId&) {
-    num_scrolls_++;
-  }
-
-  void AfterTest() override { EXPECT_EQ(1, num_scrolls_); }
+  void AfterTest() override { EXPECT_EQ(1, num_outer_viewport_scrolls_); }
 
  private:
   gfx::ScrollOffset initial_scroll_;
   gfx::Vector2dF scroll_amount_;
-  int num_scrolls_;
   scoped_refptr<Layer> scroll_layer_;
 };
 
@@ -254,16 +256,11 @@
         num_did_begin_main_frames_(0),
         num_will_commits_(0),
         num_did_commits_(0),
-        num_impl_commits_(0),
-        num_impl_scrolls_(0) {}
+        num_impl_commits_(0) {}
 
   void BeginTest() override {
-    layer_tree_host()->outer_viewport_scroll_layer()->SetScrollOffset(
-        initial_scroll_);
-    layer_tree_host()->outer_viewport_scroll_layer()->set_did_scroll_callback(
-        base::BindRepeating(
-            &LayerTreeHostScrollTestScrollAbortedCommit::DidScrollOuterViewport,
-            base::Unretained(this)));
+    SetScrollOffset(layer_tree_host()->outer_viewport_scroll_layer(),
+                    initial_scroll_);
     PostSetNeedsCommitToMainThread();
   }
 
@@ -282,7 +279,7 @@
     switch (num_will_begin_main_frames_) {
       case 1:
         // This will not be aborted because of the initial prop changes.
-        EXPECT_EQ(0, num_impl_scrolls_);
+        EXPECT_EQ(0, num_outer_viewport_scrolls_);
         EXPECT_EQ(0, layer_tree_host()->SourceFrameNumber());
         EXPECT_VECTOR_EQ(initial_scroll_,
                          root_scroll_layer->CurrentScrollOffset());
@@ -291,7 +288,7 @@
       case 2:
         // This commit will be aborted, and another commit will be
         // initiated from the redraw.
-        EXPECT_EQ(1, num_impl_scrolls_);
+        EXPECT_EQ(1, num_outer_viewport_scrolls_);
         EXPECT_EQ(1, layer_tree_host()->SourceFrameNumber());
         EXPECT_VECTOR_EQ(
             gfx::ScrollOffsetWithDelta(initial_scroll_, impl_scroll_),
@@ -301,7 +298,7 @@
         break;
       case 3:
         // This commit will not be aborted because of the scroll change.
-        EXPECT_EQ(2, num_impl_scrolls_);
+        EXPECT_EQ(2, num_outer_viewport_scrolls_);
         // The source frame number still increases even with the abort.
         EXPECT_EQ(2, layer_tree_host()->SourceFrameNumber());
         EXPECT_VECTOR_EQ(gfx::ScrollOffsetWithDelta(
@@ -309,12 +306,14 @@
                          root_scroll_layer->CurrentScrollOffset());
         EXPECT_EQ(impl_scale_ * impl_scale_,
                   layer_tree_host()->page_scale_factor());
-        root_scroll_layer->SetScrollOffset(gfx::ScrollOffsetWithDelta(
-            root_scroll_layer->CurrentScrollOffset(), second_main_scroll_));
+        SetScrollOffset(
+            root_scroll_layer,
+            gfx::ScrollOffsetWithDelta(root_scroll_layer->CurrentScrollOffset(),
+                                       second_main_scroll_));
         break;
       case 4:
         // This commit will also be aborted.
-        EXPECT_EQ(3, num_impl_scrolls_);
+        EXPECT_EQ(3, num_outer_viewport_scrolls_);
         EXPECT_EQ(3, layer_tree_host()->SourceFrameNumber());
         gfx::Vector2dF delta =
             impl_scroll_ + impl_scroll_ + impl_scroll_ + second_main_scroll_;
@@ -412,12 +411,8 @@
     }
   }
 
-  void DidScrollOuterViewport(const gfx::ScrollOffset&, const ElementId&) {
-    num_impl_scrolls_++;
-  }
-
   void AfterTest() override {
-    EXPECT_EQ(3, num_impl_scrolls_);
+    EXPECT_EQ(3, num_outer_viewport_scrolls_);
     // Verify that the embedder sees aborted commits as real commits.
     EXPECT_EQ(4, num_will_begin_main_frames_);
     EXPECT_EQ(4, num_did_begin_main_frames_);
@@ -437,7 +432,6 @@
   int num_will_commits_;
   int num_did_commits_;
   int num_impl_commits_;
-  int num_impl_scrolls_;
 };
 
 MULTI_THREAD_TEST_F(LayerTreeHostScrollTestScrollAbortedCommit);
@@ -504,20 +498,41 @@
 
   void SetupTree() override {
     LayerTreeHostScrollTest::SetupTree();
-    layer_tree_host()
-        ->outer_viewport_container_layer()
-        ->SetForceRenderSurfaceForTesting(true);
-    gfx::Transform translate;
-    translate.Translate(0.25f, 0.f);
-    layer_tree_host()->outer_viewport_container_layer()->SetTransform(
-        translate);
+
+    scoped_refptr<Layer> container = Layer::Create();
+    container->SetBounds(gfx::Size(100, 100));
+    CopyProperties(layer_tree_host()->outer_viewport_scroll_layer(),
+                   container.get());
+    CreateTransformNode(container.get()).post_translation =
+        gfx::Vector2dF(0.25, 0);
+    CreateEffectNode(container.get()).render_surface_reason =
+        RenderSurfaceReason::kTest;
+    layer_tree_host()->root_layer()->AddChild(container);
+
+    scroll_layer_ = Layer::Create();
+    scroll_layer_->SetBounds(gfx::Size(200, 200));
+    scroll_layer_->SetScrollable(gfx::Size(100, 100));
+    scroll_layer_->SetIsDrawable(true);
+    scroll_layer_->SetElementId(
+        LayerIdToElementIdForTesting(scroll_layer_->id()));
+    CopyProperties(container.get(), scroll_layer_.get());
+    CreateTransformNode(scroll_layer_.get());
+    CreateScrollNode(scroll_layer_.get());
+    layer_tree_host()->root_layer()->AddChild(scroll_layer_);
+
+    scroll_layer_->set_did_scroll_callback(base::BindRepeating(
+        &LayerTreeHostScrollTestScrollSnapping::SyncScrollFromImpl,
+        base::Unretained(this)));
+
     layer_tree_host()->SetPageScaleFactorAndLimits(1.f, 0.1f, 100.f);
   }
 
   void BeginTest() override { PostSetNeedsCommitToMainThread(); }
 
   void DrawLayersOnThread(LayerTreeHostImpl* impl) override {
-    LayerImpl* scroll_layer = impl->OuterViewportScrollLayer();
+    LayerImpl* scroll_layer =
+        impl->active_tree()->LayerById(scroll_layer_->id());
+
     gfx::Transform translate;
 
     // Check that screen space transform of the scrollable layer is correctly
@@ -545,6 +560,7 @@
   }
 
  private:
+  scoped_refptr<Layer> scroll_layer_;
   gfx::Vector2dF scroll_amount_;
 };
 
@@ -555,25 +571,16 @@
   LayerTreeHostScrollTestCaseWithChild()
       : initial_offset_(10, 20),
         javascript_scroll_(40, 5),
-        scroll_amount_(2, -1),
-        num_scrolls_(0) {}
+        scroll_amount_(2, -1) {}
 
   void SetupTree() override {
     SetInitialDeviceScaleFactor(device_scale_factor_);
     SetInitialRootBounds(gfx::Size(10, 10));
     LayerTreeHostScrollTest::SetupTree();
     Layer* root_layer = layer_tree_host()->root_layer();
+    Layer* root_scroll_layer = layer_tree_host()->outer_viewport_scroll_layer();
 
-    root_scroll_layer_ = FakePictureLayer::Create(&fake_content_layer_client_);
-    root_scroll_layer_->SetElementId(
-        LayerIdToElementIdForTesting(root_scroll_layer_->id()));
-    root_scroll_layer_->SetBounds(gfx::Size(110, 110));
-    root_scroll_layer_->SetPosition(gfx::PointF());
-    root_scroll_layer_->SetIsDrawable(true);
-
-    SetupViewport(root_layer, root_scroll_layer_, root_layer->bounds());
-
-    child_layer_ = FakePictureLayer::Create(&fake_content_layer_client_);
+    child_layer_ = Layer::Create();
     child_layer_->set_did_scroll_callback(
         base::BindRepeating(&LayerTreeHostScrollTestCaseWithChild::DidScroll,
                             base::Unretained(this)));
@@ -581,14 +588,15 @@
         LayerIdToElementIdForTesting(child_layer_->id()));
     child_layer_->SetBounds(gfx::Size(110, 110));
 
+    gfx::Vector2dF child_layer_offset;
+    // Adjust the child layer horizontally so that scrolls will never hit it.
     if (scroll_child_layer_) {
       // Scrolls on the child layer will happen at 5, 5. If they are treated
       // like device pixels, and device scale factor is 2, then they will
       // be considered at 2.5, 2.5 in logical pixels, and will miss this layer.
-      child_layer_->SetPosition(gfx::PointF(5.f, 5.f));
+      child_layer_offset = gfx::Vector2dF(5.f, 5.f);
     } else {
-      // Adjust the child layer horizontally so that scrolls will never hit it.
-      child_layer_->SetPosition(gfx::PointF(60.f, 5.f));
+      child_layer_offset = gfx::Vector2dF(60.f, 5.f);
     }
 
     child_layer_->SetIsDrawable(true);
@@ -596,24 +604,23 @@
     child_layer_->SetHitTestable(true);
     child_layer_->SetElementId(
         LayerIdToElementIdForTesting(child_layer_->id()));
-    child_layer_->SetBounds(root_scroll_layer_->bounds());
-    root_scroll_layer_->AddChild(child_layer_);
+    child_layer_->SetBounds(root_scroll_layer->bounds());
+    root_layer->AddChild(child_layer_);
+
+    CopyProperties(root_scroll_layer, child_layer_.get());
+    CreateTransformNode(child_layer_.get()).post_translation =
+        child_layer_offset;
+    CreateScrollNode(child_layer_.get());
 
     if (scroll_child_layer_) {
-      expected_scroll_layer_ = child_layer_;
-      expected_no_scroll_layer_ = root_scroll_layer_;
+      expected_scroll_layer_ = child_layer_.get();
+      expected_no_scroll_layer_ = root_scroll_layer;
     } else {
-      expected_scroll_layer_ = root_scroll_layer_;
-      expected_no_scroll_layer_ = child_layer_;
+      expected_scroll_layer_ = root_scroll_layer;
+      expected_no_scroll_layer_ = child_layer_.get();
     }
 
-    expected_scroll_layer_->SetScrollOffset(initial_offset_);
-    fake_content_layer_client_.set_bounds(root_layer->bounds());
-
-    layer_tree_host()->outer_viewport_scroll_layer()->set_did_scroll_callback(
-        base::BindRepeating(
-            &LayerTreeHostScrollTestCaseWithChild::DidScrollOuterViewport,
-            base::Unretained(this)));
+    SetScrollOffset(expected_scroll_layer_, initial_offset_);
   }
 
   void BeginTest() override { PostSetNeedsCommitToMainThread(); }
@@ -627,15 +634,12 @@
   }
 
   void DidScroll(const gfx::ScrollOffset& offset, const ElementId& element_id) {
+    SyncScrollFromImpl(offset, element_id);
     final_scroll_offset_ = expected_scroll_layer_->CurrentScrollOffset();
     EXPECT_VECTOR_EQ(offset, final_scroll_offset_);
     EXPECT_EQ(element_id, expected_scroll_layer_->element_id());
   }
 
-  void DidScrollOuterViewport(const gfx::ScrollOffset&, const ElementId&) {
-    num_scrolls_++;
-  }
-
   void UpdateLayerTreeHost() override {
     EXPECT_VECTOR_EQ(gfx::Vector2d(),
                      expected_no_scroll_layer_->CurrentScrollOffset());
@@ -651,7 +655,7 @@
             expected_scroll_layer_->CurrentScrollOffset());
 
         // Pretend like Javascript updated the scroll position itself.
-        expected_scroll_layer_->SetScrollOffset(javascript_scroll_);
+        SetScrollOffset(expected_scroll_layer_, javascript_scroll_);
         break;
       case 2:
         EXPECT_VECTOR_EQ(
@@ -663,11 +667,10 @@
 
   void DidActivateTreeOnThread(LayerTreeHostImpl* impl) override {
     LayerImpl* inner_scroll = impl->InnerViewportScrollLayer();
-    FakePictureLayerImpl* root_scroll_layer_impl =
-        static_cast<FakePictureLayerImpl*>(impl->OuterViewportScrollLayer());
-    FakePictureLayerImpl* child_layer_impl = static_cast<FakePictureLayerImpl*>(
+    LayerImpl* root_scroll_layer_impl = impl->OuterViewportScrollLayer();
+    LayerImpl* child_layer_impl =
         root_scroll_layer_impl->layer_tree_impl()->LayerById(
-            child_layer_->id()));
+            child_layer_->id());
 
     LayerImpl* expected_scroll_layer_impl = nullptr;
     LayerImpl* expected_no_scroll_layer_impl = nullptr;
@@ -749,12 +752,12 @@
 
   void AfterTest() override {
     if (scroll_child_layer_) {
-      EXPECT_EQ(0, num_scrolls_);
+      EXPECT_EQ(0, num_outer_viewport_scrolls_);
       EXPECT_VECTOR_EQ(gfx::ScrollOffsetWithDelta(javascript_scroll_,
                                                   scroll_amount_),
                        final_scroll_offset_);
     } else {
-      EXPECT_EQ(2, num_scrolls_);
+      EXPECT_EQ(2, num_outer_viewport_scrolls_);
       EXPECT_VECTOR_EQ(gfx::ScrollOffset(), final_scroll_offset_);
     }
   }
@@ -766,15 +769,11 @@
   gfx::ScrollOffset initial_offset_;
   gfx::ScrollOffset javascript_scroll_;
   gfx::Vector2d scroll_amount_;
-  int num_scrolls_;
   gfx::ScrollOffset final_scroll_offset_;
 
-  FakeContentLayerClient fake_content_layer_client_;
-
-  scoped_refptr<Layer> root_scroll_layer_;
   scoped_refptr<Layer> child_layer_;
-  scoped_refptr<Layer> expected_scroll_layer_;
-  scoped_refptr<Layer> expected_no_scroll_layer_;
+  Layer* expected_scroll_layer_;
+  Layer* expected_no_scroll_layer_;
 };
 
 TEST_F(LayerTreeHostScrollTestCaseWithChild, DeviceScaleFactor1_ScrollChild) {
@@ -822,8 +821,7 @@
       : initial_scroll_(10, 20),
         main_thread_scroll_(40, 5),
         impl_thread_scroll1_(2, -1),
-        impl_thread_scroll2_(-3, 10),
-        num_scrolls_(0) {}
+        impl_thread_scroll2_(-3, 10) {}
 
   void SetupTree() override {
     LayerTreeHostScrollTest::SetupTree();
@@ -831,12 +829,8 @@
   }
 
   void BeginTest() override {
-    layer_tree_host()->outer_viewport_scroll_layer()->SetScrollOffset(
-        initial_scroll_);
-    layer_tree_host()->outer_viewport_scroll_layer()->set_did_scroll_callback(
-        base::BindRepeating(
-            &LayerTreeHostScrollTestSimple::DidScrollOuterViewport,
-            base::Unretained(this)));
+    SetScrollOffset(layer_tree_host()->outer_viewport_scroll_layer(),
+                    initial_scroll_);
     PostSetNeedsCommitToMainThread();
   }
 
@@ -851,7 +845,8 @@
 
       // Pretend like Javascript updated the scroll position itself with a
       // change of main_thread_scroll.
-      scroll_layer->SetScrollOffset(
+      SetScrollOffset(
+          scroll_layer,
           gfx::ScrollOffsetWithDelta(
               initial_scroll_, main_thread_scroll_ + impl_thread_scroll1_));
     }
@@ -927,18 +922,13 @@
     }
   }
 
-  void DidScrollOuterViewport(const gfx::ScrollOffset&, const ElementId&) {
-    num_scrolls_++;
-  }
-
-  void AfterTest() override { EXPECT_EQ(1, num_scrolls_); }
+  void AfterTest() override { EXPECT_EQ(1, num_outer_viewport_scrolls_); }
 
  private:
   gfx::ScrollOffset initial_scroll_;
   gfx::Vector2dF main_thread_scroll_;
   gfx::Vector2dF impl_thread_scroll1_;
   gfx::Vector2dF impl_thread_scroll2_;
-  int num_scrolls_;
 };
 
 // This tests scrolling on the impl side which is only possible with a thread.
@@ -959,8 +949,8 @@
   }
 
   void BeginTest() override {
-    layer_tree_host()->outer_viewport_scroll_layer()->SetScrollOffset(
-        initial_scroll_);
+    SetScrollOffset(layer_tree_host()->outer_viewport_scroll_layer(),
+                    initial_scroll_);
     PostSetNeedsCommitToMainThread();
   }
 
@@ -1108,10 +1098,6 @@
  public:
   LayerTreeHostScrollTestScrollZeroMaxScrollOffset() = default;
 
-  void InitializeSettings(LayerTreeSettings* settings) override {
-    settings->use_layer_lists = true;
-  }
-
   void SetupTree() override {
     LayerTreeHostScrollTest::SetupTree();
 
@@ -1127,7 +1113,7 @@
                    scroller_.get());
     CreateTransformNode(scroller_.get());
     CreateScrollNode(scroller_.get());
-    layer_tree_host()->outer_viewport_scroll_layer()->AddChild(scroller_.get());
+    layer_tree_host()->root_layer()->AddChild(scroller_.get());
   }
 
   void BeginTest() override {
@@ -1203,8 +1189,8 @@
   void SetupTree() override {
     LayerTreeHostScrollTest::SetupTree();
     layer_tree_host()->outer_viewport_scroll_layer()->SetIsDrawable(false);
-    layer_tree_host()->outer_viewport_scroll_layer()->SetScrollOffset(
-        gfx::ScrollOffset(20.f, 20.f));
+    SetScrollOffset(layer_tree_host()->outer_viewport_scroll_layer(),
+                    gfx::ScrollOffset(20.f, 20.f));
     layer_tree_host()
         ->outer_viewport_scroll_layer()
         ->SetNonFastScrollableRegion(gfx::Rect(20, 20, 20, 20));
@@ -1241,10 +1227,9 @@
 
   void SetupTree() override {
     LayerTreeHostScrollTest::SetupTree();
-    layer_tree_host()
-        ->inner_viewport_scroll_layer()
-        ->AddMainThreadScrollingReasons(
-            MainThreadScrollingReason::kScrollbarScrolling);
+    GetScrollNode(layer_tree_host()->inner_viewport_scroll_layer())
+        ->main_thread_scrolling_reasons =
+        MainThreadScrollingReason::kScrollbarScrolling;
   }
 
   void DrawLayersOnThread(LayerTreeHostImpl* impl) override {
@@ -1336,12 +1321,8 @@
       : scroll_destroy_whole_tree_(false) {}
 
   void SetupTree() override {
-    LayerTreeTest::SetupTree();
+    LayerTreeHostScrollTest::SetupTree();
     Layer* root_layer = layer_tree_host()->root_layer();
-    root_layer->SetBounds(gfx::Size(10, 10));
-
-    SetupViewport(root_layer, root_layer->bounds(), root_layer->bounds());
-
     Layer* outer_scroll_layer =
         layer_tree_host()->outer_viewport_scroll_layer();
 
@@ -1402,7 +1383,6 @@
   Layer* CreateScrollLayer(Layer* parent, FakeLayerScrollClient* client) {
     scoped_refptr<PictureLayer> scroll_layer =
         PictureLayer::Create(&fake_content_layer_client_);
-    scroll_layer->SetPosition(gfx::PointF());
     scroll_layer->SetIsDrawable(true);
     scroll_layer->SetScrollable(parent->bounds());
     scroll_layer->SetHitTestable(true);
@@ -1414,7 +1394,12 @@
         &FakeLayerScrollClient::DidScroll, base::Unretained(client)));
     client->owner_ = this;
     client->layer_ = scroll_layer.get();
-    parent->AddChild(scroll_layer);
+
+    CopyProperties(parent, scroll_layer.get());
+    CreateTransformNode(scroll_layer.get());
+    CreateScrollNode(scroll_layer.get());
+    layer_tree_host()->root_layer()->AddChild(scroll_layer);
+
     return scroll_layer.get();
   }
 
@@ -1456,22 +1441,18 @@
         second_scroll_(40, 5),
         third_scroll_(20, 10),
         scroll_amount_(2, -1),
-        num_commits_(0),
-        num_scrolls_(0) {}
+        num_commits_(0) {}
 
   void InitializeSettings(LayerTreeSettings* settings) override {
+    LayerTreeHostScrollTest::InitializeSettings(settings);
     settings->main_frame_before_activation_enabled = true;
   }
 
   void BeginTest() override {
     outer_viewport_container_layer_id_ =
         layer_tree_host()->outer_viewport_container_layer()->id();
-    layer_tree_host()->outer_viewport_scroll_layer()->SetScrollOffset(
-        initial_scroll_);
-    layer_tree_host()->outer_viewport_scroll_layer()->set_did_scroll_callback(
-        base::BindRepeating(
-            &LayerTreeHostScrollTestScrollMFBA::DidScrollOuterViewport,
-            base::Unretained(this)));
+    SetScrollOffset(layer_tree_host()->outer_viewport_scroll_layer(),
+                    initial_scroll_);
     PostSetNeedsCommitToMainThread();
   }
 
@@ -1502,14 +1483,14 @@
             gfx::ScrollOffsetWithDelta(initial_scroll_, scroll_amount_),
             scroll_layer->CurrentScrollOffset());
         // Pretend like Javascript updated the scroll position itself.
-        scroll_layer->SetScrollOffset(second_scroll_);
+        SetScrollOffset(scroll_layer, second_scroll_);
         break;
       case 2:
         // Third frame does not see a scroll delta because we only did one
         // scroll for the second and third frames.
         EXPECT_VECTOR_EQ(second_scroll_, scroll_layer->CurrentScrollOffset());
         // Pretend like Javascript updated the scroll position itself.
-        scroll_layer->SetScrollOffset(third_scroll_);
+        SetScrollOffset(scroll_layer, third_scroll_);
         break;
     }
   }
@@ -1546,13 +1527,9 @@
     }
   }
 
-  void DidScrollOuterViewport(const gfx::ScrollOffset&, const ElementId&) {
-    num_scrolls_++;
-  }
-
   void AfterTest() override {
     EXPECT_EQ(3, num_commits_);
-    EXPECT_EQ(1, num_scrolls_);
+    EXPECT_EQ(1, num_outer_viewport_scrolls_);
   }
 
  private:
@@ -1570,7 +1547,6 @@
   gfx::ScrollOffset third_scroll_;
   gfx::Vector2dF scroll_amount_;
   int num_commits_;
-  int num_scrolls_;
   int outer_viewport_container_layer_id_;
 };
 
@@ -1589,20 +1565,16 @@
         num_did_commits_(0),
         num_impl_commits_(0),
         num_aborted_commits_(0),
-        num_impl_scrolls_(0),
         num_draws_(0) {}
 
   void InitializeSettings(LayerTreeSettings* settings) override {
+    LayerTreeHostScrollTest::InitializeSettings(settings);
     settings->main_frame_before_activation_enabled = true;
   }
 
   void BeginTest() override {
-    layer_tree_host()->outer_viewport_scroll_layer()->SetScrollOffset(
-        initial_scroll_);
-    layer_tree_host()->outer_viewport_scroll_layer()->set_did_scroll_callback(
-        base::BindRepeating(&LayerTreeHostScrollTestScrollAbortedCommitMFBA::
-                                DidScrollOuterViewport,
-                            base::Unretained(this)));
+    SetScrollOffset(layer_tree_host()->outer_viewport_scroll_layer(),
+                    initial_scroll_);
     PostSetNeedsCommitToMainThread();
   }
 
@@ -1621,24 +1593,26 @@
     switch (num_will_begin_main_frames_) {
       case 1:
         // This will not be aborted because of the initial prop changes.
-        EXPECT_EQ(0, num_impl_scrolls_);
+        EXPECT_EQ(0, num_outer_viewport_scrolls_);
         EXPECT_EQ(0, layer_tree_host()->SourceFrameNumber());
         EXPECT_VECTOR_EQ(initial_scroll_,
                          root_scroll_layer->CurrentScrollOffset());
         break;
       case 2:
         // This commit will not be aborted because of the scroll change.
-        EXPECT_EQ(1, num_impl_scrolls_);
+        EXPECT_EQ(1, num_outer_viewport_scrolls_);
         EXPECT_EQ(1, layer_tree_host()->SourceFrameNumber());
         EXPECT_VECTOR_EQ(
             gfx::ScrollOffsetWithDelta(initial_scroll_, impl_scroll_),
             root_scroll_layer->CurrentScrollOffset());
-        root_scroll_layer->SetScrollOffset(gfx::ScrollOffsetWithDelta(
-            root_scroll_layer->CurrentScrollOffset(), second_main_scroll_));
+        SetScrollOffset(
+            root_scroll_layer,
+            gfx::ScrollOffsetWithDelta(root_scroll_layer->CurrentScrollOffset(),
+                                       second_main_scroll_));
         break;
       case 3: {
         // This commit will be aborted.
-        EXPECT_EQ(2, num_impl_scrolls_);
+        EXPECT_EQ(2, num_outer_viewport_scrolls_);
         // The source frame number still increases even with the abort.
         EXPECT_EQ(2, layer_tree_host()->SourceFrameNumber());
         gfx::Vector2dF delta =
@@ -1649,7 +1623,7 @@
       }
       case 4: {
         // This commit will also be aborted.
-        EXPECT_EQ(3, num_impl_scrolls_);
+        EXPECT_EQ(3, num_outer_viewport_scrolls_);
         EXPECT_EQ(3, layer_tree_host()->SourceFrameNumber());
         gfx::Vector2dF delta =
             impl_scroll_ + impl_scroll_ + impl_scroll_ + second_main_scroll_;
@@ -1768,12 +1742,8 @@
     num_draws_++;
   }
 
-  void DidScrollOuterViewport(const gfx::ScrollOffset&, const ElementId&) {
-    num_impl_scrolls_++;
-  }
-
   void AfterTest() override {
-    EXPECT_EQ(3, num_impl_scrolls_);
+    EXPECT_EQ(3, num_outer_viewport_scrolls_);
     // Verify that the embedder sees aborted commits as real commits.
     EXPECT_EQ(4, num_will_begin_main_frames_);
     EXPECT_EQ(4, num_did_begin_main_frames_);
@@ -1797,7 +1767,6 @@
   int num_did_commits_;
   int num_impl_commits_;
   int num_aborted_commits_;
-  int num_impl_scrolls_;
   int num_draws_;
 };
 
@@ -1832,6 +1801,7 @@
         num_begin_main_frames_main_thread_(0) {}
 
   void InitializeSettings(LayerTreeSettings* settings) override {
+    LayerTreeHostScrollTest::InitializeSettings(settings);
     settings->enable_elastic_overscroll = true;
   }
 
@@ -1985,52 +1955,42 @@
       : initial_scroll_(10, 20), second_scroll_(0, 0) {}
 
   void BeginTest() override {
-    layer_tree_host()->inner_viewport_scroll_layer()->SetScrollOffset(
-        initial_scroll_);
-    layer_tree_host()->inner_viewport_scroll_layer()->SetBounds(
-        gfx::Size(100, 100));
+    SetScrollOffset(layer_tree_host()->outer_viewport_scroll_layer(),
+                    initial_scroll_);
     PostSetNeedsCommitToMainThread();
   }
 
   void UpdateLayerTreeHost() override {
-    Layer* scroll_layer = layer_tree_host()->inner_viewport_scroll_layer();
+    Layer* scroll_layer = layer_tree_host()->outer_viewport_scroll_layer();
     if (layer_tree_host()->SourceFrameNumber() == 0) {
       EXPECT_VECTOR_EQ(initial_scroll_, scroll_layer->CurrentScrollOffset());
     } else {
       EXPECT_VECTOR_EQ(
           gfx::ScrollOffsetWithDelta(initial_scroll_, scroll_amount_),
           scroll_layer->CurrentScrollOffset());
-      scroll_layer->SetScrollOffset(second_scroll_);
-      scroll_layer->SetOpacity(0.5f);
+      SetScrollOffset(scroll_layer, second_scroll_);
+      SetOpacity(scroll_layer, 0.5f);
     }
   }
 
   void DidActivateTreeOnThread(LayerTreeHostImpl* impl) override {
-    LayerImpl* scroll_layer = impl->InnerViewportScrollLayer();
+    LayerImpl* scroll_layer = impl->OuterViewportScrollLayer();
 
     switch (impl->active_tree()->source_frame_number()) {
       case 0:
         EXPECT_VECTOR_EQ(initial_scroll_, ScrollTreeForLayer(scroll_layer)
                                               ->GetScrollOffsetBaseForTesting(
                                                   scroll_layer->element_id()));
-        EXPECT_VECTOR_EQ(
-            initial_scroll_,
-            scroll_layer->layer_tree_impl()
-                ->property_trees()
-                ->transform_tree.Node(scroll_layer->transform_tree_index())
-                ->scroll_offset);
+        EXPECT_VECTOR_EQ(initial_scroll_,
+                         GetTransformNode(scroll_layer)->scroll_offset);
         PostSetNeedsCommitToMainThread();
         break;
       case 1:
         EXPECT_VECTOR_EQ(second_scroll_, ScrollTreeForLayer(scroll_layer)
                                              ->GetScrollOffsetBaseForTesting(
                                                  scroll_layer->element_id()));
-        EXPECT_VECTOR_EQ(
-            second_scroll_,
-            scroll_layer->layer_tree_impl()
-                ->property_trees()
-                ->transform_tree.Node(scroll_layer->transform_tree_index())
-                ->scroll_offset);
+        EXPECT_VECTOR_EQ(second_scroll_,
+                         GetTransformNode(scroll_layer)->scroll_offset);
         EndTest();
         break;
     }
@@ -2047,14 +2007,13 @@
 class LayerTreeHostScrollTestImplSideInvalidation
     : public LayerTreeHostScrollTest {
   void BeginTest() override {
-    layer_tree_host()->outer_viewport_scroll_layer()->set_did_scroll_callback(
-        base::BindRepeating(&LayerTreeHostScrollTestImplSideInvalidation::
-                                DidScrollOuterViewport,
-                            base::Unretained(this)));
     PostSetNeedsCommitToMainThread();
   }
 
-  void DidScrollOuterViewport(const gfx::ScrollOffset&, const ElementId&) {
+  void DidScrollOuterViewport(const gfx::ScrollOffset& offset,
+                              const ElementId& element_id) override {
+    LayerTreeHostScrollTest::DidScrollOuterViewport(offset, element_id);
+
     // Defer responding to the main frame until an impl-side pending tree is
     // created for the invalidation request.
     {
@@ -2076,7 +2035,8 @@
             layer_tree_host()->outer_viewport_scroll_layer();
         gfx::ScrollOffset delta_to_send =
             outer_viewport_offsets_[2] - outer_viewport_offsets_[1];
-        outer_viewport_layer->SetScrollOffset(
+        SetScrollOffset(
+            outer_viewport_layer,
             outer_viewport_layer->CurrentScrollOffset() + delta_to_send);
       } break;
       case 2:
diff --git a/cc/trees/property_tree_builder.cc b/cc/trees/property_tree_builder.cc
index 4ba9d91..e8c70c2 100644
--- a/cc/trees/property_tree_builder.cc
+++ b/cc/trees/property_tree_builder.cc
@@ -17,7 +17,7 @@
 #include "cc/trees/clip_node.h"
 #include "cc/trees/draw_property_utils.h"
 #include "cc/trees/effect_node.h"
-#include "cc/trees/layer_tree_impl.h"
+#include "cc/trees/layer_tree_host.h"
 #include "cc/trees/layer_tree_settings.h"
 #include "cc/trees/mutator_host.h"
 #include "cc/trees/scroll_node.h"
@@ -39,8 +39,6 @@
   int closest_ancestor_with_copy_request;
   uint32_t main_thread_scrolling_reasons;
   SkColor safe_opaque_background_color;
-  bool in_subtree_of_page_scale_layer;
-  bool affected_by_outer_viewport_bounds_delta;
   bool should_flatten;
   bool scroll_tree_parent_created_by_uninheritable_criteria;
   bool animation_axis_aligned_since_render_target;
@@ -51,34 +49,24 @@
 
 class PropertyTreeBuilderContext {
  public:
-  PropertyTreeBuilderContext(Layer* root_layer,
-                             const Layer* page_scale_layer,
-                             const Layer* inner_viewport_scroll_layer,
-                             const Layer* outer_viewport_scroll_layer,
-                             const ElementId overscroll_elasticity_element_id,
-                             const gfx::Vector2dF& elastic_overscroll,
-                             float page_scale_factor,
-                             const gfx::Transform& device_transform,
-                             MutatorHost* mutator_host,
-                             PropertyTrees* property_trees)
-      : root_layer_(root_layer),
-        page_scale_layer_(page_scale_layer),
-        inner_viewport_scroll_layer_(inner_viewport_scroll_layer),
-        outer_viewport_scroll_layer_(outer_viewport_scroll_layer),
-        overscroll_elasticity_element_id_(overscroll_elasticity_element_id),
-        elastic_overscroll_(elastic_overscroll),
-        page_scale_factor_(page_scale_factor),
-        device_transform_(device_transform),
-        mutator_host_(*mutator_host),
-        property_trees_(*property_trees),
-        transform_tree_(property_trees->transform_tree),
-        clip_tree_(property_trees->clip_tree),
-        effect_tree_(property_trees->effect_tree),
-        scroll_tree_(property_trees->scroll_tree) {}
+  explicit PropertyTreeBuilderContext(LayerTreeHost* layer_tree_host)
+      : layer_tree_host_(layer_tree_host),
+        root_layer_(layer_tree_host->root_layer()),
+        mutator_host_(*layer_tree_host->mutator_host()),
+        property_trees_(*layer_tree_host->property_trees()),
+        transform_tree_(property_trees_.transform_tree),
+        clip_tree_(property_trees_.clip_tree),
+        effect_tree_(property_trees_.effect_tree),
+        scroll_tree_(property_trees_.scroll_tree) {
+    // This class is for UI compositor only
+    DCHECK(!layer_tree_host->page_scale_layer());
+    DCHECK(!layer_tree_host->inner_viewport_scroll_layer());
+    DCHECK(!layer_tree_host->outer_viewport_scroll_layer());
+    DCHECK(!layer_tree_host->overscroll_elasticity_element_id());
+    DCHECK(layer_tree_host->elastic_overscroll().IsZero());
+  }
 
-  void BuildPropertyTrees(float device_scale_factor,
-                          const gfx::Rect& viewport,
-                          SkColor root_background_color) const;
+  void BuildPropertyTrees();
 
  private:
   void BuildPropertyTreesInternal(
@@ -108,14 +96,8 @@
                                    bool subtree_has_rounded_corner,
                                    bool created_transform_node) const;
 
+  LayerTreeHost* layer_tree_host_;
   Layer* root_layer_;
-  const Layer* page_scale_layer_;
-  const Layer* inner_viewport_scroll_layer_;
-  const Layer* outer_viewport_scroll_layer_;
-  const ElementId overscroll_elasticity_element_id_;
-  const gfx::Vector2dF elastic_overscroll_;
-  float page_scale_factor_;
-  const gfx::Transform& device_transform_;
   MutatorHost& mutator_host_;
   PropertyTrees& property_trees_;
   TransformTree& transform_tree_;
@@ -245,10 +227,6 @@
     bool created_render_surface,
     DataForRecursion* data_for_children) const {
   const bool is_root = !layer->parent();
-  const bool is_page_scale_layer = layer == page_scale_layer_;
-  const bool is_overscroll_elasticity_layer =
-      overscroll_elasticity_element_id_ &&
-      layer->element_id() == overscroll_elasticity_element_id_;
   const bool is_scrollable = layer->scrollable();
   // Scrolling a layer should not move it from being pixel-aligned to moving off
   // the pixel grid and becoming fuzzy. So always snap scrollable things to the
@@ -277,7 +255,6 @@
   DCHECK(!is_scrollable || is_snapped);
   bool requires_node = is_root || is_snapped || has_significant_transform ||
                        has_any_transform_animation || has_surface ||
-                       is_page_scale_layer || is_overscroll_elasticity_layer ||
                        is_at_boundary_of_3d_rendering_context ||
                        layer->HasRoundedCorner();
 
@@ -320,22 +297,14 @@
   node->flattens_inherited_transform = data_for_children->should_flatten;
   node->sorting_context_id = layer->sorting_context_id();
 
-  if (is_root || is_page_scale_layer) {
+  if (is_root) {
     // Root layer and page scale layer should not have transform or offset.
     DCHECK(layer->position().IsOrigin());
     DCHECK(parent_offset.IsZero());
     DCHECK(layer->transform().IsIdentity());
 
-    if (is_root) {
-      DCHECK(!is_page_scale_layer);
-      transform_tree_.SetRootScaleAndTransform(
-          transform_tree_.device_scale_factor(), device_transform_);
-    } else {
-      DCHECK(is_page_scale_layer);
-      transform_tree_.set_page_scale_factor(page_scale_factor_);
-      node->local.Scale(page_scale_factor_, page_scale_factor_);
-      data_for_children->in_subtree_of_page_scale_layer = true;
-    }
+    transform_tree_.SetRootScaleAndTransform(
+        transform_tree_.device_scale_factor(), gfx::Transform());
   } else {
     node->local = layer->transform();
     node->origin = layer->transform_origin();
@@ -343,9 +312,6 @@
         parent_offset + layer->position().OffsetFromOrigin();
   }
 
-  node->in_subtree_of_page_scale_layer =
-      data_for_children->in_subtree_of_page_scale_layer;
-
   // Surfaces inherently flatten transforms.
   data_for_children->should_flatten =
       layer->should_flatten_transform() || has_surface;
@@ -355,12 +321,7 @@
   GetAnimationScales(mutator_host_, layer, &node->maximum_animation_scale,
                      &node->starting_animation_scale);
 
-  if (is_overscroll_elasticity_layer) {
-    DCHECK(!is_scrollable);
-    node->scroll_offset = gfx::ScrollOffset(elastic_overscroll_);
-  } else {
-    node->scroll_offset = layer->CurrentScrollOffset();
-  }
+  node->scroll_offset = layer->CurrentScrollOffset();
 
   node->needs_local_transform_update = true;
   transform_tree_.UpdateTransforms(node->id);
@@ -491,7 +452,7 @@
   return RenderSurfaceReason::kNone;
 }
 
-static bool UpdateSubtreeHasCopyRequestRecursive(Layer* layer) {
+bool UpdateSubtreeHasCopyRequestRecursive(Layer* layer) {
   bool subtree_has_copy_request = false;
   if (layer->HasCopyRequest())
     subtree_has_copy_request = true;
@@ -554,7 +515,6 @@
   node->stable_id = layer->id();
   node->opacity = layer->opacity();
   node->blend_mode = layer->blend_mode();
-  node->unscaled_mask_target_size = layer->bounds();
   node->cache_render_surface = layer->cache_render_surface();
   node->has_copy_request = layer->HasCopyRequest();
   node->filters = layer->filters();
@@ -608,12 +568,11 @@
     }
     node->clip_id = data_from_ancestor.clip_tree_parent;
   } else {
-    // The root render surface acts as the unbounded and untransformed
-    // surface into which content is drawn. The transform node created
-    // from the root layer (which includes device scale factor) and
-    // the clip node created from the root layer (which includes
-    // viewports) apply to the root render surface's content, but not
-    // to the root render surface itself.
+    // The root render surface acts as the unbounded and untransformed surface
+    // into which content is drawn. The transform node created from the root
+    // layer (which includes device scale factor) and the clip node created from
+    // the root layer apply to the root render surface's content, but not to the
+    // root render surface itself.
     node->transform_id = TransformTree::kRootNodeId;
     node->clip_id = ClipTree::kViewportNodeId;
   }
@@ -722,14 +681,6 @@
     ScrollNode node;
     node.scrollable = scrollable;
     node.main_thread_scrolling_reasons = main_thread_scrolling_reasons;
-    node.scrolls_inner_viewport = layer == inner_viewport_scroll_layer_;
-    node.scrolls_outer_viewport = layer == outer_viewport_scroll_layer_;
-
-    if (node.scrolls_inner_viewport &&
-        data_from_ancestor.in_subtree_of_page_scale_layer) {
-      node.max_scroll_offset_affected_by_page_scale = true;
-    }
-
     node.bounds = layer->bounds();
     node.container_bounds = layer->scroll_container_bounds();
     node.offset_to_transform_parent = layer->offset_to_transform_parent();
@@ -848,29 +799,21 @@
   }
 }
 
-void PropertyTreeBuilderContext::BuildPropertyTrees(
-    float device_scale_factor,
-    const gfx::Rect& viewport,
-    SkColor root_background_color) const {
+void PropertyTreeBuilderContext::BuildPropertyTrees() {
+  property_trees_.is_main_thread = true;
+  property_trees_.is_active = false;
+
+  if (layer_tree_host_->has_copy_request())
+    UpdateSubtreeHasCopyRequestRecursive(root_layer_);
+
   if (!property_trees_.needs_rebuild) {
-    DCHECK_NE(page_scale_layer_, root_layer_);
-    if (page_scale_layer_) {
-      DCHECK_GE(page_scale_layer_->transform_tree_index(),
-                TransformTree::kRootNodeId);
-      TransformNode* node = property_trees_.transform_tree.Node(
-          page_scale_layer_->transform_tree_index());
-      draw_property_utils::UpdatePageScaleFactor(&property_trees_, node,
-                                                 page_scale_factor_);
-    }
-    draw_property_utils::UpdateElasticOverscroll(
-        &property_trees_, overscroll_elasticity_element_id_,
-        elastic_overscroll_);
-    clip_tree_.SetViewportClip(gfx::RectF(viewport));
+    clip_tree_.SetViewportClip(
+        gfx::RectF(layer_tree_host_->device_viewport_rect()));
     // SetRootScaleAndTransform will be incorrect if the root layer has
     // non-zero position, so ensure it is zero.
     DCHECK(root_layer_->position().IsOrigin());
-    transform_tree_.SetRootScaleAndTransform(device_scale_factor,
-                                             device_transform_);
+    transform_tree_.SetRootScaleAndTransform(
+        layer_tree_host_->device_scale_factor(), gfx::Transform());
     return;
   }
 
@@ -883,8 +826,6 @@
       EffectTree::kInvalidNodeId;
   data_for_recursion.closest_ancestor_with_copy_request =
       EffectTree::kInvalidNodeId;
-  data_for_recursion.in_subtree_of_page_scale_layer = false;
-  data_for_recursion.affected_by_outer_viewport_bounds_delta = false;
   data_for_recursion.should_flatten = false;
   data_for_recursion.main_thread_scrolling_reasons =
       MainThreadScrollingReason::kNotScrollingOnMain;
@@ -893,13 +834,18 @@
   data_for_recursion.compound_transform_since_render_target = gfx::Transform();
   data_for_recursion.animation_axis_aligned_since_render_target = true;
   data_for_recursion.not_axis_aligned_since_last_clip = false;
+
+  SkColor root_background_color = layer_tree_host_->background_color();
+  if (SkColorGetA(root_background_color) != 255)
+    root_background_color = SkColorSetA(root_background_color, 255);
   data_for_recursion.safe_opaque_background_color = root_background_color;
 
   property_trees_.clear();
-  transform_tree_.set_device_scale_factor(device_scale_factor);
+  transform_tree_.set_device_scale_factor(
+      layer_tree_host_->device_scale_factor());
   ClipNode root_clip;
   root_clip.clip_type = ClipNode::ClipType::APPLIES_LOCAL_CLIP;
-  root_clip.clip = gfx::RectF(viewport);
+  root_clip.clip = gfx::RectF(layer_tree_host_->device_viewport_rect());
   root_clip.transform_id = TransformTree::kRootNodeId;
   data_for_recursion.clip_tree_parent =
       clip_tree_.Insert(root_clip, ClipTree::kRootNodeId);
@@ -921,37 +867,15 @@
 
 }  // namespace
 
-void PropertyTreeBuilder::BuildPropertyTrees(
-    Layer* root_layer,
-    const Layer* page_scale_layer,
-    const Layer* inner_viewport_scroll_layer,
-    const Layer* outer_viewport_scroll_layer,
-    const ElementId overscroll_elasticity_element_id,
-    const gfx::Vector2dF& elastic_overscroll,
-    float page_scale_factor,
-    float device_scale_factor,
-    const gfx::Rect& viewport,
-    const gfx::Transform& device_transform,
-    PropertyTrees* property_trees) {
-  property_trees->is_main_thread = true;
-  property_trees->is_active = false;
-  SkColor color = root_layer->layer_tree_host()->background_color();
-  if (SkColorGetA(color) != 255)
-    color = SkColorSetA(color, 255);
-  if (root_layer->layer_tree_host()->has_copy_request())
-    UpdateSubtreeHasCopyRequestRecursive(root_layer);
-  PropertyTreeBuilderContext(
-      root_layer, page_scale_layer, inner_viewport_scroll_layer,
-      outer_viewport_scroll_layer, overscroll_elasticity_element_id,
-      elastic_overscroll, page_scale_factor, device_transform,
-      root_layer->layer_tree_host()->mutator_host(), property_trees)
-      .BuildPropertyTrees(device_scale_factor, viewport, color);
-  property_trees->ResetCachedData();
+void PropertyTreeBuilder::BuildPropertyTrees(LayerTreeHost* layer_tree_host) {
+  PropertyTreeBuilderContext(layer_tree_host).BuildPropertyTrees();
+
+  layer_tree_host->property_trees()->ResetCachedData();
   // During building property trees, all copy requests are moved from layers to
   // effect tree, which are then pushed at commit to compositor thread and
   // handled there. LayerTreeHost::has_copy_request is only required to
   // decide if we want to create a effect node. So, it can be reset now.
-  root_layer->layer_tree_host()->SetHasCopyRequest(false);
+  layer_tree_host->SetHasCopyRequest(false);
 }
 
 }  // namespace cc
diff --git a/cc/trees/property_tree_builder.h b/cc/trees/property_tree_builder.h
index 92860f2b..8103a91e 100644
--- a/cc/trees/property_tree_builder.h
+++ b/cc/trees/property_tree_builder.h
@@ -7,25 +7,15 @@
 
 #include <vector>
 
-#include "cc/trees/layer_tree_host_common.h"
-#include "cc/trees/property_tree.h"
+#include "cc/cc_export.h"
 
 namespace cc {
 
+class LayerTreeHost;
+
 class PropertyTreeBuilder {
  public:
-  static void CC_EXPORT
-  BuildPropertyTrees(Layer* root_layer,
-                     const Layer* page_scale_layer,
-                     const Layer* inner_viewport_scroll_layer,
-                     const Layer* outer_viewport_scroll_layer,
-                     const ElementId overscroll_elasticity_element_id,
-                     const gfx::Vector2dF& elastic_overscroll,
-                     float page_scale_factor,
-                     float device_scale_factor,
-                     const gfx::Rect& viewport,
-                     const gfx::Transform& device_transform,
-                     PropertyTrees* property_trees);
+  static void CC_EXPORT BuildPropertyTrees(LayerTreeHost*);
 };
 
 }  // namespace cc
diff --git a/chrome/android/BUILD.gn b/chrome/android/BUILD.gn
index ff0b383..a46ce76 100644
--- a/chrome/android/BUILD.gn
+++ b/chrome/android/BUILD.gn
@@ -8,6 +8,7 @@
 import("//build/config/python.gni")
 import("//build/util/process_version.gni")
 import("//build/util/version.gni")
+import("//chrome/android/chrome_bundle_tmpl.gni")
 import("//chrome/android/chrome_common_shared_library.gni")
 import("//chrome/android/chrome_public_apk_tmpl.gni")
 import("//chrome/android/features/dev_ui/dev_ui_module.gni")
@@ -1204,6 +1205,7 @@
   if (enable_vr) {
     deps += [ "//chrome/browser/android/vr:module_factory" ]
   }
+  deps += [ "//chrome/android/features/test_dummy/internal:base_module_native" ]
 
   allow_partitions = true
   module_descs = chrome_modern_module_descs
@@ -1220,6 +1222,7 @@
     ":chrome_jni_for_test_registration($default_toolchain)",
     "//base/test:test_support",
     "//chrome:chrome_android_core",
+    "//chrome/android/features/test_dummy/internal:base_module_native",
     "//chrome/browser/android/metrics:ukm_utils_for_test",
     "//components/autofill_assistant/browser:test_support",
     "//components/crash/android:crash_android",
@@ -1467,6 +1470,8 @@
     if (enable_vr) {
       deps += [ "//chrome/browser/android/vr:module_factory" ]
     }
+    deps +=
+        [ "//chrome/android/features/test_dummy/internal:base_module_native" ]
 
     is_monochrome = true
     allow_partitions = true
@@ -2213,40 +2218,17 @@
   }
 }
 
-# Feature modules that go into Chrome Modern application bundles.
-# Note that Mono- and Trichrome feature modules are instantiated in the
-# Mono- and Trichrome bundle target template.
-_chrome_modern_extra_modules = []
-foreach(_module_desc, chrome_modern_module_descs) {
-  chrome_feature_module(
-      "chrome_modern_public_bundle_${_module_desc.name}_bundle_module") {
-    manifest_package = chrome_public_manifest_package
-    base_module_target = ":chrome_modern_public_base_bundle_module"
-    uncompress_shared_libraries = chromium_linker_supported
-    is_monochrome_or_trichrome = false
-    is_64_bit_browser = android_64bit_target_cpu
-    include_32_bit_webview = false
-    version_code = chrome_modern_version_code
-    version_name = chrome_version_name
-    module_desc = _module_desc
-    min_sdk_version = 21
-  }
-  _module_desc.module_target =
-      ":chrome_modern_public_bundle_${_module_desc.name}_bundle_module"
-  _chrome_modern_extra_modules += [ _module_desc ]
-}
-
-android_app_bundle("chrome_modern_public_bundle") {
-  bundle_name = "ChromeModernPublic"
+chrome_bundle("chrome_modern_public_bundle") {
   base_module_target = ":chrome_modern_public_base_bundle_module"
-  command_line_flags_file = "chrome-command-line"
-  if (!is_java_debug) {
-    proguard_enabled = true
-  }
-  enable_language_splits = true
+  bundle_name = "ChromeModernPublic"
   compress_shared_libraries = true
+  include_32_bit_webview = false
+  is_64_bit_browser = android_64bit_target_cpu
+  is_monochrome_or_trichrome = false
+  manifest_package = chrome_public_manifest_package
   min_sdk_version = 21
-  extra_modules = _chrome_modern_extra_modules
+  module_descs = chrome_modern_module_descs
+  version_code = chrome_modern_version_code
 }
 
 if (is_official_build) {
@@ -2301,7 +2283,6 @@
       _version_code = monochrome_version_code
     }
   }
-  _version_name = chrome_version_name
 
   monochrome_public_apk_or_module_tmpl(_base_module_target_name) {
     forward_variables_from(invoker,
@@ -2314,7 +2295,6 @@
     target_type = "android_app_bundle_module"
     is_base_module = true
     version_code = _version_code
-    version_name = _version_name
 
     if (defined(invoker.verify_android_configuration) &&
         invoker.verify_android_configuration) {
@@ -2327,49 +2307,30 @@
     }
   }
 
-  _extra_modules = []
-  foreach(_module_desc, _module_descs) {
-    chrome_feature_module("${target_name}_${_module_desc.name}_bundle_module") {
-      manifest_package = chrome_public_manifest_package
-      base_module_target = ":$_base_module_target_name"
-      uncompress_shared_libraries = true
-      is_monochrome_or_trichrome = true
-      is_64_bit_browser =
-          defined(invoker.is_64_bit_browser) && invoker.is_64_bit_browser
-      include_32_bit_webview = defined(invoker.include_32_bit_webview) &&
-                               invoker.include_32_bit_webview
-      version_code = _version_code
-      version_name = _version_name
-      module_desc = _module_desc
-      min_sdk_version = _min_sdk_version
-    }
-    _module_desc.module_target =
-        ":${target_name}_${_module_desc.name}_bundle_module"
-    _extra_modules += [ _module_desc ]
-  }
-
-  android_app_bundle(target_name) {
-    bundle_name = _bundle_name
+  chrome_bundle(target_name) {
     base_module_target = ":$_base_module_target_name"
-    command_line_flags_file = "chrome-command-line"
-    system_image_locale_whitelist = locales - android_chrome_omitted_locales
+    bundle_name = _bundle_name
+    include_32_bit_webview = defined(invoker.include_32_bit_webview) &&
+                             invoker.include_32_bit_webview
+    is_64_bit_browser =
+        defined(invoker.is_64_bit_browser) && invoker.is_64_bit_browser
+    is_monochrome_or_trichrome = true
+    manifest_package = chrome_public_manifest_package
+    min_sdk_version = _min_sdk_version
+    module_descs = _module_descs
+    version_code = _version_code
 
     if (!is_java_debug) {
-      proguard_enabled = true
       proguard_android_sdk_dep = webview_framework_dep
       if (defined(invoker.verify_android_configuration) &&
           invoker.verify_android_configuration) {
         verify_proguard_flags = true
       }
     }
-    enable_language_splits = true
-    min_sdk_version = _min_sdk_version
 
     if (trichrome_synchronized_proguard && _is_trichrome) {
       static_library_provider = ":trichrome_library_for_bundle_apk"
     }
-
-    extra_modules = _extra_modules
   }
 }
 
diff --git a/chrome/android/OWNERS b/chrome/android/OWNERS
index 75033c71..6f884b4 100644
--- a/chrome/android/OWNERS
+++ b/chrome/android/OWNERS
@@ -16,6 +16,7 @@
 per-file BUILD.gn=estevenson@chromium.org
 per-file BUILD.gn=tiborg@chromium.org
 per-file BUILD.gn=wnwen@chromium.org
+per-file chrome_bundle_tmpl.gni=tiborg@chromium.org
 # For VR Javatest changes
 per-file BUILD.gn=bsheedy@chromium.org
 
diff --git a/chrome/android/chrome_bundle_tmpl.gni b/chrome/android/chrome_bundle_tmpl.gni
new file mode 100644
index 0000000..42a659f
--- /dev/null
+++ b/chrome/android/chrome_bundle_tmpl.gni
@@ -0,0 +1,74 @@
+# Copyright 2019 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+import("//base/android/linker/config.gni")
+import("//build/config/android/config.gni")
+import("//build/util/version.gni")
+import("//chrome/android/modules/chrome_feature_module_tmpl.gni")
+
+# Instantiates a Chrome-specific app bundle.
+#
+# Supports most attributes of chrome_feature_module and android_app_bundle,
+# plus:
+#   module_descs: List of descriptors for modules that are part of this bundle.
+#     See //chrome/android/modules/chrome_feature_modules.gni for the format of
+#     a module descriptor.
+template("chrome_bundle") {
+  _bundle_target_name = target_name
+  _extra_modules = []
+  foreach(_module_desc, invoker.module_descs) {
+    chrome_feature_module(
+        "${_bundle_target_name}__${_module_desc.name}_bundle_module") {
+      forward_variables_from(invoker,
+                             [
+                               "base_module_target",
+                               "include_32_bit_webview",
+                               "is_64_bit_browser",
+                               "is_monochrome_or_trichrome",
+                               "manifest_package",
+                               "min_sdk_version",
+                               "version_code",
+                             ])
+      module_desc = _module_desc
+      version_name = chrome_version_name
+      uncompress_shared_libraries =
+          invoker.is_monochrome_or_trichrome || chromium_linker_supported
+    }
+    _module_desc.module_target =
+        ":${_bundle_target_name}__${_module_desc.name}_bundle_module"
+    _extra_modules += [ _module_desc ]
+  }
+
+  android_app_bundle(target_name) {
+    forward_variables_from(invoker,
+                           [
+                             "base_module_target",
+                             "bundle_name",
+                             "compress_shared_libraries",
+                             "keystore_name",
+                             "keystore_password",
+                             "keystore_path",
+                             "min_sdk_version",
+                             "proguard_android_sdk_dep",
+                             "proguard_jar_path",
+                             "sign_bundle",
+                             "static_library_provider",
+                             "verify_proguard_flags",
+                           ])
+    command_line_flags_file = "chrome-command-line"
+    proguard_enabled = !is_java_debug
+    enable_language_splits = true
+    extra_modules = _extra_modules
+    system_image_locale_whitelist = locales - android_chrome_omitted_locales
+
+    # NOTE: Only sign bundle for official builds since this is very slow.
+    if (enable_chrome_android_internal && use_signing_keys &&
+        is_official_build) {
+      sign_bundle = true
+      keystore_path = chrome_keystore_path
+      keystore_name = chrome_keystore_name
+      keystore_password = chrome_keystore_password
+    }
+  }
+}
diff --git a/chrome/android/chrome_public_apk_tmpl.gni b/chrome/android/chrome_public_apk_tmpl.gni
index 5080fa07..17797eb 100644
--- a/chrome/android/chrome_public_apk_tmpl.gni
+++ b/chrome/android/chrome_public_apk_tmpl.gni
@@ -11,6 +11,7 @@
 import("//build/config/locales.gni")
 import("//build/util/version.gni")
 import("//chrome/android/chrome_common_shared_library.gni")
+import("//chrome/android/features/dev_ui/dev_ui_module.gni")
 import("//chrome/common/features.gni")
 import("//device/vr/buildflags/buildflags.gni")
 import("channel.gni")
@@ -235,7 +236,19 @@
     # for all other targets to save some binary size.
     if (_target_type == "android_app_bundle_module") {
       srcjar_deps = [ "//components/module_installer/android:module_installer_bundle_build_config" ]
-    } else {
+    } else {  # |_target_type| is "android_apk" or "instrumentation_test_apk".
+      if (dfmify_dev_ui) {
+        # Native resource split moves resources out of resources.pak, but this
+        # is a DFM feature, which APKs don't use. To make the resources split
+        # available for APKs, add dependencies to (1) Java classes, (2)
+        # resources of the resource split's DFM (e.g., DevUI DFM). The Java
+        # classes tells Chrome that the DFM is installed, which then causes the
+        # included resources to be loaded when needed.
+        deps += [
+          "//chrome/android/features/dev_ui:java",  # (1) from above.
+          "//chrome/android/features/dev_ui:pak_assets",  # (2) from above.
+        ]
+      }
       srcjar_deps = [ "//components/module_installer/android:module_installer_apk_build_config" ]
     }
 
diff --git a/chrome/android/features/tab_ui/java/res/color/dark_text_color_list.xml b/chrome/android/features/tab_ui/java/res/color/dark_text_color_list.xml
new file mode 100644
index 0000000..fa06562
--- /dev/null
+++ b/chrome/android/features/tab_ui/java/res/color/dark_text_color_list.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright 2019 The Chromium Authors. All rights reserved.
+     Use of this source code is governed by a BSD-style license that can be
+     found in the LICENSE file.
+-->
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:alpha="@dimen/default_disabled_alpha"
+        android:color="@color/default_text_color_dark" android:state_enabled="false"/>
+    <item android:color="@color/default_text_color_dark" />
+</selector>
\ No newline at end of file
diff --git a/chrome/android/features/tab_ui/java/res/drawable/tab_grid_selection_list_icon.xml b/chrome/android/features/tab_ui/java/res/drawable/tab_grid_selection_list_icon.xml
index 0c2d8daf..f0d593b 100644
--- a/chrome/android/features/tab_ui/java/res/drawable/tab_grid_selection_list_icon.xml
+++ b/chrome/android/features/tab_ui/java/res/drawable/tab_grid_selection_list_icon.xml
@@ -6,6 +6,7 @@
 <level-list xmlns:android="http://schemas.android.com/apk/res/android">
     <item android:maxLevel="@integer/list_item_level_default">
         <shape android:shape="oval">
+            <solid android:color="@android:color/transparent"/>
             <stroke
                 android:width="2dp"
                 android:color="@color/default_icon_color"/>
diff --git a/chrome/android/features/tab_ui/java/res/values/styles.xml b/chrome/android/features/tab_ui/java/res/values/styles.xml
index 70624521..74947715 100644
--- a/chrome/android/features/tab_ui/java/res/values/styles.xml
+++ b/chrome/android/features/tab_ui/java/res/values/styles.xml
@@ -6,9 +6,14 @@
      found in the LICENSE file.
 -->
 
-<resources xmlns:tools="http://schemas.android.com/tools">
-    <!-- TODO(996512): Consider to add this TextAppearance to the main styles.xml -->
-    <style name="TextAppearance.BlueTitle2Incognito" parent="TextAppearance.BlueTitle2" tools:ignore="UnusedResources">
+<resources>
+    <!-- TODO(996512): Consider to add these TextAppearance to the main styles.xml. These are non adaptive colors. -->
+    <style name="TextAppearance.BlueTitle2Incognito" parent="TextAppearance.BlueTitle2">
         <item name="android:textColor">@color/modern_blue_300</item>
     </style>
+
+    <style name="TextAppearance.BlackHeadline.Black" parent="TextAppearance.WhiteHeadline">
+        <item name="android:textColor">@color/default_text_color_dark</item>
+    </style>
+
 </resources>
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGridItemTouchHelperCallback.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGridItemTouchHelperCallback.java
index f03929f..1b1cd94 100644
--- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGridItemTouchHelperCallback.java
+++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGridItemTouchHelperCallback.java
@@ -154,7 +154,7 @@
             if (mHoveredTabIndex != TabModel.INVALID_TAB_INDEX && mActionsOnAllRelatedTabs) {
                 RecyclerView.ViewHolder selectedViewHolder =
                         mRecyclerView.findViewHolderForAdapterPosition(mSelectedTabIndex);
-                if (selectedViewHolder != null) {
+                if (selectedViewHolder != null && !mRecyclerView.isComputingLayout()) {
                     View selectedItemView = selectedViewHolder.itemView;
                     onTabMergeToGroup(mSelectedTabIndex, mHoveredTabIndex);
                     mRecyclerView.getLayoutManager().removeView(selectedItemView);
@@ -173,7 +173,7 @@
                                 .getCurrentTabModelFilter();
                 RecyclerView.ViewHolder ungroupViewHolder =
                         mRecyclerView.findViewHolderForAdapterPosition(mUnGroupTabIndex);
-                if (ungroupViewHolder != null) {
+                if (ungroupViewHolder != null && !mRecyclerView.isComputingLayout()) {
                     View ungroupItemView = ungroupViewHolder.itemView;
                     filter.moveTabOutOfGroup(
                             mModel.get(mUnGroupTabIndex).model.get(TabProperties.TAB_ID));
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGridViewBinder.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGridViewBinder.java
index 451655b..61763b4c 100644
--- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGridViewBinder.java
+++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGridViewBinder.java
@@ -11,6 +11,7 @@
 import android.os.Build;
 import android.support.graphics.drawable.AnimatedVectorDrawableCompat;
 import android.support.v4.content.res.ResourcesCompat;
+import android.support.v4.graphics.drawable.DrawableCompat;
 import android.support.v4.view.ViewCompat;
 import android.view.View;
 import android.view.ViewGroup;
@@ -127,8 +128,6 @@
             faviconView.setPadding(padding, padding, padding, padding);
         } else if (TabProperties.THUMBNAIL_FETCHER == propertyKey) {
             updateThumbnail(view, model);
-        } else if (TabProperties.IS_INCOGNITO == propertyKey) {
-            updateColor(view, model.get(TabProperties.IS_INCOGNITO));
         }
     }
 
@@ -174,6 +173,8 @@
             ((ClosableTabGridView) view)
                     .scaleTabGridCardView(
                             model.get(TabProperties.CARD_ANIMATION_STATUS), isSelected);
+        } else if (TabProperties.IS_INCOGNITO == propertyKey) {
+            updateColor(view, model.get(TabProperties.IS_INCOGNITO), TabProperties.UiType.CLOSABLE);
         }
     }
 
@@ -188,6 +189,10 @@
             boolean isSelected = model.get(TabProperties.IS_SELECTED);
             ImageView actionButton = (ImageView) view.fastFindViewById(R.id.action_button);
             actionButton.getBackground().setLevel(isSelected ? selectedLevel : defaultLevel);
+            DrawableCompat.setTintList(actionButton.getBackground().mutate(),
+                    isSelected ? model.get(
+                            TabProperties.SELECTABLE_TAB_ACTION_BUTTON_SELECTED_BACKGROUND)
+                               : model.get(TabProperties.SELECTABLE_TAB_ACTION_BUTTON_BACKGROUND));
 
             // The check should be invisible if not selected.
             actionButton.getDrawable().setAlpha(isSelected ? 255 : 0);
@@ -214,6 +219,9 @@
             ((SelectableTabGridView) view)
                     .setSelectionDelegate(model.get(TabProperties.TAB_SELECTION_DELEGATE));
             ((SelectableTabGridView) view).setItem(tabId);
+        } else if (TabProperties.IS_INCOGNITO == propertyKey) {
+            updateColor(
+                    view, model.get(TabProperties.IS_INCOGNITO), TabProperties.UiType.SELECTABLE);
         }
     }
 
@@ -237,7 +245,8 @@
         fetcher.fetch(callback);
     }
 
-    private static void updateColor(ViewLookupCachingFrameLayout rootView, boolean isIncognito) {
+    private static void updateColor(ViewLookupCachingFrameLayout rootView, boolean isIncognito,
+            @TabProperties.UiType int viewType) {
         View cardView = rootView.fastFindViewById(R.id.card_view);
         View dividerView = rootView.fastFindViewById(R.id.divider_view);
         ImageView thumbnail = (ImageView) rootView.fastFindViewById(R.id.tab_thumbnail);
@@ -261,9 +270,6 @@
         dividerView.setBackgroundColor(
                 TabUiColorProvider.getDividerColor(dividerView.getContext(), isIncognito));
 
-        ApiCompatibilityUtils.setImageTintList(actionButton,
-                TabUiColorProvider.getActionButtonTintList(actionButton.getContext(), isIncognito));
-
         ApiCompatibilityUtils.setTextAppearance(
                 ((TextView) rootView.fastFindViewById(R.id.tab_title)),
                 TabUiColorProvider.getTitleTextAppearance(isIncognito));
@@ -278,5 +284,11 @@
                     TabUiColorProvider.getHoveredCardBackgroundTintList(
                             backgroundView.getContext(), isIncognito));
         }
+
+        if (viewType == TabProperties.UiType.CLOSABLE) {
+            ApiCompatibilityUtils.setImageTintList(actionButton,
+                    TabUiColorProvider.getActionButtonTintList(
+                            actionButton.getContext(), isIncognito));
+        }
     }
 }
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabListMediator.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabListMediator.java
index 2e2ea626..3123116 100644
--- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabListMediator.java
+++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabListMediator.java
@@ -7,6 +7,7 @@
 import android.app.Activity;
 import android.content.ComponentCallbacks;
 import android.content.Context;
+import android.content.res.ColorStateList;
 import android.content.res.Configuration;
 import android.graphics.Bitmap;
 import android.graphics.drawable.Drawable;
@@ -461,8 +462,9 @@
             @Override
             public void didMoveTab(Tab tab, int newIndex, int curIndex) {
                 if (mTabModelSelector.getTabModelFilterProvider().getCurrentTabModelFilter()
-                                instanceof TabGroupModelFilter)
+                                instanceof TabGroupModelFilter) {
                     return;
+                }
                 onTabMoved(newIndex, curIndex);
             }
 
@@ -980,9 +982,28 @@
                         .build();
 
         if (mUiType == UiType.SELECTABLE) {
-            tabInfo.set(TabProperties.CHECKED_DRAWABLE_STATE_LIST,
-                    AppCompatResources.getColorStateList(
-                            mContext, R.color.default_icon_color_inverse));
+            // Incognito in both light/dark theme is the same as non-incognito mode in dark theme.
+            // Non-incognito mode and incognito in both light/dark themes in dark theme all look
+            // dark.
+            ColorStateList checkedDrawableColorList = AppCompatResources.getColorStateList(mContext,
+                    tab.isIncognito() ? R.color.default_icon_color_dark
+                                      : R.color.default_icon_color_inverse);
+            ColorStateList actionButtonBackgroundColorList =
+                    AppCompatResources.getColorStateList(mContext,
+                            tab.isIncognito() ? R.color.default_icon_color_white
+                                              : R.color.default_icon_color);
+            // TODO(995876): Update color modern_blue_300 to active_color_dark when the associated
+            // bug is landed.
+            ColorStateList actionbuttonSelectedBackgroundColorList =
+                    AppCompatResources.getColorStateList(mContext,
+                            tab.isIncognito() ? R.color.modern_blue_300
+                                              : R.color.light_active_color);
+
+            tabInfo.set(TabProperties.CHECKED_DRAWABLE_STATE_LIST, checkedDrawableColorList);
+            tabInfo.set(TabProperties.SELECTABLE_TAB_ACTION_BUTTON_BACKGROUND,
+                    actionButtonBackgroundColorList);
+            tabInfo.set(TabProperties.SELECTABLE_TAB_ACTION_BUTTON_SELECTED_BACKGROUND,
+                    actionbuttonSelectedBackgroundColorList);
         }
 
         if (index >= mModel.size()) {
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabProperties.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabProperties.java
index e02f810f..81a3e7d 100644
--- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabProperties.java
+++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabProperties.java
@@ -80,12 +80,21 @@
     public static final PropertyModel.ReadableIntPropertyKey TABSTRIP_FAVICON_BACKGROUND_COLOR_ID =
             new PropertyModel.ReadableIntPropertyKey();
 
+    public static final PropertyModel
+            .WritableObjectPropertyKey<ColorStateList> SELECTABLE_TAB_ACTION_BUTTON_BACKGROUND =
+            new PropertyModel.WritableObjectPropertyKey<>();
+
+    public static final PropertyModel.WritableObjectPropertyKey<ColorStateList>
+            SELECTABLE_TAB_ACTION_BUTTON_SELECTED_BACKGROUND =
+            new PropertyModel.WritableObjectPropertyKey<>();
+
     public static final PropertyKey[] ALL_KEYS_TAB_GRID = new PropertyKey[] {TAB_ID,
             TAB_SELECTED_LISTENER, TAB_CLOSED_LISTENER, FAVICON, THUMBNAIL_FETCHER, IPH_PROVIDER,
             TITLE, IS_SELECTED, CHECKED_DRAWABLE_STATE_LIST, CREATE_GROUP_LISTENER, ALPHA,
             CARD_ANIMATION_STATUS, SELECTABLE_TAB_CLICKED_LISTENER, TAB_SELECTION_DELEGATE,
-            IS_INCOGNITO, SELECTED_TAB_BACKGROUND_DRAWABLE_ID,
-            TABSTRIP_FAVICON_BACKGROUND_COLOR_ID};
+            IS_INCOGNITO, SELECTED_TAB_BACKGROUND_DRAWABLE_ID, TABSTRIP_FAVICON_BACKGROUND_COLOR_ID,
+            SELECTABLE_TAB_ACTION_BUTTON_BACKGROUND,
+            SELECTABLE_TAB_ACTION_BUTTON_SELECTED_BACKGROUND};
 
     public static final PropertyKey[] ALL_KEYS_TAB_STRIP =
             new PropertyKey[] {TAB_ID, TAB_SELECTED_LISTENER, TAB_CLOSED_LISTENER, FAVICON,
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabSelectionEditorLayoutBinder.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabSelectionEditorLayoutBinder.java
index 144b692..26fd19c 100644
--- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabSelectionEditorLayoutBinder.java
+++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabSelectionEditorLayoutBinder.java
@@ -31,6 +31,17 @@
         } else if (TabSelectionEditorProperties.TOOLBAR_NAVIGATION_LISTENER == propertyKey) {
             view.getToolbar().setNavigationOnClickListener(
                     model.get(TabSelectionEditorProperties.TOOLBAR_NAVIGATION_LISTENER));
+        } else if (TabSelectionEditorProperties.PRIMARY_COLOR == propertyKey) {
+            view.setBackgroundColor(model.get(TabSelectionEditorProperties.PRIMARY_COLOR));
+        } else if (TabSelectionEditorProperties.TOOLBAR_BACKGROUND_COLOR == propertyKey) {
+            view.getToolbar().setToolbarBackgroundColor(
+                    model.get(TabSelectionEditorProperties.TOOLBAR_BACKGROUND_COLOR));
+        } else if (TabSelectionEditorProperties.TOOLBAR_GROUP_BUTTON_TINT == propertyKey) {
+            view.getToolbar().setButtonTint(
+                    model.get(TabSelectionEditorProperties.TOOLBAR_GROUP_BUTTON_TINT));
+        } else if (TabSelectionEditorProperties.TOOLBAR_TEXT_APPEARANCE == propertyKey) {
+            view.getToolbar().setTextAppearance(
+                    model.get(TabSelectionEditorProperties.TOOLBAR_TEXT_APPEARANCE));
         }
     }
 }
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabSelectionEditorMediator.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabSelectionEditorMediator.java
index c1acc85..5c62502 100644
--- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabSelectionEditorMediator.java
+++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabSelectionEditorMediator.java
@@ -5,19 +5,26 @@
 package org.chromium.chrome.browser.tasks.tab_management;
 
 import android.content.Context;
+import android.content.res.ColorStateList;
+import android.support.annotation.ColorInt;
+import android.support.v7.content.res.AppCompatResources;
 import android.view.View;
 
 import androidx.annotation.Nullable;
 
+import org.chromium.base.ApiCompatibilityUtils;
 import org.chromium.base.metrics.RecordUserAction;
 import org.chromium.chrome.browser.tab.Tab;
+import org.chromium.chrome.browser.tabmodel.EmptyTabModelSelectorObserver;
 import org.chromium.chrome.browser.tabmodel.TabLaunchType;
 import org.chromium.chrome.browser.tabmodel.TabModel;
 import org.chromium.chrome.browser.tabmodel.TabModelSelector;
+import org.chromium.chrome.browser.tabmodel.TabModelSelectorObserver;
 import org.chromium.chrome.browser.tabmodel.TabModelSelectorTabModelObserver;
 import org.chromium.chrome.browser.tabmodel.TabModelUtils;
 import org.chromium.chrome.browser.tasks.tab_groups.TabGroupModelFilter;
 import org.chromium.chrome.browser.widget.selection.SelectionDelegate;
+import org.chromium.chrome.tab_ui.R;
 import org.chromium.ui.modelutil.PropertyModel;
 
 import java.util.ArrayList;
@@ -47,6 +54,7 @@
     private final PropertyModel mModel;
     private final SelectionDelegate<Integer> mSelectionDelegate;
     private final TabModelSelectorTabModelObserver mTabModelObserver;
+    private final TabModelSelectorObserver mTabModelSelectorObserver;
 
     private final View.OnClickListener mNavigationClickListener = new View.OnClickListener() {
         @Override
@@ -105,6 +113,38 @@
                 }
             }
         };
+
+        mTabModelSelectorObserver = new EmptyTabModelSelectorObserver() {
+            @Override
+            public void onTabModelSelected(TabModel newModel, TabModel oldModel) {
+                // Incognito in both light/dark theme is the same as non-incognito mode in dark
+                // theme. Non-incognito mode and incognito in both light/dark themes in dark theme
+                // all look dark.
+                boolean isIncognito = newModel.isIncognito();
+                @ColorInt
+                int primaryColor = ApiCompatibilityUtils.getColor(mContext.getResources(),
+                        isIncognito ? R.color.incognito_modern_primary_color
+                                    : R.color.modern_primary_color);
+                // TODO(995876): Update color modern_blue_300 to active_color_dark when the
+                // associated bug is landed.
+                @ColorInt
+                int toolbarBackgroundColor = ApiCompatibilityUtils.getColor(mContext.getResources(),
+                        isIncognito ? R.color.modern_blue_300 : R.color.light_active_color);
+                ColorStateList toolbarTintColorList = AppCompatResources.getColorStateList(mContext,
+                        isIncognito ? R.color.dark_text_color_list
+                                    : R.color.default_text_color_inverse_list);
+                int textAppearance = isIncognito ? R.style.TextAppearance_BlackHeadline_Black
+                                                 : R.style.TextAppearance_Headline_Inverse;
+
+                mModel.set(TabSelectionEditorProperties.PRIMARY_COLOR, primaryColor);
+                mModel.set(TabSelectionEditorProperties.TOOLBAR_BACKGROUND_COLOR,
+                        toolbarBackgroundColor);
+                mModel.set(TabSelectionEditorProperties.TOOLBAR_GROUP_BUTTON_TINT,
+                        toolbarTintColorList);
+                mModel.set(TabSelectionEditorProperties.TOOLBAR_TEXT_APPEARANCE, textAppearance);
+            }
+        };
+        mTabModelSelector.addObserver(mTabModelSelectorObserver);
     }
 
     /**
@@ -152,5 +192,8 @@
      */
     public void destroy() {
         mTabModelObserver.destroy();
+        if (mTabModelSelector != null) {
+            mTabModelSelector.removeObserver(mTabModelSelectorObserver);
+        }
     }
 }
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabSelectionEditorProperties.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabSelectionEditorProperties.java
index fef40213..a7e0507 100644
--- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabSelectionEditorProperties.java
+++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabSelectionEditorProperties.java
@@ -4,6 +4,7 @@
 
 package org.chromium.chrome.browser.tasks.tab_management;
 
+import android.content.res.ColorStateList;
 import android.view.View;
 
 import org.chromium.ui.modelutil.PropertyKey;
@@ -24,6 +25,20 @@
             .WritableObjectPropertyKey<View.OnClickListener> TOOLBAR_NAVIGATION_LISTENER =
             new PropertyModel.WritableObjectPropertyKey<>();
 
-    public static final PropertyKey[] ALL_KEYS = new PropertyKey[] {
-            IS_VISIBLE, TOOLBAR_GROUP_BUTTON_LISTENER, TOOLBAR_NAVIGATION_LISTENER};
+    public static final PropertyModel.WritableIntPropertyKey PRIMARY_COLOR =
+            new PropertyModel.WritableIntPropertyKey();
+
+    public static final PropertyModel.WritableIntPropertyKey TOOLBAR_BACKGROUND_COLOR =
+            new PropertyModel.WritableIntPropertyKey();
+
+    public static final PropertyModel
+            .WritableObjectPropertyKey<ColorStateList> TOOLBAR_GROUP_BUTTON_TINT =
+            new PropertyModel.WritableObjectPropertyKey<>();
+
+    public static final PropertyModel.WritableIntPropertyKey TOOLBAR_TEXT_APPEARANCE =
+            new PropertyModel.WritableIntPropertyKey();
+
+    public static final PropertyKey[] ALL_KEYS = new PropertyKey[] {IS_VISIBLE,
+            TOOLBAR_GROUP_BUTTON_LISTENER, TOOLBAR_NAVIGATION_LISTENER, PRIMARY_COLOR,
+            TOOLBAR_BACKGROUND_COLOR, TOOLBAR_GROUP_BUTTON_TINT, TOOLBAR_TEXT_APPEARANCE};
 }
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabSelectionEditorToolbar.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabSelectionEditorToolbar.java
index f17bdab4..6171fbf5 100644
--- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabSelectionEditorToolbar.java
+++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabSelectionEditorToolbar.java
@@ -6,10 +6,12 @@
 
 import android.content.Context;
 import android.content.res.ColorStateList;
+import android.support.annotation.ColorInt;
 import android.support.v7.content.res.AppCompatResources;
 import android.util.AttributeSet;
 import android.widget.Button;
 
+import org.chromium.chrome.browser.widget.NumberRollView;
 import org.chromium.chrome.browser.widget.TintedDrawable;
 import org.chromium.chrome.browser.widget.selection.SelectableListToolbar;
 import org.chromium.chrome.tab_ui.R;
@@ -23,6 +25,8 @@
 class TabSelectionEditorToolbar extends SelectableListToolbar<Integer> {
     private static final List<Integer> sEmptyIntegerList = Collections.emptyList();
     private Button mGroupButton;
+    @ColorInt
+    private int mBackgroundColor;
 
     public TabSelectionEditorToolbar(Context context, AttributeSet attrs) {
         super(context, attrs);
@@ -64,6 +68,14 @@
         showSelectionView(sEmptyIntegerList, true);
     }
 
+    @Override
+    protected void showSelectionView(List<Integer> selectedItems, boolean wasSelectionEnabled) {
+        super.showSelectionView(selectedItems, wasSelectionEnabled);
+        if (mBackgroundColor != 0) {
+            setBackgroundColor(mBackgroundColor);
+        }
+    }
+
     /**
      * Sets a {@link android.view.View.OnClickListener} to respond to {@code mGroupButton} clicking
      * event.
@@ -72,4 +84,30 @@
     public void setActionButtonOnClickListener(OnClickListener listener) {
         mGroupButton.setOnClickListener(listener);
     }
+
+    /**
+     * Update the tint for buttons, the navigation button and the action button, in the toolbar.
+     * @param tint New {@link ColorStateList} to use.
+     */
+    public void setButtonTint(ColorStateList tint) {
+        mGroupButton.setTextColor(tint);
+        TintedDrawable navigation = (TintedDrawable) getNavigationIcon();
+        navigation.setTint(tint);
+    }
+
+    /**
+     * Update the toolbar background color.
+     * @param backgroundColor The new color to use.
+     */
+    public void setToolbarBackgroundColor(@ColorInt int backgroundColor) {
+        mBackgroundColor = backgroundColor;
+    }
+
+    /**
+     * Update the text appearance for {@link NumberRollView}.
+     * @param resId The new text appearance to use.
+     */
+    public void setTextAppearance(int resId) {
+        mNumberRollView.setTextAppearance(resId);
+    }
 }
diff --git a/chrome/android/features/tab_ui/java/strings/android_chrome_tab_ui_strings.grd b/chrome/android/features/tab_ui/java/strings/android_chrome_tab_ui_strings.grd
index c3df219..648b62d 100644
--- a/chrome/android/features/tab_ui/java/strings/android_chrome_tab_ui_strings.grd
+++ b/chrome/android/features/tab_ui/java/strings/android_chrome_tab_ui_strings.grd
@@ -192,7 +192,7 @@
         Get organized
       </message>
       <message name="IDS_IPH_DRAG_AND_DROP_CONTENT" desc="This text shows on the in-product help dialog for drag-and-drop. It gives instructions on how to drag and drop to create a group.">
-        Drag a tab onto another tab to group them
+        To group tabs, touch &amp; hold a tab. Then, drag it onto another tab.
       </message>
 
       <!-- Tab Carousel strings -->
@@ -204,4 +204,4 @@
       </message>
     </messages>
   </release>
-</grit>
\ No newline at end of file
+</grit>
diff --git a/chrome/android/features/tab_ui/junit/src/org/chromium/chrome/browser/tasks/tab_management/TabGridItemTouchHelperCallbackUnitTest.java b/chrome/android/features/tab_ui/junit/src/org/chromium/chrome/browser/tasks/tab_management/TabGridItemTouchHelperCallbackUnitTest.java
index 0d4ffb35..ea20f9f 100644
--- a/chrome/android/features/tab_ui/junit/src/org/chromium/chrome/browser/tasks/tab_management/TabGridItemTouchHelperCallbackUnitTest.java
+++ b/chrome/android/features/tab_ui/junit/src/org/chromium/chrome/browser/tasks/tab_management/TabGridItemTouchHelperCallbackUnitTest.java
@@ -392,6 +392,33 @@
     }
 
     @Test
+    public void onReleaseTab_Merge_Scrolling() {
+        initAndAssertAllProperties();
+
+        // Simulate the selection of card#2 in TabListModel.
+        mModel.get(1).model.set(TabProperties.CARD_ANIMATION_STATUS,
+                ClosableTabGridView.AnimationStatus.SELECTED_CARD_ZOOM_IN);
+        mModel.get(1).model.set(TabProperties.ALPHA, 0.8f);
+        mItemTouchHelperCallback.setSelectedTabIndexForTesting(POSITION2);
+
+        // Simulate hovering on card#1.
+        mItemTouchHelperCallback.setHoveredTabIndexForTesting(POSITION1);
+
+        // Simulate that the recyclerView is scrolling when the drop-to-merge happens.
+        when(mRecyclerView.isComputingLayout()).thenReturn(true);
+
+        mItemTouchHelperCallback.onSelectedChanged(
+                mMockViewHolder2, ItemTouchHelper.ACTION_STATE_IDLE);
+
+        verify(mGridLayoutManager, never()).removeView(mItemView2);
+        verify(mTabGroupModelFilter, never()).mergeTabsToGroup(TAB2_ID, TAB1_ID);
+        verify(mTracker, never()).notifyEvent(eq(EventConstants.TAB_DRAG_AND_DROP_TO_GROUP));
+        assertThat(mModel.get(1).model.get(TabProperties.CARD_ANIMATION_STATUS),
+                equalTo(ClosableTabGridView.AnimationStatus.SELECTED_CARD_ZOOM_OUT));
+        assertThat(mModel.get(1).model.get(TabProperties.ALPHA), equalTo(1f));
+    }
+
+    @Test
     public void onReleaseTab_UngroupBar_Hide() {
         initAndAssertAllProperties();
         setupItemTouchHelperCallback(true);
@@ -420,6 +447,25 @@
     }
 
     @Test
+    public void onReleaseTab_Ungroup_Scrolling() {
+        initAndAssertAllProperties();
+
+        setupItemTouchHelperCallback(true);
+        mItemTouchHelperCallback.setUnGroupTabIndexForTesting(POSITION1);
+
+        // Simulate that the recyclerView is scrolling when the drop-to-ungroup happens.
+        when(mRecyclerView.isComputingLayout()).thenReturn(true);
+
+        mItemTouchHelperCallback.onSelectedChanged(
+                mMockViewHolder1, ItemTouchHelper.ACTION_STATE_IDLE);
+
+        verify(mTabGroupModelFilter, never()).moveTabOutOfGroup(TAB1_ID);
+        verify(mTabGridDialogHandler)
+                .updateUngroupBarStatus(TabGridDialogParent.UngroupBarStatus.HIDE);
+        verify(mGridLayoutManager, never()).removeView(mItemView1);
+    }
+
+    @Test
     public void onReleaseTab_Ungroup_CleanOut() {
         initAndAssertAllProperties();
 
diff --git a/chrome/android/features/test_dummy/internal/BUILD.gn b/chrome/android/features/test_dummy/internal/BUILD.gn
index bf225b7..88df7f8e 100644
--- a/chrome/android/features/test_dummy/internal/BUILD.gn
+++ b/chrome/android/features/test_dummy/internal/BUILD.gn
@@ -2,10 +2,13 @@
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
+import("//build/buildflag_header.gni")
 import("//build/config/android/rules.gni")
+import("//chrome/android/modules/buildflags.gni")
 
 android_library("java") {
   deps = [
+    ":base_module_java",
     "//base:base_java",
     "//chrome/android/features/test_dummy/public:java",
     "//third_party/android_deps:android_support_v7_appcompat_java",
@@ -15,7 +18,22 @@
       [ "java/src/org/chromium/chrome/features/test_dummy/TestDummyImpl.java" ]
 }
 
-# Code that should go into the base module.
+source_set("native") {
+  sources = [
+    "test_dummy.cc",
+  ]
+
+  deps = [
+    "//base",
+    "//chrome/android/features/test_dummy/public:native",
+  ]
+}
+
+# Java code that should go into the base module. If this were a normal feature,
+# this target would reside in the client code using the module. Since this is a
+# test dummy module, it has no pre-existing client, and hence the target is
+# squatting here for convenience. The same is true for the corresponding native
+# target.
 android_library("base_module_java") {
   deps = [
     "//base:base_java",
@@ -24,5 +42,33 @@
   ]
   java_files = [
     "java/src/org/chromium/chrome/features/test_dummy/TestDummyActivity.java",
+    "java/src/org/chromium/chrome/features/test_dummy/TestDummySupport.java",
+  ]
+
+  annotation_processor_deps = [ "//base/android/jni_generator:jni_processor" ]
+  deps += [ "//base:jni_java" ]
+}
+
+buildflag_header("buildflags") {
+  header = "buildflags.h"
+  flags = [ "USE_NATIVE_MODULES=$use_native_modules" ]
+}
+
+source_set("base_module_native") {
+  sources = [
+    "test_dummy_client.cc",
+  ]
+  deps = [
+    ":test_dummy_jni_headers",
+    "//base",
+  ]
+  public_deps = [
+    ":buildflags",
+  ]
+}
+
+generate_jni("test_dummy_jni_headers") {
+  sources = [
+    "java/src/org/chromium/chrome/features/test_dummy/TestDummySupport.java",
   ]
 }
diff --git a/chrome/android/features/test_dummy/internal/java/src/org/chromium/chrome/features/test_dummy/TestDummyImpl.java b/chrome/android/features/test_dummy/internal/java/src/org/chromium/chrome/features/test_dummy/TestDummyImpl.java
index 87347a4..a41fcac 100644
--- a/chrome/android/features/test_dummy/internal/java/src/org/chromium/chrome/features/test_dummy/TestDummyImpl.java
+++ b/chrome/android/features/test_dummy/internal/java/src/org/chromium/chrome/features/test_dummy/TestDummyImpl.java
@@ -16,10 +16,11 @@
 
 /** Test dummy implementation. */
 public class TestDummyImpl implements TestDummy {
-    @IntDef({TestCase.EXECUTE_JAVA})
+    @IntDef({TestCase.EXECUTE_JAVA, TestCase.EXECUTE_NATIVE})
     @Retention(RetentionPolicy.SOURCE)
     private @interface TestCase {
         int EXECUTE_JAVA = 0;
+        int EXECUTE_NATIVE = 1;
     }
 
     @Override
@@ -30,20 +31,29 @@
             case TestCase.EXECUTE_JAVA:
                 executeJava(activity);
                 break;
+            case TestCase.EXECUTE_NATIVE:
+                executeNative(activity);
+                break;
             default:
                 throw new RuntimeException("Unknown test case " + testCase);
         }
     }
 
-    private void executeJava(Activity activity) {
-        showDoneDialog(activity, TestCase.EXECUTE_JAVA);
-    }
-
-    private void showDoneDialog(Activity activity, @TestCase int testCase) {
+    private void showDoneDialog(Activity activity, @TestCase int testCase, boolean pass) {
+        String message = "Test Case %d: " + (pass ? "pass" : "fail");
         AlertDialog.Builder builder = new AlertDialog.Builder(activity);
         builder.setTitle("Test Dummy Result");
-        builder.setMessage(String.format(Locale.US, "Test Case %d: done", testCase));
+        builder.setMessage(String.format(Locale.US, message, testCase));
         builder.setCancelable(true);
         builder.create().show();
     }
+
+    private void executeJava(Activity activity) {
+        showDoneDialog(activity, TestCase.EXECUTE_JAVA, true);
+    }
+
+    private void executeNative(Activity activity) {
+        boolean result = TestDummySupport.openAndVerifyNativeLibrary();
+        showDoneDialog(activity, TestCase.EXECUTE_NATIVE, result);
+    }
 }
diff --git a/chrome/android/features/test_dummy/internal/java/src/org/chromium/chrome/features/test_dummy/TestDummySupport.java b/chrome/android/features/test_dummy/internal/java/src/org/chromium/chrome/features/test_dummy/TestDummySupport.java
new file mode 100644
index 0000000..a1eef3f
--- /dev/null
+++ b/chrome/android/features/test_dummy/internal/java/src/org/chromium/chrome/features/test_dummy/TestDummySupport.java
@@ -0,0 +1,21 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package org.chromium.chrome.features.test_dummy;
+
+import org.chromium.base.annotations.NativeMethods;
+
+/** Support class to proxy JNI calls from module Java to module native. */
+//@MainDex
+public class TestDummySupport {
+    /** JNI calls for exercising native parts of the DFM. */
+    @NativeMethods
+    public interface Natives {
+        boolean openAndVerifyNativeLibrary();
+    }
+
+    public static boolean openAndVerifyNativeLibrary() {
+        return TestDummySupportJni.get().openAndVerifyNativeLibrary();
+    }
+}
diff --git a/chrome/android/features/test_dummy/internal/test_dummy.cc b/chrome/android/features/test_dummy/internal/test_dummy.cc
new file mode 100644
index 0000000..383ac985
--- /dev/null
+++ b/chrome/android/features/test_dummy/internal/test_dummy.cc
@@ -0,0 +1,18 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/android/features/test_dummy/public/test_dummy.h"
+
+#include "base/logging.h"
+
+namespace test_dummy {
+
+int TestDummy() {
+  // Log something to utilize base library code. This is necessary to ensure
+  // that calls to base code are linked properly.
+  LOG(WARNING) << "Running test dummy native library.";
+  return 123;
+}
+
+}  // namespace test_dummy
diff --git a/chrome/android/features/test_dummy/internal/test_dummy_client.cc b/chrome/android/features/test_dummy/internal/test_dummy_client.cc
new file mode 100644
index 0000000..70e5221
--- /dev/null
+++ b/chrome/android/features/test_dummy/internal/test_dummy_client.cc
@@ -0,0 +1,39 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <android/dlext.h>
+#include <dlfcn.h>
+
+#include "base/android/bundle_utils.h"
+#include "base/logging.h"
+#include "chrome/android/features/test_dummy/internal/buildflags.h"
+#include "chrome/android/features/test_dummy/internal/test_dummy_jni_headers/TestDummySupport_jni.h"
+
+static jboolean JNI_TestDummySupport_OpenAndVerifyNativeLibrary(JNIEnv* env) {
+#if BUILDFLAG(USE_NATIVE_MODULES)
+  // Note that the library opened here is not closed. dlclosing() libraries has
+  // proven to be problematic. See https://crbug.com/994029.
+  void* handle =
+      base::android::BundleUtils::DlOpenModuleLibraryPartition("test_dummy");
+  if (handle == nullptr) {
+    LOG(ERROR) << "Cannot open test library: " << dlerror();
+    return false;
+  }
+
+  void* symbol = dlsym(handle, "TestDummyEntrypoint");
+  if (symbol == nullptr) {
+    LOG(ERROR) << "Cannot find test library symbol";
+    return false;
+  }
+
+  typedef int TestFunction();
+  TestFunction* test_function = reinterpret_cast<TestFunction*>(symbol);
+  if (test_function() != 123) {
+    LOG(ERROR) << "Unexpected value from test library";
+    return false;
+  }
+#endif
+
+  return true;
+}
diff --git a/chrome/android/features/test_dummy/public/BUILD.gn b/chrome/android/features/test_dummy/public/BUILD.gn
index 128169c..62a8851 100644
--- a/chrome/android/features/test_dummy/public/BUILD.gn
+++ b/chrome/android/features/test_dummy/public/BUILD.gn
@@ -8,3 +8,9 @@
   java_files =
       [ "java/src/org/chromium/chrome/features/test_dummy/TestDummy.java" ]
 }
+
+source_set("native") {
+  sources = [
+    "test_dummy.h",
+  ]
+}
diff --git a/chrome/android/features/test_dummy/public/test_dummy.h b/chrome/android/features/test_dummy/public/test_dummy.h
new file mode 100644
index 0000000..47ed75f
--- /dev/null
+++ b/chrome/android/features/test_dummy/public/test_dummy.h
@@ -0,0 +1,15 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_ANDROID_FEATURES_TEST_DUMMY_PUBLIC_TEST_DUMMY_H_
+#define CHROME_ANDROID_FEATURES_TEST_DUMMY_PUBLIC_TEST_DUMMY_H_
+
+namespace test_dummy {
+
+// The test_dummy feature's token native entrypoint.
+int TestDummy();
+
+}  // namespace test_dummy
+
+#endif  // CHROME_ANDROID_FEATURES_TEST_DUMMY_PUBLIC_TEST_DUMMY_H_
diff --git a/chrome/android/java/monochrome_public_bundle.proguard_flags.expected b/chrome/android/java/monochrome_public_bundle.proguard_flags.expected
index 1977d35..d5df36c37b 100644
--- a/chrome/android/java/monochrome_public_bundle.proguard_flags.expected
+++ b/chrome/android/java/monochrome_public_bundle.proguard_flags.expected
@@ -42,30 +42,20 @@
 -keep class com.android.webview.chromium.DrawGLFunctor
 -keep class com.android.webview.chromium.GraphicsUtils
 
-# Don't note about the API 21 compatibility code which references various
-# hidden APIs via reflection.
--dontnote com.android.webview.chromium.WebViewDelegateFactory$Api21CompatibilityDelegate
-
-# DefaultAndroidKeyStore uses reflection to access internal OpenSSL state.
--dontnote org.chromium.net.DefaultAndroidKeyStore
-
-# MediaPlayerBridge uses reflection to access internal metadata.
--dontnote org.chromium.media.MediaPlayerBridge
-
-# ProxyChangeListener$ProxyReceiver uses reflection to access internal
-# android.net.ProxyProperties.
--dontnote org.chromium.net.ProxyChangeListener$ProxyReceiver
-
 -keep class org.chromium.android_webview.AwBrowserProcess {
     java.nio.channels.FileLock sExclusiveFileLock;
 }
 
-# We strip some unused resources when preprocessing the GMS client libs.
--dontwarn com.google.android.gms.R**
-
-# Trichrome builds don't include a native library list in the main APK; it's
-# picked up from the library APK at runtime.
--dontwarn org.chromium.base.library_loader.NativeLibraries
+# Workaround for crbug/1002847. Methods of BaseGmsClient are incorrectly
+# removed even though they are required for the derived class GmsClient
+# to correctly implement Api$Client.
+# TODO: remove once crbug/1002847 resolved.
+-keep public class com.google.android.gms.common.internal.BaseGmsClient {
+  public void disconnect();
+  public void dump(java.lang.String,java.io.FileDescriptor,java.io.PrintWriter,java.lang.String[]);
+  public int getMinApkVersion();
+  public boolean requiresSignIn();
+}
 
 ################################################################################
 # ../../android_webview/support_library/boundary_interfaces/proguard.flags
@@ -150,11 +140,6 @@
 # ~1%, and reduces the method count by ~4%.
 -allowaccessmodification
 
-# The support library contains references to newer platform versions.
-# Don't warn about those in case this app is linking against an older
-# platform version.  We know about them, and they are safe.
--dontwarn android.support.**
-
 # Ensure @RemovableInRelease actually works.
 -checkdiscard class ** {
   @org.chromium.base.annotations.RemovableInRelease *;
@@ -215,9 +200,12 @@
 -assumenosideeffects class ** {
   # Remove @RemovableInRelease methods so long as return values are unused.
   @org.chromium.base.annotations.RemovableInRelease <methods>;
+}
+
+-assumevalues class ** {
   # Remove object @RemovableInRelease methods even when return value is used.
-  # Note: * in return type does not match primitives.
-  @org.chromium.base.annotations.RemovableInRelease * *(...) return null;
+  # Note: ** in return type does not match primitives.
+  @org.chromium.base.annotations.RemovableInRelease ** *(...) return null;
   # Remove boolean @RemovableInRelease methods even when return value is used.
   @org.chromium.base.annotations.RemovableInRelease boolean *(...) return false;
 }
@@ -341,10 +329,6 @@
     boolean mShiftingMode;
 }
 
-# Trichrome builds don't include a native library list in the main APK; it's
-# picked up from the library APK at runtime.
--dontwarn org.chromium.base.library_loader.NativeLibraries
-
 # Let proguard know CastMediaOptions in CastOptions is always null, so it can
 # trim unused MediaNotificationService methods. This saves about 170 methods in
 # the dex file. https://crbug.com/855081
@@ -362,6 +346,17 @@
   *** build() return null;
 }
 
+# Workaround for crbug/1002847. Methods of BaseGmsClient are incorrectly
+# removed even though they are required for the derived class GmsClient
+# to correctly implement Api$Client.
+# TODO: remove once crbug/1002847 resolved.
+-keep public class com.google.android.gms.common.internal.BaseGmsClient {
+  public void disconnect();
+  public void dump(java.lang.String,java.io.FileDescriptor,java.io.PrintWriter,java.lang.String[]);
+  public int getMinApkVersion();
+  public boolean requiresSignIn();
+}
+
 ################################################################################
 # ../../third_party/android_deps/support_mediarouter.flags
 ################################################################################
diff --git a/chrome/android/java/proguard.flags b/chrome/android/java/proguard.flags
index 5b3c41a..83f5fd7ae 100644
--- a/chrome/android/java/proguard.flags
+++ b/chrome/android/java/proguard.flags
@@ -50,10 +50,6 @@
     boolean mShiftingMode;
 }
 
-# Trichrome builds don't include a native library list in the main APK; it's
-# picked up from the library APK at runtime.
--dontwarn org.chromium.base.library_loader.NativeLibraries
-
 # Let proguard know CastMediaOptions in CastOptions is always null, so it can
 # trim unused MediaNotificationService methods. This saves about 170 methods in
 # the dex file. https://crbug.com/855081
@@ -70,3 +66,14 @@
   public <clinit>();
   *** build() return null;
 }
+
+# Workaround for crbug/1002847. Methods of BaseGmsClient are incorrectly
+# removed even though they are required for the derived class GmsClient
+# to correctly implement Api$Client.
+# TODO: remove once crbug/1002847 resolved.
+-keep public class com.google.android.gms.common.internal.BaseGmsClient {
+  public void disconnect();
+  public void dump(java.lang.String,java.io.FileDescriptor,java.io.PrintWriter,java.lang.String[]);
+  public int getMinApkVersion();
+  public boolean requiresSignIn();
+}
diff --git a/chrome/android/java/res/layout/ephemeral_tab_toolbar.xml b/chrome/android/java/res/layout/ephemeral_tab_toolbar.xml
index d92719f..0bfcc5716 100644
--- a/chrome/android/java/res/layout/ephemeral_tab_toolbar.xml
+++ b/chrome/android/java/res/layout/ephemeral_tab_toolbar.xml
@@ -3,18 +3,93 @@
      Use of this source code is governed by a BSD-style license that can be
      found in the LICENSE file. -->
 
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    android:id="@+id/ephemeral_tab_caption_view"
+<FrameLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:paddingBottom="30dp"
     android:layout_width="match_parent"
-    android:layout_height="@dimen/overlay_panel_bar_height"
-    android:background="@color/overlay_panel_bar_background_color"
-    android:orientation="vertical">
+    android:layout_height="86dp">
 
-    <TextView
-        android:id="@+id/ephemeral_tab_text"
+    <LinearLayout
+        android:id="@+id/toolbar"
         android:layout_width="match_parent"
-        android:layout_height="@dimen/overlay_panel_bar_height"
-        android:ellipsize="end"
-        android:singleLine="true"
-        android:textAppearance="@style/TextAppearance.BlackTitle1" />
-</LinearLayout>
+        android:layout_height="@dimen/toolbar_height_no_shadow"
+        android:orientation="vertical">
+
+        <View
+            android:layout_width="match_parent"
+            android:layout_height="4dp" />
+
+        <RelativeLayout
+            android:layout_width="match_parent"
+            android:layout_height="48dp"
+            android:orientation="horizontal">
+
+            <org.chromium.ui.widget.ChromeImageView
+                android:id="@+id/favicon"
+                android:layout_width="48dp"
+                android:layout_height="48dp"
+                android:layout_centerVertical="true"
+                android:layout_marginStart="8dp"
+                android:layout_marginEnd="8dp"
+                android:padding="12dp"
+                android:src="@drawable/ic_chrome"
+                app:tint="@color/default_icon_color_blue"
+                android:scaleType="fitCenter"
+                tools:ignore="ContentDescription" />
+
+            <ImageView
+                android:id="@+id/drag_handlebar"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_gravity="center_horizontal|top"
+                android:layout_marginTop="4dp"
+                android:layout_centerHorizontal="true"
+                android:importantForAccessibility="no"
+                android:src="@drawable/drag_handlebar" />
+
+            <org.chromium.ui.widget.ChromeImageView
+                android:id="@+id/open_in_new_tab"
+                android:layout_width="48dp"
+                android:layout_height="48dp"
+                android:layout_alignParentEnd="true"
+                android:layout_centerVertical="true"
+                android:padding="12dp"
+                android:src="@drawable/open_in_new_tab"
+                app:tint="@color/default_icon_color"
+                tools:ignore="ContentDescription" />
+
+            <TextView
+                android:id="@+id/ephemeral_tab_text"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:layout_marginTop="12dp"
+                android:layout_toStartOf="@id/open_in_new_tab"
+                android:layout_toEndOf="@id/favicon"
+                android:ellipsize="end"
+                android:singleLine="true"
+                android:textAppearance="@style/TextAppearance.BlackTitle1" />
+        </RelativeLayout>
+
+        <View
+            android:layout_width="match_parent"
+            android:layout_height="2dp" />
+
+        <ProgressBar
+            android:id="@+id/progress_bar"
+            style="?android:attr/progressBarStyleHorizontal"
+            android:layout_width="match_parent"
+            android:layout_height="2dp"
+            android:max="100"
+            android:progressBackgroundTint="@color/modern_blue_300"
+            android:progressTint="@color/modern_blue_600" />
+    </LinearLayout>
+
+    <org.chromium.chrome.browser.ui.widget.FadingShadowView
+        android:id="@+id/shadow"
+        android:layout_width="match_parent"
+        android:layout_height="@dimen/action_bar_shadow_height"
+        android:layout_marginTop="@dimen/toolbar_height_no_shadow"/>
+
+</FrameLayout>
diff --git a/chrome/android/java/res/values/dimens.xml b/chrome/android/java/res/values/dimens.xml
index d302dc1..e6ef3c0 100644
--- a/chrome/android/java/res/values/dimens.xml
+++ b/chrome/android/java/res/values/dimens.xml
@@ -136,6 +136,7 @@
     <!-- Overlay panel dimensions -->
     <dimen name="overlay_panel_bar_height_legacy">56dp</dimen>
     <dimen name="overlay_panel_bar_height">60dp</dimen>
+    <dimen name="preview_tab_favicon_size">24dp</dimen>
 
     <!-- Autofill keyboard accessory dimensions -->
     <dimen name="keyboard_accessory_height_with_shadow">56dp</dimen>
diff --git a/chrome/android/java/res/values/styles.xml b/chrome/android/java/res/values/styles.xml
index 23846b4c..048e9e5 100644
--- a/chrome/android/java/res/values/styles.xml
+++ b/chrome/android/java/res/values/styles.xml
@@ -17,6 +17,7 @@
 
         <!-- Status bar color -->
         <item name="android:statusBarColor" tools:targetApi="21">@android:color/black</item>
+        <item name="android:windowLightStatusBar" tools:targetApi="23">false</item>
         <item name="colorPrimaryDark">@android:color/black</item>
 
         <!-- Text colors -->
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/ephemeraltab/EphemeralTabCoordinator.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/ephemeraltab/EphemeralTabCoordinator.java
index 49bf042e..9d569bf9 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/ephemeraltab/EphemeralTabCoordinator.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/ephemeraltab/EphemeralTabCoordinator.java
@@ -4,27 +4,49 @@
 
 package org.chromium.chrome.browser.compositor.bottombar.ephemeraltab;
 
+import android.content.Context;
+import android.graphics.Bitmap;
+import android.graphics.drawable.BitmapDrawable;
+import android.graphics.drawable.Drawable;
+import android.os.Handler;
+
+import org.chromium.base.Callback;
 import org.chromium.chrome.R;
 import org.chromium.chrome.browser.ChromeActivity;
 import org.chromium.chrome.browser.compositor.bottombar.OverlayContentDelegate;
 import org.chromium.chrome.browser.compositor.bottombar.OverlayContentProgressObserver;
 import org.chromium.chrome.browser.compositor.bottombar.OverlayPanelContent;
+import org.chromium.chrome.browser.favicon.FaviconHelper;
+import org.chromium.chrome.browser.profiles.Profile;
+import org.chromium.chrome.browser.tabmodel.TabLaunchType;
+import org.chromium.chrome.browser.util.ViewUtils;
+import org.chromium.chrome.browser.widget.RoundedIconGenerator;
 import org.chromium.chrome.browser.widget.bottomsheet.BottomSheet;
 import org.chromium.chrome.browser.widget.bottomsheet.BottomSheetController;
 import org.chromium.chrome.browser.widget.bottomsheet.EmptyBottomSheetObserver;
 import org.chromium.components.embedder_support.view.ContentView;
+import org.chromium.content_public.browser.LoadUrlParams;
+import org.chromium.ui.base.PageTransition;
+
+import java.net.MalformedURLException;
+import java.net.URL;
 
 /**
  * Central class for ephemeral tab, responsible for spinning off other classes necessary to display
  * the preview tab UI.
  */
 public class EphemeralTabCoordinator {
+    /** The delay (four video frames) after which the hide progress will be hidden. */
+    private static final long HIDE_PROGRESS_BAR_DELAY_MS = (1000 / 60) * 4;
+
     // TODO(crbug/1001256): Use Context after removing dependency on OverlayPanelContent.
     private final ChromeActivity mActivity;
     private final BottomSheetController mBottomSheetController;
+    private final FaviconLoader mFaviconLoader;
     private OverlayPanelContent mPanelContent;
     private EphemeralTabSheetContent mSheetContent;
     private boolean mIsIncognito;
+    private String mUrl;
 
     /**
      * Constructor.
@@ -35,6 +57,7 @@
             ChromeActivity activity, BottomSheetController bottomSheetController) {
         mActivity = activity;
         mBottomSheetController = bottomSheetController;
+        mFaviconLoader = new FaviconLoader(mActivity);
         mBottomSheetController.getBottomSheet().addObserver(new EmptyBottomSheetObserver() {
             @Override
             public void onSheetStateChanged(int newState) {
@@ -51,12 +74,15 @@
      * @param isIncognito Whether we are currently in incognito mode.
      */
     public void requestOpenSheet(String url, String title, boolean isIncognito) {
+        mUrl = url;
         mIsIncognito = isIncognito;
-        if (mSheetContent == null) mSheetContent = new EphemeralTabSheetContent(mActivity);
-
-        // TODO(shaktisahu): If the sheet is already open, maybe close the sheet.
+        if (mSheetContent == null) {
+            mSheetContent = new EphemeralTabSheetContent(
+                    mActivity, () -> openInNewTab(), () -> onToolbarClick());
+        }
 
         getContent().loadUrl(url, true);
+        getContent().updateBrowserControlsState(true);
         mSheetContent.attachWebContents(
                 getContent().getWebContents(), (ContentView) getContent().getContainerView());
         mSheetContent.setTitleText(title);
@@ -67,12 +93,10 @@
 
     private OverlayPanelContent getContent() {
         if (mPanelContent == null) {
-            // TODO(shaktisahu): Provide implementations for OverlayContentDelegate and
-            // OverlayContentProgressObserver, to drive progress bar and favicon.
-            mPanelContent = new OverlayPanelContent(new OverlayContentDelegate(),
-                    new OverlayContentProgressObserver(), mActivity, mIsIncognito,
+            mPanelContent = new OverlayPanelContent(new EphemeralTabPanelContentDelegate(),
+                    new PageLoadProgressObserver(), mActivity, mIsIncognito,
                     mActivity.getResources().getDimensionPixelSize(
-                            R.dimen.overlay_panel_bar_height));
+                            R.dimen.toolbar_height_no_shadow));
         }
         return mPanelContent;
     }
@@ -88,4 +112,136 @@
             mPanelContent = null;
         }
     }
+
+    private void openInNewTab() {
+        if (canPromoteToNewTab() && mUrl != null) {
+            mBottomSheetController.hideContent(mSheetContent, /* animate= */ true);
+            mActivity.getCurrentTabCreator().createNewTab(
+                    new LoadUrlParams(mUrl, PageTransition.LINK), TabLaunchType.FROM_LINK,
+                    mActivity.getActivityTabProvider().get());
+        }
+    }
+
+    private void onToolbarClick() {
+        if (mBottomSheetController.getBottomSheet().getSheetState()
+                == BottomSheet.SheetState.PEEK) {
+            mBottomSheetController.expandSheet();
+        }
+    }
+
+    private boolean canPromoteToNewTab() {
+        return !mActivity.isCustomTab();
+    }
+
+    private void onFaviconAvailable(Drawable drawable) {
+        if (mSheetContent == null) return;
+        mSheetContent.startFaviconAnimation(drawable);
+    }
+
+    /**
+     * Observes the ephemeral tab web contents and loads the associated favicon.
+     */
+    private class EphemeralTabPanelContentDelegate extends OverlayContentDelegate {
+        private String mCurrentUrl;
+
+        @Override
+        public void onMainFrameLoadStarted(String url, boolean isExternalUrl) {
+            try {
+                String newHost = new URL(url).getHost();
+                String curHost = mCurrentUrl == null ? null : new URL(mCurrentUrl).getHost();
+                if (!newHost.equals(curHost)) {
+                    mCurrentUrl = url;
+                    mFaviconLoader.loadFavicon(url, (drawable) -> onFaviconAvailable(drawable));
+                }
+            } catch (MalformedURLException e) {
+                assert false : "Malformed URL should not be passed.";
+            }
+        }
+    }
+
+    /** Observes the ephemeral tab page load progress and updates the progress bar. */
+    private class PageLoadProgressObserver extends OverlayContentProgressObserver {
+        @Override
+        public void onProgressBarStarted() {
+            if (mSheetContent == null) return;
+            mSheetContent.setProgressVisible(true);
+            mSheetContent.setProgress(0);
+        }
+
+        @Override
+        public void onProgressBarUpdated(int progress) {
+            if (mSheetContent == null) return;
+            mSheetContent.setProgress(progress);
+        }
+
+        @Override
+        public void onProgressBarFinished() {
+            // Hides the Progress Bar after a delay to make sure it is rendered for at least
+            // a few frames, otherwise its completion won't be visually noticeable.
+            new Handler().postDelayed(() -> {
+                if (mSheetContent == null) return;
+                mSheetContent.setProgressVisible(false);
+            }, HIDE_PROGRESS_BAR_DELAY_MS);
+        }
+    }
+
+    /**
+     * Helper class to generate a favicon for a given URL and resize it to the desired dimensions
+     * for displaying it on the image view.
+     */
+    private static class FaviconLoader {
+        private final Context mContext;
+        private final FaviconHelper mFaviconHelper;
+        private final FaviconHelper.DefaultFaviconHelper mDefaultFaviconHelper;
+        private final RoundedIconGenerator mIconGenerator;
+        private final int mFaviconSize;
+
+        /** Constructor. */
+        public FaviconLoader(Context context) {
+            mContext = context;
+            mFaviconHelper = new FaviconHelper();
+            mDefaultFaviconHelper = new FaviconHelper.DefaultFaviconHelper();
+            mIconGenerator =
+                    ViewUtils.createDefaultRoundedIconGenerator(mContext.getResources(), true);
+            mFaviconSize =
+                    mContext.getResources().getDimensionPixelSize(R.dimen.preview_tab_favicon_size);
+        }
+
+        /**
+         * Generates a favicon for a given URL. If no favicon was could be found or generated from
+         * the URL, a default favicon will be shown.
+         * @param url The URL for which favicon is to be generated.
+         * @param callback The callback to be invoked to display the final image.
+         */
+        public void loadFavicon(final String url, Callback<Drawable> callback) {
+            FaviconHelper.FaviconImageCallback imageCallback = (bitmap, iconUrl) -> {
+                Drawable drawable = faviconDrawable(bitmap, url);
+                if (drawable == null) {
+                    drawable = mDefaultFaviconHelper.getDefaultFaviconDrawable(mContext, url, true);
+                }
+
+                callback.onResult(drawable);
+            };
+
+            mFaviconHelper.getLocalFaviconImageForURL(
+                    Profile.getLastUsedProfile(), url, mFaviconSize, imageCallback);
+        }
+
+        /**
+         * Generates a rounded bitmap for the given favicon. If the given favicon is null, generates
+         * a favicon from the URL instead.
+         */
+        private Drawable faviconDrawable(Bitmap image, String url) {
+            if (url == null) return null;
+            if (image == null) {
+                image = mIconGenerator.generateIconForUrl(url);
+                return new BitmapDrawable(mContext.getResources(),
+                        Bitmap.createScaledBitmap(image, mFaviconSize, mFaviconSize, true));
+            }
+
+            return ViewUtils.createRoundedBitmapDrawable(
+                    Bitmap.createScaledBitmap(image, mFaviconSize, mFaviconSize, true),
+                    ViewUtils.DEFAULT_FAVICON_CORNER_RADIUS);
+        }
+    }
 }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/ephemeraltab/EphemeralTabSheetContent.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/ephemeraltab/EphemeralTabSheetContent.java
index 85543c3..463485c 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/ephemeraltab/EphemeralTabSheetContent.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/ephemeraltab/EphemeralTabSheetContent.java
@@ -5,16 +5,23 @@
 package org.chromium.chrome.browser.compositor.bottombar.ephemeraltab;
 
 import android.content.Context;
+import android.graphics.drawable.Drawable;
+import android.graphics.drawable.TransitionDrawable;
 import android.support.annotation.Nullable;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewGroup;
 import android.widget.FrameLayout;
+import android.widget.ImageView;
+import android.widget.ProgressBar;
 import android.widget.TextView;
 
+import org.chromium.base.ApiCompatibilityUtils;
 import org.chromium.chrome.R;
 import org.chromium.chrome.browser.thinwebview.ThinWebView;
 import org.chromium.chrome.browser.thinwebview.ThinWebViewFactory;
+import org.chromium.chrome.browser.ui.widget.FadingShadow;
+import org.chromium.chrome.browser.ui.widget.FadingShadowView;
 import org.chromium.chrome.browser.widget.bottomsheet.BottomSheet;
 import org.chromium.components.embedder_support.view.ContentView;
 import org.chromium.content_public.browser.RenderCoordinates;
@@ -26,19 +33,30 @@
  */
 public class EphemeralTabSheetContent implements BottomSheet.BottomSheetContent {
     private final Context mContext;
+    private final Runnable mOpenNewTabCallback;
+    private final Runnable mToolbarClickCallback;
+
     private ViewGroup mToolbarView;
     private ViewGroup mSheetContentView;
 
     private WebContents mWebContents;
     private ContentView mWebContentView;
     private ThinWebView mThinWebView;
+    private FadingShadowView mShadow;
+    private Drawable mCurrentFavicon;
+    private ImageView mFaviconView;
 
     /**
      * Constructor.
      * @param context An Android context.
+     * @param openNewTabCallback Callback invoked to open a new tab.
+     * @param toolbarClickCallback Callback invoked when user clicks on the toolbar.
      */
-    public EphemeralTabSheetContent(Context context) {
+    public EphemeralTabSheetContent(
+            Context context, Runnable openNewTabCallback, Runnable toolbarClickCallback) {
         mContext = context;
+        mOpenNewTabCallback = openNewTabCallback;
+        mToolbarClickCallback = toolbarClickCallback;
 
         createThinWebView();
         createToolbarView();
@@ -58,8 +76,10 @@
         mThinWebView.attachWebContents(mWebContents, mWebContentView);
     }
 
-    // Create a ThinWebView, add it to the view hierarchy, which represents the contents of the
-    // bottom sheet.
+    /**
+     * Create a ThinWebView, add it to the view hierarchy, which represents the contents of the
+     * bottom sheet.
+     */
     private void createThinWebView() {
         mThinWebView = ThinWebViewFactory.create(mContext, new WindowAndroid(mContext));
 
@@ -74,13 +94,56 @@
     private void createToolbarView() {
         mToolbarView = (ViewGroup) LayoutInflater.from(mContext).inflate(
                 R.layout.ephemeral_tab_toolbar, null);
+        mShadow = mToolbarView.findViewById(R.id.shadow);
+        mShadow.init(ApiCompatibilityUtils.getColor(
+                             mContext.getResources(), R.color.toolbar_shadow_color),
+                FadingShadow.POSITION_TOP);
+        ImageView openInNewTabButton = mToolbarView.findViewById(R.id.open_in_new_tab);
+        openInNewTabButton.setOnClickListener(view -> mOpenNewTabCallback.run());
+
+        View toolbar = mToolbarView.findViewById(R.id.toolbar);
+        toolbar.setOnClickListener(view -> mToolbarClickCallback.run());
+
+        mFaviconView = mToolbarView.findViewById(R.id.favicon);
+        mCurrentFavicon = mFaviconView.getDrawable();
     }
 
+    /** Method to be called to start the favicon anmiation. */
+    public void startFaviconAnimation(Drawable favicon) {
+        assert favicon != null;
+
+        // TODO(shaktisahu): Find out if there is a better way for this animation.
+        Drawable presentedDrawable = favicon;
+        if (mCurrentFavicon != null && !(mCurrentFavicon instanceof TransitionDrawable)) {
+            TransitionDrawable transitionDrawable = ApiCompatibilityUtils.createTransitionDrawable(
+                    new Drawable[] {mCurrentFavicon, favicon});
+            transitionDrawable.setCrossFadeEnabled(true);
+            transitionDrawable.startTransition((int) BottomSheet.BASE_ANIMATION_DURATION_MS);
+            presentedDrawable = transitionDrawable;
+        }
+
+        mFaviconView.setImageDrawable(presentedDrawable);
+        mCurrentFavicon = favicon;
+    }
+
+    /** Sets the ephemeral tab title text. */
     public void setTitleText(String text) {
         TextView toolbarText = mToolbarView.findViewById(R.id.ephemeral_tab_text);
         toolbarText.setText(text);
     }
 
+    /** Sets the progress percentage on the progress bar. */
+    public void setProgress(int progress) {
+        ProgressBar progressBar = mToolbarView.findViewById(R.id.progress_bar);
+        progressBar.setProgress(progress);
+    }
+
+    /** Called to show or hide the progress bar. */
+    public void setProgressVisible(boolean visible) {
+        ProgressBar progressBar = mToolbarView.findViewById(R.id.progress_bar);
+        progressBar.setVisibility(visible ? View.VISIBLE : View.GONE);
+    }
+
     @Override
     public View getContentView() {
         return mSheetContentView;
@@ -120,6 +183,11 @@
     }
 
     @Override
+    public boolean hideOnScroll() {
+        return false;
+    }
+
+    @Override
     public boolean wrapContentEnabled() {
         return true;
     }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/contacts_picker/ContactsPickerToolbar.java b/chrome/android/java/src/org/chromium/chrome/browser/contacts_picker/ContactsPickerToolbar.java
index 21207da2..88e58c0 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/contacts_picker/ContactsPickerToolbar.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/contacts_picker/ContactsPickerToolbar.java
@@ -12,6 +12,7 @@
 import org.chromium.base.ApiCompatibilityUtils;
 import org.chromium.chrome.R;
 import org.chromium.chrome.browser.widget.selection.SelectableListToolbar;
+import org.chromium.chrome.browser.widget.selection.SelectionDelegate;
 import org.chromium.ui.widget.ButtonCompat;
 
 import java.util.List;
@@ -60,6 +61,15 @@
     }
 
     @Override
+    public void initialize(SelectionDelegate<ContactDetails> delegate, int titleResId,
+            int normalGroupResId, int selectedGroupResId, boolean updateStatusBarColor) {
+        super.initialize(
+                delegate, titleResId, normalGroupResId, selectedGroupResId, updateStatusBarColor);
+
+        showBackArrow();
+    }
+
+    @Override
     public void onSelectionStateChange(List<ContactDetails> selectedItems) {
         super.onSelectionStateChange(selectedItems);
 
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/contacts_picker/PickerCategoryView.java b/chrome/android/java/src/org/chromium/chrome/browser/contacts_picker/PickerCategoryView.java
index d0cf9e725..9e1e2fa 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/contacts_picker/PickerCategoryView.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/contacts_picker/PickerCategoryView.java
@@ -156,7 +156,6 @@
         mToolbar.setNavigationOnClickListener(this);
         mToolbar.initializeSearchView(this, R.string.contacts_picker_search, 0);
         mToolbar.setDelegate(delegate);
-        mToolbar.showBackArrow();
         mSelectableListLayout.configureWideDisplayStyle();
 
         mSearchButton = (ImageView) mToolbar.findViewById(R.id.search);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/notifications/scheduler/DisplayAgent.java b/chrome/android/java/src/org/chromium/chrome/browser/notifications/scheduler/DisplayAgent.java
index 474438e..95303f92 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/notifications/scheduler/DisplayAgent.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/notifications/scheduler/DisplayAgent.java
@@ -189,6 +189,7 @@
             case NotificationIntentInterceptor.IntentType.CONTENT_INTENT:
                 DisplayAgentJni.get().onUserAction(Profile.getLastUsedProfile(), clientType,
                         UserActionType.CLICK, guid, ActionButtonType.UNKNOWN_ACTION, null);
+                closeNotification(guid);
                 break;
             case NotificationIntentInterceptor.IntentType.DELETE_INTENT:
                 DisplayAgentJni.get().onUserAction(Profile.getLastUsedProfile(), clientType,
@@ -200,10 +201,16 @@
                 String buttonId = IntentUtils.safeGetStringExtra(intent, EXTRA_ACTION_BUTTON_ID);
                 DisplayAgentJni.get().onUserAction(Profile.getLastUsedProfile(), clientType,
                         UserActionType.BUTTON_CLICK, guid, actionButtonType, buttonId);
+                closeNotification(guid);
                 break;
         }
     }
 
+    private static void closeNotification(String guid) {
+        new NotificationManagerProxyImpl(ContextUtils.getApplicationContext())
+                .cancel(DISPLAY_AGENT_TAG, guid.hashCode());
+    }
+
     /**
      * Contains Android platform specific data to construct a notification.
      */
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/photo_picker/PhotoPickerToolbar.java b/chrome/android/java/src/org/chromium/chrome/browser/photo_picker/PhotoPickerToolbar.java
index 3d2be56d..6bd44ea 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/photo_picker/PhotoPickerToolbar.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/photo_picker/PhotoPickerToolbar.java
@@ -11,6 +11,7 @@
 import org.chromium.base.ApiCompatibilityUtils;
 import org.chromium.chrome.R;
 import org.chromium.chrome.browser.widget.selection.SelectableListToolbar;
+import org.chromium.chrome.browser.widget.selection.SelectionDelegate;
 
 import java.util.List;
 
@@ -62,6 +63,15 @@
     }
 
     @Override
+    public void initialize(SelectionDelegate<PickerBitmap> delegate, int titleResId,
+            int normalGroupResId, int selectedGroupResId, boolean updateStatusBarColor) {
+        super.initialize(
+                delegate, titleResId, normalGroupResId, selectedGroupResId, updateStatusBarColor);
+
+        showBackArrow();
+    }
+
+    @Override
     public void onSelectionStateChange(List<PickerBitmap> selectedItems) {
         super.onSelectionStateChange(selectedItems);
 
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/photo_picker/PickerCategoryView.java b/chrome/android/java/src/org/chromium/chrome/browser/photo_picker/PickerCategoryView.java
index b8d53814..20f04b76 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/photo_picker/PickerCategoryView.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/photo_picker/PickerCategoryView.java
@@ -62,7 +62,7 @@
      * A container class for keeping track of the data we need to show a photo/video tile in the
      * photo picker (the data we store in the cache).
      */
-    static public class Thumbnail {
+    public static class Thumbnail {
         public List<Bitmap> bitmaps;
         public String videoDuration;
 
@@ -186,7 +186,6 @@
                 false);
         toolbar.setNavigationOnClickListener(this);
         toolbar.setDelegate(delegate);
-        toolbar.showBackArrow();
         Button doneButton = (Button) toolbar.findViewById(R.id.done);
         doneButton.setOnClickListener(this);
         mVideoView = findViewById(R.id.video_player);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/preferences/password/PasswordManagerHandler.java b/chrome/android/java/src/org/chromium/chrome/browser/preferences/password/PasswordManagerHandler.java
index b2f7b45..c43cdd8 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/preferences/password/PasswordManagerHandler.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/preferences/password/PasswordManagerHandler.java
@@ -61,14 +61,6 @@
     void removeSavedPasswordEntry(int index);
 
     /**
-     * Change saved password entry at index.
-     * @param index of password entry to change.
-     * @param new_username is the username after a change.
-     * @param new_password is the password after a change.
-     */
-    void changeSavedPasswordEntry(int index, String newUsername, String newPassword);
-
-    /**
      * Remove saved exception entry at index.
      *
      * @param index of exception entry.
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/preferences/password/PasswordUIView.java b/chrome/android/java/src/org/chromium/chrome/browser/preferences/password/PasswordUIView.java
index d18caa7..5122465 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/preferences/password/PasswordUIView.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/preferences/password/PasswordUIView.java
@@ -76,12 +76,6 @@
     }
 
     @Override
-    public void changeSavedPasswordEntry(int index, String newUsername, String newPassword) {
-        PasswordUIViewJni.get().handleChangeSavedPasswordEntry(
-                mNativePasswordUIViewAndroid, PasswordUIView.this, index, newUsername, newPassword);
-    }
-
-    @Override
     public void removeSavedPasswordException(int index) {
         PasswordUIViewJni.get().handleRemoveSavedPasswordException(
                 mNativePasswordUIViewAndroid, PasswordUIView.this, index);
@@ -134,8 +128,6 @@
                 long nativePasswordUIViewAndroid, PasswordUIView caller, int index);
         void handleRemoveSavedPasswordEntry(
                 long nativePasswordUIViewAndroid, PasswordUIView caller, int index);
-        void handleChangeSavedPasswordEntry(long nativePasswordUIViewAndroid, PasswordUIView caller,
-                int index, String newUsername, String newPassword);
         void handleRemoveSavedPasswordException(
                 long nativePasswordUIViewAndroid, PasswordUIView caller, int index);
         String getAccountDashboardURL();
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappRegistry.java b/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappRegistry.java
index defa15a..68c10c3 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappRegistry.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappRegistry.java
@@ -8,16 +8,20 @@
 import android.content.SharedPreferences;
 import android.text.TextUtils;
 import android.text.format.DateUtils;
+import android.util.Pair;
 
 import org.chromium.base.ContextUtils;
 import org.chromium.base.PackageUtils;
 import org.chromium.base.StrictModeContext;
+import org.chromium.base.ThreadUtils;
 import org.chromium.base.VisibleForTesting;
 import org.chromium.base.annotations.CalledByNative;
 import org.chromium.base.task.AsyncTask;
+import org.chromium.base.task.PostTask;
 import org.chromium.chrome.browser.browserservices.permissiondelegation.TrustedWebActivityPermissionStore;
 import org.chromium.chrome.browser.browsing_data.UrlFilter;
 import org.chromium.chrome.browser.browsing_data.UrlFilterBridge;
+import org.chromium.content_public.browser.UiThreadTaskTraits;
 import org.chromium.webapk.lib.common.WebApkConstants;
 
 import java.util.ArrayList;
@@ -60,6 +64,8 @@
         private static WebappRegistry sInstance = new WebappRegistry();
     }
 
+    private boolean mIsInitialized;
+
     private HashMap<String, WebappDataStorage> mStorages;
     private SharedPreferences mPreferences;
     private TrustedWebActivityPermissionStore mTrustedWebActivityPermissionStore;
@@ -93,24 +99,27 @@
     }
 
     /**
-     * Warm up the WebappRegistry and a specific WebappDataStorage SharedPreferences.
+     * Warm up the WebappRegistry and a specific WebappDataStorage SharedPreferences. Can be called
+     * from any thread.
      * @param id The web app id to warm up in addition to the WebappRegistry.
      */
     public static void warmUpSharedPrefsForId(String id) {
-        getInstance().initStorages(id, false);
+        getInstance().initStorages(id);
     }
 
     /**
-     * Warm up the WebappRegistry and all WebappDataStorage SharedPreferences.
+     * Warm up the WebappRegistry and all WebappDataStorage SharedPreferences. Can be called from
+     * any thread.
      */
     public static void warmUpSharedPrefs() {
-        getInstance().initStorages(null, false);
+        getInstance().initStorages(null);
     }
 
     @VisibleForTesting
     public static void refreshSharedPrefsForTesting() {
         Holder.sInstance = new WebappRegistry();
-        getInstance().initStorages(null, true);
+        getInstance().clearStoragesForTesting();
+        getInstance().initStorages(null);
     }
 
     /**
@@ -343,23 +352,45 @@
         }
     }
 
-    private void initStorages(String idToInitialize, boolean replaceExisting) {
+    private void clearStoragesForTesting() {
+        ThreadUtils.assertOnUiThread();
+        mStorages.clear();
+    }
+
+    private void initStorages(String idToInitialize) {
         Set<String> webapps = mPreferences.getStringSet(KEY_WEBAPP_SET, Collections.emptySet());
         boolean initAll = (idToInitialize == null || idToInitialize.isEmpty());
 
-        // Don't overwrite any entry in mStorages unless replaceExisting is set to true.
+        if (initAll && !mIsInitialized) {
+            mTrustedWebActivityPermissionStore.initStorage();
+            mIsInitialized = true;
+        }
+
+        List<Pair<String, WebappDataStorage>> initedStorages =
+                new ArrayList<Pair<String, WebappDataStorage>>();
         if (initAll) {
             for (String id : webapps) {
-                if (replaceExisting || !mStorages.containsKey(id)) {
-                    mStorages.put(id, WebappDataStorage.open(id));
+                if (!mStorages.containsKey(id)) {
+                    initedStorages.add(Pair.create(id, WebappDataStorage.open(id)));
                 }
             }
-
-            mTrustedWebActivityPermissionStore.initStorage();
         } else {
-            if (webapps.contains(idToInitialize)
-                    && (replaceExisting || !mStorages.containsKey(idToInitialize))) {
-                mStorages.put(idToInitialize, WebappDataStorage.open(idToInitialize));
+            if (webapps.contains(idToInitialize) && !mStorages.containsKey(idToInitialize)) {
+                initedStorages.add(
+                        Pair.create(idToInitialize, WebappDataStorage.open(idToInitialize)));
+            }
+        }
+
+        PostTask.runOrPostTask(
+                UiThreadTaskTraits.DEFAULT, () -> { initStoragesOnUiThread(initedStorages); });
+    }
+
+    private void initStoragesOnUiThread(List<Pair<String, WebappDataStorage>> initedStorages) {
+        ThreadUtils.assertOnUiThread();
+
+        for (Pair<String, WebappDataStorage> initedStorage : initedStorages) {
+            if (!mStorages.containsKey(initedStorage.first)) {
+                mStorages.put(initedStorage.first, initedStorage.second);
             }
         }
     }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/widget/NumberRollView.java b/chrome/android/java/src/org/chromium/chrome/browser/widget/NumberRollView.java
index bb579d0..fe502690 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/widget/NumberRollView.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/widget/NumberRollView.java
@@ -153,4 +153,13 @@
     public void endAnimationsForTesting() {
         if (mLastRollAnimator != null) mLastRollAnimator.end();
     }
+
+    /**
+     * Update the text appearance for both {@link TextView}.
+     * @param resId The new text appearance to use.
+     */
+    public void setTextAppearance(int resId) {
+        mUpNumber.setTextAppearance(mUpNumber.getContext(), resId);
+        mDownNumber.setTextAppearance(mDownNumber.getContext(), resId);
+    }
 }
\ No newline at end of file
diff --git a/chrome/android/java/strings/android_chrome_strings_grd/IDS_IPH_DRAG_AND_DROP_CONTENT.png.sha1 b/chrome/android/java/strings/android_chrome_strings_grd/IDS_IPH_DRAG_AND_DROP_CONTENT.png.sha1
index 9105413..f259376 100644
--- a/chrome/android/java/strings/android_chrome_strings_grd/IDS_IPH_DRAG_AND_DROP_CONTENT.png.sha1
+++ b/chrome/android/java/strings/android_chrome_strings_grd/IDS_IPH_DRAG_AND_DROP_CONTENT.png.sha1
@@ -1 +1 @@
-fdccf851cb85b2bebc54d3382bc6d1da87a6dc10
\ No newline at end of file
+2c3d739a7d675557a9888e8cf0527a8fe8115206
\ No newline at end of file
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/browserservices/TrustedWebActivityTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/browserservices/TrustedWebActivityTest.java
index ada7c63..56b597dc 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/browserservices/TrustedWebActivityTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/browserservices/TrustedWebActivityTest.java
@@ -32,6 +32,7 @@
 import org.chromium.base.library_loader.ProcessInitException;
 import org.chromium.base.test.util.CommandLineFlags;
 import org.chromium.base.test.util.MinAndroidSdkLevel;
+import org.chromium.base.test.util.Restriction;
 import org.chromium.chrome.browser.ChromeSwitches;
 import org.chromium.chrome.browser.customtabs.CustomTabActivity;
 import org.chromium.chrome.browser.customtabs.CustomTabActivityTestRule;
@@ -40,6 +41,7 @@
 import org.chromium.content_public.browser.test.util.Criteria;
 import org.chromium.content_public.browser.test.util.CriteriaHelper;
 import org.chromium.net.test.EmbeddedTestServerRule;
+import org.chromium.ui.test.util.UiRestriction;
 
 import java.util.concurrent.Callable;
 import java.util.concurrent.TimeoutException;
@@ -116,6 +118,8 @@
     @Test
     @MediumTest
     @MinAndroidSdkLevel(Build.VERSION_CODES.LOLLIPOP_MR1)
+    @Restriction({UiRestriction.RESTRICTION_TYPE_PHONE})
+    // Customizing status bar color is disallowed for tablets.
     public void testStatusBarColorPrecedence() throws TimeoutException, InterruptedException {
         if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) return;
 
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 8973658..54b14fc 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
@@ -205,14 +205,6 @@
         }
 
         @Override
-        public void changeSavedPasswordEntry(int index, String newUsername, String newPassword) {
-            mSavedPasswords.set(index,
-                    new SavedPasswordEntry(
-                            mSavedPasswords.get(index).getUrl(), newUsername, newPassword));
-            updatePasswordLists();
-        }
-
-        @Override
         public void removeSavedPasswordEntry(int index) {
             assert false : "Define this method before starting to use it in tests.";
         }
@@ -236,18 +228,22 @@
         }
     }
 
-    private final static SavedPasswordEntry ZEUS_ON_EARTH =
+    private static final SavedPasswordEntry ZEUS_ON_EARTH =
             new SavedPasswordEntry("http://www.phoenicia.gr", "Zeus", "Europa");
-    private final static SavedPasswordEntry ARES_AT_OLYMP =
+    private static final SavedPasswordEntry ARES_AT_OLYMP =
             new SavedPasswordEntry("https://1-of-12.olymp.gr", "Ares", "God-o'w@r");
-    private final static SavedPasswordEntry PHOBOS_AT_OLYMP =
+    private static final SavedPasswordEntry PHOBOS_AT_OLYMP =
             new SavedPasswordEntry("https://visitor.olymp.gr", "Phobos-son-of-ares", "G0d0fF34r");
-    private final static SavedPasswordEntry DEIMOS_AT_OLYMP =
+    private static final SavedPasswordEntry DEIMOS_AT_OLYMP =
             new SavedPasswordEntry("https://visitor.olymp.gr", "Deimops-Ares-son", "G0d0fT3rr0r");
-    private final static SavedPasswordEntry HADES_AT_UNDERWORLD =
+    private static final SavedPasswordEntry HADES_AT_UNDERWORLD =
             new SavedPasswordEntry("https://underworld.gr", "", "C3rb3rus");
-    private final static SavedPasswordEntry[] GREEK_GODS = {
-            ZEUS_ON_EARTH, ARES_AT_OLYMP, PHOBOS_AT_OLYMP, DEIMOS_AT_OLYMP, HADES_AT_UNDERWORLD,
+    private static final SavedPasswordEntry[] GREEK_GODS = {
+            ZEUS_ON_EARTH,
+            ARES_AT_OLYMP,
+            PHOBOS_AT_OLYMP,
+            DEIMOS_AT_OLYMP,
+            HADES_AT_UNDERWORLD,
     };
 
     // Used to provide fake lists of stored passwords. Tests which need it can use setPasswordSource
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/webapps/WebappModeTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/webapps/WebappModeTest.java
index 3a0ee5d..7f89f0c 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/webapps/WebappModeTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/webapps/WebappModeTest.java
@@ -38,6 +38,7 @@
 import org.chromium.chrome.test.util.browser.webapps.WebappTestHelper;
 import org.chromium.content_public.browser.test.util.Criteria;
 import org.chromium.content_public.browser.test.util.CriteriaHelper;
+import org.chromium.content_public.browser.test.util.TestThreadUtils;
 
 /**
  * Tests that WebappActivities are launched correctly.
@@ -99,27 +100,29 @@
 
     @Before
     public void setUp() throws Exception {
-        WebappRegistry.refreshSharedPrefsForTesting();
+        TestThreadUtils.runOnUiThreadBlocking(() -> {
+            WebappRegistry.refreshSharedPrefsForTesting();
 
-        // Register the webapps so when the data storage is opened, the test doesn't crash. There is
-        // no race condition with the retrieval as AsyncTasks are run sequentially on the background
-        // thread.
-        WebappRegistry.getInstance().register(
-                WEBAPP_1_ID, new WebappRegistry.FetchWebappDataStorageCallback() {
-                    @Override
-                    public void onWebappDataStorageRetrieved(WebappDataStorage storage) {
-                        storage.updateFromShortcutIntent(createIntent(
-                                WEBAPP_1_ID, WEBAPP_1_URL, WEBAPP_1_TITLE, WEBAPP_ICON, true));
-                    }
-                });
-        WebappRegistry.getInstance().register(
-                WEBAPP_2_ID, new WebappRegistry.FetchWebappDataStorageCallback() {
-                    @Override
-                    public void onWebappDataStorageRetrieved(WebappDataStorage storage) {
-                        storage.updateFromShortcutIntent(createIntent(
-                                WEBAPP_1_ID, WEBAPP_1_URL, WEBAPP_1_TITLE, WEBAPP_ICON, true));
-                    }
-                });
+            // Register the webapps so when the data storage is opened, the test doesn't crash.
+            // There is no race condition with the retrieval as AsyncTasks are run sequentially on
+            // the background thread.
+            WebappRegistry.getInstance().register(
+                    WEBAPP_1_ID, new WebappRegistry.FetchWebappDataStorageCallback() {
+                        @Override
+                        public void onWebappDataStorageRetrieved(WebappDataStorage storage) {
+                            storage.updateFromShortcutIntent(createIntent(
+                                    WEBAPP_1_ID, WEBAPP_1_URL, WEBAPP_1_TITLE, WEBAPP_ICON, true));
+                        }
+                    });
+            WebappRegistry.getInstance().register(
+                    WEBAPP_2_ID, new WebappRegistry.FetchWebappDataStorageCallback() {
+                        @Override
+                        public void onWebappDataStorageRetrieved(WebappDataStorage storage) {
+                            storage.updateFromShortcutIntent(createIntent(
+                                    WEBAPP_1_ID, WEBAPP_1_URL, WEBAPP_1_TITLE, WEBAPP_ICON, true));
+                        }
+                    });
+        });
     }
 
     /**
@@ -319,7 +322,7 @@
                 Activity lastActivity = ApplicationStatus.getLastTrackedFocusedActivity();
                 return isWebappActivityReady(lastActivity);
             }
-        });
+        }, 10000, CriteriaHelper.DEFAULT_POLLING_INTERVAL);
         return (WebappActivity) ApplicationStatus.getLastTrackedFocusedActivity();
     }
 
diff --git a/chrome/android/javatests/src/org/chromium/chrome/test/smoke/ChromeBundleSmokeTest.java b/chrome/android/javatests/src/org/chromium/chrome/test/smoke/ChromeBundleSmokeTest.java
index efca77b..fc0b09c 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/test/smoke/ChromeBundleSmokeTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/test/smoke/ChromeBundleSmokeTest.java
@@ -21,8 +21,10 @@
 import org.chromium.base.test.BaseJUnit4ClassRunner;
 import org.chromium.chrome.test.pagecontroller.rules.ChromeUiApplicationTestRule;
 import org.chromium.chrome.test.pagecontroller.rules.ChromeUiAutomatorTestRule;
+import org.chromium.chrome.test.pagecontroller.utils.IUi2Locator;
 import org.chromium.chrome.test.pagecontroller.utils.Ui2Locators;
 import org.chromium.chrome.test.pagecontroller.utils.UiAutomatorUtils;
+import org.chromium.chrome.test.pagecontroller.utils.UiLocatorHelper;
 
 /** Smoke Test for Chrome bundles. */
 @SmallTest
@@ -46,18 +48,34 @@
         mChromeUiRule.launchIntoNewTabPageOnFirstRun();
     }
 
-    @Test
-    public void testModuleInstall() {
-        // Send intent that makes Chrome install the test dummy module.
+    private void runTestActivity(int testCase) {
+        // This intent will trigger installation of the module if not present.
         Context context = InstrumentationRegistry.getContext();
         Intent intent = new Intent();
         intent.setComponent(new ComponentName(mPackageName, TARGET_ACTIVITY));
-        intent.putExtra("test_case", 0); // Test case EXECUTE_JAVA.
+        intent.putExtra("test_case", testCase);
         intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_NEW_TASK);
         context.startActivity(intent);
 
-        // Wait for done dialog to show up.
-        Assert.assertTrue(UiAutomatorUtils.getInstance().getLocatorHelper().isOnScreen(
-                Ui2Locators.withText("Test Case 0: done")));
+        final String prefixText = "Test Case " + testCase + ": ";
+        IUi2Locator locator = Ui2Locators.withTextContaining(prefixText);
+
+        // Wait for result dialog to show up.
+        UiLocatorHelper locatorHelper = UiAutomatorUtils.getInstance().getLocatorHelper();
+        Assert.assertTrue(locatorHelper.isOnScreen(locator));
+
+        // Ensure the dialog text indicates a pass.
+        final String passText = prefixText + "pass";
+        Assert.assertEquals(locatorHelper.getOneTextImmediate(locator, null), passText);
+    }
+
+    @Test
+    public void testModuleJavaCodeExecution() {
+        runTestActivity(0); // Test case EXECUTE_JAVA.
+    }
+
+    @Test
+    public void testModuleNativeCodeExecution() {
+        runTestActivity(1); // Test case EXECUTE_NATIVE.
     }
 }
diff --git a/chrome/android/modules/buildflags.gni b/chrome/android/modules/buildflags.gni
index d2402b01..14050b9 100644
--- a/chrome/android/modules/buildflags.gni
+++ b/chrome/android/modules/buildflags.gni
@@ -9,7 +9,9 @@
 # This variable indicates whether the native feature module system is engaged.
 # Currently, this implies a build configuration that supports native modules,
 # and that at least one feature is using a native module.
-if (is_android && is_clang && use_lld && !is_component_build) {
+# TODO(https://crbug.com/1004329): Partitioning should work with is_debug. When
+# this bug is fixed, remove that condition here.
+if (is_android && is_clang && use_lld && !is_component_build && !is_debug) {
   use_native_modules = enable_vr && modularize_vr_native
 } else {
   use_native_modules = false
diff --git a/chrome/android/modules/test_dummy/internal/BUILD.gn b/chrome/android/modules/test_dummy/internal/BUILD.gn
index 7319089..f89ab3b 100644
--- a/chrome/android/modules/test_dummy/internal/BUILD.gn
+++ b/chrome/android/modules/test_dummy/internal/BUILD.gn
@@ -13,3 +13,16 @@
     "//chrome/android/modules/test_dummy/public:java",
   ]
 }
+
+source_set("native") {
+  sources = [
+    "entrypoints.cc",
+  ]
+
+  deps = [
+    "//chrome/android/features/test_dummy/public:native",
+  ]
+
+  # Test dummy native entrypoints belong in the partition.
+  cflags = [ "-fsymbol-partition=libtest_dummy.so" ]
+}
diff --git a/chrome/android/modules/test_dummy/internal/entrypoints.cc b/chrome/android/modules/test_dummy/internal/entrypoints.cc
new file mode 100644
index 0000000..8709c9f
--- /dev/null
+++ b/chrome/android/modules/test_dummy/internal/entrypoints.cc
@@ -0,0 +1,13 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/android/features/test_dummy/public/test_dummy.h"
+
+extern "C" {
+
+__attribute__((visibility("default"))) int TestDummyEntrypoint() {
+  return test_dummy::TestDummy();
+}
+
+}  // extern "C"
diff --git a/chrome/android/modules/test_dummy/internal/entrypoints.lst b/chrome/android/modules/test_dummy/internal/entrypoints.lst
new file mode 100644
index 0000000..386f4dd
--- /dev/null
+++ b/chrome/android/modules/test_dummy/internal/entrypoints.lst
@@ -0,0 +1 @@
+TestDummyEntrypoint
diff --git a/chrome/android/modules/test_dummy/test_dummy_module.gni b/chrome/android/modules/test_dummy/test_dummy_module.gni
index bcaca9d..d08785a1 100644
--- a/chrome/android/modules/test_dummy/test_dummy_module.gni
+++ b/chrome/android/modules/test_dummy/test_dummy_module.gni
@@ -2,6 +2,8 @@
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
+import("//chrome/android/modules/buildflags.gni")
+
 test_dummy_module_desc = {
   name = "test_dummy"
   android_manifest =
@@ -10,4 +12,13 @@
     "//chrome/android/features/test_dummy/internal:java",
     "//chrome/android/modules/test_dummy/internal:java",
   ]
+
+  if (use_native_modules) {
+    native_deps = [
+      "//chrome/android/features/test_dummy/internal:native",
+      "//chrome/android/modules/test_dummy/internal:native",
+    ]
+    native_entrypoints =
+        "//chrome/android/modules/test_dummy/internal/entrypoints.lst"
+  }
 }
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc
index f1a7876..1bc87f3 100644
--- a/chrome/browser/about_flags.cc
+++ b/chrome/browser/about_flags.cc
@@ -2608,10 +2608,6 @@
      kOsAll,
      FEATURE_VALUE_TYPE(
          autofill::features::kAutofillUpstreamEditableExpirationDate)},
-    {"enable-autofill-import-dynamic-forms",
-     flag_descriptions::kEnableAutofillImportDynamicFormsName,
-     flag_descriptions::kEnableAutofillImportDynamicFormsDescription, kOsAll,
-     FEATURE_VALUE_TYPE(autofill::features::kAutofillImportDynamicForms)},
     {"enable-autofill-local-card-migration-uses-strike-system-v2",
      flag_descriptions::kEnableAutofillLocalCardMigrationUsesStrikeSystemV2Name,
      flag_descriptions::
diff --git a/chrome/browser/android/customtabs/detached_resource_request.cc b/chrome/browser/android/customtabs/detached_resource_request.cc
index 0e90fa0..2b94bc8 100644
--- a/chrome/browser/android/customtabs/detached_resource_request.cc
+++ b/chrome/browser/android/customtabs/detached_resource_request.cc
@@ -79,8 +79,7 @@
   resource_request->url = url_;
   // The referrer is stripped if it's not set properly initially.
   resource_request->referrer = net::URLRequestJob::ComputeReferrerForPolicy(
-      referrer_policy, site_for_cookies_,
-      url::Origin::Create(site_for_cookies_), url_);
+      referrer_policy, site_for_cookies_, url_);
   resource_request->referrer_policy = referrer_policy;
   resource_request->site_for_cookies = site_for_cookies_;
   resource_request->request_initiator = url::Origin::Create(site_for_cookies_);
diff --git a/chrome/browser/android/password_ui_view_android.cc b/chrome/browser/android/password_ui_view_android.cc
index bc56b06..a532f53 100644
--- a/chrome/browser/android/password_ui_view_android.cc
+++ b/chrome/browser/android/password_ui_view_android.cc
@@ -148,18 +148,6 @@
   password_manager_presenter_.RemovePasswordException(index);
 }
 
-void PasswordUIViewAndroid::HandleChangeSavedPasswordEntry(
-    JNIEnv* env,
-    const base::android::JavaRef<jobject>&,
-    int index,
-    const JavaRef<jstring>& new_username,
-    const JavaRef<jstring>& new_password) {
-  DCHECK_EQ(State::ALIVE, state_);
-  password_manager_presenter_.ChangeSavedPassword(
-      index, ConvertJavaStringToUTF16(env, new_username),
-      ConvertJavaStringToUTF16(env, new_password));
-}
-
 void PasswordUIViewAndroid::HandleSerializePasswords(
     JNIEnv* env,
     const JavaRef<jobject>&,
diff --git a/chrome/browser/android/password_ui_view_android.h b/chrome/browser/android/password_ui_view_android.h
index 545d217..1f304d2 100644
--- a/chrome/browser/android/password_ui_view_android.h
+++ b/chrome/browser/android/password_ui_view_android.h
@@ -74,12 +74,6 @@
       JNIEnv* env,
       const base::android::JavaRef<jobject>&,
       int index);
-  void HandleChangeSavedPasswordEntry(
-      JNIEnv* env,
-      const base::android::JavaRef<jobject>&,
-      int index,
-      const base::android::JavaRef<jstring>& new_username,
-      const base::android::JavaRef<jstring>& new_password);
   void HandleSerializePasswords(
       JNIEnv* env,
       const base::android::JavaRef<jobject>&,
diff --git a/chrome/browser/android/vr/BUILD.gn b/chrome/browser/android/vr/BUILD.gn
index 03fba1b..adf2fb7 100644
--- a/chrome/browser/android/vr/BUILD.gn
+++ b/chrome/browser/android/vr/BUILD.gn
@@ -228,7 +228,7 @@
 
 if (current_toolchain == default_toolchain) {
   generate_jni_registration("jni_registration") {
-    target = "//chrome/android:chrome_modern_public_bundle_vr_bundle_module"
+    target = "//chrome/android:chrome_modern_public_bundle__vr_bundle_module"
     header_output = "$target_gen_dir/${target_name}.h"
     namespace = "vr"
   }
diff --git a/chrome/browser/chromeos/arc/tracing/arc_cpu_event.cc b/chrome/browser/chromeos/arc/tracing/arc_cpu_event.cc
index 2f1a7feb..907bbae 100644
--- a/chrome/browser/chromeos/arc/tracing/arc_cpu_event.cc
+++ b/chrome/browser/chromeos/arc/tracing/arc_cpu_event.cc
@@ -124,11 +124,10 @@
   base::ListValue list;
   for (const auto& event : cpu_events) {
     base::ListValue event_value;
-    event_value.GetList().push_back(base::Value(static_cast<int>(event.type)));
-    event_value.GetList().push_back(
-        base::Value(static_cast<double>(event.timestamp)));
-    event_value.GetList().push_back(base::Value(static_cast<int>(event.tid)));
-    list.GetList().emplace_back(std::move(event_value));
+    event_value.Append(base::Value(static_cast<int>(event.type)));
+    event_value.Append(base::Value(static_cast<double>(event.timestamp)));
+    event_value.Append(base::Value(static_cast<int>(event.tid)));
+    list.Append(std::move(event_value));
   }
   return list;
 }
@@ -136,7 +135,7 @@
 base::ListValue SerializeAllCpuEvents(const AllCpuEvents& all_cpu_events) {
   base::ListValue list;
   for (const auto& cpu_events : all_cpu_events)
-    list.GetList().emplace_back(SerializeCpuEvents(cpu_events));
+    list.Append(SerializeCpuEvents(cpu_events));
   return list;
 }
 
diff --git a/chrome/browser/chromeos/arc/tracing/arc_tracing_bridge.cc b/chrome/browser/chromeos/arc/tracing/arc_tracing_bridge.cc
index 6950210e..a2718699 100644
--- a/chrome/browser/chromeos/arc/tracing/arc_tracing_bridge.cc
+++ b/chrome/browser/chromeos/arc/tracing/arc_tracing_bridge.cc
@@ -470,9 +470,9 @@
 }
 
 void ArcTracingBridge::ArcTracingAgent::StopAndFlush(
-    tracing::mojom::RecorderPtr recorder) {
+    mojo::PendingRemote<tracing::mojom::Recorder> recorder) {
   DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
-  recorder_ = std::move(recorder);
+  recorder_.Bind(std::move(recorder));
   // |bridge_| owns us, so it's OK to pass an unretained pointer.
   bridge_->StopAndFlush(
       base::BindOnce(&ArcTracingAgent::OnTraceData, base::Unretained(this)));
diff --git a/chrome/browser/chromeos/arc/tracing/arc_tracing_bridge.h b/chrome/browser/chromeos/arc/tracing/arc_tracing_bridge.h
index d58c0903f..a86f8a6 100644
--- a/chrome/browser/chromeos/arc/tracing/arc_tracing_bridge.h
+++ b/chrome/browser/chromeos/arc/tracing/arc_tracing_bridge.h
@@ -20,6 +20,7 @@
 #include "components/arc/mojom/tracing.mojom.h"
 #include "components/arc/session/connection_observer.h"
 #include "components/keyed_service/core/keyed_service.h"
+#include "mojo/public/cpp/bindings/remote.h"
 #include "services/tracing/public/cpp/base_agent.h"
 #include "services/tracing/public/mojom/tracing.mojom.h"
 
@@ -80,12 +81,13 @@
     void StartTracing(const std::string& config,
                       base::TimeTicks coordinator_time,
                       Agent::StartTracingCallback callback) override;
-    void StopAndFlush(tracing::mojom::RecorderPtr recorder) override;
+    void StopAndFlush(
+        mojo::PendingRemote<tracing::mojom::Recorder> recorder) override;
 
     void OnTraceData(const std::string& data);
 
     ArcTracingBridge* const bridge_;
-    tracing::mojom::RecorderPtr recorder_;
+    mojo::Remote<tracing::mojom::Recorder> recorder_;
 
     DISALLOW_COPY_AND_ASSIGN(ArcTracingAgent);
   };
diff --git a/chrome/browser/chromeos/arc/tracing/arc_tracing_graphics_model.cc b/chrome/browser/chromeos/arc/tracing/arc_tracing_graphics_model.cc
index fe77774..a23fab7d 100644
--- a/chrome/browser/chromeos/arc/tracing/arc_tracing_graphics_model.cc
+++ b/chrome/browser/chromeos/arc/tracing/arc_tracing_graphics_model.cc
@@ -1339,12 +1339,11 @@
   base::ListValue list;
   for (const auto& event : events) {
     base::ListValue event_value;
-    event_value.GetList().push_back(base::Value(static_cast<int>(event.type)));
-    event_value.GetList().push_back(
-        base::Value(static_cast<double>(event.timestamp)));
+    event_value.Append(base::Value(static_cast<int>(event.type)));
+    event_value.Append(base::Value(static_cast<double>(event.timestamp)));
     if (!event.content.empty())
-      event_value.GetList().push_back(base::Value(event.content));
-    list.GetList().emplace_back(std::move(event_value));
+      event_value.Append(base::Value(event.content));
+    list.Append(std::move(event_value));
   }
   return list;
 }
@@ -1356,7 +1355,7 @@
 
   base::ListValue buffer_list;
   for (auto& buffer : events.buffer_events())
-    buffer_list.GetList().emplace_back(SerializeEvents(buffer));
+    buffer_list.Append(SerializeEvents(buffer));
 
   dictionary.SetKey(kKeyBuffers, std::move(buffer_list));
   dictionary.SetKey(kKeyGlobalEvents, SerializeEvents(events.global_events()));
@@ -1745,7 +1744,7 @@
     base::DictionaryValue view_value = SerializeEventsContainer(view.second);
     view_value.SetKey(kKeyActivity, base::Value(view.first.activity));
     view_value.SetKey(kKeyTaskId, base::Value(view.first.task_id));
-    view_list.GetList().emplace_back(std::move(view_value));
+    view_list.Append(std::move(view_value));
   }
   root->SetKey(kKeyViews, std::move(view_list));
 
diff --git a/chrome/browser/chromeos/arc/tracing/arc_value_event.cc b/chrome/browser/chromeos/arc/tracing/arc_value_event.cc
index 0995f8cb..880a0634 100644
--- a/chrome/browser/chromeos/arc/tracing/arc_value_event.cc
+++ b/chrome/browser/chromeos/arc/tracing/arc_value_event.cc
@@ -18,11 +18,10 @@
   base::ListValue list;
   for (const auto& event : value_events) {
     base::ListValue event_value;
-    event_value.GetList().push_back(base::Value(static_cast<int>(event.type)));
-    event_value.GetList().push_back(
-        base::Value(static_cast<double>(event.timestamp)));
-    event_value.GetList().push_back(base::Value(event.value));
-    list.GetList().emplace_back(std::move(event_value));
+    event_value.Append(base::Value(static_cast<int>(event.type)));
+    event_value.Append(base::Value(static_cast<double>(event.timestamp)));
+    event_value.Append(base::Value(event.value));
+    list.Append(std::move(event_value));
   }
   return list;
 }
diff --git a/chrome/browser/chromeos/certificate_provider/test_certificate_provider_extension.cc b/chrome/browser/chromeos/certificate_provider/test_certificate_provider_extension.cc
index d35ce5a..520829a 100644
--- a/chrome/browser/chromeos/certificate_provider/test_certificate_provider_extension.cc
+++ b/chrome/browser/chromeos/certificate_provider/test_certificate_provider_extension.cc
@@ -44,7 +44,7 @@
 base::Value ConvertBytesToValue(base::span<const uint8_t> bytes) {
   base::Value value(base::Value::Type::LIST);
   for (auto byte : bytes)
-    value.GetList().emplace_back(byte);
+    value.Append(byte);
   return value;
 }
 
@@ -66,7 +66,7 @@
                          ConvertBytesToValue(GetCertDer(certificate)));
   base::Value supported_hashes_value(base::Value::Type::LIST);
   for (auto supported_hash : kSupportedHashes) {
-    supported_hashes_value.GetList().emplace_back(base::Value(
+    supported_hashes_value.Append(base::Value(
         extensions::api::certificate_provider::ToString(supported_hash)));
   }
   cert_info_value.SetKey("supportedHashes", std::move(supported_hashes_value));
@@ -164,7 +164,7 @@
 base::Value TestCertificateProviderExtension::HandleCertificatesRequest() {
   base::Value cert_info_values(base::Value::Type::LIST);
   if (!should_fail_certificate_requests_)
-    cert_info_values.GetList().emplace_back(MakeCertInfoValue(*certificate_));
+    cert_info_values.Append(MakeCertInfoValue(*certificate_));
   return cert_info_values;
 }
 
diff --git a/chrome/browser/chromeos/child_accounts/parent_access_code/parent_access_service_browsertest.cc b/chrome/browser/chromeos/child_accounts/parent_access_code/parent_access_service_browsertest.cc
index 9aadea1..72848d60 100644
--- a/chrome/browser/chromeos/child_accounts/parent_access_code/parent_access_service_browsertest.cc
+++ b/chrome/browser/chromeos/child_accounts/parent_access_code/parent_access_service_browsertest.cc
@@ -43,7 +43,7 @@
   dict.SetKey(kCurrentConfigDictKey, current_config.ToDictionary());
   base::Value old_configs_value(base::Value::Type::LIST);
   for (const auto& config : old_configs)
-    old_configs_value.GetList().push_back(config.ToDictionary());
+    old_configs_value.Append(config.ToDictionary());
   dict.SetKey(kOldConfigsDictKey, std::move(old_configs_value));
   return dict;
 }
diff --git a/chrome/browser/chromeos/child_accounts/time_limit_test_utils.cc b/chrome/browser/chromeos/child_accounts/time_limit_test_utils.cc
index dd5a0cc..f259522 100644
--- a/chrome/browser/chromeos/child_accounts/time_limit_test_utils.cc
+++ b/chrome/browser/chromeos/child_accounts/time_limit_test_utils.cc
@@ -146,7 +146,7 @@
         kWindowLimitEntries, base::Value(base::Value::Type::LIST));
   }
 
-  window_limit_entries->GetList().push_back(
+  window_limit_entries->Append(
       CreateTimeWindow(day, start_time, end_time, last_updated));
 }
 
@@ -163,7 +163,7 @@
 
   usage_time_limit::TimeLimitOverride new_override(action, created_at,
                                                    base::nullopt);
-  overrides->GetList().push_back(new_override.ToDictionary());
+  overrides->Append(new_override.ToDictionary());
 }
 
 void AddOverrideWithDuration(base::Value* policy,
@@ -180,7 +180,7 @@
 
   usage_time_limit::TimeLimitOverride new_override(action, created_at,
                                                    duration);
-  overrides->GetList().push_back(new_override.ToDictionary());
+  overrides->Append(new_override.ToDictionary());
 }
 
 std::string PolicyToString(const base::Value& policy) {
diff --git a/chrome/browser/chromeos/child_accounts/usage_time_limit_processor_unittest.cc b/chrome/browser/chromeos/child_accounts/usage_time_limit_processor_unittest.cc
index 5077c08f..23de4a46 100644
--- a/chrome/browser/chromeos/child_accounts/usage_time_limit_processor_unittest.cc
+++ b/chrome/browser/chromeos/child_accounts/usage_time_limit_processor_unittest.cc
@@ -69,8 +69,8 @@
       base::TimeDelta::FromMinutes(8 * 60 + 20), last_updated);
 
   base::Value window_limit_entries(base::Value::Type::LIST);
-  window_limit_entries.GetList().push_back(std::move(monday_time_limit));
-  window_limit_entries.GetList().push_back(std::move(friday_time_limit));
+  window_limit_entries.Append(std::move(monday_time_limit));
+  window_limit_entries.Append(std::move(friday_time_limit));
 
   base::Value time_window_limit = base::Value(base::Value::Type::DICTIONARY);
   time_window_limit.SetKey("entries", std::move(window_limit_entries));
@@ -173,8 +173,8 @@
       base::Value(utils::CreatePolicyTimestamp("1 Jan 2018 9:00:00")));
 
   base::Value overrides(base::Value::Type::LIST);
-  overrides.GetList().push_back(std::move(override_one));
-  overrides.GetList().push_back(std::move(override_two));
+  overrides.Append(std::move(override_one));
+  overrides.Append(std::move(override_two));
 
   // Call tested functions.
   base::Optional<TimeLimitOverride> override_struct =
@@ -219,9 +219,9 @@
       base::Value(utils::CreatePolicyTimestamp("1 Jan 2018 8:00:00")));
 
   base::Value overrides(base::Value::Type::LIST);
-  overrides.GetList().push_back(std::move(override_one));
-  overrides.GetList().push_back(std::move(override_two));
-  overrides.GetList().push_back(std::move(override_three));
+  overrides.Append(std::move(override_one));
+  overrides.Append(std::move(override_two));
+  overrides.Append(std::move(override_three));
 
   // Call tested functions.
   base::Optional<TimeLimitOverride> override_struct =
@@ -262,10 +262,10 @@
   override_two.SetKey("created_at_millis", base::Value("1200000"));
 
   base::Value overrides(base::Value::Type::LIST);
-  overrides.GetList().push_back(std::move(override_one));
-  overrides.GetList().push_back(std::move(override_two));
-  overrides.GetList().push_back(std::move(override_three));
-  overrides.GetList().push_back(std::move(override_four));
+  overrides.Append(std::move(override_one));
+  overrides.Append(std::move(override_two));
+  overrides.Append(std::move(override_three));
+  overrides.Append(std::move(override_four));
 
   // Call tested functions.
   base::Optional<TimeLimitOverride> override_struct =
diff --git a/chrome/browser/chromeos/crostini/crostini_registry_service.cc b/chrome/browser/chromeos/crostini/crostini_registry_service.cc
index fdec66d..8a0c5144 100644
--- a/chrome/browser/chromeos/crostini/crostini_registry_service.cc
+++ b/chrome/browser/chromeos/crostini/crostini_registry_service.cc
@@ -117,7 +117,7 @@
     const google::protobuf::RepeatedPtrField<std::string>& strings) {
   base::Value result(base::Value::Type::LIST);
   for (const std::string& string : strings)
-    result.GetList().emplace_back(string);
+    result.Append(string);
   return result;
 }
 
diff --git a/chrome/browser/chromeos/crostini/crostini_util.cc b/chrome/browser/chromeos/crostini/crostini_util.cc
index fc7ee2c..346f941 100644
--- a/chrome/browser/chromeos/crostini/crostini_util.cc
+++ b/chrome/browser/chromeos/crostini/crostini_util.cc
@@ -533,7 +533,7 @@
   new_container.SetKey(prefs::kContainerKey, base::Value(container_name));
 
   ListPrefUpdate updater(pref_service, crostini::prefs::kCrostiniContainers);
-  updater->GetList().emplace_back(std::move(new_container));
+  updater->Append(std::move(new_container));
 }
 
 void RemoveLxdContainerFromPrefs(Profile* profile,
diff --git a/chrome/browser/chromeos/extensions/file_manager/private_api_drive.cc b/chrome/browser/chromeos/extensions/file_manager/private_api_drive.cc
index 195acd4..f615c5cb 100644
--- a/chrome/browser/chromeos/extensions/file_manager/private_api_drive.cc
+++ b/chrome/browser/chromeos/extensions/file_manager/private_api_drive.cc
@@ -901,7 +901,7 @@
     entry.SetKey(kAvailableOfflinePropertyName,
                  base::Value(item->metadata->available_offline));
     if (!filter_dirs || !is_dir) {
-      result->GetList().emplace_back(std::move(entry));
+      result->Append(std::move(entry));
     }
   }
 
@@ -1520,7 +1520,7 @@
     }
     dict.SetKey("entry", std::move(entry));
     dict.SetKey("highlightedBaseName", base::Value(highlight));
-    results_list->GetList().emplace_back(std::move(dict));
+    results_list->Append(std::move(dict));
   }
 
   UmaEmitSearchOutcome(true, !is_offline_, search_type_, operation_start_);
diff --git a/chrome/browser/chromeos/extensions/file_manager/private_api_file_system.cc b/chrome/browser/chromeos/extensions/file_manager/private_api_file_system.cc
index 9eca60f..d750f837 100644
--- a/chrome/browser/chromeos/extensions/file_manager/private_api_file_system.cc
+++ b/chrome/browser/chromeos/extensions/file_manager/private_api_file_system.cc
@@ -1262,7 +1262,7 @@
     entry.SetKey("fileSystemRoot", base::Value(fs_root));
     entry.SetKey("fileFullPath", base::Value(fs_path.AsUTF8Unsafe()));
     entry.SetKey("fileIsDirectory", base::Value(result.second));
-    entries->GetList().emplace_back(std::move(entry));
+    entries->Append(std::move(entry));
   }
 
   auto result = std::make_unique<base::DictionaryValue>();
diff --git a/chrome/browser/chromeos/extensions/quick_unlock_private/quick_unlock_private_api_unittest.cc b/chrome/browser/chromeos/extensions/quick_unlock_private/quick_unlock_private_api_unittest.cc
index a9b6e5a..6b76422 100644
--- a/chrome/browser/chromeos/extensions/quick_unlock_private/quick_unlock_private_api_unittest.cc
+++ b/chrome/browser/chromeos/extensions/quick_unlock_private/quick_unlock_private_api_unittest.cc
@@ -229,7 +229,7 @@
         base::Bind(&CreateFakeAuthenticator));
 
     auto params = std::make_unique<base::ListValue>();
-    params->GetList().push_back(base::Value(password));
+    params->Append(base::Value(password));
     std::unique_ptr<base::Value> result = RunFunction(func, std::move(params));
     EXPECT_TRUE(result);
     auto token_info = quick_unlock_private::TokenInfo::FromValue(*result);
@@ -246,7 +246,7 @@
         base::Bind(&CreateFakeAuthenticator));
 
     auto params = std::make_unique<base::ListValue>();
-    params->GetList().push_back(base::Value(kInvalidPassword));
+    params->Append(base::Value(kInvalidPassword));
     return RunFunctionAndReturnError(func, std::move(params));
   }
 
diff --git a/chrome/browser/chromeos/file_system_provider/registry.cc b/chrome/browser/chromeos/file_system_provider/registry.cc
index 8f50846..8b2c91ab 100644
--- a/chrome/browser/chromeos/file_system_provider/registry.cc
+++ b/chrome/browser/chromeos/file_system_provider/registry.cc
@@ -79,8 +79,7 @@
       // Only persistent subscribers should be stored in persistent storage.
       // Other ones should not be restired after a restart.
       if (subscriber_it.second.persistent) {
-        persistent_origins_value.GetList().emplace_back(
-            subscriber_it.first.spec());
+        persistent_origins_value.Append(subscriber_it.first.spec());
       }
     }
     watcher.SetKey(kPrefKeyWatcherPersistentOrigins,
diff --git a/chrome/browser/chromeos/guest_os/guest_os_share_path.cc b/chrome/browser/chromeos/guest_os/guest_os_share_path.cc
index 6ab0061..40da853 100644
--- a/chrome/browser/chromeos/guest_os/guest_os_share_path.cc
+++ b/chrome/browser/chromeos/guest_os/guest_os_share_path.cc
@@ -498,7 +498,7 @@
   }
   if (!already_shared) {
     base::Value vms(base::Value::Type::LIST);
-    vms.GetList().emplace_back(base::Value(vm_name));
+    vms.Append(base::Value(vm_name));
     shared_paths->SetKey(path.value(), std::move(vms));
   }
 }
@@ -514,8 +514,7 @@
   base::Value dict(base::Value::Type::DICTIONARY);
   for (const auto& shared_path : *shared_paths) {
     base::Value termina(base::Value::Type::LIST);
-    termina.GetList().emplace_back(
-        base::Value(crostini::kCrostiniDefaultVmName));
+    termina.Append(base::Value(crostini::kCrostiniDefaultVmName));
     dict.SetKey(shared_path.GetString(), std::move(termina));
   }
   profile_prefs->Set(prefs::kGuestOSPathsSharedToVms, std::move(dict));
diff --git a/chrome/browser/chromeos/guest_os/guest_os_share_path_unittest.cc b/chrome/browser/chromeos/guest_os/guest_os_share_path_unittest.cc
index 5e80dcf0..515e1bd 100644
--- a/chrome/browser/chromeos/guest_os/guest_os_share_path_unittest.cc
+++ b/chrome/browser/chromeos/guest_os/guest_os_share_path_unittest.cc
@@ -227,8 +227,7 @@
                                 prefs::kGuestOSPathsSharedToVms);
     base::DictionaryValue* shared_paths = update.Get();
     base::Value termina(base::Value::Type::LIST);
-    termina.GetList().emplace_back(
-        base::Value(crostini::kCrostiniDefaultVmName));
+    termina.Append(base::Value(crostini::kCrostiniDefaultVmName));
     shared_paths->SetKey(shared_path_.value(), std::move(termina));
     volume_downloads_ = file_manager::Volume::CreateForDownloads(root_);
     guest_os_share_path_->RegisterSharedPath(crostini::kCrostiniDefaultVmName,
@@ -612,10 +611,10 @@
       crostini::kCrostiniDefaultVmName);
   base::Value shared_paths(base::Value::Type::DICTIONARY);
   base::Value vms(base::Value::Type::LIST);
-  vms.GetList().emplace_back(base::Value(crostini::kCrostiniDefaultVmName));
+  vms.Append(base::Value(crostini::kCrostiniDefaultVmName));
   shared_paths.SetKey(share_path_.value(), std::move(vms));
   base::Value vms2(base::Value::Type::LIST);
-  vms2.GetList().emplace_back(base::Value(crostini::kCrostiniDefaultVmName));
+  vms2.Append(base::Value(crostini::kCrostiniDefaultVmName));
   shared_paths.SetKey(share_path2_.value(), std::move(vms2));
   profile()->GetPrefs()->Set(prefs::kGuestOSPathsSharedToVms, shared_paths);
   guest_os_share_path_->SharePersistedPaths(
@@ -703,7 +702,7 @@
                               prefs::kGuestOSPathsSharedToVms);
   base::DictionaryValue* shared_paths = update.Get();
   base::Value vms(base::Value::Type::LIST);
-  vms.GetList().emplace_back(base::Value("vm-running"));
+  vms.Append(base::Value("vm-running"));
   shared_paths->SetKey(shared_path_.value(), std::move(vms));
   guest_os_share_path_->UnsharePath(
       "vm-running", shared_path_, true,
@@ -730,7 +729,7 @@
                               prefs::kGuestOSPathsSharedToVms);
   base::DictionaryValue* shared_paths = update.Get();
   base::Value vms(base::Value::Type::LIST);
-  vms.GetList().emplace_back(base::Value("vm-not-running"));
+  vms.Append(base::Value("vm-not-running"));
   shared_paths->SetKey(shared_path_.value(), std::move(vms));
   guest_os_share_path_->UnsharePath(
       "vm-not-running", shared_path_, true,
@@ -747,7 +746,7 @@
                               prefs::kGuestOSPathsSharedToVms);
   base::DictionaryValue* shared_paths = update.Get();
   base::Value vms(base::Value::Type::LIST);
-  vms.GetList().emplace_back(base::Value("PvmDefault"));
+  vms.Append(base::Value("PvmDefault"));
   shared_paths->SetKey(shared_path_.value(), std::move(vms));
   guest_os_share_path_->UnsharePath(
       "PvmDefault", shared_path_, true,
@@ -800,20 +799,20 @@
 
   base::FilePath path1("/path1");
   base::Value path1vms(base::Value::Type::LIST);
-  path1vms.GetList().emplace_back(base::Value("vm1"));
+  path1vms.Append(base::Value("vm1"));
   shared_paths.SetKey(path1.value(), std::move(path1vms));
   base::FilePath path2("/path2");
   base::Value path2vms(base::Value::Type::LIST);
-  path2vms.GetList().emplace_back(base::Value("vm2"));
+  path2vms.Append(base::Value("vm2"));
   shared_paths.SetKey(path2.value(), std::move(path2vms));
   base::FilePath path3("/path3");
   base::Value path3vms(base::Value::Type::LIST);
-  path3vms.GetList().emplace_back(base::Value("vm3"));
+  path3vms.Append(base::Value("vm3"));
   shared_paths.SetKey(path3.value(), std::move(path3vms));
   base::FilePath path12("/path12");
   base::Value path12vms(base::Value::Type::LIST);
-  path12vms.GetList().emplace_back(base::Value("vm1"));
-  path12vms.GetList().emplace_back(base::Value("vm2"));
+  path12vms.Append(base::Value("vm1"));
+  path12vms.Append(base::Value("vm2"));
   shared_paths.SetKey(path12.value(), std::move(path12vms));
   profile()->GetPrefs()->Set(prefs::kGuestOSPathsSharedToVms, shared_paths);
 
diff --git a/chrome/browser/chromeos/login/demo_mode/demo_session.cc b/chrome/browser/chromeos/login/demo_mode/demo_session.cc
index 4721762e..98d1069c 100644
--- a/chrome/browser/chromeos/login/demo_mode/demo_session.cc
+++ b/chrome/browser/chromeos/login/demo_mode/demo_session.cc
@@ -355,7 +355,7 @@
     dict.SetString(
         "title", l10n_util::GetDisplayNameForCountry(country, current_locale));
     dict.SetBoolean("selected", current_country == country);
-    country_list.GetList().push_back(std::move(dict));
+    country_list.Append(std::move(dict));
   }
   return country_list;
 }
diff --git a/chrome/browser/chromeos/login/enterprise_enrollment_browsertest.cc b/chrome/browser/chromeos/login/enterprise_enrollment_browsertest.cc
index c58157eb..a0a020e4 100644
--- a/chrome/browser/chromeos/login/enterprise_enrollment_browsertest.cc
+++ b/chrome/browser/chromeos/login/enterprise_enrollment_browsertest.cc
@@ -296,7 +296,7 @@
             base::JSONParserOptions::JSON_ALLOW_TRAILING_COMMAS));
     base::DictionaryValue custom_option;
     custom_option.SetKey("name", base::Value("Custom"));
-    options->GetList().emplace_back(std::move(custom_option));
+    options->Append(std::move(custom_option));
     for (size_t i = 0; i < options->GetList().size(); ++i) {
       const base::Value& option = options->GetList()[i];
       // Select configuration value.
diff --git a/chrome/browser/chromeos/login/oobe_interactive_ui_test.cc b/chrome/browser/chromeos/login/oobe_interactive_ui_test.cc
index edf2799e..2d6dc63 100644
--- a/chrome/browser/chromeos/login/oobe_interactive_ui_test.cc
+++ b/chrome/browser/chromeos/login/oobe_interactive_ui_test.cc
@@ -1,3 +1,4 @@
+
 // 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.
@@ -305,7 +306,7 @@
     base::Value app(base::Value::Type::DICTIONARY);
     app.SetKey("package_name", base::Value("test.package"));
     base::Value app_list(base::Value::Type::LIST);
-    app_list.GetList().emplace_back(std::move(app));
+    app_list.Append(std::move(app));
     delegate_->OnLoadSuccess(std::move(app_list));
   }
   void Retry() override { NOTREACHED(); }
@@ -585,7 +586,13 @@
   WaitForLoginDisplayHostShutdown();
 }
 
-IN_PROC_BROWSER_TEST_P(OobeInteractiveUITest, SimpleEndToEnd) {
+// Timing out on debug bots. crbug.com/1004327
+#if defined(NDEBUG)
+#define MAYBE_SimpleEndToEnd SimpleEndToEnd
+#else
+#define MAYBE_SimpleEndToEnd DISABLED_SimpleEndToEnd
+#endif
+IN_PROC_BROWSER_TEST_P(OobeInteractiveUITest, MAYBE_SimpleEndToEnd) {
   SimpleEndToEnd();
 }
 
@@ -643,8 +650,8 @@
   WaitForLoginDisplayHostShutdown();
 }
 
-// crbug.com/997987
-#if defined(MEMORY_SANITIZER)
+// crbug.com/997987. Disabled in debug since they time out.crbug.com/1004327
+#if defined(MEMORY_SANITIZER) || !defined(NDEBUG)
 #define MAYBE_EndToEnd DISABLED_EndToEnd
 #else
 #define MAYBE_EndToEnd EndToEnd
diff --git a/chrome/browser/chromeos/login/screens/app_downloading_screen_browsertest.cc b/chrome/browser/chromeos/login/screens/app_downloading_screen_browsertest.cc
index c24113cd..cee6253f5 100644
--- a/chrome/browser/chromeos/login/screens/app_downloading_screen_browsertest.cc
+++ b/chrome/browser/chromeos/login/screens/app_downloading_screen_browsertest.cc
@@ -108,7 +108,7 @@
 
 IN_PROC_BROWSER_TEST_F(AppDownloadingScreenTest, SingleAppSelected) {
   base::Value apps(base::Value::Type::LIST);
-  apps.GetList().emplace_back("app.test.package.1");
+  apps.Append("app.test.package.1");
 
   ProfileManager::GetActiveUserProfile()->GetPrefs()->Set(
       arc::prefs::kArcFastAppReinstallPackages, std::move(apps));
@@ -141,8 +141,8 @@
 
 IN_PROC_BROWSER_TEST_F(AppDownloadingScreenTest, MultipleAppsSelected) {
   base::Value apps(base::Value::Type::LIST);
-  apps.GetList().emplace_back("app.test.package.1");
-  apps.GetList().emplace_back("app.test.package.2");
+  apps.Append("app.test.package.1");
+  apps.Append("app.test.package.2");
 
   ProfileManager::GetActiveUserProfile()->GetPrefs()->Set(
       arc::prefs::kArcFastAppReinstallPackages, std::move(apps));
diff --git a/chrome/browser/chromeos/login/screens/recommend_apps/recommend_apps_fetcher_impl.cc b/chrome/browser/chromeos/login/screens/recommend_apps/recommend_apps_fetcher_impl.cc
index 99342fd..e89f8016 100644
--- a/chrome/browser/chromeos/login/screens/recommend_apps/recommend_apps_fetcher_impl.cc
+++ b/chrome/browser/chromeos/login/screens/recommend_apps/recommend_apps_fetcher_impl.cc
@@ -622,7 +622,7 @@
       continue;
     }
 
-    output.GetList().push_back(std::move(output_map));
+    output.Append(std::move(output_map));
   }
 
   RecordUmaResponseParseResult(RECOMMEND_APPS_RESPONSE_PARSE_RESULT_NO_ERROR);
diff --git a/chrome/browser/chromeos/login/screens/recommend_apps/recommend_apps_fetcher_impl_unittest.cc b/chrome/browser/chromeos/login/screens/recommend_apps/recommend_apps_fetcher_impl_unittest.cc
index 48f4483..ed2b1d3 100644
--- a/chrome/browser/chromeos/login/screens/recommend_apps/recommend_apps_fetcher_impl_unittest.cc
+++ b/chrome/browser/chromeos/login/screens/recommend_apps/recommend_apps_fetcher_impl_unittest.cc
@@ -412,7 +412,7 @@
   app.SetKey("name", base::Value("Test app 1"));
   app.SetKey("icon", base::Value("http://test.app"));
   app.SetKey("package_name", base::Value("test.app1"));
-  expected_apps.GetList().emplace_back(std::move(app));
+  expected_apps.Append(std::move(app));
 
   EXPECT_EQ(expected_apps, delegate_.loaded_apps());
 }
@@ -480,7 +480,7 @@
   app.SetKey("name", base::Value("Test app 1"));
   app.SetKey("icon", base::Value("http://test.app"));
   app.SetKey("package_name", base::Value("test.app1"));
-  expected_apps.GetList().emplace_back(std::move(app));
+  expected_apps.Append(std::move(app));
 
   EXPECT_EQ(expected_apps, delegate_.loaded_apps());
 }
@@ -545,7 +545,7 @@
   app.SetKey("name", base::Value("Test app 1"));
   app.SetKey("icon", base::Value("http://test.app"));
   app.SetKey("package_name", base::Value("test.app1"));
-  expected_apps.GetList().emplace_back(std::move(app));
+  expected_apps.Append(std::move(app));
 
   EXPECT_EQ(expected_apps, delegate_.loaded_apps());
 }
@@ -604,7 +604,7 @@
   app.SetKey("name", base::Value("Test app 1"));
   app.SetKey("icon", base::Value("http://test.app"));
   app.SetKey("package_name", base::Value("test.app1"));
-  expected_apps.GetList().emplace_back(std::move(app));
+  expected_apps.Append(std::move(app));
 
   EXPECT_EQ(expected_apps, delegate_.loaded_apps());
 }
@@ -669,7 +669,7 @@
   app.SetKey("name", base::Value("Test app 1"));
   app.SetKey("icon", base::Value("http://test.app"));
   app.SetKey("package_name", base::Value("test.app1"));
-  expected_apps.GetList().emplace_back(std::move(app));
+  expected_apps.Append(std::move(app));
 
   EXPECT_EQ(expected_apps, delegate_.loaded_apps());
 }
@@ -729,7 +729,7 @@
   app.SetKey("name", base::Value("Test app 1"));
   app.SetKey("icon", base::Value("http://test.app"));
   app.SetKey("package_name", base::Value("test.app1"));
-  expected_apps.GetList().emplace_back(std::move(app));
+  expected_apps.Append(std::move(app));
 
   EXPECT_EQ(expected_apps, delegate_.loaded_apps());
 }
@@ -789,7 +789,7 @@
   app.SetKey("name", base::Value("Test app 1"));
   app.SetKey("icon", base::Value("http://test.app"));
   app.SetKey("package_name", base::Value("test.app1"));
-  expected_apps.GetList().emplace_back(std::move(app));
+  expected_apps.Append(std::move(app));
 
   EXPECT_EQ(expected_apps, delegate_.loaded_apps());
 }
@@ -850,7 +850,7 @@
   app.SetKey("name", base::Value("Test app 1"));
   app.SetKey("icon", base::Value("http://test.app"));
   app.SetKey("package_name", base::Value("test.app1"));
-  expected_apps.GetList().emplace_back(std::move(app));
+  expected_apps.Append(std::move(app));
 
   EXPECT_EQ(expected_apps, delegate_.loaded_apps());
 }
@@ -911,7 +911,7 @@
   app.SetKey("name", base::Value("Test app 1"));
   app.SetKey("icon", base::Value("http://test.app"));
   app.SetKey("package_name", base::Value("test.app1"));
-  expected_apps.GetList().emplace_back(std::move(app));
+  expected_apps.Append(std::move(app));
 
   EXPECT_EQ(expected_apps, delegate_.loaded_apps());
 }
@@ -960,7 +960,7 @@
   app.SetKey("name", base::Value("Test app 1"));
   app.SetKey("icon", base::Value("http://test.app"));
   app.SetKey("package_name", base::Value("test.app1"));
-  expected_apps.GetList().emplace_back(std::move(app));
+  expected_apps.Append(std::move(app));
 
   EXPECT_EQ(expected_apps, delegate_.loaded_apps());
 
@@ -1046,7 +1046,7 @@
   app.SetKey("name", base::Value("Test app 1"));
   app.SetKey("icon", base::Value("http://test.app"));
   app.SetKey("package_name", base::Value("test.app1"));
-  expected_apps.GetList().emplace_back(std::move(app));
+  expected_apps.Append(std::move(app));
 
   EXPECT_EQ(expected_apps, delegate_.loaded_apps());
 }
@@ -1130,11 +1130,11 @@
   app1.SetKey("name", base::Value("Test app 1"));
   app1.SetKey("icon", base::Value("http://test.app"));
   app1.SetKey("package_name", base::Value("test.app1"));
-  expected_apps.GetList().emplace_back(std::move(app1));
+  expected_apps.Append(std::move(app1));
 
   base::Value app2(base::Value::Type::DICTIONARY);
   app2.SetKey("package_name", base::Value("test.app2"));
-  expected_apps.GetList().emplace_back(std::move(app2));
+  expected_apps.Append(std::move(app2));
 
   EXPECT_EQ(expected_apps, delegate_.loaded_apps());
 }
@@ -1174,11 +1174,11 @@
   app1.SetKey("name", base::Value("Test app 1"));
   app1.SetKey("icon", base::Value("http://test.app"));
   app1.SetKey("package_name", base::Value("test.app1"));
-  expected_apps.GetList().emplace_back(std::move(app1));
+  expected_apps.Append(std::move(app1));
 
   base::Value app2(base::Value::Type::DICTIONARY);
   app2.SetKey("package_name", base::Value("test.app2"));
-  expected_apps.GetList().emplace_back(std::move(app2));
+  expected_apps.Append(std::move(app2));
 
   EXPECT_EQ(expected_apps, delegate_.loaded_apps());
 }
@@ -1341,7 +1341,7 @@
   app.SetKey("name", base::Value("Test app 1"));
   app.SetKey("icon", base::Value("http://test.app"));
   app.SetKey("package_name", base::Value("test.app1"));
-  expected_apps.GetList().emplace_back(std::move(app));
+  expected_apps.Append(std::move(app));
 
   EXPECT_EQ(expected_apps, delegate_.loaded_apps());
 }
diff --git a/chrome/browser/chromeos/login/screens/recommend_apps_screen_browsertest.cc b/chrome/browser/chromeos/login/screens/recommend_apps_screen_browsertest.cc
index dc6fe74..89655fe 100644
--- a/chrome/browser/chromeos/login/screens/recommend_apps_screen_browsertest.cc
+++ b/chrome/browser/chromeos/login/screens/recommend_apps_screen_browsertest.cc
@@ -69,7 +69,7 @@
     EXPECT_TRUE(started_);
     base::Value app_list(base::Value::Type::LIST);
     for (const auto& app : apps) {
-      app_list.GetList().emplace_back(app.ToValue());
+      app_list.Append(app.ToValue());
     }
     delegate_->OnLoadSuccess(app_list);
   }
@@ -296,8 +296,8 @@
   ASSERT_TRUE(fast_reinstall_packages);
 
   base::Value expected_pref_value(base::Value::Type::LIST);
-  expected_pref_value.GetList().emplace_back("test.app.foo.app1");
-  expected_pref_value.GetList().emplace_back("test.app.foo.app2");
+  expected_pref_value.Append("test.app.foo.app1");
+  expected_pref_value.Append("test.app.foo.app2");
   EXPECT_EQ(expected_pref_value, *fast_reinstall_packages);
 }
 
@@ -369,7 +369,7 @@
   ASSERT_TRUE(fast_reinstall_packages);
 
   base::Value expected_pref_value(base::Value::Type::LIST);
-  expected_pref_value.GetList().emplace_back("test.app.foo.app2");
+  expected_pref_value.Append("test.app.foo.app2");
   EXPECT_EQ(expected_pref_value, *fast_reinstall_packages);
 }
 
diff --git a/chrome/browser/chromeos/login/test/local_policy_test_server_mixin.cc b/chrome/browser/chromeos/login/test/local_policy_test_server_mixin.cc
index 15ad01b..d9a5fb6 100644
--- a/chrome/browser/chromeos/login/test/local_policy_test_server_mixin.cc
+++ b/chrome/browser/chromeos/login/test/local_policy_test_server_mixin.cc
@@ -27,7 +27,7 @@
   base::Value config(base::Value::Type::DICTIONARY);
 
   base::Value managed_users(base::Value::Type::LIST);
-  managed_users.GetList().emplace_back("*");
+  managed_users.Append("*");
   config.SetKey("managed_users", std::move(managed_users));
 
   config.SetKey("robot_api_auth_code",
@@ -136,7 +136,7 @@
   // username is set in policy responses, even if the request does not contain
   // username field.
   base::Value managed_users_list(base::Value::Type::LIST);
-  managed_users_list.GetList().emplace_back("*");
+  managed_users_list.Append("*");
   server_config_.SetKey("managed_users", std::move(managed_users_list));
   server_config_.SetKey("policy_user", base::Value(policy_user));
   server_config_.SetKey("current_key_index", base::Value(0));
@@ -159,7 +159,7 @@
   policy_type_dict.SetKey("recommended", recommended_policy.Clone());
 
   base::Value managed_users_list(base::Value::Type::LIST);
-  managed_users_list.GetList().emplace_back("*");
+  managed_users_list.Append("*");
 
   server_config_.SetKey(policy::dm_protocol::kChromeUserPolicyType,
                         std::move(policy_type_dict));
diff --git a/chrome/browser/chromeos/login/test/session_flags_manager.cc b/chrome/browser/chromeos/login/test/session_flags_manager.cc
index b99f0542..928586a5 100644
--- a/chrome/browser/chromeos/login/test/session_flags_manager.cc
+++ b/chrome/browser/chromeos/login/test/session_flags_manager.cc
@@ -237,7 +237,7 @@
     flag_value.SetKey(kFlagNameKey, base::Value(flag.first));
     flag_value.SetKey(kFlagValueKey, base::Value(flag.second));
 
-    flag_list.GetList().emplace_back(std::move(flag_value));
+    flag_list.Append(std::move(flag_value));
   }
   return flag_list;
 }
diff --git a/chrome/browser/chromeos/login/webview_login_browsertest.cc b/chrome/browser/chromeos/login/webview_login_browsertest.cc
index d0d91443..8df3f4d5 100644
--- a/chrome/browser/chromeos/login/webview_login_browsertest.cc
+++ b/chrome/browser/chromeos/login/webview_login_browsertest.cc
@@ -607,7 +607,7 @@
                            base::Value(x509_authority_cert));
 
     base::ListValue onc_certificates;
-    onc_certificates.GetList().emplace_back(std::move(onc_certificate));
+    onc_certificates.Append(std::move(onc_certificate));
 
     base::DictionaryValue onc_dict;
     onc_dict.SetKey(onc::toplevel_config::kCertificates,
diff --git a/chrome/browser/chromeos/policy/component_active_directory_policy_service_unittest.cc b/chrome/browser/chromeos/policy/component_active_directory_policy_service_unittest.cc
index 5fa3e61..1c286439 100644
--- a/chrome/browser/chromeos/policy/component_active_directory_policy_service_unittest.cc
+++ b/chrome/browser/chromeos/policy/component_active_directory_policy_service_unittest.cc
@@ -354,8 +354,8 @@
                        std::make_unique<base::Value>(1.0), nullptr);
 
   auto list = std::make_unique<base::ListValue>();
-  list->GetList().push_back(base::Value("One"));
-  list->GetList().push_back(base::Value("Two"));
+  list->Append(base::Value("One"));
+  list->Append(base::Value("Two"));
   expected_policy_.Set("ListAsSubkeys", POLICY_LEVEL_MANDATORY,
                        POLICY_SCOPE_USER, POLICY_SOURCE_ACTIVE_DIRECTORY,
                        std::move(list), nullptr);
diff --git a/chrome/browser/chromeos/policy/device_auto_update_time_restrictions_decoder_unittest.cc b/chrome/browser/chromeos/policy/device_auto_update_time_restrictions_decoder_unittest.cc
index f27ceb4..714d248 100644
--- a/chrome/browser/chromeos/policy/device_auto_update_time_restrictions_decoder_unittest.cc
+++ b/chrome/browser/chromeos/policy/device_auto_update_time_restrictions_decoder_unittest.cc
@@ -101,7 +101,7 @@
       base::DictionaryValue time_dict;
       time_dict.SetKey("start", std::move(start));
       time_dict.SetKey("end", std::move(end));
-      list_val.GetList().push_back(std::move(time_dict));
+      list_val.Append(std::move(time_dict));
     }
     return list_val;
   }
diff --git a/chrome/browser/chromeos/policy/device_auto_update_time_restrictions_utils_unittest.cc b/chrome/browser/chromeos/policy/device_auto_update_time_restrictions_utils_unittest.cc
index be9b9c98..853c58c 100644
--- a/chrome/browser/chromeos/policy/device_auto_update_time_restrictions_utils_unittest.cc
+++ b/chrome/browser/chromeos/policy/device_auto_update_time_restrictions_utils_unittest.cc
@@ -108,7 +108,7 @@
       base::DictionaryValue time_dict;
       time_dict.SetKey("start", std::move(start));
       time_dict.SetKey("end", std::move(end));
-      list_val.GetList().push_back(std::move(time_dict));
+      list_val.Append(std::move(time_dict));
     }
     return list_val;
   }
diff --git a/chrome/browser/chromeos/policy/network_configuration_updater.cc b/chrome/browser/chromeos/policy/network_configuration_updater.cc
index 888bcc0..358e73a 100644
--- a/chrome/browser/chromeos/policy/network_configuration_updater.cc
+++ b/chrome/browser/chromeos/policy/network_configuration_updater.cc
@@ -290,7 +290,7 @@
   DCHECK(onc_value->is_dict());
   base::Value recommended_list(base::Value::Type::LIST);
   for (const auto& recommended_field_name : recommended_field_names) {
-    recommended_list.GetList().push_back(base::Value(recommended_field_name));
+    recommended_list.Append(base::Value(recommended_field_name));
   }
   onc_value->SetKey(::onc::kRecommended, std::move(recommended_list));
 }
diff --git a/chrome/browser/chromeos/policy/network_configuration_updater_unittest.cc b/chrome/browser/chromeos/policy/network_configuration_updater_unittest.cc
index 6102593..e4b7ee3 100644
--- a/chrome/browser/chromeos/policy/network_configuration_updater_unittest.cc
+++ b/chrome/browser/chromeos/policy/network_configuration_updater_unittest.cc
@@ -305,8 +305,7 @@
   ASSERT_TRUE(certs->GetList().size() > client_certificate_index);
 
   base::ListValue selected_certs;
-  selected_certs.GetList().push_back(
-      certs->GetList()[client_certificate_index].Clone());
+  selected_certs.Append(certs->GetList()[client_certificate_index].Clone());
 
   chromeos::onc::OncParsedCertificates parsed_selected_certs(selected_certs);
   ASSERT_FALSE(parsed_selected_certs.has_error());
diff --git a/chrome/browser/chromeos/policy/off_hours/off_hours_proto_parser.cc b/chrome/browser/chromeos/policy/off_hours/off_hours_proto_parser.cc
index 8a90951e..9b2c07d 100644
--- a/chrome/browser/chromeos/policy/off_hours/off_hours_proto_parser.cc
+++ b/chrome/browser/chromeos/policy/off_hours/off_hours_proto_parser.cc
@@ -64,7 +64,7 @@
       ExtractIgnoredPolicyProtoTagsFromProto(container);
   auto ignored_policies_value = std::make_unique<base::ListValue>();
   for (const auto& policy : ignored_policy_proto_tags)
-    ignored_policies_value->GetList().emplace_back(policy);
+    ignored_policies_value->Append(policy);
   off_hours->SetList("ignored_policy_proto_tags",
                      std::move(ignored_policies_value));
   return off_hours;
diff --git a/chrome/browser/chromeos/policy/off_hours/off_hours_proto_parser_unittest.cc b/chrome/browser/chromeos/policy/off_hours/off_hours_proto_parser_unittest.cc
index 4028110..c1c6dfe0 100644
--- a/chrome/browser/chromeos/policy/off_hours/off_hours_proto_parser_unittest.cc
+++ b/chrome/browser/chromeos/policy/off_hours/off_hours_proto_parser_unittest.cc
@@ -114,7 +114,7 @@
   off_hours_expected.SetList("intervals", std::move(intervals_value));
   auto ignored_policies_value = std::make_unique<base::ListValue>();
   for (const auto& policy : kDefaultIgnoredPolicies)
-    ignored_policies_value->GetList().emplace_back(policy);
+    ignored_policies_value->Append(policy);
   off_hours_expected.SetList("ignored_policy_proto_tags",
                              std::move(ignored_policies_value));
 
diff --git a/chrome/browser/chromeos/policy/policy_certs_browsertest.cc b/chrome/browser/chromeos/policy/policy_certs_browsertest.cc
index a17b891..f065626e 100644
--- a/chrome/browser/chromeos/policy/policy_certs_browsertest.cc
+++ b/chrome/browser/chromeos/policy/policy_certs_browsertest.cc
@@ -795,8 +795,7 @@
     onc_cert_scope.SetKey(onc::scope::kId, base::Value(extension_id));
 
     base::Value onc_cert_trust_bits(base::Value::Type::LIST);
-    onc_cert_trust_bits.GetList().push_back(
-        base::Value(onc::certificate::kWeb));
+    onc_cert_trust_bits.Append(base::Value(onc::certificate::kWeb));
 
     base::Value onc_certificate(base::Value::Type::DICTIONARY);
     onc_certificate.SetKey(onc::certificate::kGUID, base::Value("guid"));
@@ -808,7 +807,7 @@
                            std::move(onc_cert_trust_bits));
 
     base::Value onc_certificates(base::Value::Type::LIST);
-    onc_certificates.GetList().emplace_back(std::move(onc_certificate));
+    onc_certificates.Append(std::move(onc_certificate));
 
     base::Value onc_dict(base::Value::Type::DICTIONARY);
     onc_dict.SetKey(onc::toplevel_config::kCertificates,
diff --git a/chrome/browser/chromeos/policy/signin_profile_extensions_policy_test_base.cc b/chrome/browser/chromeos/policy/signin_profile_extensions_policy_test_base.cc
index f4eded6..cbe1d50 100644
--- a/chrome/browser/chromeos/policy/signin_profile_extensions_policy_test_base.cc
+++ b/chrome/browser/chromeos/policy/signin_profile_extensions_policy_test_base.cc
@@ -5,15 +5,12 @@
 #include "chrome/browser/chromeos/policy/signin_profile_extensions_policy_test_base.h"
 
 #include "base/bind.h"
-#include "base/files/file_path.h"
-#include "base/files/file_util.h"
 #include "base/logging.h"
-#include "base/path_service.h"
 #include "base/strings/string_util.h"
 #include "chrome/browser/browser_process.h"
 #include "chrome/browser/chromeos/profiles/profile_helper.h"
+#include "chrome/browser/extensions/policy_test_utils.h"
 #include "chrome/browser/profiles/profile_manager.h"
-#include "chrome/common/chrome_paths.h"
 #include "chromeos/constants/chromeos_switches.h"
 #include "components/policy/proto/chrome_device_policy.pb.h"
 #include "net/test/embedded_test_server/embedded_test_server.h"
@@ -36,9 +33,8 @@
 void SigninProfileExtensionsPolicyTestBase::SetUpOnMainThread() {
   DevicePolicyCrosBrowserTest::SetUpOnMainThread();
 
-  embedded_test_server()->RegisterRequestHandler(base::BindRepeating(
-      &SigninProfileExtensionsPolicyTestBase::InterceptMockHttp,
-      base::Unretained(this)));
+  extensions::policy_test_utils::SetUpEmbeddedTestServer(
+      embedded_test_server());
   ASSERT_TRUE(embedded_test_server()->Start());
 }
 
@@ -56,31 +52,6 @@
   RefreshDevicePolicy();
 }
 
-std::unique_ptr<net::test_server::HttpResponse>
-SigninProfileExtensionsPolicyTestBase::InterceptMockHttp(
-    const net::test_server::HttpRequest& request) {
-  const std::string kFileNameToIntercept = "update_manifest.xml";
-  if (request.GetURL().ExtractFileName() != kFileNameToIntercept)
-    return nullptr;
-
-  base::FilePath test_data_dir;
-  base::PathService::Get(chrome::DIR_TEST_DATA, &test_data_dir);
-  // Remove the leading '/'.
-  std::string relative_manifest_path = request.GetURL().path().substr(1);
-  std::string manifest_response;
-  CHECK(base::ReadFileToString(test_data_dir.Append(relative_manifest_path),
-                               &manifest_response));
-
-  base::ReplaceSubstringsAfterOffset(
-      &manifest_response, 0, "mock.http",
-      embedded_test_server()->host_port_pair().ToString());
-
-  auto response = std::make_unique<net::test_server::BasicHttpResponse>();
-  response->set_content_type("text/xml");
-  response->set_content(manifest_response);
-  return response;
-}
-
 Profile* SigninProfileExtensionsPolicyTestBase::GetInitialProfile() {
   // Intentionally not using the |chromeos::ProfileHelper::GetSigninProfile|
   // method here, as it performs the lazy construction of the profile, while for
diff --git a/chrome/browser/chromeos/policy/signin_profile_extensions_policy_test_base.h b/chrome/browser/chromeos/policy/signin_profile_extensions_policy_test_base.h
index 10936796..dc9a5fb0 100644
--- a/chrome/browser/chromeos/policy/signin_profile_extensions_policy_test_base.h
+++ b/chrome/browser/chromeos/policy/signin_profile_extensions_policy_test_base.h
@@ -14,9 +14,6 @@
 #include "chrome/browser/profiles/profile.h"
 #include "components/version_info/channel.h"
 #include "extensions/common/features/feature_channel.h"
-#include "net/test/embedded_test_server/http_request.h"
-#include "net/test/embedded_test_server/http_response.h"
-
 namespace policy {
 
 // Base class for testing sign-in profile apps/extensions that are installed via
@@ -42,12 +39,6 @@
   const version_info::Channel channel_;
 
  private:
-  // Replace "mock.http" with "127.0.0.1:<port>" on "update_manifest.xml" files.
-  // Host resolver doesn't work here because the test file doesn't know the
-  // correct port number.
-  std::unique_ptr<net::test_server::HttpResponse> InterceptMockHttp(
-      const net::test_server::HttpRequest& request);
-
   const extensions::ScopedCurrentChannel scoped_current_channel_;
 
   DISALLOW_COPY_AND_ASSIGN(SigninProfileExtensionsPolicyTestBase);
diff --git a/chrome/browser/chromeos/policy/user_cloud_policy_manager_chromeos_browsertest.cc b/chrome/browser/chromeos/policy/user_cloud_policy_manager_chromeos_browsertest.cc
index db8c238..fa535c2 100644
--- a/chrome/browser/chromeos/policy/user_cloud_policy_manager_chromeos_browsertest.cc
+++ b/chrome/browser/chromeos/policy/user_cloud_policy_manager_chromeos_browsertest.cc
@@ -156,7 +156,7 @@
   base::Value mandatory_policy(base::Value::Type::DICTIONARY);
   base::Value startup_urls(base::Value::Type::LIST);
   for (auto* const url : kStartupURLs)
-    startup_urls.GetList().push_back(base::Value(url));
+    startup_urls.Append(base::Value(url));
   mandatory_policy.SetKey(key::kRestoreOnStartupURLs, std::move(startup_urls));
   mandatory_policy.SetKey(key::kRestoreOnStartup,
                           base::Value(SessionStartupPref::kPrefValueURLs));
diff --git a/chrome/browser/chromeos/settings/device_settings_provider.cc b/chrome/browser/chromeos/settings/device_settings_provider.cc
index 119ff14..a715fb9 100644
--- a/chrome/browser/chromeos/settings/device_settings_provider.cc
+++ b/chrome/browser/chromeos/settings/device_settings_provider.cc
@@ -764,7 +764,7 @@
     const em::DeviceNativePrintersBlacklistProto& proto(
         policy.native_device_printers_blacklist());
     for (const auto& id : proto.blacklist())
-      list.GetList().emplace_back(id);
+      list.Append(id);
     new_values_cache->SetValue(kDeviceNativePrintersBlacklist, std::move(list));
   }
 
@@ -773,7 +773,7 @@
     const em::DeviceNativePrintersWhitelistProto& proto(
         policy.native_device_printers_whitelist());
     for (const auto& id : proto.whitelist())
-      list.GetList().emplace_back(id);
+      list.Append(id);
     new_values_cache->SetValue(kDeviceNativePrintersWhitelist, std::move(list));
   }
 
diff --git a/chrome/browser/chromeos/settings/device_settings_provider_unittest.cc b/chrome/browser/chromeos/settings/device_settings_provider_unittest.cc
index c7cae63..0d18ac0 100644
--- a/chrome/browser/chromeos/settings/device_settings_provider_unittest.cc
+++ b/chrome/browser/chromeos/settings/device_settings_provider_unittest.cc
@@ -715,7 +715,7 @@
   interval.SetPath({"end", "day_of_week"}, base::Value("Wednesday"));
   interval.SetPath({"end", "hours"}, base::Value(1));
   interval.SetPath({"end", "minutes"}, base::Value(20));
-  test_list.GetList().push_back(std::move(interval));
+  test_list.Append(std::move(interval));
   SetDeviceAutoUpdateTimeRestrictions(extra_field);
   VerifyPolicyValue(kDeviceAutoUpdateTimeRestrictions, &test_list);
 }
diff --git a/chrome/browser/component_updater/supervised_user_whitelist_installer_unittest.cc b/chrome/browser/component_updater/supervised_user_whitelist_installer_unittest.cc
index 527209f..2bcecf3 100644
--- a/chrome/browser/component_updater/supervised_user_whitelist_installer_unittest.cc
+++ b/chrome/browser/component_updater/supervised_user_whitelist_installer_unittest.cc
@@ -211,10 +211,12 @@
 
     profile_attributes_storage()->AddProfile(
         GetProfilePath(kClientId), base::ASCIIToUTF16("A Profile"),
-        std::string(), base::string16(), 0, std::string(), EmptyAccountId());
+        std::string(), base::string16(), false, 0, std::string(),
+        EmptyAccountId());
     profile_attributes_storage()->AddProfile(
         GetProfilePath(kOtherClientId), base::ASCIIToUTF16("Another Profile"),
-        std::string(), base::string16(), 0, std::string(), EmptyAccountId());
+        std::string(), base::string16(), false, 0, std::string(),
+        EmptyAccountId());
 
     installer_ = SupervisedUserWhitelistInstaller::Create(
         &component_update_service_,
diff --git a/chrome/browser/download/download_browsertest.cc b/chrome/browser/download/download_browsertest.cc
index e51ce50..08fe085a 100644
--- a/chrome/browser/download/download_browsertest.cc
+++ b/chrome/browser/download/download_browsertest.cc
@@ -58,6 +58,7 @@
 #include "chrome/browser/history/history_service_factory.h"
 #include "chrome/browser/infobars/infobar_service.h"
 #include "chrome/browser/lookalikes/safety_tips/safety_tip_test_utils.h"
+#include "chrome/browser/metrics/subprocess_metrics_provider.h"
 #include "chrome/browser/permissions/permission_request_manager.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/renderer_context_menu/render_view_context_menu_browsertest_util.h"
@@ -116,6 +117,7 @@
 #include "content/public/test/test_download_http_response.h"
 #include "content/public/test/test_file_error_injector.h"
 #include "content/public/test/test_navigation_observer.h"
+#include "content/public/test/url_loader_interceptor.h"
 #include "extensions/browser/extension_dialog_auto_confirm.h"
 #include "extensions/browser/extension_registry.h"
 #include "extensions/browser/extension_system.h"
@@ -146,6 +148,7 @@
 using content::BrowserContext;
 using content::BrowserThread;
 using content::DownloadManager;
+using content::URLLoaderInterceptor;
 using content::WebContents;
 using download::DownloadItem;
 using download::DownloadUrlParameters;
@@ -2484,7 +2487,31 @@
   ASSERT_FALSE(downloads[0]->IsTemporary());
 }
 
-IN_PROC_BROWSER_TEST_F(DownloadTest, SavePageNonHTMLViaGet) {
+class DownloadTestWithHistogramTester : public DownloadTest {
+ public:
+  void SetUp() override {
+    // Drop the request for https://accounts.google.com/ListAccounts.... Whether
+    // this request exist can be platform-specific, so drop it for consistency
+    // in a histogram recording result.
+    url_loader_interceptor_ =
+        std::make_unique<URLLoaderInterceptor>(base::BindLambdaForTesting(
+            [&](URLLoaderInterceptor::RequestParams* params) {
+              return params->url_request.url.spec().find(
+                         "accounts.google.com") != std::string::npos;
+            }));
+    DownloadTest::SetUp();
+  }
+
+  void ResetURLLoaderInterceptor() { url_loader_interceptor_.reset(); }
+
+  base::HistogramTester& histogram_tester() { return histogram_tester_; }
+
+ private:
+  base::HistogramTester histogram_tester_;
+  std::unique_ptr<URLLoaderInterceptor> url_loader_interceptor_;
+};
+
+IN_PROC_BROWSER_TEST_F(DownloadTestWithHistogramTester, SavePageNonHTMLViaGet) {
   embedded_test_server()->ServeFilesFromDirectory(GetTestDataDirectory());
   ASSERT_TRUE(embedded_test_server()->Start());
   EnableFileChooser(true);
@@ -2545,6 +2572,16 @@
   ASSERT_EQ(2u, download_items.size());
   ASSERT_EQ(url, download_items[0]->GetOriginalUrl());
   ASSERT_EQ(url, download_items[1]->GetOriginalUrl());
+
+  SubprocessMetricsProvider::MergeHistogramDeltasForTesting();
+  // Assert that the NIK is populated for 4 requests:
+  // - Navigation: image.jpg
+  // - favicon.ico
+  // - SavePage: image.jpg
+  // - context menu: image.jpg
+  histogram_tester().ExpectBucketCount("HttpCache.NetworkIsolationKeyPresent",
+                                       true /*sample*/, 4 /*count*/);
+  ResetURLLoaderInterceptor();
 }
 
 // Times out often on debug ChromeOS because test is slow.
diff --git a/chrome/browser/download/download_shelf.h b/chrome/browser/download/download_shelf.h
index 95ad5e9..35b6a42 100644
--- a/chrome/browser/download/download_shelf.h
+++ b/chrome/browser/download/download_shelf.h
@@ -45,16 +45,8 @@
 
   // Download progress animations ----------------------------------------------
 
-  enum {
-    // Progress animation timer period, in milliseconds.
-    kProgressRateMs = 30,
-
-    // Size of the space used for the progress indicator.
-    kProgressIndicatorSize = 25,
-
-    // x/y offset for the file type icon.
-    kFiletypeIconOffset = (kProgressIndicatorSize - 16) / 2
-  };
+  // Size of the space used for the progress indicator.
+  static constexpr int kProgressIndicatorSize = 25;
 
   DownloadShelf();
   virtual ~DownloadShelf();
diff --git a/chrome/browser/enterprise_reporting/profile_report_generator_unittest.cc b/chrome/browser/enterprise_reporting/profile_report_generator_unittest.cc
index d2c7ace..af8a397d 100644
--- a/chrome/browser/enterprise_reporting/profile_report_generator_unittest.cc
+++ b/chrome/browser/enterprise_reporting/profile_report_generator_unittest.cc
@@ -74,7 +74,7 @@
       profile_manager()->profiles_dir().AppendASCII(kIdleProfile);
   profile_manager()->profile_attributes_storage()->AddProfile(
       profile_path, base::ASCIIToUTF16(kIdleProfile), std::string(),
-      base::string16(), 0, std::string(), EmptyAccountId());
+      base::string16(), false, 0, std::string(), EmptyAccountId());
   std::unique_ptr<em::ChromeUserProfileInfo> response =
       generator_.MaybeGenerate(profile_path, kIdleProfile);
   ASSERT_FALSE(response.get());
diff --git a/chrome/browser/enterprise_reporting/report_generator_unittest.cc b/chrome/browser/enterprise_reporting/report_generator_unittest.cc
index f17b414b..92cc37f 100644
--- a/chrome/browser/enterprise_reporting/report_generator_unittest.cc
+++ b/chrome/browser/enterprise_reporting/report_generator_unittest.cc
@@ -112,7 +112,7 @@
           profile_manager_.profile_attributes_storage()->AddProfile(
               profile_manager()->profiles_dir().AppendASCII(profile_name),
               base::ASCIIToUTF16(profile_name), std::string(), base::string16(),
-              0, std::string(), EmptyAccountId());
+              false, 0, std::string(), EmptyAccountId());
           break;
         case kActive:
           profile_manager_.CreateTestingProfile(profile_name);
diff --git a/chrome/browser/extensions/api/enterprise_device_attributes/enterprise_device_attributes_apitest.cc b/chrome/browser/extensions/api/enterprise_device_attributes/enterprise_device_attributes_apitest.cc
index 9d3f31a0a..b4f00865 100644
--- a/chrome/browser/extensions/api/enterprise_device_attributes/enterprise_device_attributes_apitest.cc
+++ b/chrome/browser/extensions/api/enterprise_device_attributes/enterprise_device_attributes_apitest.cc
@@ -7,7 +7,6 @@
 #include "base/bind.h"
 #include "base/json/json_writer.h"
 #include "base/path_service.h"
-#include "base/strings/stringprintf.h"
 #include "base/task/post_task.h"
 #include "base/values.h"
 #include "chrome/browser/browser_process.h"
@@ -15,6 +14,7 @@
 #include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h"
 #include "chrome/browser/chromeos/policy/device_policy_cros_browser_test.h"
 #include "chrome/browser/extensions/extension_apitest.h"
+#include "chrome/browser/extensions/policy_test_utils.h"
 #include "chrome/common/chrome_paths.h"
 #include "chrome/test/base/ui_test_utils.h"
 #include "chromeos/dbus/session_manager/fake_session_manager_client.h"
@@ -24,7 +24,6 @@
 #include "components/account_id/account_id.h"
 #include "components/policy/core/common/cloud/device_management_service.h"
 #include "components/policy/core/common/mock_configuration_policy_provider.h"
-#include "components/policy/policy_constants.h"
 #include "components/prefs/pref_service.h"
 #include "components/user_manager/user_manager.h"
 #include "content/public/browser/browser_task_traits.h"
@@ -33,10 +32,7 @@
 #include "content/public/test/test_utils.h"
 #include "extensions/browser/api_test_utils.h"
 #include "extensions/browser/extension_registry.h"
-#include "extensions/browser/test_extension_registry_observer.h"
 #include "extensions/test/result_catcher.h"
-#include "net/test/embedded_test_server/http_request.h"
-#include "net/test/embedded_test_server/http_response.h"
 
 namespace {
 
@@ -99,34 +95,6 @@
     set_chromeos_user_ = false;
   }
 
-  // Replace "mock.http" with "127.0.0.1:<port>" on "update_manifest.xml" files.
-  // Host resolver doesn't work here because the test file doesn't know the
-  // correct port number.
-  std::unique_ptr<net::test_server::HttpResponse> InterceptMockHttp(
-      const net::test_server::HttpRequest& request) {
-    const std::string kFileNameToIntercept = "update_manifest.xml";
-    if (request.GetURL().ExtractFileName() != kFileNameToIntercept)
-      return nullptr;
-
-    base::FilePath test_data_dir;
-    base::PathService::Get(chrome::DIR_TEST_DATA, &test_data_dir);
-    // Remove the leading '/'.
-    std::string relative_manifest_path = request.GetURL().path().substr(1);
-    std::string manifest_response;
-    CHECK(base::ReadFileToString(test_data_dir.Append(relative_manifest_path),
-                                 &manifest_response));
-
-    base::ReplaceSubstringsAfterOffset(
-        &manifest_response, 0, "mock.http",
-        embedded_test_server()->host_port_pair().ToString());
-
-    std::unique_ptr<net::test_server::BasicHttpResponse> response(
-        new net::test_server::BasicHttpResponse());
-    response->set_content_type("text/xml");
-    response->set_content(manifest_response);
-    return response;
-  }
-
  protected:
   // ExtensionApiTest
   void SetUpCommandLine(base::CommandLine* command_line) override {
@@ -192,29 +160,6 @@
     ExtensionApiTest::SetUpOnMainThread();
   }
 
-  void SetPolicy() {
-    // Extensions that are force-installed come from an update URL, which
-    // defaults to the webstore. Use a mock URL for this test with an update
-    // manifest that includes the crx file of the test extension.
-    GURL update_manifest_url(
-        embedded_test_server()->GetURL(kUpdateManifestPath));
-
-    std::unique_ptr<base::ListValue> forcelist(new base::ListValue);
-    forcelist->AppendString(base::StringPrintf(
-        "%s;%s", kTestExtensionID, update_manifest_url.spec().c_str()));
-
-    policy::PolicyMap policy;
-    policy.Set(policy::key::kExtensionInstallForcelist,
-               policy::POLICY_LEVEL_MANDATORY, policy::POLICY_SCOPE_MACHINE,
-               policy::POLICY_SOURCE_CLOUD, std::move(forcelist), nullptr);
-
-    // Set the policy and wait until the extension is installed.
-    extensions::TestExtensionRegistryObserver observer(
-        ExtensionRegistry::Get(profile()));
-    policy_provider_.UpdateChromePolicy(policy);
-    observer.WaitForExtensionLoaded();
-  }
-
   // Load |page_url| in |browser| and wait for PASSED or FAILED notification.
   // The functionality of this function is reduced functionality of
   // RunExtensionSubtest(), but we don't use it here because it requires
@@ -248,11 +193,12 @@
       AccountId::FromUserEmailGaiaId(kAffiliatedUserEmail,
                                      kAffiliatedUserGaiaId);
 
+  policy::MockConfigurationPolicyProvider policy_provider_;
+
  private:
   chromeos::ScopedStubInstallAttributes test_install_attributes_{
       chromeos::StubInstallAttributes::CreateCloudManaged("fake-domain",
                                                           "fake-id")};
-  policy::MockConfigurationPolicyProvider policy_provider_;
   policy::DevicePolicyCrosTestHelper test_helper_;
   chromeos::system::ScopedFakeStatisticsProvider fake_statistics_provider_;
 };
@@ -262,13 +208,11 @@
 }
 
 IN_PROC_BROWSER_TEST_P(EnterpriseDeviceAttributesTest, Success) {
-  // Setup |URLLoaderInterceptor|, which is required for force-installing the
-  // test extension through policy.
-  embedded_test_server()->RegisterRequestHandler(
-      base::BindRepeating(&EnterpriseDeviceAttributesTest::InterceptMockHttp,
-                          base::Unretained(this)));
+  policy_test_utils::SetUpEmbeddedTestServer(embedded_test_server());
   ASSERT_TRUE(embedded_test_server()->Start());
-  SetPolicy();
+  policy_test_utils::SetExtensionInstallForcelistPolicy(
+      kTestExtensionID, embedded_test_server()->GetURL(kUpdateManifestPath),
+      profile(), &policy_provider_);
 
   EXPECT_EQ(GetParam().affiliated, user_manager::UserManager::Get()
                                        ->FindUser(affiliated_account_id_)
diff --git a/chrome/browser/extensions/api/enterprise_platform_keys/enterprise_platform_keys_apitest_nss.cc b/chrome/browser/extensions/api/enterprise_platform_keys/enterprise_platform_keys_apitest_nss.cc
index aa1e7cd6..36988ba 100644
--- a/chrome/browser/extensions/api/enterprise_platform_keys/enterprise_platform_keys_apitest_nss.cc
+++ b/chrome/browser/extensions/api/enterprise_platform_keys/enterprise_platform_keys_apitest_nss.cc
@@ -11,23 +11,18 @@
 #include "base/path_service.h"
 #include "base/run_loop.h"
 #include "base/stl_util.h"
-#include "base/strings/stringprintf.h"
 #include "base/task/post_task.h"
 #include "chrome/browser/extensions/api/platform_keys/platform_keys_test_base.h"
+#include "chrome/browser/extensions/policy_test_utils.h"
 #include "chrome/browser/net/nss_context.h"
 #include "chrome/common/chrome_paths.h"
-#include "components/policy/core/common/policy_map.h"
-#include "components/policy/policy_constants.h"
 #include "content/public/browser/browser_task_traits.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/common/content_switches.h"
 #include "crypto/nss_util_internal.h"
 #include "crypto/scoped_test_system_nss_key_slot.h"
 #include "extensions/browser/extension_registry.h"
-#include "extensions/browser/test_extension_registry_observer.h"
 #include "net/cert/nss_cert_database.h"
-#include "net/test/embedded_test_server/http_request.h"
-#include "net/test/embedded_test_server/http_response.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
@@ -168,9 +163,7 @@
   }
 
   void SetUpOnMainThread() override {
-    embedded_test_server()->RegisterRequestHandler(
-        base::BindRepeating(&EnterprisePlatformKeysTest::InterceptMockHttp,
-                            base::Unretained(this)));
+    policy_test_utils::SetUpEmbeddedTestServer(embedded_test_server());
     PlatformKeysTestBase::SetUpOnMainThread();
   }
 
@@ -184,57 +177,7 @@
     done_callback.Run();
   }
 
-  void SetPolicy() {
-    // Extensions that are force-installed come from an update URL, which
-    // defaults to the webstore. Use a mock URL for this test with an update
-    // manifest that includes the crx file of the test extension.
-    GURL update_manifest_url(
-        embedded_test_server()->GetURL(kUpdateManifestPath));
-
-    std::unique_ptr<base::ListValue> forcelist(new base::ListValue);
-    forcelist->AppendString(base::StringPrintf(
-        "%s;%s", kTestExtensionID, update_manifest_url.spec().c_str()));
-
-    policy::PolicyMap policy;
-    policy.Set(policy::key::kExtensionInstallForcelist,
-               policy::POLICY_LEVEL_MANDATORY, policy::POLICY_SCOPE_MACHINE,
-               policy::POLICY_SOURCE_CLOUD, std::move(forcelist), nullptr);
-
-    // Set the policy and wait until the extension is installed.
-    TestExtensionRegistryObserver observer(ExtensionRegistry::Get(profile()));
-    mock_policy_provider()->UpdateChromePolicy(policy);
-    observer.WaitForExtensionWillBeInstalled();
-  }
-
  private:
-  // Replace "mock.http" with "127.0.0.1:<port>" on "update_manifest.xml" files.
-  // Host resolver doesn't work here because the test file doesn't know the
-  // correct port number.
-  std::unique_ptr<net::test_server::HttpResponse> InterceptMockHttp(
-      const net::test_server::HttpRequest& request) {
-    const std::string kFileNameToIntercept = "update_manifest.xml";
-    if (request.GetURL().ExtractFileName() != kFileNameToIntercept)
-      return nullptr;
-
-    base::FilePath test_data_dir;
-    base::PathService::Get(chrome::DIR_TEST_DATA, &test_data_dir);
-    // Remove the leading '/'.
-    std::string relative_manifest_path = request.GetURL().path().substr(1);
-    std::string manifest_response;
-    CHECK(base::ReadFileToString(test_data_dir.Append(relative_manifest_path),
-                                 &manifest_response));
-
-    base::ReplaceSubstringsAfterOffset(
-        &manifest_response, 0, "mock.http",
-        embedded_test_server()->host_port_pair().ToString());
-
-    std::unique_ptr<net::test_server::BasicHttpResponse> response(
-        new net::test_server::BasicHttpResponse());
-    response->set_content_type("text/xml");
-    response->set_content(manifest_response);
-    return response;
-  }
-
   void PrepareTestSystemSlotOnIO(
       crypto::ScopedTestSystemNSSKeySlot* system_slot) override {
     // Import a private key to the system slot.  The Javascript part of this
@@ -263,7 +206,9 @@
                   loop.QuitClosure()));
    loop.Run();
   }
-  SetPolicy();
+  policy_test_utils::SetExtensionInstallForcelistPolicy(
+      kTestExtensionID, embedded_test_server()->GetURL(kUpdateManifestPath),
+      profile(), mock_policy_provider());
 
   // By default, the system token is disabled.
   std::string system_token_availability = "";
diff --git a/chrome/browser/extensions/policy_test_utils.cc b/chrome/browser/extensions/policy_test_utils.cc
new file mode 100644
index 0000000..8771b4ae
--- /dev/null
+++ b/chrome/browser/extensions/policy_test_utils.cc
@@ -0,0 +1,90 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/extensions/policy_test_utils.h"
+
+#include "base/files/file_util.h"
+#include "base/path_service.h"
+#include "base/values.h"
+#include "chrome/browser/profiles/profile.h"
+#include "chrome/common/chrome_paths.h"
+#include "components/policy/core/common/mock_configuration_policy_provider.h"
+#include "components/policy/policy_constants.h"
+#include "extensions/browser/extension_registry.h"
+#include "extensions/browser/test_extension_registry_observer.h"
+#include "net/test/embedded_test_server/embedded_test_server.h"
+#include "net/test/embedded_test_server/http_request.h"
+#include "net/test/embedded_test_server/http_response.h"
+#include "url/gurl.h"
+
+namespace extensions {
+
+namespace policy_test_utils {
+
+namespace {
+
+constexpr char kFileNameToIntercept[] = "update_manifest.xml";
+
+// Replace "mock.http" with "127.0.0.1:<port>" on "update_manifest.xml" files.
+// Host resolver doesn't work here because the test file doesn't know the
+// correct port number.
+std::unique_ptr<net::test_server::HttpResponse> InterceptMockHttp(
+    net::EmbeddedTestServer* embedded_test_server,
+    const net::test_server::HttpRequest& request) {
+  if (request.GetURL().ExtractFileName() != kFileNameToIntercept)
+    return nullptr;
+
+  base::FilePath test_data_dir;
+  base::PathService::Get(chrome::DIR_TEST_DATA, &test_data_dir);
+  // Remove the leading '/'.
+  std::string relative_manifest_path = request.GetURL().path().substr(1);
+  std::string manifest_response;
+  CHECK(base::ReadFileToString(test_data_dir.Append(relative_manifest_path),
+                               &manifest_response));
+
+  base::ReplaceSubstringsAfterOffset(
+      &manifest_response, 0, "mock.http",
+      embedded_test_server->host_port_pair().ToString());
+
+  auto response = std::make_unique<net::test_server::BasicHttpResponse>();
+  response->set_content_type("text/xml");
+  response->set_content(manifest_response);
+  return response;
+}
+
+}  // namespace
+
+void SetUpEmbeddedTestServer(net::EmbeddedTestServer* embedded_test_server) {
+  embedded_test_server->RegisterRequestHandler(
+      base::BindRepeating(&InterceptMockHttp, embedded_test_server));
+}
+
+void SetExtensionInstallForcelistPolicy(
+    const ExtensionId& extension_id,
+    const GURL& update_manifest_url,
+    Profile* profile,
+    policy::MockConfigurationPolicyProvider* policy_provider) {
+  // Extensions that are force-installed come from an update URL, which defaults
+  // to the webstore. Use a mock URL for test with an update manifest that
+  // includes the crx file of the test extension.
+  base::Value forcelist(base::Value::Type::LIST);
+  forcelist.Append(base::StringPrintf("%s;%s", extension_id.c_str(),
+                                      update_manifest_url.spec().c_str()));
+
+  policy::PolicyMap policy;
+  policy.Set(policy::key::kExtensionInstallForcelist,
+             policy::POLICY_LEVEL_MANDATORY, policy::POLICY_SCOPE_MACHINE,
+             policy::POLICY_SOURCE_CLOUD,
+             base::Value::ToUniquePtrValue(std::move(forcelist)), nullptr);
+
+  // Set the policy and wait until the extension is installed.
+  extensions::TestExtensionRegistryObserver observer(
+      ExtensionRegistry::Get(profile));
+  policy_provider->UpdateChromePolicy(policy);
+  observer.WaitForExtensionLoaded();
+}
+
+}  // namespace policy_test_utils
+
+}  // namespace extensions
diff --git a/chrome/browser/extensions/policy_test_utils.h b/chrome/browser/extensions/policy_test_utils.h
new file mode 100644
index 0000000..a8d812d
--- /dev/null
+++ b/chrome/browser/extensions/policy_test_utils.h
@@ -0,0 +1,44 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_EXTENSIONS_POLICY_TEST_UTILS_H_
+#define CHROME_BROWSER_EXTENSIONS_POLICY_TEST_UTILS_H_
+
+#include "extensions/common/extension_id.h"
+
+class GURL;
+class Profile;
+
+namespace net {
+namespace test_server {
+class EmbeddedTestServer;
+}  // namespace test_server
+}  // namespace net
+
+namespace policy {
+class MockConfigurationPolicyProvider;
+}  // namespace policy
+
+namespace extensions {
+
+namespace policy_test_utils {
+
+// Intercepts "update_manifest.xml" files requests.
+void SetUpEmbeddedTestServer(
+    net::test_server::EmbeddedTestServer* embedded_test_server);
+
+// Assigns an |extension_id| and its |update_manifest_url| to the
+// "ExtensionInstallForcelist" user policy.
+// This will cause the extension to get force-installed.
+void SetExtensionInstallForcelistPolicy(
+    const ExtensionId& extension_id,
+    const GURL& update_manifest_url,
+    Profile* profile,
+    policy::MockConfigurationPolicyProvider* policy_provider);
+
+}  // namespace policy_test_utils
+
+}  // namespace extensions
+
+#endif  // CHROME_BROWSER_EXTENSIONS_POLICY_TEST_UTILS_H_
diff --git a/chrome/browser/flag-metadata.json b/chrome/browser/flag-metadata.json
index 8d70531..c22041f 100644
--- a/chrome/browser/flag-metadata.json
+++ b/chrome/browser/flag-metadata.json
@@ -950,11 +950,6 @@
     "expiry_milestone": 80
   },
   {
-    "name": "enable-autofill-import-dynamic-forms",
-    "owners": [ "hozhng@google.com", "jiahuiguo@google.com" ],
-    "expiry_milestone": 79
-  },
-  {
     "name": "enable-autofill-local-card-migration-uses-strike-system-v2",
     "owners": [ "annelim@google.com", "jsaul@google.com" , "jiahuiguo@google.com"],
     "expiry_milestone": 84
diff --git a/chrome/browser/flag_descriptions.cc b/chrome/browser/flag_descriptions.cc
index f380d69..df1cca6 100644
--- a/chrome/browser/flag_descriptions.cc
+++ b/chrome/browser/flag_descriptions.cc
@@ -516,12 +516,6 @@
     "If enabled, local cards from unsupported networks will not be offered "
     "local card migration.";
 
-const char kEnableAutofillImportDynamicFormsName[] =
-    "Allow credit card import from dynamic forms after entry";
-const char kEnableAutofillImportDynamicFormsDescription[] =
-    "If enabled, offers credit card save for dynamic forms from the page after "
-    "information has been entered into them.";
-
 const char kEnableAutofillLocalCardMigrationUsesStrikeSystemV2Name[] =
     "Enable limit on offering to migrate local cards repeatedly using the "
     "updated strike system implementation";
diff --git a/chrome/browser/flag_descriptions.h b/chrome/browser/flag_descriptions.h
index 01a62afc..5ce73d1 100644
--- a/chrome/browser/flag_descriptions.h
+++ b/chrome/browser/flag_descriptions.h
@@ -321,9 +321,6 @@
 extern const char kEnableAutofillDoNotMigrateUnsupportedLocalCardsName[];
 extern const char kEnableAutofillDoNotMigrateUnsupportedLocalCardsDescription[];
 
-extern const char kEnableAutofillImportDynamicFormsName[];
-extern const char kEnableAutofillImportDynamicFormsDescription[];
-
 extern const char kEnableAutofillLocalCardMigrationUsesStrikeSystemV2Name[];
 extern const char
     kEnableAutofillLocalCardMigrationUsesStrikeSystemV2Description[];
diff --git a/chrome/browser/notifications/scheduler/notification_schedule_service_browsertest.cc b/chrome/browser/notifications/scheduler/notification_schedule_service_browsertest.cc
new file mode 100644
index 0000000..8cb9a63
--- /dev/null
+++ b/chrome/browser/notifications/scheduler/notification_schedule_service_browsertest.cc
@@ -0,0 +1,177 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <memory>
+#include <set>
+#include <string>
+#include <utility>
+
+#include "base/macros.h"
+#include "base/run_loop.h"
+#include "base/strings/utf_string_conversions.h"
+#include "base/test/scoped_feature_list.h"
+#include "chrome/browser/notifications/scheduler/notification_background_task_scheduler_impl.h"
+#include "chrome/browser/notifications/scheduler/public/display_agent.h"
+#include "chrome/browser/notifications/scheduler/public/features.h"
+#include "chrome/browser/notifications/scheduler/public/notification_params.h"
+#include "chrome/browser/notifications/scheduler/public/notification_schedule_service.h"
+#include "chrome/browser/notifications/scheduler/public/notification_scheduler_client.h"
+#include "chrome/browser/notifications/scheduler/public/notification_scheduler_client_registrar.h"
+#include "chrome/browser/notifications/scheduler/schedule_service_factory_helper.h"
+#include "chrome/browser/profiles/profile.h"
+#include "chrome/browser/ui/browser.h"
+#include "chrome/test/base/in_process_browser_test.h"
+#include "content/public/browser/browser_context.h"
+#include "content/public/browser/storage_partition.h"
+
+namespace notifications {
+namespace {
+
+const base::FilePath::CharType kTestDir[] =
+    FILE_PATH_LITERAL("NotificationScheduleServiceTest");
+
+class TestClient : public NotificationSchedulerClient {
+ public:
+  TestClient() {}
+  ~TestClient() override = default;
+
+ private:
+  // NotificationSchedulerClient implementation.
+  void BeforeShowNotification(
+      std::unique_ptr<NotificationData> notification_data,
+      NotificationDataCallback callback) override {
+    std::move(callback).Run(std::move(notification_data));
+  }
+
+  void OnSchedulerInitialized(bool success,
+                              std::set<std::string> guids) override {
+    DCHECK(success);
+  }
+
+  void OnUserAction(const UserActionData& action_data) override {}
+
+  DISALLOW_COPY_AND_ASSIGN(TestClient);
+};
+
+class TestBackgroundTaskScheduler : public NotificationBackgroundTaskScheduler {
+ public:
+  TestBackgroundTaskScheduler() = default;
+  ~TestBackgroundTaskScheduler() override = default;
+
+  // Waits until a background task has been updated.
+  void WaitForTaskUpdated() {
+    DCHECK(!run_loop_);
+    run_loop_ = std::make_unique<base::RunLoop>();
+    run_loop_->Run();
+  }
+
+  base::TimeDelta window_start() { return window_start_; }
+
+ private:
+  void QuitRunLoopIfNeeded() {
+    if (run_loop_ && run_loop_->running()) {
+      run_loop_->Quit();
+    }
+  }
+
+  // NotificationBackgroundTaskScheduler implementation.
+  void Schedule(notifications::SchedulerTaskTime scheduler_task_time,
+                base::TimeDelta window_start,
+                base::TimeDelta window_end) override {
+    QuitRunLoopIfNeeded();
+  }
+
+  void Cancel() override { QuitRunLoopIfNeeded(); }
+
+  base::TimeDelta window_start_;
+  std::unique_ptr<base::RunLoop> run_loop_;
+
+  DISALLOW_COPY_AND_ASSIGN(TestBackgroundTaskScheduler);
+};
+
+// Browser test for notification scheduling system. Uses real database
+// instances. Mainly to cover service initialization flow in chrome layer.
+class NotificationScheduleServiceTest : public InProcessBrowserTest {
+ public:
+  NotificationScheduleServiceTest() : task_scheduler_(nullptr) {
+    scoped_feature_list_.InitWithFeatures(
+        {features::kNotificationScheduleService}, {});
+  }
+
+  ~NotificationScheduleServiceTest() override {}
+
+ protected:
+  void SetUpOnMainThread() override {
+    InProcessBrowserTest::SetUpOnMainThread();
+    ASSERT_TRUE(tmp_dir_.CreateUniqueTempDir());
+  }
+
+  void TearDownOnMainThread() override {
+    InProcessBrowserTest::TearDownOnMainThread();
+    ASSERT_TRUE(tmp_dir_.Delete());
+  }
+
+  // Initializes |service_|. Injects database test data before this call.
+  void Init() {
+    auto* profile = browser()->profile();
+    auto client = std::make_unique<TestClient>();
+    auto client_registrar =
+        std::make_unique<NotificationSchedulerClientRegistrar>();
+    client_registrar->RegisterClient(SchedulerClientType::kTest1,
+                                     std::move(client));
+    auto display_agent = notifications::DisplayAgent::Create();
+    auto background_task_scheduler =
+        std::make_unique<TestBackgroundTaskScheduler>();
+    task_scheduler_ = background_task_scheduler.get();
+    auto* db_provider =
+        content::BrowserContext::GetDefaultStoragePartition(profile)
+            ->GetProtoDatabaseProvider();
+    NotificationScheduleService* service =
+        static_cast<NotificationScheduleService*>(
+            CreateNotificationScheduleService(
+                std::move(client_registrar),
+                std::move(background_task_scheduler), std::move(display_agent),
+                db_provider, tmp_dir_.GetPath().Append(kTestDir),
+                profile->IsOffTheRecord()));
+    service_ = std::unique_ptr<NotificationScheduleService>(service);
+  }
+
+  NotificationScheduleService* schedule_service() { return service_.get(); }
+
+  TestBackgroundTaskScheduler* task_scheduler() {
+    DCHECK(task_scheduler_);
+    return task_scheduler_;
+  }
+
+ private:
+  base::test::ScopedFeatureList scoped_feature_list_;
+  base::ScopedTempDir tmp_dir_;
+  std::unique_ptr<NotificationScheduleService> service_;
+  TestBackgroundTaskScheduler* task_scheduler_;
+
+  DISALLOW_COPY_AND_ASSIGN(NotificationScheduleServiceTest);
+};
+
+// Test to schedule a notification.
+IN_PROC_BROWSER_TEST_F(NotificationScheduleServiceTest, ScheduleNotification) {
+  Init();
+  ScheduleParams schedule_params;
+  schedule_params.deliver_time_start = base::Time::Now();
+  schedule_params.deliver_time_end =
+      base::Time::Now() + base::TimeDelta::FromMinutes(5);
+  NotificationData data;
+  data.title = base::UTF8ToUTF16("title");
+  data.message = base::UTF8ToUTF16("message");
+  auto params = std::make_unique<notifications::NotificationParams>(
+      notifications::SchedulerClientType::kTest1, std::move(data),
+      std::move(schedule_params));
+  schedule_service()->Schedule(std::move(params));
+
+  // A background task should be scheduled.
+  task_scheduler()->WaitForTaskUpdated();
+  EXPECT_LE(task_scheduler()->window_start(), base::TimeDelta::FromMinutes(5));
+}
+
+}  // namespace
+}  // namespace notifications
diff --git a/chrome/browser/notifications/scheduler/public/notification_schedule_service.h b/chrome/browser/notifications/scheduler/public/notification_schedule_service.h
index 17e7ef0..b12f0d2 100644
--- a/chrome/browser/notifications/scheduler/public/notification_schedule_service.h
+++ b/chrome/browser/notifications/scheduler/public/notification_schedule_service.h
@@ -42,9 +42,10 @@
   // Returns the user action handler to process notification events.
   virtual UserActionHandler* GetUserActionHandler() = 0;
 
+  ~NotificationScheduleService() override = default;
+
  protected:
   NotificationScheduleService() = default;
-  ~NotificationScheduleService() override = default;
 
  private:
   DISALLOW_COPY_AND_ASSIGN(NotificationScheduleService);
diff --git a/chrome/browser/performance_manager/graph/graph_impl.h b/chrome/browser/performance_manager/graph/graph_impl.h
index 7aee1304d5..bd735d9d 100644
--- a/chrome/browser/performance_manager/graph/graph_impl.h
+++ b/chrome/browser/performance_manager/graph/graph_impl.h
@@ -20,7 +20,6 @@
 #include "base/sequence_checker.h"
 #include "chrome/browser/performance_manager/public/graph/graph.h"
 #include "chrome/browser/performance_manager/public/graph/node_attached_data.h"
-#include "services/metrics/public/cpp/mojo_ukm_recorder.h"
 #include "services/metrics/public/cpp/ukm_recorder.h"
 
 namespace performance_manager {
diff --git a/chrome/browser/performance_manager/performance_manager_impl.cc b/chrome/browser/performance_manager/performance_manager_impl.cc
index 014f3d1..db5ba4d5 100644
--- a/chrome/browser/performance_manager/performance_manager_impl.cc
+++ b/chrome/browser/performance_manager/performance_manager_impl.cc
@@ -29,7 +29,6 @@
 #include "chrome/browser/performance_manager/graph/worker_node_impl.h"
 #include "chrome/browser/performance_manager/observers/isolation_context_metrics.h"
 #include "chrome/browser/performance_manager/observers/metrics_collector.h"
-#include "content/public/browser/system_connector.h"
 #include "content/public/common/content_features.h"
 
 #if defined(OS_LINUX)
@@ -292,13 +291,9 @@
 }
 
 void PerformanceManagerImpl::OnStart() {
-  // Some tests don't initialize the service manager connection, so this class
-  // tolerates its absence for tests.
-  auto* connector = content::GetSystemConnector();
-  task_runner_->PostTask(
-      FROM_HERE, base::BindOnce(&PerformanceManagerImpl::OnStartImpl,
-                                base::Unretained(this),
-                                connector ? connector->Clone() : nullptr));
+  task_runner_->PostTask(FROM_HERE,
+                         base::BindOnce(&PerformanceManagerImpl::OnStartImpl,
+                                        base::Unretained(this)));
 }
 
 void PerformanceManagerImpl::RunCallbackWithGraphImpl(
@@ -315,8 +310,7 @@
   std::move(graph_callback).Run(&graph_);
 }
 
-void PerformanceManagerImpl::OnStartImpl(
-    std::unique_ptr<service_manager::Connector> connector) {
+void PerformanceManagerImpl::OnStartImpl() {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
 
   graph_.PassToGraph(std::make_unique<FreezeOriginTrialPolicyAggregator>());
@@ -339,10 +333,7 @@
 #endif  // BUILDFLAG(USE_TCMALLOC)
 #endif  // defined(OS_LINUX)
 
-  if (connector) {
-    ukm_recorder_ = ukm::MojoUkmRecorder::Create(connector.get());
-    graph_.set_ukm_recorder(ukm_recorder_.get());
-  }
+  graph_.set_ukm_recorder(ukm::UkmRecorder::Get());
 }
 
 }  // namespace performance_manager
diff --git a/chrome/browser/performance_manager/performance_manager_impl.h b/chrome/browser/performance_manager/performance_manager_impl.h
index 8d83b240..ef5d135 100644
--- a/chrome/browser/performance_manager/performance_manager_impl.h
+++ b/chrome/browser/performance_manager/performance_manager_impl.h
@@ -21,14 +21,9 @@
 #include "chrome/browser/performance_manager/public/performance_manager.h"
 #include "chrome/browser/performance_manager/public/render_process_host_proxy.h"
 #include "chrome/browser/performance_manager/public/web_contents_proxy.h"
-#include "services/resource_coordinator/public/mojom/coordination_unit.mojom.h"
 
 class GURL;
 
-namespace ukm {
-class MojoUkmRecorder;
-}  // namespace ukm
-
 namespace performance_manager {
 
 class PageNodeImpl;
@@ -145,7 +140,7 @@
   void BatchDeleteNodesImpl(std::vector<std::unique_ptr<NodeBase>> nodes);
 
   void OnStart();
-  void OnStartImpl(std::unique_ptr<service_manager::Connector> connector);
+  void OnStartImpl();
   void RunCallbackWithGraphImpl(GraphImplCallback graph_callback);
   void RunCallbackWithGraph(GraphCallback graph_callback);
 
@@ -157,10 +152,6 @@
   const scoped_refptr<base::SequencedTaskRunner> task_runner_;
   GraphImpl graph_;
 
-  // Provided to |graph_|.
-  // TODO(siggi): This no longer needs to go through mojo.
-  std::unique_ptr<ukm::MojoUkmRecorder> ukm_recorder_;
-
   SEQUENCE_CHECKER(sequence_checker_);
 
   DISALLOW_COPY_AND_ASSIGN(PerformanceManagerImpl);
diff --git a/chrome/browser/policy/policy_browsertest.cc b/chrome/browser/policy/policy_browsertest.cc
index 208d200d..53016eaa 100644
--- a/chrome/browser/policy/policy_browsertest.cc
+++ b/chrome/browser/policy/policy_browsertest.cc
@@ -5873,6 +5873,7 @@
   // The component uses HTTPS only for network interception purposes.
   update_client::CrxComponent crx_component;
   crx_component.pk_hash.assign(std::begin(jebg_hash), std::end(jebg_hash));
+  crx_component.app_id = "jebgalgnebhfojomionfpkfelancnnkf";
   crx_component.version = base::Version("0.9");
   crx_component.installer = scoped_refptr<MockInstaller>(new MockInstaller());
   crx_component.requires_network_encryption = true;
diff --git a/chrome/browser/previews/hints_fetcher_browsertest.cc b/chrome/browser/previews/hints_fetcher_browsertest.cc
index 78a227a..2057c96 100644
--- a/chrome/browser/previews/hints_fetcher_browsertest.cc
+++ b/chrome/browser/previews/hints_fetcher_browsertest.cc
@@ -101,9 +101,8 @@
   ~HintsFetcherDisabledBrowserTest() override = default;
 
   void SetUpOnMainThread() override {
-    g_browser_process->network_quality_tracker()
-        ->ReportEffectiveConnectionTypeForTesting(
-            net::EFFECTIVE_CONNECTION_TYPE_2G);
+    content::NetworkConnectionChangeSimulator().SetConnectionType(
+        network::mojom::ConnectionType::CONNECTION_2G);
 
     InProcessBrowserTest::SetUpOnMainThread();
   }
diff --git a/chrome/browser/previews/previews_lite_page_redirect_url_loader.cc b/chrome/browser/previews/previews_lite_page_redirect_url_loader.cc
index 8defd79b..35efb3dea 100644
--- a/chrome/browser/previews/previews_lite_page_redirect_url_loader.cc
+++ b/chrome/browser/previews/previews_lite_page_redirect_url_loader.cc
@@ -171,7 +171,6 @@
 
   redirect_info_ = net::RedirectInfo::ComputeRedirectInfo(
       modified_resource_request_.method, modified_resource_request_.url,
-      modified_resource_request_.request_initiator,
       modified_resource_request_.site_for_cookies,
       net::URLRequest::UPDATE_FIRST_PARTY_URL_ON_REDIRECT,
       modified_resource_request_.referrer_policy,
diff --git a/chrome/browser/previews/previews_offline_helper.cc b/chrome/browser/previews/previews_offline_helper.cc
index f00b6e3..ffbf70e0 100644
--- a/chrome/browser/previews/previews_offline_helper.cc
+++ b/chrome/browser/previews/previews_offline_helper.cc
@@ -146,7 +146,9 @@
       offline_pages::OfflinePageModelFactory::GetForBrowserContext(
           browser_context);
 
-  if (offline_page_model_) {
+  if (offline_page_model_ &&
+      base::FeatureList::IsEnabled(
+          previews::features::kOfflinePreviewsFalsePositivePrevention)) {
     offline_page_model_->AddObserver(this);
     // Schedule a low priority task with a slight delay to ensure that the
     // expensive DB query doesn't occur during startup or during other user
diff --git a/chrome/browser/profiles/gaia_info_update_service.cc b/chrome/browser/profiles/gaia_info_update_service.cc
index af78255..2f6f943 100644
--- a/chrome/browser/profiles/gaia_info_update_service.cc
+++ b/chrome/browser/profiles/gaia_info_update_service.cc
@@ -43,16 +43,20 @@
       IdentityManagerFactory::GetForProfile(profile_);
   identity_manager->AddObserver(this);
 
-  if (!identity_manager->HasPrimaryAccount()) {
-    // Handle the case when the primary account was cleared while loading the
-    // profile, before the |GAIAInfoUpdateService| is created.
-    OnUsernameChanged(std::string());
-  }
-
   PrefService* prefs = profile_->GetPrefs();
   last_updated_ = base::Time::FromInternalValue(
       prefs->GetInt64(prefs::kProfileGAIAInfoUpdateTime));
-  ScheduleNextUpdate();
+
+  // TODO(msalama): Once Unconsented primary account is available on startup,
+  // remove the wait on refresh tokens.
+  if (identity_manager->AreRefreshTokensLoaded()) {
+    if (!identity_manager->HasUnconsentedPrimaryAccount()) {
+      // Handle the case when the primary account was cleared while loading the
+      // profile, before the |GAIAInfoUpdateService| is created.
+      OnUsernameChanged(std::string());
+    }
+    ScheduleNextUpdate();
+  }
 }
 
 GAIAInfoUpdateService::~GAIAInfoUpdateService() {
@@ -63,7 +67,7 @@
   // The user must be logged in.
   signin::IdentityManager* identity_manager =
       IdentityManagerFactory::GetForProfile(profile_);
-  if (!identity_manager->HasPrimaryAccount())
+  if (!identity_manager->HasUnconsentedPrimaryAccount())
     return;
 
   if (profile_image_downloader_)
@@ -124,7 +128,6 @@
   ProfileDownloader::PictureStatus picture_status =
       downloader->GetProfilePictureStatus();
   std::string picture_url = downloader->GetProfilePictureURL();
-
   ProfileAttributesEntry* entry;
   if (!g_browser_process->profile_manager()->GetProfileAttributesStorage().
           GetProfileAttributesWithPath(profile_->GetPath(), &entry)) {
@@ -229,3 +232,18 @@
     const CoreAccountInfo& previous_primary_account_info) {
   OnUsernameChanged(std::string());
 }
+
+void GAIAInfoUpdateService::OnUnconsentedPrimaryAccountChanged(
+    const CoreAccountInfo& unconsented_primary_account_info) {
+  OnUsernameChanged(unconsented_primary_account_info.gaia);
+}
+
+void GAIAInfoUpdateService::OnRefreshTokensLoaded() {
+  signin::IdentityManager* identity_manager =
+      IdentityManagerFactory::GetForProfile(profile_);
+
+  if (!identity_manager->HasUnconsentedPrimaryAccount()) {
+    OnUsernameChanged(std::string());
+  }
+  ScheduleNextUpdate();
+}
diff --git a/chrome/browser/profiles/gaia_info_update_service.h b/chrome/browser/profiles/gaia_info_update_service.h
index 1b97069..3e6394c8 100644
--- a/chrome/browser/profiles/gaia_info_update_service.h
+++ b/chrome/browser/profiles/gaia_info_update_service.h
@@ -60,6 +60,9 @@
       const CoreAccountInfo& primary_account_info) override;
   void OnPrimaryAccountCleared(
       const CoreAccountInfo& previous_primary_account_info) override;
+  void OnUnconsentedPrimaryAccountChanged(
+      const CoreAccountInfo& unconsented_primary_account_info) override;
+  void OnRefreshTokensLoaded() override;
 
   Profile* profile_;
   std::unique_ptr<ProfileDownloader> profile_image_downloader_;
diff --git a/chrome/browser/profiles/gaia_info_update_service_unittest.cc b/chrome/browser/profiles/gaia_info_update_service_unittest.cc
index c24fd78..1b4eda9 100644
--- a/chrome/browser/profiles/gaia_info_update_service_unittest.cc
+++ b/chrome/browser/profiles/gaia_info_update_service_unittest.cc
@@ -379,7 +379,7 @@
 
 TEST_F(GAIAInfoUpdateServiceTest, LogIn) {
   // Log in.
-  EXPECT_CALL(*service(), Update());
+  EXPECT_CALL(*service(), Update()).Times(testing::AtLeast(1));
   identity_test_env()->SetPrimaryAccount("pat@example.com");
 }
 
diff --git a/chrome/browser/profiles/profile_attributes_entry.cc b/chrome/browser/profiles/profile_attributes_entry.cc
index 7302e632..de8f67f 100644
--- a/chrome/browser/profiles/profile_attributes_entry.cc
+++ b/chrome/browser/profiles/profile_attributes_entry.cc
@@ -47,6 +47,8 @@
 const char ProfileAttributesEntry::kBackgroundAppsKey[] = "background_apps";
 const char ProfileAttributesEntry::kProfileIsEphemeral[] = "is_ephemeral";
 const char ProfileAttributesEntry::kUserNameKey[] = "user_name";
+const char ProfileAttributesEntry::kIsConsentedPrimaryAccountKey[] =
+    "is_consented_primary_account";
 
 // static
 void ProfileAttributesEntry::RegisterLocalStatePrefs(
@@ -89,7 +91,7 @@
     // left-overs from legacy supervised users. Just unlock them, so users can
     // keep using them.
     SetLocalAuthCredentials(std::string());
-    SetAuthInfo(std::string(), base::string16());
+    SetAuthInfo(std::string(), base::string16(), false);
     SetIsSigninRequired(false);
 #endif
   }
@@ -212,12 +214,19 @@
   return profile_info_cache_->ProfileIsUsingDefaultNameAtIndex(profile_index());
 }
 
+SigninState ProfileAttributesEntry::GetSigninState() const {
+  bool is_consented_primary_account = GetBool(kIsConsentedPrimaryAccountKey);
+  if (!GetGAIAId().empty() || !GetUserName().empty()) {
+    return is_consented_primary_account
+               ? SigninState::kSignedInWithConsentedPrimaryAccount
+               : SigninState::kSignedInWithUnconsentedPrimaryAccount;
+  }
+  DCHECK(!is_consented_primary_account);
+  return SigninState::kNotSignedIn;
+}
+
 bool ProfileAttributesEntry::IsAuthenticated() const {
-  // The profile is authenticated if the gaia_id of the info is not empty.
-  // If it is empty, also check if the user name is not empty.  This latter
-  // check is needed in case the profile has not been loaded yet and the
-  // gaia_id property has not yet been written.
-  return !GetGAIAId().empty() || !GetUserName().empty();
+  return GetBool(kIsConsentedPrimaryAccountKey);
 }
 
 bool ProfileAttributesEntry::IsUsingDefaultAvatar() const {
@@ -361,10 +370,11 @@
   profile_info_cache_->NotifyOnProfileAvatarChanged(profile_path);
 }
 
-void ProfileAttributesEntry::SetAuthInfo(
-    const std::string& gaia_id, const base::string16& user_name) {
+void ProfileAttributesEntry::SetAuthInfo(const std::string& gaia_id,
+                                         const base::string16& user_name,
+                                         bool is_consented_primary_account) {
   profile_info_cache_->SetAuthInfoOfProfileAtIndex(
-      profile_index(), gaia_id, user_name);
+      profile_index(), gaia_id, user_name, is_consented_primary_account);
 }
 
 size_t ProfileAttributesEntry::profile_index() const {
diff --git a/chrome/browser/profiles/profile_attributes_entry.h b/chrome/browser/profiles/profile_attributes_entry.h
index cf363985..4f2e9e9 100644
--- a/chrome/browser/profiles/profile_attributes_entry.h
+++ b/chrome/browser/profiles/profile_attributes_entry.h
@@ -25,6 +25,12 @@
 class PrefService;
 class ProfileInfoCache;
 
+enum class SigninState {
+  kNotSignedIn,
+  kSignedInWithUnconsentedPrimaryAccount,
+  kSignedInWithConsentedPrimaryAccount,
+};
+
 class ProfileAttributesEntry {
  public:
   static void RegisterLocalStatePrefs(PrefRegistrySimple* registry);
@@ -86,6 +92,8 @@
   // Returns true if the profile is using a default name, typically of the
   // format "Person %d".
   bool IsUsingDefaultName() const;
+  // Returns Signin state.
+  SigninState GetSigninState() const;
   // Returns true if the profile is signed in.
   bool IsAuthenticated() const;
   // Returns true if the Profile is using the default avatar, which is one of
@@ -120,7 +128,9 @@
   void SetIsAuthError(bool value);
   void SetAvatarIconIndex(size_t icon_index);
 
-  void SetAuthInfo(const std::string& gaia_id, const base::string16& user_name);
+  void SetAuthInfo(const std::string& gaia_id,
+                   const base::string16& user_name,
+                   bool is_consented_primary_account);
 
   // Lock/Unlock the profile, should be called only if force-sign-in is enabled.
   void LockForceSigninProfile(bool is_lock);
@@ -129,6 +139,7 @@
   static const char kBackgroundAppsKey[];
   static const char kProfileIsEphemeral[];
   static const char kUserNameKey[];
+  static const char kIsConsentedPrimaryAccountKey[];
 
  private:
   friend class ProfileInfoCache;
diff --git a/chrome/browser/profiles/profile_attributes_storage.h b/chrome/browser/profiles/profile_attributes_storage.h
index 0b81e52c..f3e487a 100644
--- a/chrome/browser/profiles/profile_attributes_storage.h
+++ b/chrome/browser/profiles/profile_attributes_storage.h
@@ -51,6 +51,7 @@
                           const base::string16& name,
                           const std::string& gaia_id,
                           const base::string16& user_name,
+                          bool is_consented_primary_account,
                           size_t icon_index,
                           const std::string& supervised_user_id,
                           const AccountId& account_id) = 0;
diff --git a/chrome/browser/profiles/profile_attributes_storage_unittest.cc b/chrome/browser/profiles/profile_attributes_storage_unittest.cc
index eff8cf5..8273d8bb 100644
--- a/chrome/browser/profiles/profile_attributes_storage_unittest.cc
+++ b/chrome/browser/profiles/profile_attributes_storage_unittest.cc
@@ -171,7 +171,7 @@
         base::StringPrintf("testing_profile_gaia%" PRIuS, number_of_profiles),
         base::ASCIIToUTF16(base::StringPrintf("testing_profile_user%" PRIuS,
                                               number_of_profiles)),
-        number_of_profiles, std::string(""), EmptyAccountId());
+        true, number_of_profiles, std::string(""), EmptyAccountId());
 
     EXPECT_EQ(number_of_profiles + 1, storage()->GetNumberOfProfiles());
   }
@@ -208,7 +208,7 @@
   storage()->AddProfile(GetProfilePath("new_profile_path_1"),
                         base::ASCIIToUTF16("new_profile_name_1"),
                         std::string("new_profile_gaia_1"),
-                        base::ASCIIToUTF16("new_profile_username_1"), 1,
+                        base::ASCIIToUTF16("new_profile_username_1"), true, 1,
                         std::string(""), EmptyAccountId());
 
   VerifyAndResetCallExpectations();
@@ -458,14 +458,14 @@
   ASSERT_TRUE(storage()->GetProfileAttributesWithPath(path, &entry));
 
   EXPECT_CALL(observer(), OnProfileAuthInfoChanged(path)).Times(1);
-  entry->SetAuthInfo("", base::string16());
+  entry->SetAuthInfo("", base::string16(), false);
   VerifyAndResetCallExpectations();
-  ASSERT_FALSE(entry->IsAuthenticated());
+  ASSERT_EQ(entry->GetSigninState(), SigninState::kNotSignedIn);
   EXPECT_EQ(base::string16(), entry->GetUserName());
   EXPECT_EQ("", entry->GetGAIAId());
 
   EXPECT_CALL(observer(), OnProfileAuthInfoChanged(path)).Times(1);
-  entry->SetAuthInfo("foo", base::ASCIIToUTF16("bar"));
+  entry->SetAuthInfo("foo", base::ASCIIToUTF16("bar"), true);
   VerifyAndResetCallExpectations();
   ASSERT_TRUE(entry->IsAuthenticated());
   EXPECT_EQ(base::ASCIIToUTF16("bar"), entry->GetUserName());
@@ -508,13 +508,13 @@
 
   storage()->AddProfile(GetProfilePath("alpha_path"),
                         base::ASCIIToUTF16("alpha"), std::string("alpha_gaia"),
-                        base::ASCIIToUTF16("alpha_username"), 1,
+                        base::ASCIIToUTF16("alpha_username"), true, 1,
                         std::string(""), EmptyAccountId());
 
   storage()->AddProfile(GetProfilePath("lima_path"), base::ASCIIToUTF16("lima"),
                         std::string("lima_gaia"),
-                        base::ASCIIToUTF16("lima_username"), 1, std::string(""),
-                        EmptyAccountId());
+                        base::ASCIIToUTF16("lima_username"), true, 1,
+                        std::string(""), EmptyAccountId());
 
   ProfileAttributesEntry* entry;
   ASSERT_TRUE(storage()->GetProfileAttributesWithPath(
@@ -619,7 +619,7 @@
         GetProfilePath(base::StringPrintf("testing_profile_path%" PRIuS, i));
     EXPECT_CALL(observer(), OnProfileAdded(profile_path)).Times(1);
     storage()->AddProfile(profile_path, base::string16(), std::string(),
-                          base::string16(), icon_index, std::string(),
+                          base::string16(), false, icon_index, std::string(),
                           EmptyAccountId());
     VerifyAndResetCallExpectations();
   }
@@ -692,7 +692,7 @@
   base::FilePath profile_path = GetProfilePath("path_1");
   EXPECT_CALL(observer(), OnProfileAdded(profile_path)).Times(1);
   storage()->AddProfile(profile_path, base::ASCIIToUTF16("name_1"),
-                        std::string(), base::string16(), kIconIndex,
+                        std::string(), base::string16(), false, kIconIndex,
                         std::string(), EmptyAccountId());
   ASSERT_EQ(1U, storage()->GetNumberOfProfiles());
   VerifyAndResetCallExpectations();
@@ -773,7 +773,7 @@
   base::FilePath profile_path = GetProfilePath("path_1");
   EXPECT_CALL(observer(), OnProfileAdded(profile_path)).Times(1);
   storage()->AddProfile(profile_path, base::ASCIIToUTF16("name_1"),
-                        std::string(), base::string16(), kIconIndex,
+                        std::string(), base::string16(), false, kIconIndex,
                         std::string(), EmptyAccountId());
   EXPECT_EQ(1U, storage()->GetNumberOfProfiles());
   content::RunAllTasksUntilIdle();
@@ -808,7 +808,7 @@
   base::FilePath profile_path = GetProfilePath("path_1");
   EXPECT_CALL(observer(), OnProfileAdded(profile_path)).Times(1);
   storage()->AddProfile(profile_path, base::ASCIIToUTF16("name_1"),
-                        std::string(), base::string16(), kIconIndex,
+                        std::string(), base::string16(), false, kIconIndex,
                         std::string(), EmptyAccountId());
   EXPECT_EQ(1U, storage()->GetNumberOfProfiles());
   VerifyAndResetCallExpectations();
diff --git a/chrome/browser/profiles/profile_downloader.cc b/chrome/browser/profiles/profile_downloader.cc
index 071b5ef..61b8235 100644
--- a/chrome/browser/profiles/profile_downloader.cc
+++ b/chrome/browser/profiles/profile_downloader.cc
@@ -67,8 +67,9 @@
 
   // TODO(triploblastic@): Remove explicit conversion once ProfileDownloader
   // has been fixed to use CoreAccountId.
-  account_id_ = account_id.empty() ? identity_manager_->GetPrimaryAccountId().id
-                                   : account_id;
+  account_id_ = account_id.empty()
+                    ? identity_manager_->GetUnconsentedPrimaryAccountId().id
+                    : account_id;
   StartFetchingOAuth2AccessToken();
 }
 
diff --git a/chrome/browser/profiles/profile_info_cache.cc b/chrome/browser/profiles/profile_info_cache.cc
index e544d27..b10361b 100644
--- a/chrome/browser/profiles/profile_info_cache.cc
+++ b/chrome/browser/profiles/profile_info_cache.cc
@@ -115,6 +115,7 @@
                                          const base::string16& name,
                                          const std::string& gaia_id,
                                          const base::string16& user_name,
+                                         bool is_consented_primary_account,
                                          size_t icon_index,
                                          const std::string& supervised_user_id,
                                          const AccountId& account_id) {
@@ -134,6 +135,10 @@
   info->SetString(kNameKey, name);
   info->SetString(kGAIAIdKey, gaia_id);
   info->SetString(ProfileAttributesEntry::kUserNameKey, user_name);
+  DCHECK(!is_consented_primary_account || !gaia_id.empty() ||
+         !user_name.empty());
+  info->SetBoolean(ProfileAttributesEntry::kIsConsentedPrimaryAccountKey,
+                   is_consented_primary_account);
   info->SetString(ProfileAttributesEntry::kAvatarIconKey,
                   profiles::GetDefaultAvatarIconUrl(icon_index));
   // Default value for whether background apps are running is false.
@@ -398,9 +403,16 @@
 void ProfileInfoCache::SetAuthInfoOfProfileAtIndex(
     size_t index,
     const std::string& gaia_id,
-    const base::string16& user_name) {
-  // If both gaia_id and username are unchanged, abort early.
-  if (gaia_id == GetGAIAIdOfProfileAtIndex(index) &&
+    const base::string16& user_name,
+    bool is_consented_primary_account) {
+  bool is_consented_primary_account_state;
+  GetInfoForProfileAtIndex(index)->GetBoolean(
+      ProfileAttributesEntry::kIsConsentedPrimaryAccountKey,
+      &is_consented_primary_account_state);
+
+  // If gaia_id, username and consent state are unchanged, abort early.
+  if (is_consented_primary_account_state == is_consented_primary_account &&
+      gaia_id == GetGAIAIdOfProfileAtIndex(index) &&
       user_name == GetUserNameOfProfileAtIndex(index)) {
     return;
   }
@@ -410,6 +422,10 @@
 
   info->SetString(kGAIAIdKey, gaia_id);
   info->SetString(ProfileAttributesEntry::kUserNameKey, user_name);
+  DCHECK(!is_consented_primary_account || !gaia_id.empty() ||
+         !user_name.empty());
+  info->SetBoolean(ProfileAttributesEntry::kIsConsentedPrimaryAccountKey,
+                   is_consented_primary_account);
 
   SetInfoForProfileAtIndex(index, std::move(info));
 
@@ -740,10 +756,12 @@
                                   const base::string16& name,
                                   const std::string& gaia_id,
                                   const base::string16& user_name,
+                                  bool is_consented_primary_account,
                                   size_t icon_index,
                                   const std::string& supervised_user_id,
                                   const AccountId& account_id) {
-  AddProfileToCache(profile_path, name, gaia_id, user_name, icon_index,
+  AddProfileToCache(profile_path, name, gaia_id, user_name,
+                    is_consented_primary_account, icon_index,
                     supervised_user_id, account_id);
 }
 
diff --git a/chrome/browser/profiles/profile_info_cache.h b/chrome/browser/profiles/profile_info_cache.h
index 8a4cf2e..6cd3d14 100644
--- a/chrome/browser/profiles/profile_info_cache.h
+++ b/chrome/browser/profiles/profile_info_cache.h
@@ -58,6 +58,7 @@
                          const base::string16& name,
                          const std::string& gaia_id,
                          const base::string16& user_name,
+                         bool is_consented_primary_account,
                          size_t icon_index,
                          const std::string& supervised_user_id,
                          const AccountId& account_id);
@@ -111,7 +112,8 @@
   void SetNameOfProfileAtIndex(size_t index, const base::string16& name);
   void SetAuthInfoOfProfileAtIndex(size_t index,
                                    const std::string& gaia_id,
-                                   const base::string16& user_name);
+                                   const base::string16& user_name,
+                                   bool is_consented_primary_account);
   // Will be removed SOON with ProfileInfoCache tests. Do not use!
   void SetAvatarIconOfProfileAtIndex(size_t index, size_t icon_index);
   void SetIsOmittedProfileAtIndex(size_t index, bool is_omitted);
@@ -143,6 +145,7 @@
                   const base::string16& name,
                   const std::string& gaia_id,
                   const base::string16& user_name,
+                  bool is_consented_primary_account,
                   size_t icon_index,
                   const std::string& supervised_user_id,
                   const AccountId& account_id) override;
diff --git a/chrome/browser/profiles/profile_info_cache_unittest.cc b/chrome/browser/profiles/profile_info_cache_unittest.cc
index aaaebe3c..9ebc8b7f 100644
--- a/chrome/browser/profiles/profile_info_cache_unittest.cc
+++ b/chrome/browser/profiles/profile_info_cache_unittest.cc
@@ -152,8 +152,8 @@
 #endif
 
     GetCache()->AddProfileToCache(profile_path, profile_name, std::string(),
-                                  base::string16(), i, supervised_user_id,
-                                  EmptyAccountId());
+                                  base::string16(), false, i,
+                                  supervised_user_id, EmptyAccountId());
     GetCache()->SetBackgroundStatusOfProfileAtIndex(i, true);
     base::string16 gaia_name = ASCIIToUTF16(base::StringPrintf("gaia_%ud", i));
     GetCache()->SetGAIANameOfProfileAtIndex(i, gaia_name);
@@ -203,14 +203,14 @@
 
   base::FilePath path_1 = GetProfilePath("path_1");
   GetCache()->AddProfileToCache(path_1, ASCIIToUTF16("name_1"), std::string(),
-                                base::string16(), 0, std::string(),
+                                base::string16(), false, 0, std::string(),
                                 EmptyAccountId());
   EXPECT_EQ(1u, GetCache()->GetNumberOfProfiles());
 
   base::FilePath path_2 = GetProfilePath("path_2");
   base::string16 name_2 = ASCIIToUTF16("name_2");
   GetCache()->AddProfileToCache(path_2, name_2, std::string(), base::string16(),
-                                0, std::string(), EmptyAccountId());
+                                false, 0, std::string(), EmptyAccountId());
   EXPECT_EQ(2u, GetCache()->GetNumberOfProfiles());
 
   GetCache()->DeleteProfileFromCache(path_1);
@@ -224,10 +224,10 @@
 TEST_F(ProfileInfoCacheTest, MutateProfile) {
   GetCache()->AddProfileToCache(
       GetProfilePath("path_1"), ASCIIToUTF16("name_1"), std::string(),
-      base::string16(), 0, std::string(), EmptyAccountId());
+      base::string16(), false, 0, std::string(), EmptyAccountId());
   GetCache()->AddProfileToCache(
       GetProfilePath("path_2"), ASCIIToUTF16("name_2"), std::string(),
-      base::string16(), 0, std::string(), EmptyAccountId());
+      base::string16(), false, 0, std::string(), EmptyAccountId());
 
   base::string16 new_name = ASCIIToUTF16("new_name");
   GetCache()->SetNameOfProfileAtIndex(1, new_name);
@@ -236,7 +236,7 @@
 
   base::string16 new_user_name = ASCIIToUTF16("user_name");
   std::string new_gaia_id = "12345";
-  GetCache()->SetAuthInfoOfProfileAtIndex(1, new_gaia_id, new_user_name);
+  GetCache()->SetAuthInfoOfProfileAtIndex(1, new_gaia_id, new_user_name, true);
   EXPECT_EQ(new_user_name, GetCache()->GetUserNameOfProfileAtIndex(1));
   EXPECT_EQ(new_gaia_id, GetCache()->GetGAIAIdOfProfileAtIndex(1));
   EXPECT_NE(new_user_name, GetCache()->GetUserNameOfProfileAtIndex(0));
@@ -260,12 +260,12 @@
 TEST_F(ProfileInfoCacheTest, Sort) {
   base::string16 name_a = ASCIIToUTF16("apple");
   GetCache()->AddProfileToCache(GetProfilePath("path_a"), name_a, std::string(),
-                                base::string16(), 0, std::string(),
+                                base::string16(), false, 0, std::string(),
                                 EmptyAccountId());
 
   base::string16 name_c = ASCIIToUTF16("cat");
   GetCache()->AddProfileToCache(GetProfilePath("path_c"), name_c, std::string(),
-                                base::string16(), 0, std::string(),
+                                base::string16(), false, 0, std::string(),
                                 EmptyAccountId());
 
   // Sanity check the initial order.
@@ -275,7 +275,7 @@
   // Add a new profile (start with a capital to test case insensitive sorting.
   base::string16 name_b = ASCIIToUTF16("Banana");
   GetCache()->AddProfileToCache(GetProfilePath("path_b"), name_b, std::string(),
-                                base::string16(), 0, std::string(),
+                                base::string16(), false, 0, std::string(),
                                 EmptyAccountId());
 
   // Verify the new order.
@@ -304,10 +304,10 @@
 TEST_F(ProfileInfoCacheTest, BackgroundModeStatus) {
   GetCache()->AddProfileToCache(
       GetProfilePath("path_1"), ASCIIToUTF16("name_1"), std::string(),
-      base::string16(), 0, std::string(), EmptyAccountId());
+      base::string16(), false, 0, std::string(), EmptyAccountId());
   GetCache()->AddProfileToCache(
       GetProfilePath("path_2"), ASCIIToUTF16("name_2"), std::string(),
-      base::string16(), 0, std::string(), EmptyAccountId());
+      base::string16(), false, 0, std::string(), EmptyAccountId());
 
   EXPECT_FALSE(GetCache()->GetBackgroundStatusOfProfileAtIndex(0));
   EXPECT_FALSE(GetCache()->GetBackgroundStatusOfProfileAtIndex(1));
@@ -331,10 +331,10 @@
 TEST_F(ProfileInfoCacheTest, GAIAName) {
   GetCache()->AddProfileToCache(
       GetProfilePath("path_1"), ASCIIToUTF16("Person 1"), std::string(),
-      base::string16(), 0, std::string(), EmptyAccountId());
+      base::string16(), false, 0, std::string(), EmptyAccountId());
   base::string16 profile_name(ASCIIToUTF16("Person 2"));
   GetCache()->AddProfileToCache(GetProfilePath("path_2"), profile_name,
-                                std::string(), base::string16(), 0,
+                                std::string(), base::string16(), false, 0,
                                 std::string(), EmptyAccountId());
 
   int index1 = GetCache()->GetIndexOfProfileWithPath(GetProfilePath("path_1"));
@@ -371,12 +371,14 @@
   const int kDefaultAvatarIndex = 0;
   const int kOtherAvatarIndex = 1;
   const int kGaiaPictureSize = 256;  // Standard size of a Gaia account picture.
-  GetCache()->AddProfileToCache(
-      GetProfilePath("path_1"), ASCIIToUTF16("name_1"), std::string(),
-      base::string16(), kDefaultAvatarIndex, std::string(), EmptyAccountId());
-  GetCache()->AddProfileToCache(
-      GetProfilePath("path_2"), ASCIIToUTF16("name_2"), std::string(),
-      base::string16(), kDefaultAvatarIndex, std::string(), EmptyAccountId());
+  GetCache()->AddProfileToCache(GetProfilePath("path_1"),
+                                ASCIIToUTF16("name_1"), std::string(),
+                                base::string16(), false, kDefaultAvatarIndex,
+                                std::string(), EmptyAccountId());
+  GetCache()->AddProfileToCache(GetProfilePath("path_2"),
+                                ASCIIToUTF16("name_2"), std::string(),
+                                base::string16(), false, kDefaultAvatarIndex,
+                                std::string(), EmptyAccountId());
 
   // Sanity check.
   EXPECT_EQ(NULL, GetCache()->GetGAIAPictureOfProfileAtIndex(0));
@@ -446,7 +448,7 @@
 TEST_F(ProfileInfoCacheTest, PersistGAIAPicture) {
   GetCache()->AddProfileToCache(
       GetProfilePath("path_1"), ASCIIToUTF16("name_1"), std::string(),
-      base::string16(), 0, std::string(), EmptyAccountId());
+      base::string16(), false, 0, std::string(), EmptyAccountId());
   gfx::Image gaia_image(gfx::test::CreateImage());
 
   GetCache()->SetGAIAPictureOfProfileAtIndex(0, gaia_image);
@@ -470,7 +472,7 @@
 #if BUILDFLAG(ENABLE_SUPERVISED_USERS)
 TEST_F(ProfileInfoCacheTest, SetSupervisedUserId) {
   GetCache()->AddProfileToCache(GetProfilePath("test"), ASCIIToUTF16("Test"),
-                                std::string(), base::string16(), 0,
+                                std::string(), base::string16(), false, 0,
                                 std::string(), EmptyAccountId());
   EXPECT_FALSE(GetCache()->ProfileIsSupervisedAtIndex(0));
 
@@ -496,7 +498,7 @@
       ui::ResourceBundle::GetSharedInstance().GetImageNamed(id));
 
   GetCache()->AddProfileToCache(GetProfilePath("path_1"), profile_name,
-                                std::string(), base::string16(), 0,
+                                std::string(), base::string16(), false, 0,
                                 std::string(), EmptyAccountId());
 
   // Set empty GAIA info.
@@ -554,7 +556,8 @@
     base::string16 profile_name = ASCIIToUTF16(kTestCases[i].profile_name);
 
     GetCache()->AddProfileToCache(profile_path, profile_name, std::string(),
-                                  base::string16(), i, "", EmptyAccountId());
+                                  base::string16(), false, i, "",
+                                  EmptyAccountId());
 
     EXPECT_EQ(profile_path, GetCache()->GetPathOfProfileAtIndex(i));
     EXPECT_EQ(profile_name, GetCache()->GetNameOfProfileAtIndex(i));
@@ -610,10 +613,11 @@
     // profiles 1 and 3.
     if (i | 1u) {
       GetCache()->AddProfileToCache(profile_path, profile_name, std::string(),
-                                    base::string16(), i, "", EmptyAccountId());
+                                    base::string16(), false, i, "",
+                                    EmptyAccountId());
     } else {
       GetCache()->AddProfile(profile_path, profile_name, std::string(),
-                             base::string16(), i, "", EmptyAccountId());
+                             base::string16(), false, i, "", EmptyAccountId());
     }
 
     ASSERT_EQ(i + 1, GetCache()->GetNumberOfProfiles());
@@ -663,24 +667,24 @@
 
   base::FilePath path_1 = GetProfilePath("path_1");
   GetCache()->AddProfileToCache(path_1, ASCIIToUTF16("Default Profile"),
-                                std::string(), base::string16(), 0,
+                                std::string(), base::string16(), false, 0,
                                 std::string(), EmptyAccountId());
   base::FilePath path_2 = GetProfilePath("path_2");
   GetCache()->AddProfileToCache(path_2, ASCIIToUTF16("First user"),
-                                std::string(), base::string16(), 1,
+                                std::string(), base::string16(), false, 1,
                                 std::string(), EmptyAccountId());
   base::string16 name_3 = ASCIIToUTF16("Lemonade");
   base::FilePath path_3 = GetProfilePath("path_3");
   GetCache()->AddProfileToCache(path_3, name_3, std::string(), base::string16(),
-                                2, std::string(), EmptyAccountId());
+                                false, 2, std::string(), EmptyAccountId());
   base::string16 name_4 = ASCIIToUTF16("Batman");
   base::FilePath path_4 = GetProfilePath("path_4");
   GetCache()->AddProfileToCache(path_4, name_4, std::string(), base::string16(),
-                                3, std::string(), EmptyAccountId());
+                                false, 3, std::string(), EmptyAccountId());
   base::string16 name_5 = ASCIIToUTF16("Person 2");
   base::FilePath path_5 = GetProfilePath("path_5");
   GetCache()->AddProfileToCache(path_5, name_5, std::string(), base::string16(),
-                                2, std::string(), EmptyAccountId());
+                                false, 2, std::string(), EmptyAccountId());
 
   EXPECT_EQ(5U, GetCache()->GetNumberOfProfiles());
 
@@ -724,7 +728,7 @@
   base::FilePath profile_path = GetProfilePath("path_1");
 
   GetCache()->AddProfileToCache(profile_path, ASCIIToUTF16("name_1"),
-                                std::string(), base::string16(), 0,
+                                std::string(), base::string16(), false, 0,
                                 std::string(), EmptyAccountId());
 
   gfx::Image gaia_image(gfx::test::CreateImage());
@@ -768,19 +772,19 @@
   base::string16 name_1 = ASCIIToUTF16("Default Profile");
   base::FilePath path_1 = GetProfilePath("path_1");
   GetCache()->AddProfileToCache(path_1, name_1, std::string(), base::string16(),
-                                0, std::string(), EmptyAccountId());
+                                false, 0, std::string(), EmptyAccountId());
   base::string16 name_2 = ASCIIToUTF16("First user");
   base::FilePath path_2 = GetProfilePath("path_2");
   GetCache()->AddProfileToCache(path_2, name_2, std::string(), base::string16(),
-                                1, std::string(), EmptyAccountId());
+                                false, 1, std::string(), EmptyAccountId());
   base::string16 name_3 = ASCIIToUTF16("Lemonade");
   base::FilePath path_3 = GetProfilePath("path_3");
   GetCache()->AddProfileToCache(path_3, name_3, std::string(), base::string16(),
-                                2, std::string(), EmptyAccountId());
+                                false, 2, std::string(), EmptyAccountId());
   base::string16 name_4 = ASCIIToUTF16("Batman");
   base::FilePath path_4 = GetProfilePath("path_4");
   GetCache()->AddProfileToCache(path_4, name_4, std::string(), base::string16(),
-                                3, std::string(), EmptyAccountId());
+                                false, 3, std::string(), EmptyAccountId());
   EXPECT_EQ(4U, GetCache()->GetNumberOfProfiles());
 
   ResetCache();
@@ -805,8 +809,8 @@
       AccountId::FromUserEmailGaiaId("email1", "111111"));
   base::string16 name_1 = ASCIIToUTF16("name_1");
   GetCache()->AddProfileToCache(path_1, name_1, account_id_1.GetGaiaId(),
-                                UTF8ToUTF16(account_id_1.GetUserEmail()), 0,
-                                std::string(), EmptyAccountId());
+                                UTF8ToUTF16(account_id_1.GetUserEmail()), true,
+                                0, std::string(), EmptyAccountId());
   EXPECT_EQ(1u, GetCache()->GetNumberOfProfiles());
 
   base::FilePath path_2 = GetProfilePath("path_2");
@@ -814,8 +818,8 @@
   const AccountId account_id_2(
       AccountId::FromUserEmailGaiaId("email2", "222222"));
   GetCache()->AddProfileToCache(path_2, name_2, account_id_2.GetGaiaId(),
-                                UTF8ToUTF16(account_id_2.GetUserEmail()), 0,
-                                std::string(), EmptyAccountId());
+                                UTF8ToUTF16(account_id_2.GetUserEmail()), true,
+                                0, std::string(), EmptyAccountId());
   EXPECT_EQ(2u, GetCache()->GetNumberOfProfiles());
 
   base::FilePath path_3 = GetProfilePath("path_3");
@@ -823,8 +827,8 @@
   const AccountId account_id_3(
       AccountId::FromUserEmailGaiaId("email3", "333333"));
   GetCache()->AddProfileToCache(path_3, name_3, account_id_3.GetGaiaId(),
-                                UTF8ToUTF16(account_id_3.GetUserEmail()), 0,
-                                std::string(), EmptyAccountId());
+                                UTF8ToUTF16(account_id_3.GetUserEmail()), false,
+                                0, std::string(), EmptyAccountId());
   EXPECT_EQ(3u, GetCache()->GetNumberOfProfiles());
 
   base::FilePath path_4 = GetProfilePath("path_4");
@@ -832,8 +836,8 @@
   const AccountId account_id_4(
       AccountId::FromUserEmailGaiaId("email4", "444444"));
   GetCache()->AddProfileToCache(path_4, name_4, account_id_4.GetGaiaId(),
-                                UTF8ToUTF16(account_id_4.GetUserEmail()), 0,
-                                std::string(), EmptyAccountId());
+                                UTF8ToUTF16(account_id_4.GetUserEmail()), false,
+                                0, std::string(), EmptyAccountId());
   EXPECT_EQ(4u, GetCache()->GetNumberOfProfiles());
 
   GetCache()->RemoveProfileByAccountId(account_id_3);
diff --git a/chrome/browser/profiles/profile_list_desktop.cc b/chrome/browser/profiles/profile_list_desktop.cc
index 7af8ac25..6b2557a6 100644
--- a/chrome/browser/profiles/profile_list_desktop.cc
+++ b/chrome/browser/profiles/profile_list_desktop.cc
@@ -52,7 +52,7 @@
     item->legacy_supervised = entry->IsLegacySupervised();
     item->child_account = entry->IsChild();
     item->signed_in = entry->IsAuthenticated();
-    if (!item->signed_in) {
+    if (entry->GetSigninState() == SigninState::kNotSignedIn) {
       item->username = l10n_util::GetStringUTF16(
           item->legacy_supervised ? IDS_LEGACY_SUPERVISED_USER_AVATAR_LABEL :
                                     IDS_PROFILES_LOCAL_PROFILE_STATE);
diff --git a/chrome/browser/profiles/profile_list_desktop_unittest.cc b/chrome/browser/profiles/profile_list_desktop_unittest.cc
index b961c48..c4877af3 100644
--- a/chrome/browser/profiles/profile_list_desktop_unittest.cc
+++ b/chrome/browser/profiles/profile_list_desktop_unittest.cc
@@ -77,8 +77,8 @@
   void AddOmittedProfile(const std::string& name) {
     ProfileAttributesStorage* storage = manager()->profile_attributes_storage();
     storage->AddProfile(manager()->profiles_dir().AppendASCII(name),
-                        ASCIIToUTF16(name), std::string(), base::string16(), 0,
-                        "TEST_ID", EmptyAccountId());
+                        ASCIIToUTF16(name), std::string(), base::string16(),
+                        false, 0, "TEST_ID", EmptyAccountId());
   }
 
   int change_count() const { return mock_observer_->change_count(); }
diff --git a/chrome/browser/profiles/profile_manager.cc b/chrome/browser/profiles/profile_manager.cc
index 72136e5..2fccd26 100644
--- a/chrome/browser/profiles/profile_manager.cc
+++ b/chrome/browser/profiles/profile_manager.cc
@@ -567,7 +567,8 @@
     if (profiles::IsDefaultAvatarIconUrl(icon_url, &icon_index)) {
       // add profile to cache with user selected name and avatar
       GetProfileAttributesStorage().AddProfile(
-          profile_path, name, std::string(), base::string16(), icon_index,
+          profile_path, name, std::string(), base::string16(),
+          /*is_consented_primary_account=*/false, icon_index,
           /*supervised_user_id=*/std::string(), EmptyAccountId());
     }
   }
@@ -1577,7 +1578,10 @@
 
   signin::IdentityManager* identity_manager =
       IdentityManagerFactory::GetForProfile(profile);
-  CoreAccountInfo account_info = identity_manager->GetPrimaryAccountInfo();
+  bool is_consented_primary_account = identity_manager->HasPrimaryAccount();
+  CoreAccountInfo account_info =
+      identity_manager->GetUnconsentedPrimaryAccountInfo();
+
   base::string16 username = base::UTF8ToUTF16(account_info.email);
 
   ProfileAttributesStorage& storage = GetProfileAttributesStorage();
@@ -1592,7 +1596,8 @@
       bool was_authenticated_status = entry->IsAuthenticated();
 #endif
       // The ProfileAttributesStorage's info must match the Identity Manager.
-      entry->SetAuthInfo(account_info.gaia, username);
+      entry->SetAuthInfo(account_info.gaia, username,
+                         is_consented_primary_account);
 #if !defined(OS_ANDROID) && !defined(OS_CHROMEOS)
       // Sign out if force-sign-in policy is enabled and profile is not signed
       // in.
@@ -1640,7 +1645,8 @@
 #endif
 
   storage.AddProfile(profile->GetPath(), profile_name, account_info.gaia,
-                     username, icon_index, supervised_user_id, account_id);
+                     username, is_consented_primary_account, icon_index,
+                     supervised_user_id, account_id);
 
   if (profile->GetPrefs()->GetBoolean(prefs::kForceEphemeralProfiles)) {
     ProfileAttributesEntry* entry;
diff --git a/chrome/browser/profiles/profile_manager_unittest.cc b/chrome/browser/profiles/profile_manager_unittest.cc
index f6d586b..279c9c1 100644
--- a/chrome/browser/profiles/profile_manager_unittest.cc
+++ b/chrome/browser/profiles/profile_manager_unittest.cc
@@ -202,8 +202,8 @@
         profile_manager->GetProfileAttributesStorage();
     size_t num_profiles = storage.GetNumberOfProfiles();
     base::FilePath path = temp_dir_.GetPath().AppendASCII(path_suffix);
-    storage.AddProfile(path, profile_name, std::string(), base::string16(), 0,
-                       std::string(), EmptyAccountId());
+    storage.AddProfile(path, profile_name, std::string(), base::string16(),
+                       false, 0, std::string(), EmptyAccountId());
     EXPECT_EQ(num_profiles + 1u, storage.GetNumberOfProfiles());
     return profile_manager->GetProfile(path);
   }
@@ -666,14 +666,14 @@
   EXPECT_EQ(0u, storage.GetNumberOfProfiles());
 
   storage.AddProfile(profile_manager->user_data_dir().AppendASCII("path_1"),
-                     ASCIIToUTF16("name_1"), "12345", base::string16(), 0,
+                     ASCIIToUTF16("name_1"), "12345", base::string16(), true, 0,
                      std::string(), EmptyAccountId());
   storage.AddProfile(profile_manager->user_data_dir().AppendASCII("path_2"),
-                     ASCIIToUTF16("name_2"), "23456", base::string16(), 0,
+                     ASCIIToUTF16("name_2"), "23456", base::string16(), true, 0,
                      std::string(), EmptyAccountId());
   storage.AddProfile(profile_manager->user_data_dir().AppendASCII("path_3"),
-                     ASCIIToUTF16("name_3"), "34567", base::string16(), 0,
-                     std::string(), EmptyAccountId());
+                     ASCIIToUTF16("name_3"), "34567", base::string16(), false,
+                     0, std::string(), EmptyAccountId());
 
   ASSERT_EQ(3u, storage.GetNumberOfProfiles());
 
@@ -697,10 +697,10 @@
   EXPECT_EQ(0u, storage.GetNumberOfProfiles());
 
   storage.AddProfile(profile_manager->user_data_dir().AppendASCII("path_1"),
-                     ASCIIToUTF16("name_1"), "12345", base::string16(), 0,
+                     ASCIIToUTF16("name_1"), "12345", base::string16(), true, 0,
                      std::string(), EmptyAccountId());
   storage.AddProfile(profile_manager->user_data_dir().AppendASCII("path_2"),
-                     ASCIIToUTF16("name_2"), "23456", base::string16(), 0,
+                     ASCIIToUTF16("name_2"), "23456", base::string16(), true, 0,
                      std::string(), EmptyAccountId());
 
   ASSERT_EQ(2u, storage.GetNumberOfProfiles());
@@ -1197,7 +1197,7 @@
   base::FilePath path1 =
       profile_manager->user_data_dir().AppendASCII(profile_name1);
   storage.AddProfile(path1, base::UTF8ToUTF16(profile_name1), std::string(),
-                     base::UTF8ToUTF16(profile_name1), 0, std::string(),
+                     base::UTF8ToUTF16(profile_name1), true, 0, std::string(),
                      EmptyAccountId());
   storage.GetAllProfilesAttributes()[0]->SetIsEphemeral(true);
   ASSERT_TRUE(base::CreateDirectory(path1));
@@ -1206,7 +1206,7 @@
   base::FilePath path2 =
       profile_manager->user_data_dir().AppendASCII(profile_name2);
   storage.AddProfile(path2, base::UTF8ToUTF16(profile_name2), std::string(),
-                     base::UTF8ToUTF16(profile_name2), 0, std::string(),
+                     base::UTF8ToUTF16(profile_name2), true, 0, std::string(),
                      EmptyAccountId());
   ASSERT_EQ(2u, storage.GetNumberOfProfiles());
   ASSERT_TRUE(base::CreateDirectory(path2));
@@ -1246,7 +1246,7 @@
   base::FilePath path1 =
       profile_manager->user_data_dir().AppendASCII(profile_name1);
   storage.AddProfile(path1, base::UTF8ToUTF16(profile_name1), std::string(),
-                     base::UTF8ToUTF16(profile_name1), 0, std::string(),
+                     base::UTF8ToUTF16(profile_name1), true, 0, std::string(),
                      EmptyAccountId());
   storage.GetAllProfilesAttributes()[0]->SetIsEphemeral(true);
   ASSERT_TRUE(base::CreateDirectory(path1));
@@ -1490,14 +1490,14 @@
   ProfileAttributesEntry* entry = storage.GetAllProfilesAttributes()[0];
   // For a signed in profile with a default name we still display
   // IDS_SINGLE_PROFILE_DISPLAY_NAME.
-  entry->SetAuthInfo("12345", ASCIIToUTF16("user@gmail.com"));
+  entry->SetAuthInfo("12345", ASCIIToUTF16("user@gmail.com"), true);
   EXPECT_EQ(profile_name1, entry->GetName());
   EXPECT_EQ(default_profile_name,
             profiles::GetAvatarNameForProfile(profile1->GetPath()));
 
   // For a signed in profile with a non-default Gaia given name we display the
   // Gaia given name.
-  entry->SetAuthInfo("12345", ASCIIToUTF16("user@gmail.com"));
+  entry->SetAuthInfo("12345", ASCIIToUTF16("user@gmail.com"), true);
   const base::string16 gaia_given_name(ASCIIToUTF16("given name"));
   entry->SetGAIAGivenName(gaia_given_name);
   EXPECT_EQ(gaia_given_name, entry->GetName());
@@ -1550,20 +1550,20 @@
 
   ASSERT_TRUE(storage.GetProfileAttributesWithPath(profile1->GetPath(),
                                                    &entry));
-  entry->SetAuthInfo("12345", email1);
+  entry->SetAuthInfo("12345", email1, true);
   entry->SetGAIAGivenName(base::string16());
   entry->SetGAIAName(base::string16());
 
   // This may resort the cache, so be extra cautious to use the right profile.
   ASSERT_TRUE(storage.GetProfileAttributesWithPath(profile2->GetPath(),
                                                    &entry));
-  entry->SetAuthInfo("23456", email2);
+  entry->SetAuthInfo("23456", email2, true);
   entry->SetGAIAGivenName(base::string16());
   entry->SetGAIAName(base::string16());
 
   ASSERT_TRUE(storage.GetProfileAttributesWithPath(profile3->GetPath(),
                                                    &entry));
-  entry->SetAuthInfo("34567", email3);
+  entry->SetAuthInfo("34567", email3, true);
   entry->SetGAIAGivenName(base::string16());
   entry->SetGAIAName(base::string16());
 
@@ -1609,7 +1609,8 @@
   ProfileAttributesStorage& storage =
       profile_manager->GetProfileAttributesStorage();
   storage.AddProfile(dest_path2, ASCIIToUTF16(profile_name2), "23456",
-                     base::string16(), 0, std::string(), EmptyAccountId());
+                     base::string16(), true, 0, std::string(),
+                     EmptyAccountId());
   content::RunAllTasksUntilIdle();
 
   EXPECT_EQ(1u, profile_manager->GetLoadedProfiles().size());
@@ -1658,10 +1659,10 @@
   ProfileAttributesStorage& storage =
       profile_manager->GetProfileAttributesStorage();
   storage.AddProfile(dest_path2, ASCIIToUTF16(profile_name2), "23456",
-                     ASCIIToUTF16(profile_name2), 1, std::string(),
+                     ASCIIToUTF16(profile_name2), true, 1, std::string(),
                      EmptyAccountId());
   storage.AddProfile(dest_path3, ASCIIToUTF16(profile_name3), "34567",
-                     ASCIIToUTF16(profile_name3), 2, std::string(),
+                     ASCIIToUTF16(profile_name3), true, 2, std::string(),
                      EmptyAccountId());
 
   content::RunAllTasksUntilIdle();
diff --git a/chrome/browser/profiles/profile_shortcut_manager_unittest_win.cc b/chrome/browser/profiles/profile_shortcut_manager_unittest_win.cc
index 36df8c1..9d69da5 100644
--- a/chrome/browser/profiles/profile_shortcut_manager_unittest_win.cc
+++ b/chrome/browser/profiles/profile_shortcut_manager_unittest_win.cc
@@ -91,9 +91,9 @@
         << location.ToString();
     ASSERT_FALSE(ProfileShortcutExistsAtDefaultPath(profile_1_name_))
         << location.ToString();
-    profile_attributes_storage_->AddProfile(profile_1_path_, profile_1_name_,
-                                            std::string(), base::string16(), 0,
-                                            std::string(), EmptyAccountId());
+    profile_attributes_storage_->AddProfile(
+        profile_1_path_, profile_1_name_, std::string(), base::string16(),
+        false, 0, std::string(), EmptyAccountId());
     // Also create a non-badged shortcut for Chrome, which is conveniently done
     // by |CreateProfileShortcut()| since there is only one profile.
     profile_shortcut_manager_->CreateProfileShortcut(profile_1_path_);
@@ -108,9 +108,9 @@
         << location.ToString();
     ASSERT_FALSE(ProfileShortcutExistsAtDefaultPath(profile_1_name_))
         << location.ToString();
-    profile_attributes_storage_->AddProfile(profile_1_path_, profile_1_name_,
-                                            std::string(), base::string16(), 0,
-                                            std::string(), EmptyAccountId());
+    profile_attributes_storage_->AddProfile(
+        profile_1_path_, profile_1_name_, std::string(), base::string16(),
+        false, 0, std::string(), EmptyAccountId());
     // Create a non profile shortcut for Chrome.
     base::ScopedBlockingCall scoped_blocking_call(
         FROM_HERE, base::BlockingType::MAY_BLOCK);
@@ -252,9 +252,9 @@
                                  const base::FilePath& profile_path) {
     ASSERT_FALSE(ProfileShortcutExistsAtDefaultPath(profile_name))
         << location.ToString();
-    profile_attributes_storage_->AddProfile(profile_path, profile_name,
-                                            std::string(), base::string16(), 0,
-                                            std::string(), EmptyAccountId());
+    profile_attributes_storage_->AddProfile(
+        profile_path, profile_name, std::string(), base::string16(), false, 0,
+        std::string(), EmptyAccountId());
     profile_shortcut_manager_->CreateProfileShortcut(profile_path);
     task_environment_.RunUntilIdle();
     ValidateProfileShortcut(location, profile_name, profile_path);
@@ -422,9 +422,9 @@
   ASSERT_TRUE(ProfileShortcutExistsAtDefaultPath(base::string16()));
 
   // Create a second profile without a shortcut.
-  profile_attributes_storage_->AddProfile(profile_2_path_, profile_2_name_,
-                                          std::string(), base::string16(), 0,
-                                          std::string(), EmptyAccountId());
+  profile_attributes_storage_->AddProfile(
+      profile_2_path_, profile_2_name_, std::string(), base::string16(), false,
+      0, std::string(), EmptyAccountId());
   task_environment_.RunUntilIdle();
 
   // Ensure that the second profile doesn't have a shortcut and that the first
@@ -748,9 +748,9 @@
       CreateRegularSystemLevelShortcut(FROM_HERE);
 
   // Create the initial profile.
-  profile_attributes_storage_->AddProfile(profile_1_path_, profile_1_name_,
-                                          std::string(), base::string16(), 0,
-                                          std::string(), EmptyAccountId());
+  profile_attributes_storage_->AddProfile(
+      profile_1_path_, profile_1_name_, std::string(), base::string16(), false,
+      0, std::string(), EmptyAccountId());
   task_environment_.RunUntilIdle();
   ASSERT_EQ(1u, profile_attributes_storage_->GetNumberOfProfiles());
 
@@ -767,9 +767,9 @@
   EXPECT_TRUE(base::PathExists(system_level_shortcut_path));
 
   // Create a third profile without a shortcut and ensure it doesn't get one.
-  profile_attributes_storage_->AddProfile(profile_3_path_, profile_3_name_,
-                                          std::string(), base::string16(), 0,
-                                          std::string(), EmptyAccountId());
+  profile_attributes_storage_->AddProfile(
+      profile_3_path_, profile_3_name_, std::string(), base::string16(), false,
+      0, std::string(), EmptyAccountId());
   task_environment_.RunUntilIdle();
   EXPECT_FALSE(ProfileShortcutExistsAtDefaultPath(profile_3_name_));
 
diff --git a/chrome/browser/profiles/profile_window_browsertest.cc b/chrome/browser/profiles/profile_window_browsertest.cc
index 8a5f847..b153c4f8 100644
--- a/chrome/browser/profiles/profile_window_browsertest.cc
+++ b/chrome/browser/profiles/profile_window_browsertest.cc
@@ -102,7 +102,8 @@
   base::FilePath profile_path =
       manager->user_data_dir().AppendASCII(relative_path);
   storage.AddProfile(profile_path, base::ASCIIToUTF16(name), std::string(),
-                     base::string16(), 0u, std::string(), EmptyAccountId());
+                     base::string16(), false, 0u, std::string(),
+                     EmptyAccountId());
 
   EXPECT_EQ(starting_number_of_profiles + 1u, storage.GetNumberOfProfiles());
   return profile_path;
diff --git a/chrome/browser/resources/chromeos/assistant_optin/assistant_voice_match.css b/chrome/browser/resources/chromeos/assistant_optin/assistant_voice_match.css
index 0cfaeb0..fefffcf 100644
--- a/chrome/browser/resources/chromeos/assistant_optin/assistant_voice_match.css
+++ b/chrome/browser/resources/chromeos/assistant_optin/assistant_voice_match.css
@@ -19,15 +19,17 @@
   color: #757575;
 }
 
-#voice-match-video-container {
+#voice-match-animation-container {
   flex-grow: 1;
 }
 
-#voice-match-video {
+#voice-match-animation {
+  height: 170px;
   left: 50%;
   position: relative;
   top: 50%;
   transform: translate(-50%, -50%);
+  width: 255px;
 }
 
 #already-setup-video-container {
diff --git a/chrome/browser/resources/chromeos/assistant_optin/assistant_voice_match.html b/chrome/browser/resources/chromeos/assistant_optin/assistant_voice_match.html
index 347d7ce..4ddea63 100644
--- a/chrome/browser/resources/chromeos/assistant_optin/assistant_voice_match.html
+++ b/chrome/browser/resources/chromeos/assistant_optin/assistant_voice_match.html
@@ -4,6 +4,7 @@
 
 <link rel="import" href="chrome://resources/polymer/v1_0/iron-icon/iron-icon.html">
 <link rel="import" href="chrome://resources/cr_elements/icons.html">
+<link rel="import" href="chrome://resources/cr_elements/chromeos/cr_lottie/cr_lottie.html">
 <dom-module id="assistant-voice-match">
   <template>
     <link rel="stylesheet" href="../login/oobe_flex_layout.css">
@@ -24,10 +25,11 @@
             <div class="content" id="no-dsp-message"
                 i18n-content="assistantVoiceMatchNoDspMessage">
             </div>
-            <div id="voice-match-video-container">
-              <video id="voice-match-video" muted autoplay loop>
-                <source src="voice_laptop_1x.webm" type="video/webm">
-              </video>
+            <div id="voice-match-animation-container">
+              <div id="voice-match-animation">
+                <cr-lottie animation-url="voice_match_animation.json">
+                </cr-lottie>
+              </div>
             </div>
           </div>
           <div id="recording-container">
diff --git a/chrome/browser/resources/chromeos/assistant_optin/voice_laptop_1x.webm b/chrome/browser/resources/chromeos/assistant_optin/voice_laptop_1x.webm
deleted file mode 100644
index 2d4af89..0000000
--- a/chrome/browser/resources/chromeos/assistant_optin/voice_laptop_1x.webm
+++ /dev/null
Binary files differ
diff --git a/chrome/browser/resources/chromeos/login/fingerprint_setup.html b/chrome/browser/resources/chromeos/login/fingerprint_setup.html
index 2149428..4a9b5484 100644
--- a/chrome/browser/resources/chromeos/login/fingerprint_setup.html
+++ b/chrome/browser/resources/chromeos/login/fingerprint_setup.html
@@ -84,7 +84,8 @@
       <div slot="footer" class="layout vertical center">
         <div id="sensorLocationContainer">
           <template is="dom-if" if="[[shouldUseLottieAnimation_]]">
-            <cr-lottie animation-url="fingerprint_scanner_animation.json">
+            <cr-lottie id="scannerLocationLottie"
+                animation-url="fingerprint_scanner_animation.json">
             </cr-lottie>
           </template>
           <template is="dom-if" if="[[!shouldUseLottieAnimation_]]">
diff --git a/chrome/browser/resources/chromeos/login/fingerprint_setup.js b/chrome/browser/resources/chromeos/login/fingerprint_setup.js
index 51ef71f..ce80764 100644
--- a/chrome/browser/resources/chromeos/login/fingerprint_setup.js
+++ b/chrome/browser/resources/chromeos/login/fingerprint_setup.js
@@ -176,6 +176,13 @@
    */
   onContinueToSensorLocationScreen_: function(e) {
     this.showScreen_('placeFinger');
+
+    if (this.shouldUseLottieAnimation_) {
+      const placeFingerScreen = this.getActiveScreen_();
+      let lottieElement = /** @type{CrLottieElement} */ (
+          placeFingerScreen.querySelector('#scannerLocationLottie'));
+      lottieElement.setPlay(true);
+    }
   },
 
   /**
diff --git a/chrome/browser/resources/local_ntp/customize.js b/chrome/browser/resources/local_ntp/customize.js
index 3530c8b4..6d530d04 100644
--- a/chrome/browser/resources/local_ntp/customize.js
+++ b/chrome/browser/resources/local_ntp/customize.js
@@ -765,6 +765,7 @@
       $(customize.IDS.BACKGROUNDS_MENU) :
       $(customize.IDS.TILES);
   if (configData.richerPicker && customize.builtTiles) {
+    tileContainer.focus();
     return;
   }
   customize.builtTiles = true;
@@ -855,7 +856,7 @@
   $(customize.IDS.BACKGROUNDS_DEFAULT_ICON).onClickOverride =
       $(customize.IDS.BACKGROUNDS_DEFAULT).onkeydown;
 
-  $(customize.IDS.TILES).focus();
+  tileContainer.focus();
 };
 
 /**
diff --git a/chrome/browser/resources/settings/people_page/setup_fingerprint_dialog.html b/chrome/browser/resources/settings/people_page/setup_fingerprint_dialog.html
index d7ce231a..298e790 100644
--- a/chrome/browser/resources/settings/people_page/setup_fingerprint_dialog.html
+++ b/chrome/browser/resources/settings/people_page/setup_fingerprint_dialog.html
@@ -72,7 +72,7 @@
           <div id="scannerLocationLottie"
             hidden="[[!showScannerLocation_(step_)]]" aria-live="polite"
             aria-label="$i18n{configureFingerprintScannerStepAriaLabel}">
-            <cr-lottie animation-url="finger_print.json">
+            <cr-lottie animation-url="finger_print.json" autoplay>
             </cr-lottie>
           </div>
         </template>
diff --git a/chrome/browser/safe_browsing/cloud_content_scanning/deep_scanning_dialog_delegate.cc b/chrome/browser/safe_browsing/cloud_content_scanning/deep_scanning_dialog_delegate.cc
index 76e62f1..73c59f55 100644
--- a/chrome/browser/safe_browsing/cloud_content_scanning/deep_scanning_dialog_delegate.cc
+++ b/chrome/browser/safe_browsing/cloud_content_scanning/deep_scanning_dialog_delegate.cc
@@ -15,6 +15,7 @@
 #include "base/task/task_traits.h"
 #include "chrome/browser/browser_process.h"
 #include "chrome/browser/policy/browser_dm_token_storage.h"
+#include "chrome/browser/policy/machine_level_user_cloud_policy_controller.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/safe_browsing/download_protection/check_client_download_request.h"
 #include "chrome/grit/generated_resources.h"
@@ -36,6 +37,11 @@
 
 namespace {
 
+std::string* GetDMTokenForTestingStorage() {
+  static std::string dm_token;
+  return &dm_token;
+}
+
 // Global pointer of factory function (RepeatingCallback) used to create
 // instances of DeepScanningDialogDelegate in tests.  !is_null() only in tests.
 DeepScanningDialogDelegate::Factory* GetFactoryStorage() {
@@ -215,8 +221,8 @@
   if (!base::FeatureList::IsEnabled(kDeepScanningOfUploads))
     return false;
 
-  // If there's no DM token, the upload will fail, so we can skip uploading now.
-  if (policy::BrowserDMTokenStorage::Get()->RetrieveDMToken().empty())
+  // If there's no DM token, the upload will fail.
+  if (GetDMToken().empty())
     return false;
 
   // See if content compliance checks are needed.
@@ -309,6 +315,11 @@
   *GetFactoryStorage() = factory;
 }
 
+// static
+void DeepScanningDialogDelegate::SetDMTokenForTesting(const char* dm_token) {
+  *GetDMTokenForTestingStorage() = dm_token;
+}
+
 DeepScanningDialogDelegate::DeepScanningDialogDelegate(
     content::WebContents* web_contents,
     Data data,
@@ -366,6 +377,25 @@
   MaybeCompleteScanRequest();
 }
 
+// static
+std::string DeepScanningDialogDelegate::GetDMToken() {
+  std::string dm_token = *GetDMTokenForTestingStorage();
+
+#if !defined(OS_CHROMEOS)
+  // This is not compiled on chromeos because
+  // MachineLevelUserCloudPolicyController does not exist.  Also,
+  // policy::BrowserDMTokenStorage::Get()->RetrieveDMToken() does not return a
+  // valid token either.  Once these are fixed the #if !defined can be removed.
+
+  if (dm_token.empty() && policy::MachineLevelUserCloudPolicyController::
+                              IsMachineLevelUserCloudPolicyEnabled()) {
+    dm_token = policy::BrowserDMTokenStorage::Get()->RetrieveDMToken();
+  }
+#endif
+
+  return dm_token;
+}
+
 bool DeepScanningDialogDelegate::UploadData() {
   if (data_.do_dlp_scan) {
     // Create a string data source based on all the text.
@@ -418,8 +448,7 @@
     request->set_request_malware_scan(std::move(malware_request));
   }
 
-  request->set_dm_token(
-      policy::BrowserDMTokenStorage::Get()->RetrieveDMToken());
+  request->set_dm_token(GetDMToken());
 }
 
 void DeepScanningDialogDelegate::FillAllResultsWith(bool status) {
@@ -450,7 +479,8 @@
   if (!dialog_)
     return false;
 
-  dialog_->AcceptTabModalDialog();
+  RunCallback();
+  dialog_->CancelTabModalDialog();
   return true;
 }
 
diff --git a/chrome/browser/safe_browsing/cloud_content_scanning/deep_scanning_dialog_delegate.h b/chrome/browser/safe_browsing/cloud_content_scanning/deep_scanning_dialog_delegate.h
index 111c82d5..5eb164df 100644
--- a/chrome/browser/safe_browsing/cloud_content_scanning/deep_scanning_dialog_delegate.h
+++ b/chrome/browser/safe_browsing/cloud_content_scanning/deep_scanning_dialog_delegate.h
@@ -144,6 +144,9 @@
   // DeepScanningDialogDelegates.
   static void SetFactoryForTesting(Factory factory);
 
+  // Overrides the DM token used for testing purposes.
+  static void SetDMTokenForTesting(const char* dm_token);
+
  protected:
   DeepScanningDialogDelegate(content::WebContents* web_contents,
                              Data data,
@@ -164,6 +167,9 @@
  private:
   class FileSourceRequest;
 
+  // Gets the device level DM token to use with deep scans.
+  static std::string GetDMToken();
+
   // Uploads data for deep scanning.  Returns true if uploading is occurring in
   // the background and false if there is nothing to do.
   bool UploadData();
diff --git a/chrome/browser/safe_browsing/cloud_content_scanning/deep_scanning_dialog_delegate_unittest.cc b/chrome/browser/safe_browsing/cloud_content_scanning/deep_scanning_dialog_delegate_unittest.cc
index 45417977..29046a5 100644
--- a/chrome/browser/safe_browsing/cloud_content_scanning/deep_scanning_dialog_delegate_unittest.cc
+++ b/chrome/browser/safe_browsing/cloud_content_scanning/deep_scanning_dialog_delegate_unittest.cc
@@ -10,7 +10,6 @@
 #include "base/run_loop.h"
 #include "base/strings/utf_string_conversions.h"
 #include "base/test/scoped_feature_list.h"
-#include "chrome/browser/policy/fake_browser_dm_token_storage.h"
 #include "chrome/test/base/testing_browser_process.h"
 #include "chrome/test/base/testing_profile.h"
 #include "chrome/test/base/testing_profile_manager.h"
@@ -110,13 +109,10 @@
   BaseTest() : profile_manager_(TestingBrowserProcess::GetGlobal()) {
     EXPECT_TRUE(profile_manager_.SetUp());
     profile_ = profile_manager_.CreateTestingProfile("test-user");
-
-    // Set a client id, otherwise it is not possible to set a DM token.
-    fake_dm_token_storage_.SetClientId("client_id");
   }
 
   void SetDMToken(const char* dm_token) {
-    fake_dm_token_storage_.SetDMToken(dm_token);
+    DeepScanningDialogDelegate::SetDMTokenForTesting(dm_token);
   }
 
   void EnableFeatures(const std::vector<base::Feature>& features) {
@@ -149,7 +145,6 @@
   TestingPrefServiceSimple pref_service_;
   TestingProfileManager profile_manager_;
   TestingProfile* profile_;
-  policy::FakeBrowserDMTokenStorage fake_dm_token_storage_;
 };
 
 using DeepScanningDialogDelegateIsEnabledTest = BaseTest;
diff --git a/chrome/browser/signin/signin_global_error_unittest.cc b/chrome/browser/signin/signin_global_error_unittest.cc
index d46e3f871..07859797 100644
--- a/chrome/browser/signin/signin_global_error_unittest.cc
+++ b/chrome/browser/signin/signin_global_error_unittest.cc
@@ -64,7 +64,8 @@
     ASSERT_TRUE(profile_manager_.profile_attributes_storage()->
         GetProfileAttributesWithPath(profile()->GetPath(), &entry));
 
-    entry->SetAuthInfo(account_info.gaia, base::UTF8ToUTF16(kTestEmail));
+    entry->SetAuthInfo(account_info.gaia, base::UTF8ToUTF16(kTestEmail),
+                       /*is_consented_primary_account=*/true);
 
     global_error_ = SigninGlobalErrorFactory::GetForProfile(profile());
     error_controller_ = SigninErrorControllerFactory::GetForProfile(profile());
diff --git a/chrome/browser/signin/signin_profile_attributes_updater.cc b/chrome/browser/signin/signin_profile_attributes_updater.cc
index cbe1958..076df05d 100644
--- a/chrome/browser/signin/signin_profile_attributes_updater.cc
+++ b/chrome/browser/signin/signin_profile_attributes_updater.cc
@@ -49,13 +49,14 @@
     return;
   }
 
-  if (identity_manager_->HasPrimaryAccount()) {
-    CoreAccountInfo account_info = identity_manager_->GetPrimaryAccountInfo();
-    entry->SetAuthInfo(account_info.gaia,
-                       base::UTF8ToUTF16(account_info.email));
+  CoreAccountInfo account_info =
+      identity_manager_->GetUnconsentedPrimaryAccountInfo();
+  if (!account_info.IsEmpty()) {
+    entry->SetAuthInfo(account_info.gaia, base::UTF8ToUTF16(account_info.email),
+                       identity_manager_->HasPrimaryAccount());
   } else {
     entry->SetLocalAuthCredentials(std::string());
-    entry->SetAuthInfo(std::string(), base::string16());
+    entry->SetAuthInfo(std::string(), base::string16(), false);
     if (!signin_util::IsForceSigninEnabled())
       entry->SetIsSigninRequired(false);
   }
@@ -80,3 +81,8 @@
     const CoreAccountInfo& previous_primary_account_info) {
   UpdateProfileAttributes();
 }
+
+void SigninProfileAttributesUpdater::OnUnconsentedPrimaryAccountChanged(
+    const CoreAccountInfo& unconsented_primary_account_info) {
+  UpdateProfileAttributes();
+}
diff --git a/chrome/browser/signin/signin_profile_attributes_updater.h b/chrome/browser/signin/signin_profile_attributes_updater.h
index 29a2067..0c77301c 100644
--- a/chrome/browser/signin/signin_profile_attributes_updater.h
+++ b/chrome/browser/signin/signin_profile_attributes_updater.h
@@ -44,6 +44,8 @@
       const CoreAccountInfo& primary_account_info) override;
   void OnPrimaryAccountCleared(
       const CoreAccountInfo& previous_primary_account_info) override;
+  void OnUnconsentedPrimaryAccountChanged(
+      const CoreAccountInfo& unconsented_primary_account_info) override;
 
   signin::IdentityManager* identity_manager_;
   SigninErrorController* signin_error_controller_;
diff --git a/chrome/browser/signin/signin_profile_attributes_updater_unittest.cc b/chrome/browser/signin/signin_profile_attributes_updater_unittest.cc
index be012041..63c674c 100644
--- a/chrome/browser/signin/signin_profile_attributes_updater_unittest.cc
+++ b/chrome/browser/signin/signin_profile_attributes_updater_unittest.cc
@@ -74,7 +74,7 @@
   ProfileAttributesEntry* entry;
   ASSERT_TRUE(profile_manager_.profile_attributes_storage()
                   ->GetProfileAttributesWithPath(profile_path_, &entry));
-  ASSERT_FALSE(entry->IsAuthenticated());
+  ASSERT_EQ(entry->GetSigninState(), SigninState::kNotSignedIn);
   EXPECT_FALSE(entry->IsSigninRequired());
 
   // Signin.
@@ -85,7 +85,7 @@
 
   // Signout.
   identity_test_env_.ClearPrimaryAccount();
-  EXPECT_FALSE(entry->IsAuthenticated());
+  EXPECT_EQ(entry->GetSigninState(), SigninState::kNotSignedIn);
   EXPECT_FALSE(entry->IsSigninRequired());
 }
 #endif  // !defined(OS_CHROMEOS)
@@ -149,7 +149,7 @@
   EXPECT_EQ(kEmail, base::UTF16ToUTF8(entry->GetUserName()));
 
   identity_test_env_.ClearPrimaryAccount();
-  EXPECT_FALSE(entry->IsAuthenticated());
+  EXPECT_EQ(entry->GetSigninState(), SigninState::kNotSignedIn);
   EXPECT_TRUE(entry->IsSigninRequired());
 }
 #endif
diff --git a/chrome/browser/ui/apps/app_info_dialog.h b/chrome/browser/ui/apps/app_info_dialog.h
index abe2ef4..e4ea140 100644
--- a/chrome/browser/ui/apps/app_info_dialog.h
+++ b/chrome/browser/ui/apps/app_info_dialog.h
@@ -48,6 +48,12 @@
                           const extensions::Extension* app);
 #endif
 
+// Shows the chrome app information in an independent dialog box and runs
+// close_callback when the app info window is closed.
+void ShowAppInfo(Profile* profile,
+                 const extensions::Extension* app,
+                 const base::Closure& close_callback);
+
 // Shows the chrome app information in a native dialog box.
 void ShowAppInfoInNativeDialog(content::WebContents* web_contents,
                                Profile* profile,
diff --git a/chrome/browser/ui/ash/assistant/proactive_suggestions_client_impl.cc b/chrome/browser/ui/ash/assistant/proactive_suggestions_client_impl.cc
index 933570ba..73d799c3 100644
--- a/chrome/browser/ui/ash/assistant/proactive_suggestions_client_impl.cc
+++ b/chrome/browser/ui/ash/assistant/proactive_suggestions_client_impl.cc
@@ -6,9 +6,40 @@
 
 #include "ash/public/cpp/assistant/proactive_suggestions.h"
 #include "chrome/browser/profiles/profile.h"
+#include "chrome/browser/sync/profile_sync_service_factory.h"
 #include "chrome/browser/ui/ash/assistant/proactive_suggestions_loader.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/browser_list.h"
+#include "components/sync/driver/sync_service.h"
+#include "components/sync/driver/sync_user_settings.h"
+
+namespace {
+
+// Helpers ---------------------------------------------------------------------
+
+syncer::SyncService* GetSyncService(Profile* profile) {
+  return profile->IsSyncAllowed()
+             ? ProfileSyncServiceFactory::GetForProfile(profile)
+             : nullptr;
+}
+
+bool IsHistorySyncEnabledWithoutPassphrase(Profile* profile) {
+  auto* sync_service = GetSyncService(profile);
+  if (!sync_service)
+    return false;
+
+  const auto* user_settings = sync_service->GetUserSettings();
+  if (!user_settings)
+    return false;
+
+  return user_settings->GetSelectedTypes().Has(
+             syncer::UserSelectableType::kHistory) &&
+         !user_settings->IsUsingSecondaryPassphrase();
+}
+
+}  // namespace
+
+// ProactiveSuggestionsClientImpl ----------------------------------------------
 
 ProactiveSuggestionsClientImpl::ProactiveSuggestionsClientImpl(
     Profile* profile)
@@ -20,6 +51,12 @@
   // We observe the singleton BrowserList to receive events pertaining to the
   // currently active browser.
   BrowserList::AddObserver(this);
+
+  // We observe the SyncService to detect changes in user sync settings which
+  // may affect whether or not we will observe the active browser.
+  auto* sync_service = GetSyncService(profile_);
+  if (sync_service)
+    sync_service->AddObserver(this);
 }
 
 ProactiveSuggestionsClientImpl::~ProactiveSuggestionsClientImpl() {
@@ -31,6 +68,10 @@
   if (active_browser_)
     active_browser_->tab_strip_model()->RemoveObserver(this);
 
+  auto* sync_service = GetSyncService(profile_);
+  if (sync_service)
+    sync_service->RemoveObserver(this);
+
   BrowserList::RemoveObserver(this);
   ash::AssistantState::Get()->RemoveObserver(this);
 }
@@ -90,6 +131,12 @@
   UpdateActiveState();
 }
 
+void ProactiveSuggestionsClientImpl::OnStateChanged(syncer::SyncService* sync) {
+  // When the state of the SyncService has changed, we may need to resume/pause
+  // observation of the browser. We accomplish this by updating active state.
+  UpdateActiveState();
+}
+
 void ProactiveSuggestionsClientImpl::SetActiveBrowser(Browser* browser) {
   if (browser == active_browser_)
     return;
@@ -161,10 +208,13 @@
   auto* tab_strip_model = active_browser_->tab_strip_model();
 
   // We never observe browsers that are off the record and we never observe
-  // browsers when the user has disabled either Assistant or screen context.
+  // browsers when the user has disabled either Assistant or screen context. We
+  // also don't observe the browser when the user has disabled history sync or
+  // is using a sync passphrase.
   if (active_browser_->profile()->IsOffTheRecord() ||
       !ash::AssistantState::Get()->settings_enabled().value_or(false) ||
-      !ash::AssistantState::Get()->context_enabled().value_or(false)) {
+      !ash::AssistantState::Get()->context_enabled().value_or(false) ||
+      !IsHistorySyncEnabledWithoutPassphrase(profile_)) {
     tab_strip_model->RemoveObserver(this);
     SetActiveContents(nullptr);
     return;
diff --git a/chrome/browser/ui/ash/assistant/proactive_suggestions_client_impl.h b/chrome/browser/ui/ash/assistant/proactive_suggestions_client_impl.h
index b6d2ecb..fdc1c216c 100644
--- a/chrome/browser/ui/ash/assistant/proactive_suggestions_client_impl.h
+++ b/chrome/browser/ui/ash/assistant/proactive_suggestions_client_impl.h
@@ -13,6 +13,7 @@
 #include "base/memory/scoped_refptr.h"
 #include "chrome/browser/ui/browser_list_observer.h"
 #include "chrome/browser/ui/tabs/tab_strip_model_observer.h"
+#include "components/sync/driver/sync_service_observer.h"
 #include "content/public/browser/web_contents_observer.h"
 
 class ProactiveSuggestionsLoader;
@@ -25,7 +26,8 @@
                                        public BrowserListObserver,
                                        public TabStripModelObserver,
                                        public content::WebContentsObserver,
-                                       public ash::AssistantStateObserver {
+                                       public ash::AssistantStateObserver,
+                                       public syncer::SyncServiceObserver {
  public:
   explicit ProactiveSuggestionsClientImpl(Profile* profile);
   ~ProactiveSuggestionsClientImpl() override;
@@ -52,6 +54,9 @@
   void OnAssistantSettingsEnabled(bool enabled) override;
   void OnAssistantContextEnabled(bool enabled) override;
 
+  // syncer::SyncServiceObserver:
+  void OnStateChanged(syncer::SyncService* sync) override;
+
  private:
   void SetActiveBrowser(Browser* browser);
   void SetActiveContents(content::WebContents* contents);
diff --git a/chrome/browser/ui/ash/launcher/chrome_launcher_controller.cc b/chrome/browser/ui/ash/launcher/chrome_launcher_controller.cc
index 50b691be..18ca5eb3 100644
--- a/chrome/browser/ui/ash/launcher/chrome_launcher_controller.cc
+++ b/chrome/browser/ui/ash/launcher/chrome_launcher_controller.cc
@@ -866,11 +866,7 @@
                             AppInfoLaunchSource::FROM_SHELF,
                             AppInfoLaunchSource::NUM_LAUNCH_SOURCES);
 
-  ShowAppInfoInNativeDialog(BrowserList::GetInstance()
-                                ->GetLastActive()
-                                ->tab_strip_model()
-                                ->GetActiveWebContents(),
-                            profile, extension, base::Closure());
+  ShowAppInfo(profile, extension, base::Closure());
 }
 
 ///////////////////////////////////////////////////////////////////////////////
diff --git a/chrome/browser/ui/ash/vpn_list_forwarder.cc b/chrome/browser/ui/ash/vpn_list_forwarder.cc
index 405ce38a..da6ba029 100644
--- a/chrome/browser/ui/ash/vpn_list_forwarder.cc
+++ b/chrome/browser/ui/ash/vpn_list_forwarder.cc
@@ -10,13 +10,9 @@
 #include "base/location.h"
 #include "base/logging.h"
 #include "base/threading/thread_task_runner_handle.h"
-#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/chromeos/profiles/profile_helper.h"
 #include "chrome/browser/profiles/profile.h"
 #include "components/user_manager/user.h"
-#include "components/user_manager/user_manager.h"
-#include "content/public/browser/notification_service.h"
-#include "content/public/browser/notification_source.h"
 #include "extensions/browser/extension_registry.h"
 #include "extensions/common/extension.h"
 #include "extensions/common/extension_set.h"
@@ -83,9 +79,8 @@
     AttachToPrimaryUserProfile();
   } else {
     // If no user is logged in, wait until the first user logs in (thus becoming
-    // the primary user) and a profile is created for that user.
-    registrar_.Add(this, chrome::NOTIFICATION_PROFILE_CREATED,
-                   content::NotificationService::AllSources());
+    // the primary user).
+    user_manager::UserManager::Get()->AddSessionStateObserver(this);
   }
 
   ash::GetNetworkConfigService(
@@ -93,6 +88,7 @@
 }
 
 VpnListForwarder::~VpnListForwarder() {
+  user_manager::UserManager::Get()->RemoveSessionStateObserver(this);
   if (extension_registry_)
     extension_registry_->RemoveObserver(this);
   if (arc_vpn_provider_manager_)
@@ -148,26 +144,12 @@
   extension_registry_ = nullptr;
 }
 
-void VpnListForwarder::Observe(int type,
-                               const content::NotificationSource& source,
-                               const content::NotificationDetails& details) {
-  DCHECK_EQ(chrome::NOTIFICATION_PROFILE_CREATED, type);
-  const Profile* const profile = content::Source<Profile>(source).ptr();
-  if (!chromeos::ProfileHelper::Get()->IsPrimaryProfile(profile)) {
-    // If the profile that was just created does not belong to the primary user
-    // (e.g. login profile), ignore it.
-    return;
-  }
-
-  // The first user logged in (thus becoming the primary user) and a profile was
-  // created for that user. Stop observing profile creation. Wait one message
-  // loop cycle to allow other code which observes the
-  // chrome::NOTIFICATION_PROFILE_CREATED notification to finish initializing
-  // the profile, then start observing the primary user's extension registry.
-  registrar_.RemoveAll();
-  base::ThreadTaskRunnerHandle::Get()->PostTask(
-      FROM_HERE, base::BindOnce(&VpnListForwarder::AttachToPrimaryUserProfile,
-                                weak_factory_.GetWeakPtr()));
+void VpnListForwarder::ActiveUserChanged(user_manager::User* active_user) {
+  DCHECK_EQ(user_manager::UserManager::Get()->GetPrimaryUser(), active_user);
+  active_user->AddProfileCreatedObserver(
+      base::BindOnce(&VpnListForwarder::AttachToPrimaryUserProfile,
+                     weak_factory_.GetWeakPtr()));
+  user_manager::UserManager::Get()->RemoveSessionStateObserver(this);
 }
 
 void VpnListForwarder::SetVpnProviders() {
diff --git a/chrome/browser/ui/ash/vpn_list_forwarder.h b/chrome/browser/ui/ash/vpn_list_forwarder.h
index 7dbd8a5..2fc695e 100644
--- a/chrome/browser/ui/ash/vpn_list_forwarder.h
+++ b/chrome/browser/ui/ash/vpn_list_forwarder.h
@@ -10,8 +10,7 @@
 #include "base/memory/weak_ptr.h"
 #include "chrome/browser/ui/app_list/arc/arc_vpn_provider_manager.h"
 #include "chromeos/services/network_config/public/mojom/cros_network_config.mojom.h"
-#include "content/public/browser/notification_observer.h"
-#include "content/public/browser/notification_registrar.h"
+#include "components/user_manager/user_manager.h"
 #include "extensions/browser/extension_registry_observer.h"
 #include "mojo/public/cpp/bindings/remote.h"
 
@@ -22,9 +21,10 @@
 // Forwards a list of third party (Extension and Arc) VPN providers in the
 // primary user's profile to the chromeos.network_config.mojom service for
 // use in the Settings and Ash UI code.
-class VpnListForwarder : public app_list::ArcVpnProviderManager::Observer,
-                         public extensions::ExtensionRegistryObserver,
-                         public content::NotificationObserver {
+class VpnListForwarder
+    : public app_list::ArcVpnProviderManager::Observer,
+      public extensions::ExtensionRegistryObserver,
+      public user_manager::UserManager::UserSessionStateObserver {
  public:
   VpnListForwarder();
   ~VpnListForwarder() override;
@@ -46,10 +46,8 @@
                            extensions::UnloadedExtensionReason reason) override;
   void OnShutdown(extensions::ExtensionRegistry* registry) override;
 
-  // content::NotificationObserver:
-  void Observe(int type,
-               const content::NotificationSource& source,
-               const content::NotificationDetails& details) override;
+  // user_manager::UserManager::UserSessionStateObserver:
+  void ActiveUserChanged(user_manager::User* active_user) override;
 
  private:
   // Calls cros_network_config_->SetVpnProviders with the current provider list.
@@ -82,8 +80,6 @@
   base::flat_map<std::string, chromeos::network_config::mojom::VpnProviderPtr>
       vpn_providers_;
 
-  content::NotificationRegistrar registrar_;
-
   base::WeakPtrFactory<VpnListForwarder> weak_factory_{this};
 
   DISALLOW_COPY_AND_ASSIGN(VpnListForwarder);
diff --git a/chrome/browser/ui/passwords/settings/password_manager_presenter.cc b/chrome/browser/ui/passwords/settings/password_manager_presenter.cc
index f110b63..6ec295f 100644
--- a/chrome/browser/ui/passwords/settings/password_manager_presenter.cc
+++ b/chrome/browser/ui/passwords/settings/password_manager_presenter.cc
@@ -228,16 +228,6 @@
 }
 
 void PasswordManagerPresenter::ChangeSavedPassword(
-    size_t index,
-    const base::string16& new_username,
-    const base::Optional<base::string16>& new_password) {
-  DCHECK_LT(index, password_map_.size());
-
-  ChangeSavedPasswords(std::next(password_map_.begin(), index)->second,
-                       new_username, new_password);
-}
-
-void PasswordManagerPresenter::ChangeSavedPassword(
     const std::string& sort_key,
     const base::string16& new_username,
     const base::Optional<base::string16>& new_password) {
diff --git a/chrome/browser/ui/passwords/settings/password_manager_presenter.h b/chrome/browser/ui/passwords/settings/password_manager_presenter.h
index 642cef8..fdd047f 100644
--- a/chrome/browser/ui/passwords/settings/password_manager_presenter.h
+++ b/chrome/browser/ui/passwords/settings/password_manager_presenter.h
@@ -60,11 +60,7 @@
   // Gets the password exception entry at |index|.
   const autofill::PasswordForm* GetPasswordException(size_t index) const;
 
-  // Changes the username and password at |index|, or corresponding to
-  // |sort_key|.
-  void ChangeSavedPassword(size_t index,
-                           const base::string16& new_username,
-                           const base::Optional<base::string16>& new_password);
+  // Changes the username and password corresponding to |sort_key|.
   void ChangeSavedPassword(const std::string& sort_key,
                            const base::string16& new_username,
                            const base::Optional<base::string16>& new_password);
diff --git a/chrome/browser/ui/passwords/settings/password_manager_presenter_unittest.cc b/chrome/browser/ui/passwords/settings/password_manager_presenter_unittest.cc
index 4c23a05f..51d7ef7 100644
--- a/chrome/browser/ui/passwords/settings/password_manager_presenter_unittest.cc
+++ b/chrome/browser/ui/passwords/settings/password_manager_presenter_unittest.cc
@@ -119,40 +119,6 @@
     task_environment_.RunUntilIdle();
   }
 
-  int GetPasswordIndex(base::StringPiece origin,
-                       base::StringPiece old_username,
-                       base::StringPiece old_password) {
-    std::vector<std::unique_ptr<autofill::PasswordForm>> password_forms =
-        mock_controller_.GetPasswordManagerPresenter()->GetAllPasswords();
-    return std::find_if(
-               password_forms.begin(), password_forms.end(),
-               [origin, old_username, old_password](const auto& password_form) {
-                 return password_form->signon_realm ==
-                            GURL(origin).GetOrigin().spec() &&
-                        password_form->username_value ==
-                            base::ASCIIToUTF16(old_username) &&
-                        password_form->password_value ==
-                            base::ASCIIToUTF16(old_password);
-               }) -
-           password_forms.begin();
-  }
-
-  void ChangeSavedPasswordByIndex(
-      base::StringPiece origin,
-      base::StringPiece old_username,
-      base::StringPiece old_password,
-      base::StringPiece new_username,
-      base::Optional<base::StringPiece> new_password) {
-    mock_controller_.GetPasswordManagerPresenter()->ChangeSavedPassword(
-        GetPasswordIndex(origin, old_username, old_password),
-        base::ASCIIToUTF16(new_username),
-        new_password ? base::make_optional(base::ASCIIToUTF16(*new_password))
-                     : base::nullopt);
-    // The password store posts mutation tasks to a background thread, thus we
-    // need to spin the message loop here.
-    task_environment_.RunUntilIdle();
-  }
-
   void UpdatePasswordLists() {
     mock_controller_.GetPasswordManagerPresenter()->UpdatePasswordLists();
     task_environment_.RunUntilIdle();
@@ -197,21 +163,6 @@
 }
 
 TEST_F(PasswordManagerPresenterTest,
-       ChangeSavedPasswordByIndex_RejectEmptyPassword) {
-  AddPasswordEntry(GURL(kExampleCom), "user", "pass");
-  EXPECT_CALL(GetUIController(), SetPasswordList(SizeIs(1)));
-  EXPECT_CALL(GetUIController(), SetPasswordExceptionList(IsEmpty()));
-  UpdatePasswordLists();
-  EXPECT_THAT(GetUsernamesAndPasswords(GetStoredPasswordsForRealm(kExampleCom)),
-              ElementsAre(Pair("user", "pass")));
-  testing::Mock::VerifyAndClearExpectations(&GetUIController());
-
-  ChangeSavedPasswordByIndex(kExampleCom, "user", "pass", "new_user", "");
-  EXPECT_THAT(GetUsernamesAndPasswords(GetStoredPasswordsForRealm(kExampleCom)),
-              ElementsAre(Pair("user", "pass")));
-}
-
-TEST_F(PasswordManagerPresenterTest,
        ChangeSavedPasswordBySortKey_ChangeUsername) {
   AddPasswordEntry(GURL(kExampleCom), "user", "pass");
   EXPECT_CALL(GetUIController(), SetPasswordList(SizeIs(1)));
@@ -228,22 +179,6 @@
 }
 
 TEST_F(PasswordManagerPresenterTest,
-       ChangeSavedPasswordByIndex_ChangeUsername) {
-  AddPasswordEntry(GURL(kExampleCom), "user", "pass");
-  EXPECT_CALL(GetUIController(), SetPasswordList(SizeIs(1)));
-  EXPECT_CALL(GetUIController(), SetPasswordExceptionList(IsEmpty()));
-  UpdatePasswordLists();
-  EXPECT_THAT(GetUsernamesAndPasswords(GetStoredPasswordsForRealm(kExampleCom)),
-              ElementsAre(Pair("user", "pass")));
-  testing::Mock::VerifyAndClearExpectations(&GetUIController());
-
-  ChangeSavedPasswordByIndex(kExampleCom, "user", "pass", "new_user",
-                             base::nullopt);
-  EXPECT_THAT(GetUsernamesAndPasswords(GetStoredPasswordsForRealm(kExampleCom)),
-              ElementsAre(Pair("new_user", "pass")));
-}
-
-TEST_F(PasswordManagerPresenterTest,
        ChangeSavedPasswordBySortKey_ChangeUsernameAndPassword) {
   AddPasswordEntry(GURL(kExampleCom), "user", "pass");
   EXPECT_CALL(GetUIController(), SetPasswordList(SizeIs(1)));
@@ -260,22 +195,6 @@
 }
 
 TEST_F(PasswordManagerPresenterTest,
-       ChangeSavedPasswordByIndex_ChangeUsernameAndPassword) {
-  AddPasswordEntry(GURL(kExampleCom), "user", "pass");
-  EXPECT_CALL(GetUIController(), SetPasswordList(SizeIs(1)));
-  EXPECT_CALL(GetUIController(), SetPasswordExceptionList(IsEmpty()));
-  UpdatePasswordLists();
-  EXPECT_THAT(GetUsernamesAndPasswords(GetStoredPasswordsForRealm(kExampleCom)),
-              ElementsAre(Pair("user", "pass")));
-  testing::Mock::VerifyAndClearExpectations(&GetUIController());
-
-  ChangeSavedPasswordByIndex(kExampleCom, "user", "pass", "new_user",
-                             "new_pass");
-  EXPECT_THAT(GetUsernamesAndPasswords(GetStoredPasswordsForRealm(kExampleCom)),
-              ElementsAre(Pair("new_user", "new_pass")));
-}
-
-TEST_F(PasswordManagerPresenterTest,
        ChangeSavedPasswordBySortKey_RejectSameUsernameForSameRealm) {
   AddPasswordEntry(GURL(kExampleCom), "user", "pass");
   AddPasswordEntry(GURL(kExampleCom), "user2", "pass2");
@@ -293,23 +212,6 @@
 }
 
 TEST_F(PasswordManagerPresenterTest,
-       ChangeSavedPasswordByIndex_RejectSameUsernameForSameRealm) {
-  AddPasswordEntry(GURL(kExampleCom), "user", "pass");
-  AddPasswordEntry(GURL(kExampleCom), "user2", "pass2");
-  EXPECT_CALL(GetUIController(), SetPasswordList(SizeIs(2)));
-  EXPECT_CALL(GetUIController(), SetPasswordExceptionList(IsEmpty()));
-  UpdatePasswordLists();
-  EXPECT_THAT(GetUsernamesAndPasswords(GetStoredPasswordsForRealm(kExampleCom)),
-              ElementsAre(Pair("user", "pass"), Pair("user2", "pass2")));
-  testing::Mock::VerifyAndClearExpectations(&GetUIController());
-
-  ChangeSavedPasswordByIndex(kExampleCom, "user", "pass", "user2",
-                             base::nullopt);
-  EXPECT_THAT(GetUsernamesAndPasswords(GetStoredPasswordsForRealm(kExampleCom)),
-              ElementsAre(Pair("user", "pass"), Pair("user2", "pass2")));
-}
-
-TEST_F(PasswordManagerPresenterTest,
        ChangeSavedPasswordBySortKey_DontRejectSameUsernameForDifferentRealm) {
   AddPasswordEntry(GURL(kExampleCom), "user", "pass");
   AddPasswordEntry(GURL(kExampleOrg), "user2", "pass2");
@@ -331,27 +233,6 @@
 }
 
 TEST_F(PasswordManagerPresenterTest,
-       ChangeSavedPasswordByIndex_DontRejectSameUsernameForDifferentRealm) {
-  AddPasswordEntry(GURL(kExampleCom), "user", "pass");
-  AddPasswordEntry(GURL(kExampleOrg), "user2", "pass2");
-  EXPECT_CALL(GetUIController(), SetPasswordList(SizeIs(2)));
-  EXPECT_CALL(GetUIController(), SetPasswordExceptionList(IsEmpty()));
-  UpdatePasswordLists();
-  EXPECT_THAT(GetUsernamesAndPasswords(GetStoredPasswordsForRealm(kExampleCom)),
-              ElementsAre(Pair("user", "pass")));
-  EXPECT_THAT(GetUsernamesAndPasswords(GetStoredPasswordsForRealm(kExampleOrg)),
-              ElementsAre(Pair("user2", "pass2")));
-  testing::Mock::VerifyAndClearExpectations(&GetUIController());
-
-  ChangeSavedPasswordByIndex(kExampleCom, "user", "pass", "user2",
-                             base::nullopt);
-  EXPECT_THAT(GetUsernamesAndPasswords(GetStoredPasswordsForRealm(kExampleCom)),
-              ElementsAre(Pair("user2", "pass")));
-  EXPECT_THAT(GetUsernamesAndPasswords(GetStoredPasswordsForRealm(kExampleOrg)),
-              ElementsAre(Pair("user2", "pass2")));
-}
-
-TEST_F(PasswordManagerPresenterTest,
        ChangeSavedPasswordBySortKey_UpdateDuplicates) {
   AddPasswordEntry(GURL(std::string(kExampleCom) + "pathA"), "user", "pass");
   AddPasswordEntry(GURL(std::string(kExampleCom) + "pathB"), "user", "pass");
@@ -369,25 +250,6 @@
       ElementsAre(Pair("new_user", "new_pass"), Pair("new_user", "new_pass")));
 }
 
-TEST_F(PasswordManagerPresenterTest,
-       ChangeSavedPasswordByIndex_UpdateDuplicates) {
-  AddPasswordEntry(GURL(std::string(kExampleCom) + "pathA"), "user", "pass");
-  AddPasswordEntry(GURL(std::string(kExampleCom) + "pathB"), "user", "pass");
-
-  EXPECT_CALL(GetUIController(), SetPasswordList(SizeIs(1)));
-  EXPECT_CALL(GetUIController(), SetPasswordExceptionList(IsEmpty()));
-  UpdatePasswordLists();
-  EXPECT_THAT(GetUsernamesAndPasswords(GetStoredPasswordsForRealm(kExampleCom)),
-              ElementsAre(Pair("user", "pass"), Pair("user", "pass")));
-  testing::Mock::VerifyAndClearExpectations(&GetUIController());
-
-  ChangeSavedPasswordByIndex(kExampleCom, "user", "pass", "new_user",
-                             "new_pass");
-  EXPECT_THAT(
-      GetUsernamesAndPasswords(GetStoredPasswordsForRealm(kExampleCom)),
-      ElementsAre(Pair("new_user", "new_pass"), Pair("new_user", "new_pass")));
-}
-
 TEST_F(PasswordManagerPresenterTest, UIControllerIsCalled) {
   EXPECT_CALL(GetUIController(), SetPasswordList(IsEmpty()));
   EXPECT_CALL(GetUIController(), SetPasswordExceptionList(IsEmpty()));
diff --git a/chrome/browser/ui/views/apps/app_info_dialog/app_info_dialog_views.cc b/chrome/browser/ui/views/apps/app_info_dialog/app_info_dialog_views.cc
index c7616940..f0de1903 100644
--- a/chrome/browser/ui/views/apps/app_info_dialog/app_info_dialog_views.cc
+++ b/chrome/browser/ui/views/apps/app_info_dialog/app_info_dialog_views.cc
@@ -14,6 +14,8 @@
 #include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/ui/apps/app_info_dialog.h"
+#include "chrome/browser/ui/browser.h"
+#include "chrome/browser/ui/scoped_tabbed_browser_displayer.h"
 #include "chrome/browser/ui/views/apps/app_info_dialog/app_info_dialog_container.h"
 #include "chrome/browser/ui/views/apps/app_info_dialog/app_info_footer_panel.h"
 #include "chrome/browser/ui/views/apps/app_info_dialog/app_info_header_panel.h"
@@ -50,6 +52,7 @@
 // The color of the separator used inside the dialog - should match the app
 // list's app_list::kDialogSeparatorColor
 constexpr SkColor kDialogSeparatorColor = SkColorSetRGB(0xD1, 0xD1, 0xD1);
+constexpr gfx::Size kDialogSize = gfx::Size(380, 490);
 
 }  // namespace
 
@@ -76,11 +79,21 @@
 }
 #endif
 
+void ShowAppInfo(Profile* profile,
+                 const extensions::Extension* app,
+                 const base::Closure& close_callback) {
+  views::DialogDelegate* dialog = CreateDialogContainerForView(
+      std::make_unique<AppInfoDialog>(profile, app), kDialogSize,
+      close_callback);
+  views::Widget* dialog_widget =
+      views::DialogDelegate::CreateDialogWidget(dialog, nullptr, nullptr);
+  dialog_widget->Show();
+}
+
 void ShowAppInfoInNativeDialog(content::WebContents* web_contents,
                                Profile* profile,
                                const extensions::Extension* app,
                                const base::Closure& close_callback) {
-  constexpr gfx::Size kDialogSize = gfx::Size(380, 490);
   views::DialogDelegate* dialog = CreateDialogContainerForView(
       std::make_unique<AppInfoDialog>(profile, app), kDialogSize,
       close_callback);
diff --git a/chrome/browser/ui/views/autofill/payments/save_card_bubble_views_browsertest.cc b/chrome/browser/ui/views/autofill/payments/save_card_bubble_views_browsertest.cc
index 2555f0c..f3cc02fa 100644
--- a/chrome/browser/ui/views/autofill/payments/save_card_bubble_views_browsertest.cc
+++ b/chrome/browser/ui/views/autofill/payments/save_card_bubble_views_browsertest.cc
@@ -1950,8 +1950,7 @@
 // dynamic change form.
 IN_PROC_BROWSER_TEST_F(SaveCardBubbleViewsFullFormBrowserTest,
                        Logic_CanOfferToSaveDynamicForm) {
-  scoped_feature_list_.InitWithFeatures(
-      {features::kAutofillUpstream, features::kAutofillImportDynamicForms}, {});
+  scoped_feature_list_.InitAndEnableFeature(features::kAutofillUpstream);
 
   // Start sync.
   harness_->SetupSync();
diff --git a/chrome/browser/ui/views/critical_notification_bubble_view.cc b/chrome/browser/ui/views/critical_notification_bubble_view.cc
index 3edc0e5..acb11a2 100644
--- a/chrome/browser/ui/views/critical_notification_bubble_view.cc
+++ b/chrome/browser/ui/views/critical_notification_bubble_view.cc
@@ -29,18 +29,6 @@
 
 using base::UserMetricsAction;
 
-namespace {
-
-// How long to give the user until auto-restart if no action is taken. The code
-// assumes this to be less than a minute.
-const int kCountdownDuration = 30;  // Seconds.
-
-// How often to refresh the bubble UI to update the counter. As long as the
-// countdown is in seconds, this should be 1000 or lower.
-const int kRefreshBubbleEvery = 1000;  // Millisecond.
-
-}  // namespace
-
 ////////////////////////////////////////////////////////////////////////////////
 // CriticalNotificationBubbleView
 
@@ -54,9 +42,11 @@
 CriticalNotificationBubbleView::~CriticalNotificationBubbleView() {
 }
 
-int CriticalNotificationBubbleView::GetRemainingTime() const {
-  base::TimeDelta time_lapsed = base::TimeTicks::Now() - bubble_created_;
-  return kCountdownDuration - time_lapsed.InSeconds();
+base::TimeDelta CriticalNotificationBubbleView::GetRemainingTime() const {
+  // How long to give the user until auto-restart if no action is taken.
+  constexpr auto kCountdownDuration = base::TimeDelta::FromSeconds(30);
+  const base::TimeDelta time_lapsed = base::TimeTicks::Now() - bubble_created_;
+  return kCountdownDuration - time_lapsed;
 }
 
 void CriticalNotificationBubbleView::OnCountdown() {
@@ -67,8 +57,7 @@
     return;
   }
 
-  int seconds = GetRemainingTime();
-  if (seconds <= 0) {
+  if (GetRemainingTime() <= base::TimeDelta()) {
     // Time's up!
     upgrade_detector->acknowledge_critical_update();
 
@@ -85,11 +74,12 @@
 }
 
 base::string16 CriticalNotificationBubbleView::GetWindowTitle() const {
-  int seconds = GetRemainingTime();
-  return seconds > 0 ? l10n_util::GetPluralStringFUTF16(
-                           IDS_CRITICAL_NOTIFICATION_TITLE, seconds)
-                     : l10n_util::GetStringUTF16(
-                           IDS_CRITICAL_NOTIFICATION_TITLE_ALTERNATE);
+  const auto remaining_time = GetRemainingTime();
+  return remaining_time > base::TimeDelta()
+             ? l10n_util::GetPluralStringFUTF16(IDS_CRITICAL_NOTIFICATION_TITLE,
+                                                remaining_time.InSeconds())
+             : l10n_util::GetStringUTF16(
+                   IDS_CRITICAL_NOTIFICATION_TITLE_ALTERNATE);
 }
 
 void CriticalNotificationBubbleView::WindowClosing() {
@@ -139,9 +129,8 @@
       margins().width());
   AddChildView(std::move(message));
 
-  refresh_timer_.Start(FROM_HERE,
-      base::TimeDelta::FromMilliseconds(kRefreshBubbleEvery),
-      this, &CriticalNotificationBubbleView::OnCountdown);
+  refresh_timer_.Start(FROM_HERE, base::TimeDelta::FromSeconds(1), this,
+                       &CriticalNotificationBubbleView::OnCountdown);
 
   base::RecordAction(UserMetricsAction("CriticalNotificationShown"));
 }
diff --git a/chrome/browser/ui/views/critical_notification_bubble_view.h b/chrome/browser/ui/views/critical_notification_bubble_view.h
index 31e86e7..1360110 100644
--- a/chrome/browser/ui/views/critical_notification_bubble_view.h
+++ b/chrome/browser/ui/views/critical_notification_bubble_view.h
@@ -26,9 +26,8 @@
       const views::ViewHierarchyChangedDetails& details) override;
 
  private:
-  // Helper function to calculate the remaining time (in seconds) until
-  // spontaneous reboot.
-  int GetRemainingTime() const;
+  // Helper function to calculate the remaining time until spontaneous reboot.
+  base::TimeDelta GetRemainingTime() const;
 
   // Called when the timer fires each time the clock ticks.
   void OnCountdown();
diff --git a/chrome/browser/ui/views/download/download_item_view.cc b/chrome/browser/ui/views/download/download_item_view.cc
index 06853006..fc74c86 100644
--- a/chrome/browser/ui/views/download/download_item_view.cc
+++ b/chrome/browser/ui/views/download/download_item_view.cc
@@ -94,8 +94,7 @@
 constexpr int kDefaultDownloadItemHeight = 48;
 
 // Amount of time between accessible alert events.
-constexpr base::TimeDelta kAccessibleAlertInterval =
-    base::TimeDelta::FromSeconds(30);
+constexpr auto kAccessibleAlertInterval = base::TimeDelta::FromSeconds(30);
 
 // The separator is drawn as a border. It's one dp wide.
 class SeparatorBorder : public views::Border {
@@ -219,8 +218,7 @@
   dropdown_button->SetAccessibleName(l10n_util::GetStringUTF16(
       IDS_DOWNLOAD_ITEM_DROPDOWN_BUTTON_ACCESSIBLE_TEXT));
 
-  dropdown_button->SetBorder(
-      views::CreateEmptyBorder(gfx::Insets(kDropdownBorderWidth)));
+  dropdown_button->SetBorder(views::CreateEmptyBorder(gfx::Insets(10)));
   dropdown_button->set_has_ink_drop_action_on_click(false);
   dropdown_button->SetFocusForPlatform();
   dropdown_button_ = AddChildView(std::move(dropdown_button));
@@ -244,8 +242,7 @@
   if (progress_timer_.IsRunning())
     return;
   progress_start_time_ = base::TimeTicks::Now();
-  progress_timer_.Start(FROM_HERE, base::TimeDelta::FromMilliseconds(
-                                       DownloadShelf::kProgressRateMs),
+  progress_timer_.Start(FROM_HERE, base::TimeDelta::FromMilliseconds(30),
                         base::Bind(&DownloadItemView::ProgressTimerFired,
                                    base::Unretained(this)));
 }
@@ -391,7 +388,7 @@
       FROM_HERE,
       base::BindOnce(&DownloadItemView::Reenable,
                      weak_ptr_factory_.GetWeakPtr()),
-      base::TimeDelta::FromMilliseconds(kDisabledOnOpenDuration));
+      base::TimeDelta::FromSeconds(3));
 
   // Notify our parent.
   shelf_->OpenedDownload();
@@ -684,8 +681,10 @@
     return;
 
   // Draw the icon image.
-  int icon_x = progress_x + DownloadShelf::kFiletypeIconOffset;
-  int icon_y = progress_y + DownloadShelf::kFiletypeIconOffset;
+  constexpr int kFiletypeIconOffset =
+      (DownloadShelf::kProgressIndicatorSize - 16) / 2;
+  int icon_x = progress_x + kFiletypeIconOffset;
+  int icon_y = progress_y + kFiletypeIconOffset;
   cc::PaintFlags flags;
   // Use an alpha to make the image look disabled.
   if (!GetEnabled())
diff --git a/chrome/browser/ui/views/download/download_item_view.h b/chrome/browser/ui/views/download/download_item_view.h
index e43fc6f..966bc705 100644
--- a/chrome/browser/ui/views/download/download_item_view.h
+++ b/chrome/browser/ui/views/download/download_item_view.h
@@ -152,9 +152,6 @@
   // dangerous download.
   static constexpr int kSaveDiscardButtonPadding = 5;
 
-  // The touchable space around the dropdown button's icon.
-  static constexpr int kDropdownBorderWidth = 10;
-
   // The space on the right side of the dangerous download label.
   static constexpr int kLabelPadding = 8;
 
@@ -164,10 +161,6 @@
   // Height/width of the erro icon, also in dp.
   static constexpr int kErrorIconSize = 27;
 
-  // How long we keep the item disabled after the user clicked it to open the
-  // downloaded item.
-  static constexpr int kDisabledOnOpenDuration = 3000;
-
   void OpenDownload();
 
   // Submits the downloaded file to the safebrowsing download feedback service.
diff --git a/chrome/browser/ui/views/download/download_shelf_view.cc b/chrome/browser/ui/views/download/download_shelf_view.cc
index 0d9ba02..797bd3f9 100644
--- a/chrome/browser/ui/views/download/download_shelf_view.cc
+++ b/chrome/browser/ui/views/download/download_shelf_view.cc
@@ -97,8 +97,12 @@
       l10n_util::GetStringUTF16(IDS_ACCNAME_DOWNLOADS_BAR));
   GetViewAccessibility().OverrideRole(ax::mojom::Role::kGroup);
 
-  mouse_watcher_.set_notify_on_exit_time(
-      base::TimeDelta::FromMilliseconds(kNotifyOnExitTimeMS));
+  // Delay 5 seconds if the mouse leaves the shelf by way of entering another
+  // window. This is much larger than the normal delay as opening a download is
+  // most likely going to trigger a new window to appear over the button. Delay
+  // a long time so that the user has a chance to quickly close the other app
+  // and return to chrome with the download shelf still open.
+  mouse_watcher_.set_notify_on_exit_time(base::TimeDelta::FromSeconds(5));
   SetID(VIEW_ID_DOWNLOAD_SHELF);
   parent->AddChildView(this);
 }
diff --git a/chrome/browser/ui/views/download/download_shelf_view.h b/chrome/browser/ui/views/download/download_shelf_view.h
index 17c5eae..8352a02 100644
--- a/chrome/browser/ui/views/download/download_shelf_view.h
+++ b/chrome/browser/ui/views/download/download_shelf_view.h
@@ -117,13 +117,6 @@
   // Padding between the show all link and close button.
   static constexpr int kCloseAndLinkPadding = 6;
 
-  // Amount of time to delay if the mouse leaves the shelf by way of entering
-  // another window. This is much larger than the normal delay as opening a
-  // download is most likely going to trigger a new window to appear over the
-  // button. Delay the time so that the user has a chance to quickly close the
-  // other app and return to chrome with the download shelf still open.
-  static constexpr int kNotifyOnExitTimeMS = 5000;
-
   // Adds a View representing a download to this DownloadShelfView.
   // DownloadShelfView takes ownership of the View, and will delete it as
   // necessary.
diff --git a/chrome/browser/ui/views/frame/browser_view.cc b/chrome/browser/ui/views/frame/browser_view.cc
index 56050a2..9dd19e50 100644
--- a/chrome/browser/ui/views/frame/browser_view.cc
+++ b/chrome/browser/ui/views/frame/browser_view.cc
@@ -234,9 +234,6 @@
 // locate this object using just the handle.
 const char* const kBrowserViewKey = "__BROWSER_VIEW__";
 
-// The number of milliseconds between loading animation frames.
-const int kLoadingAnimationFrameTimeMs = 30;
-
 // See SetDisableRevealerDelayForTesting().
 bool g_disable_revealer_delay_for_testing = false;
 
@@ -792,9 +789,9 @@
     if (!loading_animation_timer_.IsRunning()) {
       // Loads are happening, and the timer isn't running, so start it.
       loading_animation_start_ = base::TimeTicks::Now();
-      loading_animation_timer_.Start(FROM_HERE,
-          TimeDelta::FromMilliseconds(kLoadingAnimationFrameTimeMs), this,
-          &BrowserView::LoadingAnimationCallback);
+      loading_animation_timer_.Start(FROM_HERE, TimeDelta::FromMilliseconds(30),
+                                     this,
+                                     &BrowserView::LoadingAnimationCallback);
     }
   } else {
     if (loading_animation_timer_.IsRunning()) {
diff --git a/chrome/browser/ui/views/hover_button.cc b/chrome/browser/ui/views/hover_button.cc
index c90725e..9cc6769 100644
--- a/chrome/browser/ui/views/hover_button.cc
+++ b/chrome/browser/ui/views/hover_button.cc
@@ -343,11 +343,7 @@
     }
   }
 
-  // If possible, take advantage of the |views::Label| tooltip behavior, which
-  // only sets the tooltip when the text is too long.
-  if (title_)
-    return this;
-  return label();
+  return this;
 }
 
 void HoverButton::OnBoundsChanged(const gfx::Rect& previous_bounds) {
diff --git a/chrome/browser/ui/views/media_router/cast_dialog_helper.cc b/chrome/browser/ui/views/media_router/cast_dialog_helper.cc
index 5a41393..d352e332 100644
--- a/chrome/browser/ui/views/media_router/cast_dialog_helper.cc
+++ b/chrome/browser/ui/views/media_router/cast_dialog_helper.cc
@@ -21,7 +21,7 @@
   const int extra_borders =
       kPrimaryIconSize - throbber->CalculatePreferredSize().height();
   throbber_container->SetBorder(views::CreateEmptyBorder(
-      gfx::Insets(extra_borders / 2 + kPrimaryIconBorderWidth)));
+      gfx::Insets(extra_borders / 2) + kPrimaryIconBorder));
   throbber_container->AddChildView(throbber);
   return throbber_container;
 }
diff --git a/chrome/browser/ui/views/media_router/cast_dialog_helper.h b/chrome/browser/ui/views/media_router/cast_dialog_helper.h
index 182a5333..11e87e0c 100644
--- a/chrome/browser/ui/views/media_router/cast_dialog_helper.h
+++ b/chrome/browser/ui/views/media_router/cast_dialog_helper.h
@@ -13,7 +13,7 @@
 
 // Icon sizes in DIP.
 constexpr int kPrimaryIconSize = 20;
-constexpr int kPrimaryIconBorderWidth = 6;
+constexpr auto kPrimaryIconBorder = gfx::Insets(6);
 
 // Creates a view containing a throbber. The throbber has a border around it so
 // that the view's size is the same with the primary icon with its border.
diff --git a/chrome/browser/ui/views/media_router/cast_dialog_no_sinks_view.cc b/chrome/browser/ui/views/media_router/cast_dialog_no_sinks_view.cc
index 6bc0f85..3b7fae1 100644
--- a/chrome/browser/ui/views/media_router/cast_dialog_no_sinks_view.cc
+++ b/chrome/browser/ui/views/media_router/cast_dialog_no_sinks_view.cc
@@ -42,12 +42,10 @@
   looking_for_sinks_view_ = CreateLookingForSinksView();
   AddChildView(looking_for_sinks_view_);
 
-  constexpr int kThrobberDurationInSeconds = 3;
-  base::PostDelayedTask(
-      FROM_HERE, {content::BrowserThread::UI},
-      base::BindOnce(&CastDialogNoSinksView::ShowHelpIconView,
-                     weak_factory_.GetWeakPtr()),
-      base::TimeDelta::FromSeconds(kThrobberDurationInSeconds));
+  base::PostDelayedTask(FROM_HERE, {content::BrowserThread::UI},
+                        base::BindOnce(&CastDialogNoSinksView::ShowHelpIconView,
+                                       weak_factory_.GetWeakPtr()),
+                        base::TimeDelta::FromSeconds(3));
 }
 
 CastDialogNoSinksView::~CastDialogNoSinksView() = default;
@@ -93,8 +91,7 @@
                       gfx::CreateVectorIcon(::vector_icons::kHelpOutlineIcon,
                                             kPrimaryIconSize, icon_color));
   help_icon->SetFocusForPlatform();
-  help_icon->SetBorder(
-      views::CreateEmptyBorder(gfx::Insets(kPrimaryIconBorderWidth)));
+  help_icon->SetBorder(views::CreateEmptyBorder(kPrimaryIconBorder));
   help_icon->SetAccessibleName(
       l10n_util::GetStringUTF16(IDS_MEDIA_ROUTER_NO_DEVICES_FOUND_BUTTON));
   HoverButton* view =
diff --git a/chrome/browser/ui/views/media_router/cast_dialog_sink_button.cc b/chrome/browser/ui/views/media_router/cast_dialog_sink_button.cc
index e609a64..f50b183 100644
--- a/chrome/browser/ui/views/media_router/cast_dialog_sink_button.cc
+++ b/chrome/browser/ui/views/media_router/cast_dialog_sink_button.cc
@@ -79,8 +79,7 @@
     const gfx::ImageSkia& image) {
   auto icon_view = std::make_unique<views::ImageView>();
   icon_view->SetImage(image);
-  icon_view->SetBorder(
-      views::CreateEmptyBorder(gfx::Insets(kPrimaryIconBorderWidth)));
+  icon_view->SetBorder(views::CreateEmptyBorder(kPrimaryIconBorder));
   return icon_view;
 }
 
diff --git a/chrome/browser/ui/views/media_router/media_router_views_ui.cc b/chrome/browser/ui/views/media_router/media_router_views_ui.cc
index 7a5505e..a72f0fd 100644
--- a/chrome/browser/ui/views/media_router/media_router_views_ui.cc
+++ b/chrome/browser/ui/views/media_router/media_router_views_ui.cc
@@ -80,7 +80,7 @@
   auto source_it = std::find_if(
       sources.begin(), sources.end(),
       [](const auto& source) { return source.IsCastPresentationUrl(); });
-  return source_it != sources.end() ? *source_it : MediaSource("");
+  return source_it != sources.end() ? *source_it : MediaSource(std::string());
 }
 
 }  // namespace
@@ -105,7 +105,7 @@
     // which will occur):
     //   * after loading is complete and,
     //   ** capture has begun and fullscreen requested,
-    //   ** kMaxSecondsToWaitForCapture seconds have passed without capture,
+    //   ** 10 seconds have passed without capture,
     //   * another navigation is started,
     //   * the WebContents is destroyed.
     if (web_contents->IsLoading()) {
@@ -114,7 +114,7 @@
       FullScreenFirstVideoElement(web_contents);
     }
   }
-  ~WebContentsFullscreenOnLoadedObserver() override {}
+  ~WebContentsFullscreenOnLoadedObserver() override = default;
 
   // content::WebContentsObserver implementation.
   void DidStopLoading() override {
@@ -139,21 +139,6 @@
   }
 
  private:
-  const GURL file_url_;
-
-  // Time intervals used by the logic that detects if capture has started.
-  const int kMaxSecondsToWaitForCapture = 10;
-  const int kPollIntervalInSeconds = 1;
-
-  // The time at which fullscreen was requested.
-  base::TimeTicks fullscreen_request_time_;
-
-  // Poll timer to monitor the capturer count when fullscreening local files.
-  //
-  // TODO(crbug.com/540965): Add a method to WebContentsObserver to report
-  // capturer count changes and get rid of this polling-based approach.
-  base::OneShotTimer capture_poll_timer_;
-
   // Sends a request for full screen to the WebContents targeted at the first
   // video element.  The request is only sent after capture has begun.
   void FullScreenFirstVideoElement(content::WebContents* web_contents) {
@@ -176,8 +161,9 @@
       client->RequestFullscreenVideoElement();
       delete this;
       return;
-    } else if (base::TimeTicks::Now() - fullscreen_request_time_ >
-               base::TimeDelta::FromSeconds(kMaxSecondsToWaitForCapture)) {
+    }
+    if (base::TimeTicks::Now() - fullscreen_request_time_ >
+        base::TimeDelta::FromSeconds(10)) {
       // If content capture hasn't started within the timeout skip fullscreen.
       DLOG(WARNING) << "Capture of local content did not start within timeout";
       delete this;
@@ -185,14 +171,25 @@
     }
 
     capture_poll_timer_.Start(
-        FROM_HERE, base::TimeDelta::FromSeconds(kPollIntervalInSeconds),
+        FROM_HERE, base::TimeDelta::FromSeconds(1),
         base::BindRepeating(
             &WebContentsFullscreenOnLoadedObserver::FullscreenIfContentCaptured,
             base::Unretained(this), web_contents));
   }
+
+  const GURL file_url_;
+
+  // The time at which fullscreen was requested.
+  base::TimeTicks fullscreen_request_time_;
+
+  // Poll timer to monitor the capturer count when fullscreening local files.
+  //
+  // TODO(crbug.com/540965): Add a method to WebContentsObserver to report
+  // capturer count changes and get rid of this polling-based approach.
+  base::OneShotTimer capture_poll_timer_;
 };
 
-MediaRouterViewsUI::MediaRouterViewsUI() : initiator_(nullptr) {}
+MediaRouterViewsUI::MediaRouterViewsUI() = default;
 
 MediaRouterViewsUI::~MediaRouterViewsUI() {
   for (CastDialogController::Observer& observer : observers_)
@@ -917,9 +914,8 @@
     const GURL& file_url,
     content::WebContents* web_contents,
     const RouteRequestResult& result) {
-  if (result.result_code() == RouteRequestResult::OK) {
+  if (result.result_code() == RouteRequestResult::OK)
     new WebContentsFullscreenOnLoadedObserver(file_url, web_contents);
-  }
 }
 
 void MediaRouterViewsUI::MaybeReportFileInformation(
@@ -937,10 +933,9 @@
     load_params.transition_type = ui::PAGE_TRANSITION_GENERATED;
     initiator_->GetController().LoadURLWithParams(load_params);
     return initiator_;
-  } else {
-    return chrome::AddSelectedTabWithURL(GetBrowser(), url,
-                                         ui::PAGE_TRANSITION_LINK);
   }
+  return chrome::AddSelectedTabWithURL(GetBrowser(), url,
+                                       ui::PAGE_TRANSITION_LINK);
 }
 
 MediaRouter* MediaRouterViewsUI::GetMediaRouter() const {
diff --git a/chrome/browser/ui/views/media_router/media_router_views_ui.h b/chrome/browser/ui/views/media_router/media_router_views_ui.h
index 4635e5b..50d0ed4 100644
--- a/chrome/browser/ui/views/media_router/media_router_views_ui.h
+++ b/chrome/browser/ui/views/media_router/media_router_views_ui.h
@@ -408,7 +408,7 @@
   base::WeakPtr<PresentationServiceDelegateImpl> presentation_service_delegate_;
 
   // WebContents for the tab for which the Cast dialog is shown.
-  content::WebContents* initiator_;
+  content::WebContents* initiator_ = nullptr;
 
   // The dialog that handles opening the file dialog and validating and
   // returning the results.
diff --git a/chrome/browser/ui/views/overlay/overlay_window_views.cc b/chrome/browser/ui/views/overlay/overlay_window_views.cc
index 39d6339..027fb9dd 100644
--- a/chrome/browser/ui/views/overlay/overlay_window_views.cc
+++ b/chrome/browser/ui/views/overlay/overlay_window_views.cc
@@ -51,57 +51,52 @@
 }
 
 namespace {
-constexpr gfx::Size kMinWindowSize = gfx::Size(260, 146);
+constexpr gfx::Size kMinWindowSize(260, 146);
 
-const int kOverlayBorderThickness = 10;
+constexpr int kOverlayBorderThickness = 10;
 
 // The opacity of the controls scrim.
-const double kControlsScrimOpacity = 0.6;
+constexpr double kControlsScrimOpacity = 0.6;
 
 #if defined(OS_CHROMEOS)
 // The opacity of the resize handle control.
-const double kResizeHandleOpacity = 0.38;
+constexpr double kResizeHandleOpacity = 0.38;
 #endif
 
 // Size of a primary control.
-constexpr gfx::Size kPrimaryControlSize = gfx::Size(36, 36);
+constexpr gfx::Size kPrimaryControlSize(36, 36);
 
 // Margin from the bottom of the window for primary controls.
-const int kPrimaryControlBottomMargin = 8;
+constexpr int kPrimaryControlBottomMargin = 8;
 
 // Size of a secondary control.
-constexpr gfx::Size kSecondaryControlSize = gfx::Size(20, 20);
+constexpr gfx::Size kSecondaryControlSize(20, 20);
 
 // Margin from the bottom of the window for secondary controls.
-const int kSecondaryControlBottomMargin = 16;
+constexpr int kSecondaryControlBottomMargin = 16;
 
 // Margin between controls.
-const int kControlMargin = 32;
-
-// Delay in milliseconds before controls bounds are updated. It is the same as
-// HIDE_NOTIFICATION_DELAY_MILLIS in MediaSessionTabHelper.java
-const int kUpdateControlsBoundsDelayMs = 1000;
+constexpr int kControlMargin = 32;
 
 // Returns the quadrant the OverlayWindowViews is primarily in on the current
 // work area.
 OverlayWindowViews::WindowQuadrant GetCurrentWindowQuadrant(
     const gfx::Rect window_bounds,
     content::PictureInPictureWindowController* controller) {
-  gfx::Rect work_area =
+  const gfx::Rect work_area =
       display::Screen::GetScreen()
           ->GetDisplayNearestWindow(
               controller->GetInitiatorWebContents()->GetTopLevelNativeWindow())
           .work_area();
-  gfx::Point window_center = window_bounds.CenterPoint();
+  const gfx::Point window_center = window_bounds.CenterPoint();
 
   // Check which quadrant the center of the window appears in.
+  const bool top = window_center.y() < work_area.height() / 2;
   if (window_center.x() < work_area.width() / 2) {
-    return (window_center.y() < work_area.height() / 2)
-               ? OverlayWindowViews::WindowQuadrant::kTopLeft
+    return top ? OverlayWindowViews::WindowQuadrant::kTopLeft
                : OverlayWindowViews::WindowQuadrant::kBottomLeft;
   }
-  return (window_center.y() < work_area.height() / 2)
-             ? OverlayWindowViews::WindowQuadrant::kTopRight
+  return top ? OverlayWindowViews::WindowQuadrant::kTopRight
              : OverlayWindowViews::WindowQuadrant::kBottomRight;
 }
 
@@ -202,9 +197,11 @@
     content::PictureInPictureWindowController* controller)
     : controller_(controller),
       hide_controls_timer_(
-      FROM_HERE, base::TimeDelta::FromMilliseconds(2500 /* 2.5 seconds */),
-      base::BindRepeating(&OverlayWindowViews::UpdateControlsVisibility,
-                          base::Unretained(this), false /* is_visible */)) {
+          FROM_HERE,
+          base::TimeDelta::FromMilliseconds(2500),
+          base::BindRepeating(&OverlayWindowViews::UpdateControlsVisibility,
+                              base::Unretained(this),
+                              false /* is_visible */)) {
   views::Widget::InitParams params(views::Widget::InitParams::TYPE_WINDOW);
   params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
   params.bounds = CalculateAndUpdateWindowBounds();
@@ -506,8 +503,7 @@
 
   update_controls_bounds_timer_ = std::make_unique<base::OneShotTimer>();
   update_controls_bounds_timer_->Start(
-      FROM_HERE,
-      base::TimeDelta::FromMilliseconds(kUpdateControlsBoundsDelayMs),
+      FROM_HERE, base::TimeDelta::FromSeconds(1),
       base::BindOnce(&OverlayWindowViews::OnUpdateControlsBounds,
                      base::Unretained(this)));
 }
diff --git a/chrome/browser/ui/views/overlay/resize_handle_button.cc b/chrome/browser/ui/views/overlay/resize_handle_button.cc
index ee6b361..aeba6fb 100644
--- a/chrome/browser/ui/views/overlay/resize_handle_button.cc
+++ b/chrome/browser/ui/views/overlay/resize_handle_button.cc
@@ -17,8 +17,8 @@
 
 namespace {
 
-const int kResizeHandleButtonMargin = 4;
-const int kResizeHandleButtonSize = 16;
+constexpr int kResizeHandleButtonMargin = 4;
+constexpr int kResizeHandleButtonSize = 16;
 
 constexpr SkColor kResizeHandleIconColor = SK_ColorWHITE;
 
diff --git a/chrome/browser/ui/views/profiles/profile_menu_view.cc b/chrome/browser/ui/views/profiles/profile_menu_view.cc
index 3283941..9b8b1472 100644
--- a/chrome/browser/ui/views/profiles/profile_menu_view.cc
+++ b/chrome/browser/ui/views/profiles/profile_menu_view.cc
@@ -115,19 +115,19 @@
 // needed to make the icon look smaller, otherwise it looks too big compared to
 // the other icons. See crbug.com/951751 for more information.
 gfx::ImageSkia GetGoogleIconForUserMenu(int icon_size) {
-  constexpr int kIconPadding = 2;
+  constexpr gfx::Insets kIconPadding = gfx::Insets(2);
   SkColor icon_color =
       ui::NativeTheme::GetInstanceForNativeUi()->GetSystemColor(
           ui::NativeTheme::kColorId_DefaultIconColor);
   // |CreateVectorIcon()| doesn't override colors specified in the .icon file,
   // therefore the image has to be colored manually with |CreateColorMask()|.
-  gfx::ImageSkia google_icon = gfx::CreateVectorIcon(
-      kGoogleGLogoIcon, icon_size - 2 * kIconPadding, gfx::kPlaceholderColor);
+  gfx::ImageSkia google_icon =
+      gfx::CreateVectorIcon(kGoogleGLogoIcon, icon_size - kIconPadding.width(),
+                            gfx::kPlaceholderColor);
   gfx::ImageSkia grey_google_icon =
       gfx::ImageSkiaOperations::CreateColorMask(google_icon, icon_color);
 
-  return gfx::CanvasImageSource::CreatePadded(grey_google_icon,
-                                              gfx::Insets(kIconPadding));
+  return gfx::CanvasImageSource::CreatePadded(grey_google_icon, kIconPadding);
 }
 #endif
 
@@ -172,6 +172,7 @@
   BuildAutofillButtons();
   BuildAccountFeatureButtons();
   BuildSelectableProfiles();
+  BuildProfileFeatureButtons();
 }
 
 void ProfileMenuView::OnAvatarMenuChanged(
@@ -465,6 +466,28 @@
   }
 }
 
+void ProfileMenuView::BuildProfileFeatureButtons() {
+  constexpr float kIconToImageRatio = 0.75;
+
+  AddProfileFeatureButton(
+      ImageForMenu(kUserMenuGuestIcon, kIconToImageRatio),
+      l10n_util::GetStringUTF16(IDS_PROFILES_OPEN_GUEST_PROFILE_BUTTON),
+      base::BindRepeating(&ProfileMenuView::OnGuestProfileButtonClicked,
+                          base::Unretained(this)));
+
+  AddProfileFeatureButton(
+      ImageForMenu(vector_icons::kSettingsIcon, kIconToImageRatio),
+      l10n_util::GetStringUTF16(IDS_PROFILES_MANAGE_USERS_BUTTON),
+      base::BindRepeating(&ProfileMenuView::OnManageProfilesButtonClicked,
+                          base::Unretained(this)));
+
+  AddProfileFeatureButton(
+      ImageForMenu(kCloseAllIcon, kIconToImageRatio),
+      l10n_util::GetStringUTF16(IDS_PROFILES_CLOSE_ALL_WINDOWS_BUTTON),
+      base::BindRepeating(&ProfileMenuView::OnExitProfileButtonClicked,
+                          base::Unretained(this)));
+}
+
 void ProfileMenuView::AddProfileMenuView(AvatarMenu* avatar_menu) {
   // Separate items into active and alternatives.
   const AvatarMenu::Item* active_item = nullptr;
diff --git a/chrome/browser/ui/views/profiles/profile_menu_view.h b/chrome/browser/ui/views/profiles/profile_menu_view.h
index 0317d59..21f1e4d1 100644
--- a/chrome/browser/ui/views/profiles/profile_menu_view.h
+++ b/chrome/browser/ui/views/profiles/profile_menu_view.h
@@ -102,6 +102,7 @@
   void BuildAutofillButtons();
   void BuildAccountFeatureButtons();
   void BuildSelectableProfiles();
+  void BuildProfileFeatureButtons();
 
   // Adds the profile chooser view.
   void AddProfileMenuView(AvatarMenu* avatar_menu);
diff --git a/chrome/browser/ui/views/profiles/profile_menu_view_base.cc b/chrome/browser/ui/views/profiles/profile_menu_view_base.cc
index e57a0555..df3774a 100644
--- a/chrome/browser/ui/views/profiles/profile_menu_view_base.cc
+++ b/chrome/browser/ui/views/profiles/profile_menu_view_base.cc
@@ -78,7 +78,6 @@
 
 std::unique_ptr<views::View> CreateBorderedBoxView(
     std::unique_ptr<views::View> children_container) {
-  constexpr int kOuterMargin = 16;
   constexpr int kBorderThickness = 1;
   const SkColor kBorderColor =
       ui::NativeTheme::GetInstanceForNativeUi()->GetSystemColor(
@@ -97,7 +96,8 @@
   // margins.
   auto outer_view = std::make_unique<views::View>();
   outer_view->SetLayoutManager(std::make_unique<views::FillLayout>());
-  outer_view->SetBorder(views::CreateEmptyBorder(gfx::Insets(kOuterMargin)));
+  constexpr auto kOuterMargin = gfx::Insets(16);
+  outer_view->SetBorder(views::CreateEmptyBorder(kOuterMargin));
   outer_view->AddChildView(std::move(children_container));
 
   return outer_view;
@@ -232,7 +232,7 @@
     const gfx::VectorIcon& icon,
     const base::string16& text,
     base::RepeatingClosure action) {
-  constexpr int kVerticalMargin = 8;
+  constexpr auto kMargins = gfx::Insets(8, 0);
   constexpr int kButtonSpacing = 6;
   constexpr int kIconSize = 16;
   constexpr int kIconPadding = 6;
@@ -247,8 +247,8 @@
   if (!shortcut_features_container_->GetLayoutManager()) {
     views::BoxLayout* layout = shortcut_features_container_->SetLayoutManager(
         std::make_unique<views::BoxLayout>(
-            views::BoxLayout::Orientation::kHorizontal,
-            gfx::Insets(kVerticalMargin, 0), kButtonSpacing));
+            views::BoxLayout::Orientation::kHorizontal, kMargins,
+            kButtonSpacing));
     layout->set_main_axis_alignment(
         views::BoxLayout::MainAxisAlignment::kCenter);
   }
@@ -297,15 +297,14 @@
 void ProfileMenuViewBase::AddSelectableProfile(const gfx::Image& image,
                                                const base::string16& name,
                                                base::RepeatingClosure action) {
-  constexpr int kTopMargin = 8;
+  constexpr auto kMargins = gfx::Insets(8, 0, 0, 0);
   constexpr int kImageSize = 22;
 
   // Initialize layout if this is the first time a button is added.
   if (!selectable_profiles_container_->GetLayoutManager()) {
     selectable_profiles_container_->SetLayoutManager(
         std::make_unique<views::BoxLayout>(
-            views::BoxLayout::Orientation::kVertical,
-            gfx::Insets(kTopMargin, 0, 0, 0)));
+            views::BoxLayout::Orientation::kVertical, kMargins));
   }
 
   gfx::Image sized_image =
@@ -313,6 +312,26 @@
                                    kImageSize, profiles::SHAPE_CIRCLE);
   views::Button* button = selectable_profiles_container_->AddChildView(
       std::make_unique<HoverButton>(this, sized_image.AsImageSkia(), name));
+
+  RegisterClickAction(button, std::move(action));
+}
+
+void ProfileMenuViewBase::AddProfileFeatureButton(
+    const gfx::ImageSkia& icon,
+    const base::string16& text,
+    base::RepeatingClosure action) {
+  constexpr int kIconSize = 22;
+
+  // Initialize layout if this is the first time a button is added.
+  if (!profile_features_container_->GetLayoutManager()) {
+    profile_features_container_->SetLayoutManager(
+        std::make_unique<views::BoxLayout>(
+            views::BoxLayout::Orientation::kVertical));
+  }
+
+  views::Button* button = profile_features_container_->AddChildView(
+      std::make_unique<HoverButton>(this, SizeImage(icon, kIconSize), text));
+
   RegisterClickAction(button, std::move(action));
 }
 
@@ -427,6 +446,8 @@
 
   selectable_profiles_container_ =
       components->AddChildView(std::make_unique<views::View>());
+  profile_features_container_ =
+      components->AddChildView(std::make_unique<views::View>());
 
   // Create a scroll view to hold the components.
   auto scroll_view = std::make_unique<views::ScrollView>();
diff --git a/chrome/browser/ui/views/profiles/profile_menu_view_base.h b/chrome/browser/ui/views/profiles/profile_menu_view_base.h
index f70365e..12f6755 100644
--- a/chrome/browser/ui/views/profiles/profile_menu_view_base.h
+++ b/chrome/browser/ui/views/profiles/profile_menu_view_base.h
@@ -106,6 +106,9 @@
   void AddSelectableProfile(const gfx::Image& image,
                             const base::string16& name,
                             base::RepeatingClosure action);
+  void AddProfileFeatureButton(const gfx::ImageSkia& icon,
+                               const base::string16& text,
+                               base::RepeatingClosure action);
   // 0 < |icon_to_image_ratio| <= 1 is the size ratio of |icon| in the returned
   // image. E.g. a value of 0.8 means that |icon| only takes up 80% of the
   // returned image, with the rest being padding around it.
@@ -213,6 +216,7 @@
   views::View* shortcut_features_container_ = nullptr;
   views::View* account_features_container_ = nullptr;
   views::View* selectable_profiles_container_ = nullptr;
+  views::View* profile_features_container_ = nullptr;
 
   CloseBubbleOnTabActivationHelper close_bubble_helper_;
 
diff --git a/chrome/browser/ui/views/profiles/profile_menu_view_browsertest.cc b/chrome/browser/ui/views/profiles/profile_menu_view_browsertest.cc
index 1fcefb9..ea14e54 100644
--- a/chrome/browser/ui/views/profiles/profile_menu_view_browsertest.cc
+++ b/chrome/browser/ui/views/profiles/profile_menu_view_browsertest.cc
@@ -87,7 +87,8 @@
   ProfileAttributesEntry* entry_signed_in;
   ASSERT_TRUE(storage.GetProfileAttributesWithPath(profile->GetPath(),
                                                    &entry_signed_in));
-  entry_signed_in->SetAuthInfo("12345", base::UTF8ToUTF16(signed_in_email));
+  entry_signed_in->SetAuthInfo("12345", base::UTF8ToUTF16(signed_in_email),
+                               true);
   profile->GetPrefs()->SetString(prefs::kGoogleServicesHostedDomain,
                                  "google.com");
 }
@@ -668,12 +669,15 @@
  public:
   // List of actionable items in the correct order as they appear in the menu.
   // If a new button is added to the menu, it should also be added to this list.
-  static constexpr ProfileMenuView::ActionableItem kOrderedActionableItems[6] =
+  static constexpr ProfileMenuView::ActionableItem kOrderedActionableItems[9] =
       {ProfileMenuView::ActionableItem::kPasswordsButton,
        ProfileMenuView::ActionableItem::kCreditCardsButton,
        ProfileMenuView::ActionableItem::kAddressesButton,
        ProfileMenuView::ActionableItem::kOtherProfileButton,
        ProfileMenuView::ActionableItem::kOtherProfileButton,
+       ProfileMenuView::ActionableItem::kGuestProfileButton,
+       ProfileMenuView::ActionableItem::kManageProfilesButton,
+       ProfileMenuView::ActionableItem::kExitProfileButton,
        // The first button is added again to finish the cycle and test that
        // there are no other buttons at the end.
        ProfileMenuView::ActionableItem::kPasswordsButton};
@@ -711,11 +715,14 @@
  public:
   // List of actionable items in the correct order as they appear in the menu.
   // If a new button is added to the menu, it should also be added to this list.
-  static constexpr ProfileMenuView::ActionableItem kOrderedActionableItems[5] =
+  static constexpr ProfileMenuView::ActionableItem kOrderedActionableItems[8] =
       {ProfileMenuView::ActionableItem::kPasswordsButton,
        ProfileMenuView::ActionableItem::kCreditCardsButton,
        ProfileMenuView::ActionableItem::kAddressesButton,
        ProfileMenuView::ActionableItem::kManageGoogleAccountButton,
+       ProfileMenuView::ActionableItem::kGuestProfileButton,
+       ProfileMenuView::ActionableItem::kManageProfilesButton,
+       ProfileMenuView::ActionableItem::kExitProfileButton,
        // The first button is added again to finish the cycle and test that
        // there are no other buttons at the end.
        ProfileMenuView::ActionableItem::kPasswordsButton};
@@ -757,12 +764,15 @@
  public:
   // List of actionable items in the correct order as they appear in the menu.
   // If a new button is added to the menu, it should also be added to this list.
-  static constexpr ProfileMenuView::ActionableItem kOrderedActionableItems[6] =
+  static constexpr ProfileMenuView::ActionableItem kOrderedActionableItems[9] =
       {ProfileMenuView::ActionableItem::kPasswordsButton,
        ProfileMenuView::ActionableItem::kCreditCardsButton,
        ProfileMenuView::ActionableItem::kAddressesButton,
        ProfileMenuView::ActionableItem::kManageGoogleAccountButton,
        ProfileMenuView::ActionableItem::kSignoutButton,
+       ProfileMenuView::ActionableItem::kGuestProfileButton,
+       ProfileMenuView::ActionableItem::kManageProfilesButton,
+       ProfileMenuView::ActionableItem::kExitProfileButton,
        // The first button is added again to finish the cycle and test that
        // there are no other buttons at the end.
        ProfileMenuView::ActionableItem::kPasswordsButton};
diff --git a/chrome/browser/ui/views/screen_capture_notification_ui_views.cc b/chrome/browser/ui/views/screen_capture_notification_ui_views.cc
index a80858e0..b96f2d6 100644
--- a/chrome/browser/ui/views/screen_capture_notification_ui_views.cc
+++ b/chrome/browser/ui/views/screen_capture_notification_ui_views.cc
@@ -37,8 +37,6 @@
 
 const int kHorizontalMargin = 10;
 const float kWindowAlphaValue = 0.96f;
-const int kPaddingVertical = 5;
-const int kPaddingHorizontal = 10;
 
 namespace {
 
@@ -259,9 +257,9 @@
 views::NonClientFrameView*
 ScreenCaptureNotificationUIViews::CreateNonClientFrameView(
     views::Widget* widget) {
-  views::BubbleFrameView* frame = new views::BubbleFrameView(
-      gfx::Insets(), gfx::Insets(kPaddingVertical, kPaddingHorizontal,
-                                 kPaddingVertical, kPaddingHorizontal));
+  constexpr auto kPadding = gfx::Insets(5, 10);
+  views::BubbleFrameView* frame =
+      new views::BubbleFrameView(gfx::Insets(), kPadding);
   SkColor color = widget->GetNativeTheme()->GetSystemColor(
       ui::NativeTheme::kColorId_DialogBackground);
   frame->SetBubbleBorder(std::unique_ptr<views::BubbleBorder>(
diff --git a/chrome/browser/ui/views/send_tab_to_self/send_tab_to_self_bubble_device_button.cc b/chrome/browser/ui/views/send_tab_to_self/send_tab_to_self_bubble_device_button.cc
index b55cccd42..7ee1f7d6 100644
--- a/chrome/browser/ui/views/send_tab_to_self/send_tab_to_self_bubble_device_button.cc
+++ b/chrome/browser/ui/views/send_tab_to_self/send_tab_to_self_bubble_device_button.cc
@@ -22,10 +22,6 @@
 
 namespace {
 
-// Icon sizes in DIP.
-constexpr int kPrimaryIconSize = 20;
-constexpr int kPrimaryIconBorderWidth = 6;
-
 enum class DeviceIconType {
   DESKTOP = 0,
   PHONE = 1,
@@ -52,6 +48,7 @@
       vector_icon = &kSendTabToSelfIcon;
   }
 
+  constexpr int kPrimaryIconSize = 20;
   return gfx::CreateVectorIcon(*vector_icon, kPrimaryIconSize,
                                GetColorfromTheme());
 }
@@ -66,8 +63,8 @@
   }
   auto icon_view = std::make_unique<views::ImageView>();
   icon_view->SetImage(image);
-  icon_view->SetBorder(
-      views::CreateEmptyBorder(gfx::Insets(kPrimaryIconBorderWidth)));
+  constexpr auto kPrimaryIconBorder = gfx::Insets(6);
+  icon_view->SetBorder(views::CreateEmptyBorder(kPrimaryIconBorder));
   return icon_view;
 }
 
diff --git a/chrome/browser/ui/views/sharing/sharing_dialog_view.cc b/chrome/browser/ui/views/sharing/sharing_dialog_view.cc
index 980a982..e763d253 100644
--- a/chrome/browser/ui/views/sharing/sharing_dialog_view.cc
+++ b/chrome/browser/ui/views/sharing/sharing_dialog_view.cc
@@ -33,11 +33,6 @@
 
 namespace {
 
-// Icon sizes in DIP.
-constexpr int kPrimaryIconSize = 20;
-constexpr int kPrimaryIconBorderWidth = 8;
-constexpr int kHeaderImageHeight = 100;
-
 SkColor GetColorFromTheme() {
   const ui::NativeTheme* native_theme =
       ui::NativeTheme::GetInstanceForNativeUi();
@@ -48,12 +43,13 @@
 std::unique_ptr<views::ImageView> CreateIconView(const gfx::ImageSkia& icon) {
   auto icon_view = std::make_unique<views::ImageView>();
   icon_view->SetImage(icon);
-  icon_view->SetBorder(
-      views::CreateEmptyBorder(gfx::Insets(kPrimaryIconBorderWidth)));
+  constexpr auto kPrimaryIconBorder = gfx::Insets(8);
+  icon_view->SetBorder(views::CreateEmptyBorder(kPrimaryIconBorder));
   return icon_view;
 }
 
 gfx::ImageSkia CreateVectorIcon(const gfx::VectorIcon& vector_icon) {
+  constexpr int kPrimaryIconSize = 20;
   return gfx::CreateVectorIcon(vector_icon, kPrimaryIconSize,
                                GetColorFromTheme());
 }
@@ -224,6 +220,7 @@
   ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
   const gfx::ImageSkia* image = rb.GetNativeImageNamed(image_id).ToImageSkia();
   gfx::Size image_size(image->width(), image->height());
+  constexpr int kHeaderImageHeight = 100;
   const int image_width = image->width() * kHeaderImageHeight / image->height();
   image_size.SetToMin(gfx::Size(image_width, kHeaderImageHeight));
 
diff --git a/chrome/browser/ui/views/status_bubble_views.cc b/chrome/browser/ui/views/status_bubble_views.cc
index 060e16b..44e6dcf 100644
--- a/chrome/browser/ui/views/status_bubble_views.cc
+++ b/chrome/browser/ui/views/status_bubble_views.cc
@@ -52,32 +52,32 @@
 namespace {
 
 // The alpha and color of the bubble's shadow.
-const SkColor kShadowColor = SkColorSetARGB(30, 0, 0, 0);
+constexpr SkColor kShadowColor = SkColorSetARGB(30, 0, 0, 0);
 
 // The roundedness of the edges of our bubble.
-const int kBubbleCornerRadius = 4;
+constexpr int kBubbleCornerRadius = 4;
 
 // How close the mouse can get to the infobubble before it starts sliding
 // off-screen.
-const int kMousePadding = 20;
+constexpr int kMousePadding = 20;
 
 // The horizontal offset of the text within the status bubble, not including the
 // outer shadow ring.
-const int kTextPositionX = 5;
+constexpr int kTextPositionX = 5;
 
 // The minimum horizontal space between the (right) end of the text and the edge
 // of the status bubble, not including the outer shadow ring.
-const int kTextHorizPadding = 5;
+constexpr int kTextHorizPadding = 5;
 
 // Delays before we start hiding or showing the bubble after we receive a
 // show or hide request.
-const int kShowDelay = 80;
-const int kHideDelay = 250;
+constexpr auto kShowDelay = base::TimeDelta::FromMilliseconds(80);
+constexpr auto kHideDelay = base::TimeDelta::FromMilliseconds(250);
 
 // How long each fade should last for.
 constexpr auto kShowFadeDuration = base::TimeDelta::FromMilliseconds(120);
 constexpr auto kHideFadeDuration = base::TimeDelta::FromMilliseconds(200);
-const int kFramerate = 25;
+constexpr int kFramerate = 25;
 
 // How long each expansion step should take.
 constexpr auto kMinExpansionStepDuration =
@@ -335,7 +335,7 @@
   if (state_ == BUBBLE_SHOWING_TIMER) {
     // We hadn't yet begun showing anything when we received a new request
     // for something to show, so we start from scratch.
-    RestartTimer(base::TimeDelta::FromMilliseconds(kShowDelay));
+    RestartTimer(kShowDelay);
   }
 }
 
@@ -352,7 +352,7 @@
 void StatusBubbleViews::StatusView::StartHiding() {
   if (state_ == BUBBLE_SHOWN) {
     state_ = BUBBLE_HIDING_TIMER;
-    StartTimer(base::TimeDelta::FromMilliseconds(kHideDelay));
+    StartTimer(kHideDelay);
   } else if (state_ == BUBBLE_SHOWING_FADE) {
     state_ = BUBBLE_HIDING_FADE;
     // Figure out where we are in the current fade.
@@ -371,7 +371,7 @@
   if (state_ == BUBBLE_HIDDEN) {
     GetWidget()->ShowInactive();
     state_ = BUBBLE_SHOWING_TIMER;
-    StartTimer(base::TimeDelta::FromMilliseconds(kShowDelay));
+    StartTimer(kShowDelay);
   } else if (state_ == BUBBLE_HIDING_TIMER) {
     state_ = BUBBLE_SHOWN;
     CancelTimer();
diff --git a/chrome/browser/ui/views/tabs/tab_drag_controller.cc b/chrome/browser/ui/views/tabs/tab_drag_controller.cc
index 398d39a0..210ca66 100644
--- a/chrome/browser/ui/views/tabs/tab_drag_controller.cc
+++ b/chrome/browser/ui/views/tabs/tab_drag_controller.cc
@@ -69,21 +69,20 @@
 
 namespace {
 
-// Delay, in ms, during dragging before we bring a window to front.
-const int kBringToFrontDelay = 750;
-
 // Initial delay before moving tabs when the dragged tab is close to the edge of
 // the stacked tabs.
-const int kMoveAttachedInitialDelay = 600;
+constexpr auto kMoveAttachedInitialDelay =
+    base::TimeDelta::FromMilliseconds(600);
 
 // Delay for moving tabs after the initial delay has passed.
-const int kMoveAttachedSubsequentDelay = 300;
+constexpr auto kMoveAttachedSubsequentDelay =
+    base::TimeDelta::FromMilliseconds(300);
 
 // A dragged window is forced to be a bit smaller than maximized bounds during a
 // drag. This prevents the dragged browser widget from getting maximized at
 // creation and makes it easier to drag tabs out of a restored window that had
 // maximized size.
-const int kMaximizedWindowInset = 10;  // DIPs.
+constexpr int kMaximizedWindowInset = 10;  // DIPs.
 
 #if defined(OS_CHROMEOS)
 
@@ -804,7 +803,7 @@
   }
   if (current_state_ == DragState::kDraggingWindow) {
     bring_to_front_timer_.Start(
-        FROM_HERE, base::TimeDelta::FromMilliseconds(kBringToFrontDelay),
+        FROM_HERE, base::TimeDelta::FromMilliseconds(750),
         base::Bind(&TabDragController::BringWindowUnderPointToFront,
                    base::Unretained(this), point_in_screen));
   }
@@ -1020,7 +1019,7 @@
 
 void TabDragController::StartMoveStackedTimerIfNecessary(
     const gfx::Point& point_in_screen,
-    int delay_ms) {
+    base::TimeDelta delay) {
   DCHECK(attached_context_);
 
   base::Optional<int> touch_index = attached_context_->GetActiveTouchIndex();
@@ -1032,13 +1031,13 @@
   if (attached_context_->ShouldDragToNextStackedTab(
           bounds, *touch_index, mouse_has_ever_moved_right_)) {
     move_stacked_timer_.Start(
-        FROM_HERE, base::TimeDelta::FromMilliseconds(delay_ms),
+        FROM_HERE, delay,
         base::Bind(&TabDragController::MoveAttachedToNextStackedIndex,
                    base::Unretained(this), point_in_screen));
   } else if (attached_context_->ShouldDragToPreviousStackedTab(
                  bounds, *touch_index, mouse_has_ever_moved_left_)) {
     move_stacked_timer_.Start(
-        FROM_HERE, base::TimeDelta::FromMilliseconds(delay_ms),
+        FROM_HERE, delay,
         base::Bind(&TabDragController::MoveAttachedToPreviousStackedIndex,
                    base::Unretained(this), point_in_screen));
   }
diff --git a/chrome/browser/ui/views/tabs/tab_drag_controller.h b/chrome/browser/ui/views/tabs/tab_drag_controller.h
index 970713a..4b31f0d 100644
--- a/chrome/browser/ui/views/tabs/tab_drag_controller.h
+++ b/chrome/browser/ui/views/tabs/tab_drag_controller.h
@@ -305,9 +305,8 @@
 
   // If necessary starts the |move_stacked_timer_|. The timer is started if
   // close enough to an edge with stacked tabs.
-  void StartMoveStackedTimerIfNecessary(
-      const gfx::Point& point_in_screen,
-      int delay_ms);
+  void StartMoveStackedTimerIfNecessary(const gfx::Point& point_in_screen,
+                                        base::TimeDelta delay);
 
   // Returns the TabDragContext for the specified window, or NULL if
   // one doesn't exist or isn't compatible.
diff --git a/chrome/browser/ui/views/toolbar/toolbar_action_view.cc b/chrome/browser/ui/views/toolbar/toolbar_action_view.cc
index 375c75bb..3122001 100644
--- a/chrome/browser/ui/views/toolbar/toolbar_action_view.cc
+++ b/chrome/browser/ui/views/toolbar/toolbar_action_view.cc
@@ -40,15 +40,6 @@
 
 using views::LabelButtonBorder;
 
-namespace {
-
-// Toolbar action buttons have no insets because the badges are drawn right at
-// the edge of the view's area. Other badding (such as centering the icon) is
-// handled directly by the Image.
-const int kBorderInset = 0;
-
-}  // namespace
-
 ////////////////////////////////////////////////////////////////////////////////
 // ToolbarActionView::Delegate
 
@@ -121,8 +112,10 @@
     const {
   std::unique_ptr<LabelButtonBorder> border =
       LabelButton::CreateDefaultBorder();
-  border->set_insets(
-      gfx::Insets(kBorderInset, kBorderInset, kBorderInset, kBorderInset));
+  // Toolbar action buttons have no insets because the badges are drawn right at
+  // the edge of the view's area. Other padding (such as centering the icon) is
+  // handled directly by the Image.
+  border->set_insets(gfx::Insets());
   return border;
 }
 
diff --git a/chrome/browser/ui/views/toolbar/toolbar_button.cc b/chrome/browser/ui/views/toolbar/toolbar_button.cc
index e620189..b3167d5 100644
--- a/chrome/browser/ui/views/toolbar/toolbar_button.cc
+++ b/chrome/browser/ui/views/toolbar/toolbar_button.cc
@@ -141,7 +141,7 @@
 void ToolbarButton::SetLabelSideSpacing(int spacing) {
   gfx::Insets label_insets;
   // Add the spacing only if text is non-empty.
-  if (GetText().empty()) {
+  if (!GetText().empty()) {
     // Add spacing to the opposing side.
     if (GetHorizontalAlignment() == gfx::ALIGN_RIGHT) {
       label_insets = gfx::Insets(0, spacing, 0, 0);
@@ -218,13 +218,12 @@
     y_position_on_lbuttondown_ = event.y();
 
     // Schedule a task that will show the menu.
-    const int kMenuTimerDelay = 500;
     base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
         FROM_HERE,
         base::BindOnce(&ToolbarButton::ShowDropDownMenu,
                        show_menu_factory_.GetWeakPtr(),
                        ui::GetMenuSourceTypeForEvent(event)),
-        base::TimeDelta::FromMilliseconds(kMenuTimerDelay));
+        base::TimeDelta::FromMilliseconds(500));
   }
 
   return LabelButton::OnMousePressed(event);
diff --git a/chrome/browser/ui/views/web_apps/web_app_frame_toolbar_view.cc b/chrome/browser/ui/views/web_apps/web_app_frame_toolbar_view.cc
index 77c7c68..607ebe9 100644
--- a/chrome/browser/ui/views/web_apps/web_app_frame_toolbar_view.cc
+++ b/chrome/browser/ui/views/web_apps/web_app_frame_toolbar_view.cc
@@ -172,9 +172,9 @@
         std::move(model), delegate,
         views::CustomFrameView::GetWindowTitleFontList());
     // Padding around content setting icons.
-    constexpr int kContentSettingIconInteriorPadding = 4;
-    image_view->SetBorder(views::CreateEmptyBorder(
-        gfx::Insets(kContentSettingIconInteriorPadding)));
+    constexpr auto kContentSettingIconInteriorPadding = gfx::Insets(4);
+    image_view->SetBorder(
+        views::CreateEmptyBorder(kContentSettingIconInteriorPadding));
     image_view->disable_animation();
     views::SetHitTestComponent(image_view.get(), static_cast<int>(HTCLIENT));
     content_setting_views_.push_back(image_view.get());
diff --git a/chrome/browser/ui/views/webauthn/authenticator_qr_sheet_view.cc b/chrome/browser/ui/views/webauthn/authenticator_qr_sheet_view.cc
index 0e6abbc..18fa6bd 100644
--- a/chrome/browser/ui/views/webauthn/authenticator_qr_sheet_view.cc
+++ b/chrome/browser/ui/views/webauthn/authenticator_qr_sheet_view.cc
@@ -90,7 +90,7 @@
   ~QRView() override {}
 
   void RefreshQRCode(const uint8_t new_qr_data[QRCode::kInputBytes]) {
-    state_++;
+    state_ = (state_ + 1) % 6;
     qr_tiles_ = qr_.Generate(new_qr_data);
     SchedulePaint();
   }
@@ -108,7 +108,7 @@
     // kV is the intensity of the colors in the QR code.
     constexpr uint8_t kV = 0x70;
     SkColor on;
-    switch (state_ % 6) {
+    switch (state_) {
       case 0:
         on = SkColorSetARGB(0xff, kV, 0, 0);
         break;
@@ -175,7 +175,7 @@
 
     for (int y = 0; y < rows; y++) {
       uint8_t current_byte;
-      unsigned bits = 0;
+      int bits = 0;
 
       for (int x = 0; x < kDinoWidth; x++) {
         if (bits == 0) {
@@ -198,7 +198,7 @@
 
   QRCode qr_;
   base::span<const uint8_t, QRCode::kTotalSize> qr_tiles_;
-  unsigned state_ = 0;
+  int state_ = 0;
 
   DISALLOW_COPY_AND_ASSIGN(QRView);
 };
diff --git a/chrome/browser/ui/webui/chromeos/add_supervision/add_supervision_ui_browsertest.cc b/chrome/browser/ui/webui/chromeos/add_supervision/add_supervision_ui_browsertest.cc
index 74557d8..f0995d1 100644
--- a/chrome/browser/ui/webui/chromeos/add_supervision/add_supervision_ui_browsertest.cc
+++ b/chrome/browser/ui/webui/chromeos/add_supervision/add_supervision_ui_browsertest.cc
@@ -204,6 +204,39 @@
   ASSERT_TRUE(ConfirmSignoutDialog::IsShowing());
 }
 
+IN_PROC_BROWSER_TEST_F(AddSupervisionBrowserTest, UMATest) {
+  base::HistogramTester histogram_tester;
+  base::UserActionTester user_action_tester;
+
+  // Should see 0 Add Supervision enrollment metrics at first.
+  histogram_tester.ExpectTotalCount("AddSupervisionDialog.Enrollment", 0);
+
+  // Should see 0 user actions at first.
+  EXPECT_EQ(user_action_tester.GetActionCount(
+                "AddSupervisionDialog_AttemptedSignoutAfterEnrollment"),
+            0);
+
+  // Open the Add Supervision URL.
+  ui_test_utils::NavigateToURL(browser(), add_supervision_webui_url());
+  content::WaitForLoadStop(contents());
+
+  // Simulate supervision being enabled.
+  ASSERT_TRUE(content::ExecuteScript(
+      contents(), std::string(kGetAddSupervisionUIElementJS) +
+                      std::string(".server.notifySupervisionEnabled()")));
+
+  // Should see 1 Add Supervision process completed.
+  histogram_tester.ExpectUniqueSample(
+      "AddSupervisionDialog.Enrollment",
+      AddSupervisionMetricsRecorder::EnrollmentState::kCompleted, 1);
+  histogram_tester.ExpectTotalCount("AddSupervisionDialog.Enrollment", 1);
+
+  // Should see 1 EnrollmentCompleted action.
+  EXPECT_EQ(user_action_tester.GetActionCount(
+                "AddSupervisionDialog_EnrollmentCompleted"),
+            1);
+}
+
 #endif  // !defined(MEMORY_SANITIZER)
 
 }  // namespace chromeos
diff --git a/chrome/browser/ui/webui/chromeos/assistant_optin/assistant_optin_ui.cc b/chrome/browser/ui/webui/chromeos/assistant_optin/assistant_optin_ui.cc
index e91c9555..1098869 100644
--- a/chrome/browser/ui/webui/chromeos/assistant_optin/assistant_optin_ui.cc
+++ b/chrome/browser/ui/webui/chromeos/assistant_optin/assistant_optin_ui.cc
@@ -27,6 +27,7 @@
 #include "content/public/browser/web_ui_data_source.h"
 #include "content/public/common/content_features.h"
 #include "net/base/url_util.h"
+#include "ui/chromeos/resources/grit/ui_chromeos_resources.h"
 #include "ui/views/widget/widget.h"
 #include "ui/wm/core/window_animations.h"
 
@@ -80,6 +81,9 @@
   source->AddResourcePath("assistant_logo.png", IDR_ASSISTANT_LOGO_PNG);
   source->AddBoolean("hotwordDspAvailable", chromeos::IsHotwordDspAvailable());
   source->SetDefaultResource(IDR_ASSISTANT_OPTIN_HTML);
+  source->AddResourcePath("voice_match_animation.json",
+                          IDR_ASSISTANT_VOICE_MATCH_ANIMATION);
+  source->OverrideContentSecurityPolicyWorkerSrc("worker-src blob: 'self';");
   content::WebUIDataSource::Add(Profile::FromWebUI(web_ui), source);
 
   // Do not zoom for Assistant opt-in web contents.
diff --git a/chrome/browser/ui/webui/signin/signin_error_ui.cc b/chrome/browser/ui/webui/signin/signin_error_ui.cc
index 5a6f3eff..e7739d6 100644
--- a/chrome/browser/ui/webui/signin/signin_error_ui.cc
+++ b/chrome/browser/ui/webui/signin/signin_error_ui.cc
@@ -132,6 +132,9 @@
               .GetAllProfilesAttributes();
       DCHECK(!email.empty());
       for (const ProfileAttributesEntry* entry : entries) {
+        if (!entry->IsAuthenticated())
+          continue;
+
         if (gaia::AreEmailsSame(base::UTF16ToUTF8(email),
                                 base::UTF16ToUTF8(entry->GetUserName()))) {
           handler->set_duplicate_profile_path(entry->GetPath());
diff --git a/chrome/browser/ui/webui/signin/signin_utils_desktop.cc b/chrome/browser/ui/webui/signin/signin_utils_desktop.cc
index 80d414c..9352d98 100644
--- a/chrome/browser/ui/webui/signin/signin_utils_desktop.cc
+++ b/chrome/browser/ui/webui/signin/signin_utils_desktop.cc
@@ -85,6 +85,9 @@
                 .GetAllProfilesAttributes();
 
         for (const ProfileAttributesEntry* entry : entries) {
+          if (!entry->IsAuthenticated())
+            continue;
+
           // For backward compatibility, need to check also the username of the
           // profile, since the GAIA ID may not have been set yet in the
           // ProfileAttributesStorage.  It will be set once the profile
diff --git a/chrome/chrome_cleaner/os/disk_util.cc b/chrome/chrome_cleaner/os/disk_util.cc
index 19aea33..8528e67b 100644
--- a/chrome/chrome_cleaner/os/disk_util.cc
+++ b/chrome/chrome_cleaner/os/disk_util.cc
@@ -304,42 +304,6 @@
   }
 }
 
-bool CollectPathsRecursivelyWithLimits(const base::FilePath& file_path,
-                                       size_t max_files,
-                                       size_t max_filesize,
-                                       bool allow_folders,
-                                       FilePathSet* paths) {
-  DCHECK(paths);
-
-  FilePathSet collected_paths;
-  collected_paths.Insert(file_path);
-
-  size_t count_files = 0;
-  base::FileEnumerator file_enum(
-      file_path, true,
-      base::FileEnumerator::FILES | base::FileEnumerator::DIRECTORIES);
-  for (base::FilePath file = file_enum.Next(); !file.empty();
-       file = file_enum.Next()) {
-    if (count_files >= max_files)
-      return false;
-    ++count_files;
-
-    base::FileEnumerator::FileInfo file_info = file_enum.GetInfo();
-    if (file_info.IsDirectory()) {
-      if (!allow_folders)
-        return false;
-    } else {
-      if (static_cast<size_t>(file_info.GetSize()) >= max_filesize)
-        return false;
-    }
-
-    collected_paths.Insert(file);
-  }
-
-  paths->CopyFrom(collected_paths);
-  return true;
-}
-
 bool PathContainsWildcards(const base::FilePath& file_path) {
   base::FilePath::StringType name(file_path.value());
   return NameContainsWildcards(name);
diff --git a/chrome/chrome_cleaner/os/disk_util.h b/chrome/chrome_cleaner/os/disk_util.h
index 5d69ed72a..70a31af 100644
--- a/chrome/chrome_cleaner/os/disk_util.h
+++ b/chrome/chrome_cleaner/os/disk_util.h
@@ -47,17 +47,6 @@
 void CollectMatchingPaths(const base::FilePath& root_path,
                           std::vector<base::FilePath>* matches);
 
-// Collect files and folders under |file_path| and add them to |paths|.
-// |max_files| limits the number of files to be added to |pup|. Returns false if
-// a file is bigger than |max_filesize| a file has a greater size than
-// |max_filesize| or if a folder is found when |allow_folders| is false. |paths|
-// is left unchanged when this function returns false.
-bool CollectPathsRecursivelyWithLimits(const base::FilePath& file_path,
-                                       size_t max_files,
-                                       size_t max_filesize,
-                                       bool allow_folders,
-                                       FilePathSet* paths);
-
 // Return true when a file path contains the wild-card characters '*' or '?'.
 bool PathContainsWildcards(const base::FilePath& file_path);
 
diff --git a/chrome/chrome_cleaner/pup_data/BUILD.gn b/chrome/chrome_cleaner/pup_data/BUILD.gn
index 6dc889dd..c0b924b 100644
--- a/chrome/chrome_cleaner/pup_data/BUILD.gn
+++ b/chrome/chrome_cleaner/pup_data/BUILD.gn
@@ -11,8 +11,6 @@
   sources = [
     "pup_data.cc",
     "pup_data.h",
-    "pup_disk_util.cc",
-    "pup_disk_util.h",
     "uws_catalog.h",
   ]
 
@@ -81,7 +79,6 @@
     "dynamic_pup_unittest.cc",
     "pup_cleaner_util_unittest.cc",
     "pup_data_unittest.cc",
-    "pup_disk_util_unittest.cc",
   ]
 
   deps = [
diff --git a/chrome/chrome_cleaner/pup_data/pup_disk_util.cc b/chrome/chrome_cleaner/pup_data/pup_disk_util.cc
deleted file mode 100644
index 5cf1cf4..0000000
--- a/chrome/chrome_cleaner/pup_data/pup_disk_util.cc
+++ /dev/null
@@ -1,46 +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/chrome_cleaner/pup_data/pup_disk_util.h"
-
-#include "base/files/file_enumerator.h"
-#include "base/files/file_path.h"
-#include "base/files/file_util.h"
-#include "base/logging.h"
-#include "chrome/chrome_cleaner/os/disk_util.h"
-
-namespace chrome_cleaner {
-
-void CollectPathsRecursively(const base::FilePath& file_path,
-                             PUPData::PUP* pup) {
-  DCHECK(pup);
-
-  // Avoid enumerating the folder content if the folder is already in the pup's
-  // disk footprints.
-  if (!pup->AddDiskFootprint(file_path))
-    return;
-
-  base::FileEnumerator file_enum(
-      file_path,
-      true,
-      base::FileEnumerator::FILES | base::FileEnumerator::DIRECTORIES);
-  for (base::FilePath file = file_enum.Next(); !file.empty();
-       file = file_enum.Next()) {
-    pup->AddDiskFootprint(file);
-  }
-}
-
-bool CollectPathsRecursivelyWithLimits(const base::FilePath& file_path,
-                                       size_t max_files,
-                                       size_t max_filesize,
-                                       bool allow_folders,
-                                       PUPData::PUP* pup) {
-  return CollectPathsRecursivelyWithLimits(file_path,
-                                           max_files,
-                                           max_filesize,
-                                           allow_folders,
-                                           &pup->expanded_disk_footprints);
-}
-
-}  // namespace chrome_cleaner
diff --git a/chrome/chrome_cleaner/pup_data/pup_disk_util.h b/chrome/chrome_cleaner/pup_data/pup_disk_util.h
deleted file mode 100644
index 8969999..0000000
--- a/chrome/chrome_cleaner/pup_data/pup_disk_util.h
+++ /dev/null
@@ -1,35 +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_CHROME_CLEANER_PUP_DATA_PUP_DISK_UTIL_H_
-#define CHROME_CHROME_CLEANER_PUP_DATA_PUP_DISK_UTIL_H_
-
-#include <vector>
-
-#include "chrome/chrome_cleaner/pup_data/pup_data.h"
-
-namespace base {
-class FilePath;
-}
-
-namespace chrome_cleaner {
-
-// Collect files and folders under |file_path| and add them to |pup|.
-void CollectPathsRecursively(const base::FilePath& file_path,
-                             PUPData::PUP* pup);
-
-// Collect files and folders under |file_path| and add them to |pup|.
-// |max_files| limits the number of files to be added to |pup|. Returns false if
-// a file is bigger than |max_filesize| a file has a greater size than
-// |max_filesize| or if a folder is found when |allow_folders| is false. |pup|
-// is left unchanged when this function returns false.
-bool CollectPathsRecursivelyWithLimits(const base::FilePath& file_path,
-                                       size_t max_files,
-                                       size_t max_filesize,
-                                       bool allow_folders,
-                                       PUPData::PUP* pup);
-
-}  // namespace chrome_cleaner
-
-#endif  // CHROME_CHROME_CLEANER_PUP_DATA_PUP_DISK_UTIL_H_
diff --git a/chrome/chrome_cleaner/pup_data/pup_disk_util_unittest.cc b/chrome/chrome_cleaner/pup_data/pup_disk_util_unittest.cc
deleted file mode 100644
index 2c108d1f..0000000
--- a/chrome/chrome_cleaner/pup_data/pup_disk_util_unittest.cc
+++ /dev/null
@@ -1,128 +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/chrome_cleaner/pup_data/pup_disk_util.h"
-
-#include "base/files/file_path.h"
-#include "base/files/file_util.h"
-#include "base/files/scoped_temp_dir.h"
-#include "chrome/chrome_cleaner/os/disk_util.h"
-#include "chrome/chrome_cleaner/os/file_path_set.h"
-#include "chrome/chrome_cleaner/pup_data/pup_cleaner_util.h"
-#include "chrome/chrome_cleaner/test/test_file_util.h"
-#include "chrome/chrome_cleaner/test/test_pup_data.h"
-#include "chrome/chrome_cleaner/test/test_registry_util.h"
-#include "testing/gmock/include/gmock/gmock.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace chrome_cleaner {
-
-namespace {
-
-const wchar_t kFileName1[] = L"Filename one";
-const wchar_t kFileName2[] = L"Filename two";
-const wchar_t kFileName3[] = L"Third filename";
-const wchar_t kSubFolder[] = L"folder";
-const char kFileContent1[] = "This is the file content.";
-const char kFileContent2[] = "Hi!";
-const char kFileContent3[] = "Hello World!";
-
-}  // namespace
-
-class PUPDiskUtilTests : public testing::Test {
- public:
-  void SetUp() override {
-    ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
-    ASSERT_TRUE(base::CreateTemporaryDirInDir(
-        temp_dir_.GetPath(), kSubFolder, &subfolder_path_));
-  }
-
-  base::FilePath CreateFileInTopDir(const base::FilePath& basename,
-                                    const char* content,
-                                    size_t content_length) {
-    base::FilePath file_path = temp_dir_.GetPath().Append(basename);
-    CreateFileWithContent(file_path, content, content_length);
-    return file_path;
-  }
-
-  base::FilePath CreateFileInSubfolder(const base::FilePath& basename,
-                                       const char* content,
-                                       size_t content_length) {
-    base::FilePath file_path = subfolder_path_.Append(basename);
-    CreateFileWithContent(file_path, content, content_length);
-    return file_path;
-  }
-
- protected:
-  base::ScopedTempDir temp_dir_;
-  base::FilePath subfolder_path_;
-};
-
-TEST_F(PUPDiskUtilTests, CollectPathsRecursively) {
-  base::FilePath file_path1 = CreateFileInTopDir(
-      base::FilePath(kFileName1), kFileContent1, sizeof(kFileContent1));
-  base::FilePath file_path2 = CreateFileInTopDir(
-      base::FilePath(kFileName2), kFileContent2, sizeof(kFileContent2));
-  base::FilePath file_path3 = CreateFileInSubfolder(
-      base::FilePath(kFileName3), kFileContent3, sizeof(kFileContent3));
-
-  SimpleTestPUP pup;
-  CollectPathsRecursively(temp_dir_.GetPath(), &pup);
-
-  // Adding the same path twice, should not add it again.
-  CollectPathsRecursively(temp_dir_.GetPath(), &pup);
-  FilePathSet expected_file_paths;
-  expected_file_paths.Insert(temp_dir_.GetPath());
-  expected_file_paths.Insert(file_path1);
-  expected_file_paths.Insert(file_path2);
-  expected_file_paths.Insert(subfolder_path_);
-  expected_file_paths.Insert(file_path3);
-
-  EXPECT_EQ(expected_file_paths, pup.expanded_disk_footprints);
-}
-
-TEST_F(PUPDiskUtilTests, CollectPathsRecursivelyWithLimits) {
-  base::FilePath file_path1 = CreateFileInTopDir(
-      base::FilePath(kFileName1), kFileContent1, sizeof(kFileContent1));
-  base::FilePath file_path2 = CreateFileInTopDir(
-      base::FilePath(kFileName2), kFileContent2, sizeof(kFileContent2));
-  base::FilePath file_path3 = CreateFileInSubfolder(
-      base::FilePath(kFileName3), kFileContent3, sizeof(kFileContent3));
-
-  static const bool kAllowFolders = true;
-  static const bool kForbidFolders = false;
-  static const size_t kSmallFileSizes = 5;
-  static const size_t kLargeFileSizes = 50000;
-  // Collect only 1 file: must fail because there is more than 1 file.
-  SimpleTestPUP pup;
-  EXPECT_FALSE(CollectPathsRecursivelyWithLimits(
-      temp_dir_.GetPath(), 1, kLargeFileSizes, kAllowFolders, &pup));
-  EXPECT_TRUE(pup.expanded_disk_footprints.empty());
-
-  // Collect files with a small file limit: must fail.
-  pup.ClearDiskFootprints();
-  EXPECT_FALSE(CollectPathsRecursivelyWithLimits(
-      temp_dir_.GetPath(), 5, kSmallFileSizes, kAllowFolders, &pup));
-  EXPECT_TRUE(pup.expanded_disk_footprints.empty());
-
-  // Collect a folder: must fail with |kForbidFolders|.
-  pup.ClearDiskFootprints();
-  EXPECT_FALSE(CollectPathsRecursivelyWithLimits(
-      temp_dir_.GetPath(), 5, kLargeFileSizes, kForbidFolders, &pup));
-  EXPECT_TRUE(pup.expanded_disk_footprints.empty());
-
-  // Collect 5 files: must pass.
-  pup.ClearDiskFootprints();
-  EXPECT_TRUE(CollectPathsRecursivelyWithLimits(
-      temp_dir_.GetPath(), 5, kLargeFileSizes, kAllowFolders, &pup));
-  FilePathSet expected_file_paths;
-  expected_file_paths.Insert(temp_dir_.GetPath());
-  expected_file_paths.Insert(file_path1);
-  expected_file_paths.Insert(file_path2);
-  expected_file_paths.Insert(file_path3);
-  expected_file_paths.Insert(subfolder_path_);
-  EXPECT_EQ(expected_file_paths, pup.expanded_disk_footprints);
-}
-
-}  // namespace chrome_cleaner
diff --git a/chrome/chrome_cleaner/scanner/BUILD.gn b/chrome/chrome_cleaner/scanner/BUILD.gn
index d1d4a59..f837a525 100644
--- a/chrome/chrome_cleaner/scanner/BUILD.gn
+++ b/chrome/chrome_cleaner/scanner/BUILD.gn
@@ -25,7 +25,6 @@
     "//base",
     "//chrome/chrome_cleaner/constants:common_strings",
     "//chrome/chrome_cleaner/os:common_os",
-    "//chrome/chrome_cleaner/pup_data:pup_data_base",
     "//chrome/chrome_cleaner/scanner:signature_matcher_api",
     "//chrome/chrome_cleaner/settings",
     "//chrome/chrome_cleaner/strings",
diff --git a/chrome/chrome_cleaner/scanner/matcher_util.cc b/chrome/chrome_cleaner/scanner/matcher_util.cc
index 5897d3d..17ea84f2 100644
--- a/chrome/chrome_cleaner/scanner/matcher_util.cc
+++ b/chrome/chrome_cleaner/scanner/matcher_util.cc
@@ -24,125 +24,11 @@
 #include "chrome/chrome_cleaner/os/file_path_sanitization.h"
 #include "chrome/chrome_cleaner/os/registry_util.h"
 #include "chrome/chrome_cleaner/os/task_scheduler.h"
-#include "chrome/chrome_cleaner/pup_data/pup_disk_util.h"
 #include "chrome/chrome_cleaner/scanner/signature_matcher_api.h"
 #include "chrome/chrome_cleaner/strings/string_util.h"
 
 namespace chrome_cleaner {
 
-namespace {
-// The maximum file size for computing the digest of listed files.
-const size_t kMaxFileSizeToLog = 2 * kMegaByte;
-
-void LogFile(const base::FilePath& file_path) {
-  if (IsFileSizeLessThan(file_path, kMaxFileSizeToLog)) {
-    std::string digest;
-    if (ComputeSHA256DigestOfPath(file_path, &digest)) {
-      LOG(INFO) << " -- '" << SanitizePath(file_path)
-                << "' digest = " << digest;
-    } else {
-      LOG(ERROR) << "Failed to get digest for : '" << SanitizePath(file_path)
-                 << "'.";
-    }
-  } else {
-    LOG(INFO) << " -- '" << SanitizePath(file_path) << "'";
-  }
-}
-
-}  // namespace
-
-const size_t kKiloByte = 1024;         // File size in bytes.
-const size_t kMegaByte = 1024 * 1024;  // File size in bytes.
-// The maximum number of files to log when listing the content of a folder.
-const size_t kMaxFilesInFolderToLog = 10;
-
-bool IsFileSizeLessThan(const base::FilePath& path, size_t size) {
-  int64_t file_size = 0;
-  return (base::GetFileSize(path, &file_size) &&
-          static_cast<size_t>(file_size) < size);
-}
-
-bool MatchSingleFileWithPattern(const base::FilePath& root_path,
-                                const base::string16& pattern,
-                                bool include_folders,
-                                base::FilePath* match) {
-  DCHECK(match);
-
-  base::FilePath match_found;
-  bool found_one = false;
-
-  int file_type = base::FileEnumerator::FILES;
-  if (include_folders)
-    file_type |= base::FileEnumerator::DIRECTORIES;
-
-  if (NameContainsWildcards(pattern)) {
-    base::FileEnumerator file_enum(root_path, false, file_type, pattern);
-    for (base::FilePath file = file_enum.Next(); !file.empty();
-         file = file_enum.Next()) {
-      if (NameMatchesPattern(file.BaseName().value(), pattern, 0)) {
-        if (found_one) {
-          return false;
-        } else {
-          match_found = file;
-          found_one = true;
-        }
-      }
-    }
-  } else {
-    match_found = root_path.Append(pattern);
-    if (base::PathExists(match_found))
-      found_one = true;
-  }
-
-  if (found_one)
-    *match = match_found;
-  return found_one;
-}
-
-void DeleteSoftwareRegistryKeys(const base::string16& software_key_path,
-                                PUPData::PUP* pup) {
-  DCHECK(pup);
-  PUPData::DeleteRegistryKeyIfPresent(
-      RegKeyPath(HKEY_CURRENT_USER, software_key_path.c_str(), KEY_WOW64_32KEY),
-      pup);
-  PUPData::DeleteRegistryKeyIfPresent(
-      RegKeyPath(HKEY_LOCAL_MACHINE, software_key_path.c_str(),
-                 KEY_WOW64_32KEY),
-      pup);
-  PUPData::DeleteRegistryKeyIfPresent(
-      RegKeyPath(HKEY_CURRENT_USER, software_key_path.c_str(), KEY_WOW64_64KEY),
-      pup);
-  PUPData::DeleteRegistryKeyIfPresent(
-      RegKeyPath(HKEY_LOCAL_MACHINE, software_key_path.c_str(),
-                 KEY_WOW64_64KEY),
-      pup);
-}
-
-void CollectPathRecursively(const base::FilePath& path, PUPData::PUP* pup) {
-  DCHECK(pup);
-  if (base::PathExists(path))
-    CollectPathsRecursively(path, pup);
-}
-
-void CollectSinglePath(const base::FilePath& path, PUPData::PUP* pup) {
-  DCHECK(pup);
-  if (base::PathExists(path) && !base::DirectoryExists(path))
-    pup->AddDiskFootprint(path);
-}
-
-void CollectDiskFootprintRecursively(int csidl,
-                                     const base::char16* path,
-                                     PUPData::PUP* pup) {
-  DCHECK_NE(csidl, PUPData::kInvalidCsidl);
-  DCHECK(path);
-
-  base::FilePath expanded_path(
-      ExpandSpecialFolderPath(csidl, base::FilePath(path)));
-  if (expanded_path.empty())
-    return;
-  CollectPathRecursively(expanded_path, pup);
-}
-
 bool IsKnownFileByDigest(const base::FilePath& path,
                          const SignatureMatcherAPI* signature_matcher,
                          const char* const digests[],
@@ -234,42 +120,4 @@
   return false;
 }
 
-void LogFoundDigest(const base::FilePath file_path,
-                    const char* prefix,
-                    PUPData::PUP* pup) {
-  DCHECK(prefix);
-  std::string digest;
-  int64_t size = -1;
-  if (!base::GetFileSize(file_path, &size))
-    PLOG(ERROR) << "Failed to get size for: '" << SanitizePath(file_path)
-                << "'.";
-
-  if (ComputeSHA256DigestOfPath(file_path, &digest)) {
-    LOG(INFO) << "Found digest for " << prefix << ", path: '"
-              << SanitizePath(file_path) << "', digest: '" << digest
-              << "', size: '" << size << "'.";
-  } else {
-    LOG(INFO) << "Failed to get digest for " << prefix << ", path: '"
-              << SanitizePath(file_path) << "', size: '" << size << "'.";
-  }
-}
-
-void LogFoundDigest(const base::FilePath file_path, const char* prefix) {
-  LogFoundDigest(file_path, prefix, nullptr);
-}
-
-void LogFolderContent(const base::FilePath& folder_path) {
-  base::FileEnumerator file_enum(folder_path, true,
-                                 base::FileEnumerator::FILES);
-  size_t nb_files = 0;
-  for (base::FilePath file_path = file_enum.Next(); !file_path.empty();
-       file_path = file_enum.Next()) {
-    LogFile(file_path);
-    if (++nb_files > kMaxFilesInFolderToLog) {
-      LOG(INFO) << "The folder contains too many files.";
-      return;
-    }
-  }
-}
-
 }  // namespace chrome_cleaner
diff --git a/chrome/chrome_cleaner/scanner/matcher_util.h b/chrome/chrome_cleaner/scanner/matcher_util.h
index c792c14..a02a7fd 100644
--- a/chrome/chrome_cleaner/scanner/matcher_util.h
+++ b/chrome/chrome_cleaner/scanner/matcher_util.h
@@ -10,8 +10,6 @@
 #include <vector>
 
 #include "base/strings/string16.h"
-#include "chrome/chrome_cleaner/pup_data/pup_data.h"
-#include "chrome/chrome_cleaner/settings/matching_options.h"
 
 namespace base {
 class FilePath;
@@ -21,33 +19,6 @@
 
 class SignatureMatcherAPI;
 
-extern const size_t kKiloByte;
-extern const size_t kMegaByte;
-extern const size_t kMaxFilesInFolderToLog;  // Exposed for unittests.
-
-// Return whether the file |path| has a smaller size than |size|.
-bool IsFileSizeLessThan(const base::FilePath& path, size_t size);
-
-// Find a single matching file for |pattern| located in |root_path|. Wild-cards
-// are allowed in |pattern| only. |include_folders| flag controls whether or not
-// the folders should be taken into account. |match| is set to the matching file
-// path. If none or more than one file are found, the function returns false.
-bool MatchSingleFileWithPattern(const base::FilePath& root_path,
-                                const base::string16& pattern,
-                                bool include_folders,
-                                base::FilePath* match);
-
-void DeleteSoftwareRegistryKeys(const base::string16& software_key_path,
-                                PUPData::PUP* pup);
-
-void CollectSinglePath(const base::FilePath& path, PUPData::PUP* pup);
-
-void CollectPathRecursively(const base::FilePath& path, PUPData::PUP* pup);
-
-void CollectDiskFootprintRecursively(int csidl,
-                                     const base::char16* path,
-                                     PUPData::PUP* pup);
-
 bool IsKnownFileByDigest(const base::FilePath& path,
                          const SignatureMatcherAPI* signature_matcher,
                          const char* const digests[],
@@ -77,17 +48,6 @@
                               const base::char16* const names[],
                               size_t names_length);
 
-// Log the found digest of |file_path| described by |prefix|.
-void LogFoundDigest(const base::FilePath file_path,
-                    const char* prefix,
-                    PUPData::PUP* pup);
-
-// This is equivalent to the above LogFoundDigest(file_path, prefix, nullptr).
-void LogFoundDigest(const base::FilePath file_path, const char* prefix);
-
-// This is equivalent to the above LogFolderContent(folder_path, nullptr).
-void LogFolderContent(const base::FilePath& folder_path);
-
 }  // namespace chrome_cleaner
 
 #endif  // CHROME_CHROME_CLEANER_SCANNER_MATCHER_UTIL_H_
diff --git a/chrome/chrome_cleaner/scanner/matcher_util_unittest.cc b/chrome/chrome_cleaner/scanner/matcher_util_unittest.cc
index 940ba19..0802a5a 100644
--- a/chrome/chrome_cleaner/scanner/matcher_util_unittest.cc
+++ b/chrome/chrome_cleaner/scanner/matcher_util_unittest.cc
@@ -249,201 +249,4 @@
                                        base::size(kKnownCompanyNames)));
 }
 
-TEST(MatcherUtilTest, MatchSingleFileWithPattern) {
-  base::ScopedTempDir temp_dir;
-  ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
-  base::FilePath match;
-
-  // Collect no path.
-  EXPECT_FALSE(
-      MatchSingleFileWithPattern(temp_dir.GetPath(), L"*", false, &match));
-
-  // Collect exactly one path matching the pattern.
-  base::FilePath file_path1(temp_dir.GetPath().Append(L"dummy.1.tar.gz"));
-  base::FilePath file_path2(temp_dir.GetPath().Append(L"uws-name.exe"));
-  CreateFileWithContent(file_path1, kFileContent, sizeof(kFileContent));
-  CreateFileWithContent(file_path2, kFileContent, sizeof(kFileContent));
-  match.clear();
-  EXPECT_TRUE(MatchSingleFileWithPattern(temp_dir.GetPath(), L"*.*.*.*", false,
-                                         &match));
-  EXPECT_EQ(file_path1, match);
-  match.clear();
-  EXPECT_TRUE(MatchSingleFileWithPattern(temp_dir.GetPath(), L"uws*.exe", false,
-                                         &match));
-  EXPECT_EQ(file_path2, match);
-  match.clear();
-  EXPECT_TRUE(MatchSingleFileWithPattern(temp_dir.GetPath(), LR"(uws-????.exe)",
-                                         false, &match));
-  EXPECT_EQ(file_path2, match);
-
-  // Collecting multiple paths should fail.
-  base::FilePath file_path3(temp_dir.GetPath().Append(L"dummy.2.tar.gz"));
-  CreateFileWithContent(file_path3, kFileContent, sizeof(kFileContent));
-  EXPECT_FALSE(MatchSingleFileWithPattern(temp_dir.GetPath(), L"*.*.*.*", false,
-                                          &match));
-}
-
-TEST(MatcherUtilTest, MatchSingleFileWithPatternWithFolders) {
-  base::ScopedTempDir temp_dir;
-  ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
-  base::FilePath match;
-
-  // Collect no path.
-  EXPECT_FALSE(
-      MatchSingleFileWithPattern(temp_dir.GetPath(), L"*", true, &match));
-
-  // Add a folder to the main folder.
-  base::FilePath folder = temp_dir.GetPath().Append(L"folder");
-  ASSERT_TRUE(base::CreateDirectory(folder));
-
-  // Collect exactly one path matching the pattern.
-  base::FilePath file_path(temp_dir.GetPath().Append(L"dummy.1.tar.gz"));
-  CreateFileWithContent(file_path, kFileContent, sizeof(kFileContent));
-
-  match.clear();
-  EXPECT_TRUE(MatchSingleFileWithPattern(temp_dir.GetPath(), L"*.*.*.*", false,
-                                         &match));
-  EXPECT_EQ(file_path, match);
-
-  match.clear();
-  EXPECT_TRUE(
-      MatchSingleFileWithPattern(temp_dir.GetPath(), L"*.*.*.*", true, &match));
-  EXPECT_EQ(file_path, match);
-
-  // Collect with a wild-card matching everything.
-  match.clear();
-  EXPECT_TRUE(
-      MatchSingleFileWithPattern(temp_dir.GetPath(), L"*", false, &match));
-  EXPECT_EQ(file_path, match);
-
-  match.clear();
-  EXPECT_FALSE(
-      MatchSingleFileWithPattern(temp_dir.GetPath(), L"*", true, &match));
-  EXPECT_TRUE(match.empty());
-
-  // Collecting the folder.
-  EXPECT_FALSE(
-      MatchSingleFileWithPattern(temp_dir.GetPath(), L"fold?r", false, &match));
-  EXPECT_TRUE(match.empty());
-
-  EXPECT_TRUE(
-      MatchSingleFileWithPattern(temp_dir.GetPath(), L"fold?r", true, &match));
-  EXPECT_EQ(folder, match);
-}
-
-TEST(MatcherUtilTest, CollectPathRecursively) {
-  base::ScopedTempDir temp_dir;
-  ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
-
-  // Add a folder to the main folder.
-  base::FilePath folder = temp_dir.GetPath().Append(L"folder");
-  ASSERT_TRUE(base::CreateDirectory(folder));
-  base::FilePath subfolder = folder.Append(L"subfolder");
-  ASSERT_TRUE(base::CreateDirectory(subfolder));
-
-  base::FilePath file_path1(folder.Append(kFileName1));
-  CreateFileWithContent(file_path1, kFileContent, sizeof(kFileContent));
-  base::FilePath file_path2(subfolder.Append(kFileName2));
-  CreateFileWithContent(file_path2, kFileContent, sizeof(kFileContent));
-
-  base::FilePath nonexistent_path = temp_dir.GetPath().Append(L"nonexistent");
-
-  SimpleTestPUP pup;
-  CollectPathRecursively(nonexistent_path, &pup);
-  EXPECT_TRUE(pup.expanded_disk_footprints.empty());
-
-  CollectPathRecursively(folder, &pup);
-  EXPECT_FALSE(pup.expanded_disk_footprints.empty());
-
-  ExpectDiskFootprint(pup, folder);
-  ExpectDiskFootprint(pup, subfolder);
-  ExpectDiskFootprint(pup, file_path1);
-  ExpectDiskFootprint(pup, file_path2);
-}
-
-TEST(MatcherUtilTest, CollectDiskFootprintRecursively) {
-  base::FilePath local_appdata_path(
-      ExpandSpecialFolderPath(CSIDL_LOCAL_APPDATA, base::FilePath()));
-  base::ScopedTempDir temp_dir;
-  ASSERT_TRUE(temp_dir.CreateUniqueTempDirUnderPath(local_appdata_path));
-
-  // Add a folder to the main folder.
-  base::FilePath folder = temp_dir.GetPath().Append(L"folder");
-  ASSERT_TRUE(base::CreateDirectory(folder));
-  base::FilePath subfolder = folder.Append(L"subfolder");
-  ASSERT_TRUE(base::CreateDirectory(subfolder));
-
-  base::FilePath file_path1(folder.Append(kFileName1));
-  CreateFileWithContent(file_path1, kFileContent, sizeof(kFileContent));
-  base::FilePath file_path2(subfolder.Append(kFileName2));
-  CreateFileWithContent(file_path2, kFileContent, sizeof(kFileContent));
-
-  // Create the relative paths.
-  base::FilePath basename = temp_dir.GetPath().BaseName();
-  base::FilePath folder_path = basename.Append(L"Folder");
-  base::FilePath not_folder_path = basename.Append(L"not_Folder");
-
-  SimpleTestPUP pup;
-  // Collect in the wrong CSIDL.
-  CollectDiskFootprintRecursively(CSIDL_APPDATA, folder_path.value().c_str(),
-                                  &pup);
-  EXPECT_TRUE(pup.expanded_disk_footprints.empty());
-
-  // Collect in the good CSIDL but an inexisting folder.
-  CollectDiskFootprintRecursively(CSIDL_LOCAL_APPDATA,
-                                  not_folder_path.value().c_str(), &pup);
-  EXPECT_TRUE(pup.expanded_disk_footprints.empty());
-
-  // Collect the right files.
-  CollectDiskFootprintRecursively(CSIDL_LOCAL_APPDATA,
-                                  folder_path.value().c_str(), &pup);
-  EXPECT_FALSE(pup.expanded_disk_footprints.empty());
-
-  ExpectDiskFootprint(pup, folder);
-  ExpectDiskFootprint(pup, subfolder);
-  ExpectDiskFootprint(pup, file_path1);
-  ExpectDiskFootprint(pup, file_path2);
-}
-
-TEST_F(LoggingTest, LogFolderContent) {
-  base::ScopedTempDir temp_dir;
-  ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
-  base::FilePath temp_dir_path = temp_dir.GetPath();
-  base::FilePath file_path1(temp_dir_path.Append(kFileName1));
-  base::FilePath file_path2(temp_dir_path.Append(kFileName2));
-  CreateFileWithContent(file_path1, kFileContent, sizeof(kFileContent));
-  CreateFileWithContent(file_path2, kFileContent, sizeof(kFileContent));
-
-  // Add a folder to the main folder.
-  base::FilePath subfolder = temp_dir.GetPath().Append(L"folder");
-  ASSERT_TRUE(base::CreateDirectory(subfolder));
-  base::FilePath file_path3(subfolder.Append(kFileName3));
-  CreateFileWithContent(file_path3, kFileContent, sizeof(kFileContent));
-
-  LOG(INFO) << "Logging content of " << temp_dir.GetPath().value();
-
-  LogFolderContent(temp_dir.GetPath());
-
-  const std::string filename1 = base::WideToUTF8(kFileName1);
-  const std::string filename2 = base::WideToUTF8(kFileName2);
-  const std::string filename3 = base::WideToUTF8(kFileName3);
-  EXPECT_TRUE(logger_.LoggingMessagesContain(filename1));
-  EXPECT_TRUE(logger_.LoggingMessagesContain(filename2));
-  EXPECT_TRUE(logger_.LoggingMessagesContain(filename3));
-
-  // Add more files in the folder than maximum to be logged.
-  logger_.FlushMessages();
-  for (size_t count = 0; count < kMaxFilesInFolderToLog; ++count) {
-    base::FilePath file_path(temp_dir_path.Append(
-        base::StrCat({L"dummy", base::NumberToString16(count)})));
-    CreateFileWithContent(file_path, kFileContent, sizeof(kFileContent));
-  }
-
-  LOG(INFO) << "Logging content of " << temp_dir.GetPath().value();
-  LogFolderContent(temp_dir.GetPath());
-
-  EXPECT_TRUE(
-      logger_.LoggingMessagesContain("The folder contains too many files"));
-}
-
 }  // namespace chrome_cleaner
diff --git a/chrome/installer/mac/signing/pipeline.py b/chrome/installer/mac/signing/pipeline.py
index 898c0d4..f801c3b 100644
--- a/chrome/installer/mac/signing/pipeline.py
+++ b/chrome/installer/mac/signing/pipeline.py
@@ -118,35 +118,62 @@
         notarize.staple(os.path.join(paths.work, part_path))
 
 
-def _package_and_sign_dmg(paths, dist_config):
-    """Packages, signs, and verifies a DMG for a signed build product.
+def _package_and_sign_item(packager, paths, dist_config):
+    """Creates, signs, and verifies a packaged item (PKG/DMG).
 
     Args:
+        packager: A function that turns the .app into a packaged item and
+            returns the path to the packaged item. The function will be called
+            with (model.Paths, model.Distribution, config.CodeSignConfig).
         paths: A |model.Paths| object.
-        dist_config: A |config.CodeSignConfig| for the |dist|.
+        dist_config: The |config.CodeSignConfig| object.
 
     Returns:
-        The path to the signed DMG file.
+        The path to the signed packaged file.
     """
     dist = dist_config.distribution
 
-    dmg_path = _package_dmg(paths, dist, dist_config)
+    package_path = packager(paths, dist, dist_config)
 
-    # dmg_identifier is like dmg_name but without the .dmg suffix. If a
-    # brand code is in use, use the actual brand code instead of the
-    # name fragment, to avoid leaking the association between brand
-    # codes and their meanings.
-    dmg_identifier = dist_config.packaging_basename
+    # item_identifier is the PKG/DMG name but without the file extension. If a
+    # brand code is in use, use the actual brand code instead of the name
+    # fragment, to avoid leaking the association between brand codes and their
+    # meanings.
+    item_identifier = dist_config.packaging_basename
     if dist.branding_code:
-        dmg_identifier = dist_config.packaging_basename.replace(
+        item_identifier = dist_config.packaging_basename.replace(
             dist.packaging_name_fragment, dist.branding_code)
 
     product = model.CodeSignedProduct(
-        dmg_path, dmg_identifier, sign_with_identifier=True)
+        package_path, item_identifier, sign_with_identifier=True)
     signing.sign_part(paths, dist_config, product)
     signing.verify_part(paths, product)
 
-    return dmg_path
+    return package_path
+
+
+def _package_pkg(paths, dist, config):
+    """Packages a Chrome application bundle into a PKG.
+
+    Args:
+        paths: A |model.Paths| object.
+        dist: The |model.Distribution| for which the product was customized.
+        config: The |config.CodeSignConfig| object.
+
+    Returns:
+        A path to the produced PKG file.
+    """
+    pkg_path = os.path.join(paths.output,
+                            '{}.pkg'.format(config.packaging_basename))
+    app_path = os.path.join(paths.work, config.app_dir)
+
+    commands.run_command([
+        'pkgbuild', '--identifier', config.base_bundle_id, '--version',
+        config.version, '--component', app_path, '--install-location',
+        '/Applications', pkg_path
+    ])
+
+    return pkg_path
 
 
 def _package_dmg(paths, dist, config):
@@ -247,6 +274,22 @@
                              cwd=paths.work)
 
 
+def _intermediate_work_dir_name(dist_config):
+    """Returns the name of an intermediate work directory for a distribution.
+
+    Args:
+        dist_config: A |config.CodeSignConfig| for the |model.Distribution|.
+
+    Returns:
+        The work directory name to use.
+    """
+    if dist_config.distribution.branding_code:
+        return '{}-{}'.format(dist_config.packaging_basename,
+                              dist_config.distribution.branding_code)
+
+    return dist_config.packaging_basename
+
+
 def sign_all(orig_paths, config, disable_packaging=False, do_notarization=True):
     """For each distribution in |config|, performs customization, signing, and
     DMG packaging and places the resulting signed DMG in |orig_paths.output|.
@@ -282,8 +325,8 @@
                 else:
                     dest_dir = notary_paths.work
 
-                dest_dir = os.path.join(dest_dir,
-                                        dist_config.packaging_basename)
+                dest_dir = os.path.join(
+                    dest_dir, _intermediate_work_dir_name(dist_config))
                 _customize_and_sign_chrome(paths, dist_config, dest_dir,
                                            signed_frameworks)
 
@@ -306,8 +349,8 @@
             for result in notarize.wait_for_results(uuids_to_config.keys(),
                                                     config):
                 dist_config = uuids_to_config[result]
-                dest_dir = os.path.join(notary_paths.work,
-                                        dist_config.packaging_basename)
+                dest_dir = os.path.join(
+                    notary_paths.work, _intermediate_work_dir_name(dist_config))
                 _staple_chrome(notary_paths.replace_work(dest_dir), dist_config)
 
         # After all apps are optionally notarized, package as required.
@@ -315,21 +358,25 @@
             uuids_to_package_path = {}
             for dist in config.distributions:
                 dist_config = dist.to_config(config)
+                paths = orig_paths.replace_work(
+                    os.path.join(notary_paths.work,
+                                 _intermediate_work_dir_name(dist_config)))
 
                 if dist.package_as_dmg:
-                    paths = orig_paths.replace_work(
-                        os.path.join(notary_paths.work,
-                                     dist_config.packaging_basename))
-
-                    dmg_path = _package_and_sign_dmg(paths, dist_config)
+                    dmg_path = _package_and_sign_item(_package_dmg, paths,
+                                                      dist_config)
 
                     if do_notarization:
                         uuid = notarize.submit(dmg_path, dist_config)
                         uuids_to_package_path[uuid] = dmg_path
 
                 if dist.package_as_pkg:
-                    # TODO(avi): Do packaging as a pkg here.
-                    pass
+                    pkg_path = _package_and_sign_item(_package_pkg, paths,
+                                                      dist_config)
+
+                    if do_notarization:
+                        uuid = notarize.submit(pkg_path, dist_config)
+                        uuids_to_package_path[uuid] = pkg_path
 
             # Wait for packaging notarization results to come back, stapling as
             # they do.
diff --git a/chrome/installer/mac/signing/pipeline_test.py b/chrome/installer/mac/signing/pipeline_test.py
index 958b0d14..82f2adb 100644
--- a/chrome/installer/mac/signing/pipeline_test.py
+++ b/chrome/installer/mac/signing/pipeline_test.py
@@ -240,18 +240,20 @@
             mock.call('$W/App Product Canary.app')
         ])
 
-    def test_package_and_sign_no_branding(self, **kwargs):
+    def test_package_and_sign_dmg_no_branding(self, **kwargs):
         manager = mock.Mock()
         for attr in kwargs:
             manager.attach_mock(kwargs[attr], attr)
 
         config = test_config.TestConfig()
-        dist = model.Distribution()
+        dist = model.Distribution(package_as_dmg=True, package_as_pkg=False)
         dist_config = dist.to_config(config)
 
         paths = self.paths.replace_work('$W')
-        self.assertEqual('$O/AppProduct-99.0.9999.99.dmg',
-                         pipeline._package_and_sign_dmg(paths, dist_config))
+        self.assertEqual(
+            '$O/AppProduct-99.0.9999.99.dmg',
+            pipeline._package_and_sign_item(pipeline._package_dmg, paths,
+                                            dist_config))
 
         manager.assert_has_calls([
             mock.call.make_dir('$W/empty'),
@@ -272,19 +274,55 @@
         self.assertEqual('AppProduct-99.0.9999.99',
                          kwargs['sign_part'].mock_calls[0][1][2].identifier)
 
-    def test_package_and_sign_branding(self, **kwargs):
+    def test_package_and_sign_pkg_no_branding(self, **kwargs):
+        manager = mock.Mock()
+        for attr in kwargs:
+            manager.attach_mock(kwargs[attr], attr)
+
+        config = test_config.TestConfig()
+        dist = model.Distribution(package_as_dmg=False, package_as_pkg=True)
+        dist_config = dist.to_config(config)
+
+        paths = self.paths.replace_work('$W')
+        self.assertEqual(
+            '$O/AppProduct-99.0.9999.99.pkg',
+            pipeline._package_and_sign_item(pipeline._package_pkg, paths,
+                                            dist_config))
+
+        manager.assert_has_calls([
+            mock.call.run_command(mock.ANY),
+            mock.call.sign_part(paths, dist_config, mock.ANY),
+            mock.call.verify_part(paths, mock.ANY)
+        ])
+
+        run_command = [
+            call for call in manager.mock_calls if call[0] == 'run_command'
+        ][0]
+        pkgbuild_args = run_command[1][0]
+
+        self.assertEqual('test.signing.bundle_id',
+                         _get_adjacent_item(pkgbuild_args, '--identifier'))
+        self.assertEqual('99.0.9999.99',
+                         _get_adjacent_item(pkgbuild_args, '--version'))
+
+    def test_package_and_sign_dmg_branding(self, **kwargs):
         manager = mock.Mock()
         for attr in kwargs:
             manager.attach_mock(kwargs[attr], attr)
 
         config = test_config.TestConfig()
         dist = model.Distribution(
-            branding_code='MOO', packaging_name_fragment='ForCows')
+            branding_code='MOO',
+            packaging_name_fragment='ForCows',
+            package_as_dmg=True,
+            package_as_pkg=False)
         dist_config = dist.to_config(config)
 
         paths = self.paths.replace_work('$W')
-        self.assertEqual('$O/AppProduct-99.0.9999.99-ForCows.dmg',
-                         pipeline._package_and_sign_dmg(paths, dist_config))
+        self.assertEqual(
+            '$O/AppProduct-99.0.9999.99-ForCows.dmg',
+            pipeline._package_and_sign_item(pipeline._package_dmg, paths,
+                                            dist_config))
 
         manager.assert_has_calls([
             mock.call.make_dir('$W/empty'),
@@ -305,6 +343,41 @@
         self.assertEqual('AppProduct-99.0.9999.99-MOO',
                          kwargs['sign_part'].mock_calls[0][1][2].identifier)
 
+    def test_package_and_sign_pkg_branding(self, **kwargs):
+        manager = mock.Mock()
+        for attr in kwargs:
+            manager.attach_mock(kwargs[attr], attr)
+
+        config = test_config.TestConfig()
+        dist = model.Distribution(
+            branding_code='MOO',
+            packaging_name_fragment='ForCows',
+            package_as_dmg=False,
+            package_as_pkg=True)
+        dist_config = dist.to_config(config)
+
+        paths = self.paths.replace_work('$W')
+        self.assertEqual(
+            '$O/AppProduct-99.0.9999.99-ForCows.pkg',
+            pipeline._package_and_sign_item(pipeline._package_pkg, paths,
+                                            dist_config))
+
+        manager.assert_has_calls([
+            mock.call.run_command(mock.ANY),
+            mock.call.sign_part(paths, dist_config, mock.ANY),
+            mock.call.verify_part(paths, mock.ANY)
+        ])
+
+        run_command = [
+            call for call in manager.mock_calls if call[0] == 'run_command'
+        ][0]
+        pkgbuild_args = run_command[1][0]
+
+        self.assertEqual('test.signing.bundle_id',
+                         _get_adjacent_item(pkgbuild_args, '--identifier'))
+        self.assertEqual('99.0.9999.99',
+                         _get_adjacent_item(pkgbuild_args, '--version'))
+
     def test_package_dmg_no_customize(self, **kwargs):
         dist = model.Distribution()
         config = test_config.TestConfig()
@@ -451,7 +524,7 @@
     'signing.pipeline', **{
         m: mock.DEFAULT
         for m in ('_customize_and_sign_chrome', '_staple_chrome',
-                  '_package_and_sign_dmg', '_package_installer_tools')
+                  '_package_and_sign_item', '_package_installer_tools')
     })
 @mock.patch('signing.commands.tempfile.mkdtemp', _get_work_dir)
 class TestSignAll(unittest.TestCase):
@@ -460,7 +533,7 @@
         _get_work_dir.count = 0
         self.paths = model.Paths('$I', '$O', None)
 
-    def test_sign_basic_distribution(self, **kwargs):
+    def test_sign_basic_distribution_dmg(self, **kwargs):
         manager = mock.Mock()
         for attr in kwargs:
             manager.attach_mock(kwargs[attr], attr)
@@ -471,10 +544,25 @@
         kwargs['wait_for_results'].side_effect = [
             iter([app_uuid]), iter([dmg_uuid])
         ]
-        kwargs[
-            '_package_and_sign_dmg'].return_value = '$O/AppProduct-99.0.9999.99.dmg'
 
-        config = test_config.TestConfig()
+        def package_and_sign_side_effect(packager, paths, dist_config):
+            if packager == pipeline._package_dmg:
+                return '$O/AppProduct-99.0.9999.99.dmg'
+            assert False
+
+        kwargs[
+            '_package_and_sign_item'].side_effect = package_and_sign_side_effect
+
+        class Config(test_config.TestConfig):
+
+            @property
+            def distributions(self):
+                return [
+                    model.Distribution(
+                        package_as_dmg=True, package_as_pkg=False),
+                ]
+
+        config = Config()
         pipeline.sign_all(self.paths, config)
 
         self.assertEqual(1, kwargs['_package_installer_tools'].call_count)
@@ -500,7 +588,8 @@
                 mock.ANY),
 
             # Make the DMG.
-            mock.call._package_and_sign_dmg(mock.ANY, mock.ANY),
+            mock.call._package_and_sign_item(pipeline._package_dmg, mock.ANY,
+                                             mock.ANY),
 
             # Notarize the DMG.
             mock.call.submit('$O/AppProduct-99.0.9999.99.dmg', mock.ANY),
@@ -514,6 +603,156 @@
             mock.call._package_installer_tools(mock.ANY, mock.ANY),
         ])
 
+    def test_sign_basic_distribution_pkg(self, **kwargs):
+        manager = mock.Mock()
+        for attr in kwargs:
+            manager.attach_mock(kwargs[attr], attr)
+
+        app_uuid = 'b2ce64e5-4fae-4043-9c20-d9ff53065b2a'
+        pkg_uuid = 'cb811baf-5d35-4caa-adf4-1f61b4991eed'
+        kwargs['submit'].side_effect = [app_uuid, pkg_uuid]
+        kwargs['wait_for_results'].side_effect = [
+            iter([app_uuid]), iter([pkg_uuid])
+        ]
+
+        def package_and_sign_side_effect(packager, paths, dist_config):
+            if packager == pipeline._package_pkg:
+                return '$O/AppProduct-99.0.9999.99.pkg'
+            assert False
+
+        kwargs[
+            '_package_and_sign_item'].side_effect = package_and_sign_side_effect
+
+        class Config(test_config.TestConfig):
+
+            @property
+            def distributions(self):
+                return [
+                    model.Distribution(
+                        package_as_dmg=False, package_as_pkg=True),
+                ]
+
+        config = Config()
+        pipeline.sign_all(self.paths, config)
+
+        self.assertEqual(1, kwargs['_package_installer_tools'].call_count)
+
+        manager.assert_has_calls([
+            # First customize the distribution and sign it.
+            mock.call._customize_and_sign_chrome(
+                mock.ANY, mock.ANY, '$W_1/AppProduct-99.0.9999.99', mock.ANY),
+
+            # Prepare the app for notarization.
+            mock.call.run_command([
+                'zip', '--recurse-paths', '--symlinks', '--quiet',
+                '$W_1/AppProduct-99.0.9999.99.zip', 'App Product.app'
+            ],
+                                  cwd='$W_1/AppProduct-99.0.9999.99'),
+            mock.call.submit('$W_1/AppProduct-99.0.9999.99.zip', mock.ANY),
+            mock.call.shutil.rmtree('$W_2'),
+            mock.call.wait_for_results({
+                app_uuid: None
+            }.keys(), mock.ANY),
+            mock.call._staple_chrome(
+                self.paths.replace_work('$W_1/AppProduct-99.0.9999.99'),
+                mock.ANY),
+
+            # Make the DMG.
+            mock.call._package_and_sign_item(pipeline._package_pkg, mock.ANY,
+                                             mock.ANY),
+
+            # Notarize the DMG.
+            mock.call.submit('$O/AppProduct-99.0.9999.99.pkg', mock.ANY),
+            mock.call.wait_for_results({
+                pkg_uuid: None
+            }.keys(), mock.ANY),
+            mock.call.staple('$O/AppProduct-99.0.9999.99.pkg'),
+            mock.call.shutil.rmtree('$W_1'),
+
+            # Package the installer tools.
+            mock.call._package_installer_tools(mock.ANY, mock.ANY),
+        ])
+
+    def test_sign_basic_distribution_dmg_pkg(self, **kwargs):
+        manager = mock.Mock()
+        for attr in kwargs:
+            manager.attach_mock(kwargs[attr], attr)
+
+        app_uuid = '6de7df90-cf07-4213-9ce6-45f83588a386'
+        dmg_uuid = '7f77eefd-6c9d-4271-9367-760dc78a49dd'
+        pkg_uuid = '364d9b29-a0a0-4661-b366-e35449197671'
+        kwargs['submit'].side_effect = [app_uuid, dmg_uuid, pkg_uuid]
+        kwargs['wait_for_results'].side_effect = [
+            iter([app_uuid]), iter([dmg_uuid, pkg_uuid])
+        ]
+
+        def package_and_sign_side_effect(packager, paths, dist_config):
+            if packager == pipeline._package_dmg:
+                return '$O/AppProduct-99.0.9999.99.dmg'
+            if packager == pipeline._package_pkg:
+                return '$O/AppProduct-99.0.9999.99.pkg'
+            assert False
+
+        kwargs[
+            '_package_and_sign_item'].side_effect = package_and_sign_side_effect
+
+        class Config(test_config.TestConfig):
+
+            @property
+            def distributions(self):
+                return [
+                    model.Distribution(
+                        package_as_dmg=True, package_as_pkg=True),
+                ]
+
+        config = Config()
+        pipeline.sign_all(self.paths, config)
+
+        self.assertEqual(1, kwargs['_package_installer_tools'].call_count)
+
+        manager.assert_has_calls([
+            # First customize the distribution and sign it.
+            mock.call._customize_and_sign_chrome(
+                mock.ANY, mock.ANY, '$W_1/AppProduct-99.0.9999.99', mock.ANY),
+
+            # Prepare the app for notarization.
+            mock.call.run_command([
+                'zip', '--recurse-paths', '--symlinks', '--quiet',
+                '$W_1/AppProduct-99.0.9999.99.zip', 'App Product.app'
+            ],
+                                  cwd='$W_1/AppProduct-99.0.9999.99'),
+            mock.call.submit('$W_1/AppProduct-99.0.9999.99.zip', mock.ANY),
+            mock.call.shutil.rmtree('$W_2'),
+            mock.call.wait_for_results({
+                app_uuid: None
+            }.keys(), mock.ANY),
+            mock.call._staple_chrome(
+                self.paths.replace_work('$W_1/AppProduct-99.0.9999.99'),
+                mock.ANY),
+
+            # Make the DMG, and submit for notarization.
+            mock.call._package_and_sign_item(pipeline._package_dmg, mock.ANY,
+                                             mock.ANY),
+            mock.call.submit('$O/AppProduct-99.0.9999.99.dmg', mock.ANY),
+
+            # Make the PKG, and submit for notarization.
+            mock.call._package_and_sign_item(pipeline._package_pkg, mock.ANY,
+                                             mock.ANY),
+            mock.call.submit('$O/AppProduct-99.0.9999.99.pkg', mock.ANY),
+
+            # Wait for notarization results.
+            mock.call.wait_for_results({
+                dmg_uuid: None,
+                pkg_uuid: None
+            }.keys(), mock.ANY),
+            mock.call.staple('$O/AppProduct-99.0.9999.99.dmg'),
+            mock.call.staple('$O/AppProduct-99.0.9999.99.pkg'),
+            mock.call.shutil.rmtree('$W_1'),
+
+            # Package the installer tools.
+            mock.call._package_installer_tools(mock.ANY, mock.ANY),
+        ])
+
     def test_sign_no_packaging(self, **kwargs):
         manager = mock.Mock()
         for attr in kwargs:
@@ -571,7 +810,8 @@
             mock.call.shutil.rmtree('$W_2'),
 
             # Make the DMG.
-            mock.call._package_and_sign_dmg(mock.ANY, mock.ANY),
+            mock.call._package_and_sign_item(pipeline._package_dmg, mock.ANY,
+                                             mock.ANY),
             mock.call.shutil.rmtree('$W_1'),
 
             # Package the installer tools.
@@ -606,10 +846,6 @@
         for attr in kwargs:
             manager.attach_mock(kwargs[attr], attr)
 
-        kwargs['submit'].return_value = '6a017701-6545-4f01-bb15-1169443d0e12'
-        kwargs['wait_for_results'].return_value = iter(
-            '6a017701-6545-4f01-bb15-1169443d0e12')
-
         class Config(test_config.TestConfig):
 
             @property
@@ -617,29 +853,67 @@
                 return [
                     model.Distribution(),
                     model.Distribution(
-                        branding_code='MOO', packaging_name_fragment='ForCows'),
+                        branding_code='MOO',
+                        packaging_name_fragment='ForCows',
+                        package_as_dmg=True,
+                        package_as_pkg=False),
+                    model.Distribution(
+                        branding_code='ARF',
+                        packaging_name_fragment='ForDogs',
+                        package_as_dmg=False,
+                        package_as_pkg=True),
+                    model.Distribution(
+                        branding_code='MOOF',
+                        packaging_name_fragment='ForDogcows',
+                        package_as_dmg=True,
+                        package_as_pkg=True),
                 ]
 
         config = Config()
         pipeline.sign_all(self.paths, config, do_notarization=False)
 
         self.assertEqual(1, kwargs['_package_installer_tools'].call_count)
-        self.assertEqual(2, kwargs['_customize_and_sign_chrome'].call_count)
+        self.assertEqual(4, kwargs['_customize_and_sign_chrome'].call_count)
 
         manager.assert_has_calls([
+            # Customizations.
             mock.call._customize_and_sign_chrome(
                 mock.ANY, mock.ANY, '$W_1/AppProduct-99.0.9999.99', mock.ANY),
             mock.call.shutil.rmtree('$W_2'),
             mock.call._customize_and_sign_chrome(
-                mock.ANY, mock.ANY, '$W_1/AppProduct-99.0.9999.99-ForCows',
+                mock.ANY, mock.ANY, '$W_1/AppProduct-99.0.9999.99-ForCows-MOO',
                 mock.ANY),
             mock.call.shutil.rmtree('$W_3'),
-            mock.call._package_and_sign_dmg(
+            mock.call._customize_and_sign_chrome(
+                mock.ANY, mock.ANY, '$W_1/AppProduct-99.0.9999.99-ForDogs-ARF',
+                mock.ANY),
+            mock.call.shutil.rmtree('$W_4'),
+            mock.call._customize_and_sign_chrome(
+                mock.ANY, mock.ANY,
+                '$W_1/AppProduct-99.0.9999.99-ForDogcows-MOOF', mock.ANY),
+            mock.call.shutil.rmtree('$W_5'),
+
+            # Packaging and signing.
+            mock.call._package_and_sign_item(
+                pipeline._package_dmg,
                 self.paths.replace_work('$W_1/AppProduct-99.0.9999.99'),
                 mock.ANY),
-            mock.call._package_and_sign_dmg(
-                self.paths.replace_work('$W_1/AppProduct-99.0.9999.99-ForCows'),
-                mock.ANY),
+            mock.call._package_and_sign_item(
+                pipeline._package_dmg,
+                self.paths.replace_work(
+                    '$W_1/AppProduct-99.0.9999.99-ForCows-MOO'), mock.ANY),
+            mock.call._package_and_sign_item(
+                pipeline._package_pkg,
+                self.paths.replace_work(
+                    '$W_1/AppProduct-99.0.9999.99-ForDogs-ARF'), mock.ANY),
+            mock.call._package_and_sign_item(
+                pipeline._package_dmg,
+                self.paths.replace_work(
+                    '$W_1/AppProduct-99.0.9999.99-ForDogcows-MOOF'), mock.ANY),
+            mock.call._package_and_sign_item(
+                pipeline._package_pkg,
+                self.paths.replace_work(
+                    '$W_1/AppProduct-99.0.9999.99-ForDogcows-MOOF'), mock.ANY),
             mock.call.shutil.rmtree('$W_1'),
 
             # Finally the installer tools.
diff --git a/chrome/installer/util/lzma_util.cc b/chrome/installer/util/lzma_util.cc
index 5ed402f..f7c6ed133 100644
--- a/chrome/installer/util/lzma_util.cc
+++ b/chrome/installer/util/lzma_util.cc
@@ -258,16 +258,29 @@
       break;
     }
 
-    if ((!WriteFile(hFile, outBuffer + offset, (DWORD)outSizeProcessed,
-                    &written, NULL)) ||
-        (written != outSizeProcessed)) {
-      ret = GetLastError();
-      PLOG(ERROR) << L"Error returned by WriteFile";
-      CloseHandle(hFile);
-      unpack_status_ = UNPACK_WRITE_FILE_ERROR;
-      break;
+    // Don't write all of the data at once because this can lead to kernel
+    // address-space exhaustion on 32-bit Windows (see https://crbug.com/1001022
+    // for details).
+    constexpr size_t kMaxWriteAmount = 8 * 1024 * 1024;
+    for (size_t total_written = 0; total_written < outSizeProcessed; /**/) {
+      const size_t write_amount =
+          std::min(kMaxWriteAmount, outSizeProcessed - total_written);
+      if ((!WriteFile(hFile, outBuffer + offset + total_written,
+                      static_cast<DWORD>(write_amount), &written, nullptr)) ||
+          (written != write_amount)) {
+        ret = GetLastError();
+        PLOG(ERROR) << L"Error returned by WriteFile";
+        CloseHandle(hFile);
+        unpack_status_ = UNPACK_WRITE_FILE_ERROR;
+        break;
+      }
+      total_written += write_amount;
     }
 
+    // Break out of the file loop if the write loop failed.
+    if (unpack_status_ != UNPACK_NO_ERROR)
+      break;
+
     if (SzBitWithVals_Check(&db.MTime, i)) {
       if (!SetFileTime(hFile, NULL, NULL,
                        (const FILETIME*)(&db.MTime.Vals[i]))) {
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn
index 7d3b2309..cbf29fd 100644
--- a/chrome/test/BUILD.gn
+++ b/chrome/test/BUILD.gn
@@ -296,6 +296,8 @@
       "../browser/chromeos/settings/scoped_cros_settings_test_helper.h",
       "../browser/component_updater/fake_cros_component_manager.cc",
       "../browser/component_updater/fake_cros_component_manager.h",
+      "../browser/extensions/policy_test_utils.cc",
+      "../browser/extensions/policy_test_utils.h",
       "../browser/ui/ash/accessibility/fake_accessibility_controller.cc",
       "../browser/ui/ash/accessibility/fake_accessibility_controller.h",
       "base/browser_process_platform_part_test_api_chromeos.cc",
@@ -991,6 +993,7 @@
       "../browser/net/websocket_browsertest.cc",
       "../browser/no_best_effort_tasks_browsertest.cc",
       "../browser/no_best_effort_tasks_during_startup_browsertest.cc",
+      "../browser/notifications/scheduler/notification_schedule_service_browsertest.cc",
       "../browser/ntp_snippets/content_suggestions_service_factory_browsertest.cc",
       "../browser/ntp_tiles/ntp_tiles_browsertest.cc",
       "../browser/optimization_guide/optimization_guide_keyed_service_browsertest.cc",
diff --git a/chrome/test/data/webui/cr_elements/cr_lottie_tests.js b/chrome/test/data/webui/cr_elements/cr_lottie_tests.js
index bc7b194..5453071 100644
--- a/chrome/test/data/webui/cr_elements/cr_lottie_tests.js
+++ b/chrome/test/data/webui/cr_elements/cr_lottie_tests.js
@@ -60,6 +60,7 @@
     PolymerTest.clearBody();
     crLottieElement = document.createElement('cr-lottie');
     crLottieElement.animationUrl = SAMPLE_LOTTIE;
+    crLottieElement.autoplay = true;
 
     container = document.createElement('div');
     container.style.width = '300px';
@@ -108,6 +109,26 @@
     await waitForResizeEvent;
   });
 
+  test('TestPlayPause', async () => {
+    const waitForInitializeEvent =
+        test_util.eventToPromise('cr-lottie-initialized', crLottieElement);
+    await waitForInitializeEvent;
+
+    const waitForPlayingEvent =
+        test_util.eventToPromise('cr-lottie-playing', crLottieElement);
+    await waitForPlayingEvent;
+
+    const waitForPauseEvent =
+        test_util.eventToPromise('cr-lottie-paused', crLottieElement);
+    crLottieElement.setPlay(false);
+    await waitForPauseEvent;
+
+    const waitForPlayingEventAgain =
+        test_util.eventToPromise('cr-lottie-playing', crLottieElement);
+    crLottieElement.setPlay(true);
+    await waitForPlayingEventAgain;
+  });
+
   test('TestRenderFrame', async () => {
     // Offscreen canvas has a race issue when used in this test framework. To
     // ensure that we capture a frame from the animation and not an empty frame,
diff --git a/chrome/test/data/webui/settings/chromeos/os_people_page_test.js b/chrome/test/data/webui/settings/chromeos/os_people_page_test.js
index adae196e..9569b9d 100644
--- a/chrome/test/data/webui/settings/chromeos/os_people_page_test.js
+++ b/chrome/test/data/webui/settings/chromeos/os_people_page_test.js
@@ -147,6 +147,8 @@
     test('GAIA name and picture, account manager enabled', async () => {
       loadTimeData.overrideValues({
         isAccountManagerEnabled: true,
+        // settings-account-manager requires this to have a value.
+        secondaryGoogleAccountSigninAllowed: true,
       });
       peoplePage = document.createElement('os-settings-people-page');
       peoplePage.pageVisibility = settings.pageVisibility;
diff --git a/chrome/test/data/webui/settings/chromeos/os_settings_browsertest.js b/chrome/test/data/webui/settings/chromeos/os_settings_browsertest.js
index c651135..0489240 100644
--- a/chrome/test/data/webui/settings/chromeos/os_settings_browsertest.js
+++ b/chrome/test/data/webui/settings/chromeos/os_settings_browsertest.js
@@ -192,7 +192,7 @@
   }
 };
 
-// Disabled due to: https://crbug.com/1003483
+// Flaky in debug. https://crbug.com/1003483
 TEST_F('OSSettingsAppManagementPageTest', 'MAYBE_AllJsTests', () => {
   mocha.run();
 });
@@ -260,7 +260,7 @@
   }
 };
 
-// Disabled due to: https://crbug.com/1003483
+// Flaky in debug. https://crbug.com/1003483
 TEST_F('OSSettingsAppManagementManagedAppTest', 'MAYBE_AllJsTests', () => {
   mocha.run();
 });
@@ -684,6 +684,11 @@
 var OSSettingsPeoplePageAccountManagerTest =
     class extends OSSettingsBrowserTest {
   /** @override */
+  get featureList() {
+    return {enabled: ['chromeos::features::kAccountManager']};
+  }
+
+  /** @override */
   get browsePreload() {
     return super.browsePreload + 'people_page/account_manager.html';
   }
@@ -832,8 +837,7 @@
   }
 };
 
-// Disabled due to: https://crbug.com/1003562
-TEST_F('OSSettingsPeoplePageTest', 'DISABLED_AllJsTests', () => {
+TEST_F('OSSettingsPeoplePageTest', 'AllJsTests', () => {
   mocha.run();
 });
 
@@ -851,7 +855,7 @@
   }
 };
 
-// Disabled due to: https://crbug.com/1003483
+// Flaky in debug. https://crbug.com/1003483
 TEST_F('OSSettingsPersonalizationPageTest', 'MAYBE_AllJsTests', () => {
   mocha.run();
 });
@@ -1008,7 +1012,7 @@
   }
 };
 
-// Disabled due to: https://crbug.com/1003483
+// Flaky in debug. https://crbug.com/1003483
 TEST_F('OSSettingsResetPageTest', 'MAYBE_AllJsTests', () => {
   mocha.run();
 });
diff --git a/chrome/updater/installer.cc b/chrome/updater/installer.cc
index 904c9ed..6da9530 100644
--- a/chrome/updater/installer.cc
+++ b/chrome/updater/installer.cc
@@ -24,12 +24,12 @@
 const char kNullVersion[] = "0.0.0.0";
 
 // Returns the full path to the installation directory for the application
-// identified by the |crx_id|.
-base::FilePath GetAppInstallDir(const std::string& crx_id) {
+// identified by the |app_id|.
+base::FilePath GetAppInstallDir(const std::string& app_id) {
   base::FilePath app_install_dir;
   if (GetProductDirectory(&app_install_dir)) {
     app_install_dir = app_install_dir.AppendASCII(kAppsDir);
-    app_install_dir = app_install_dir.AppendASCII(crx_id);
+    app_install_dir = app_install_dir.AppendASCII(app_id);
   }
   return app_install_dir;
 }
@@ -39,10 +39,8 @@
 Installer::InstallInfo::InstallInfo() : version(kNullVersion) {}
 Installer::InstallInfo::~InstallInfo() = default;
 
-Installer::Installer(const std::vector<uint8_t>& pk_hash)
-    : pk_hash_(pk_hash),
-      crx_id_(update_client::GetCrxIdFromPublicKeyHash(pk_hash)),
-      install_info_(std::make_unique<InstallInfo>()) {}
+Installer::Installer(const std::string& app_id)
+    : app_id_(app_id), install_info_(std::make_unique<InstallInfo>()) {}
 
 Installer::~Installer() = default;
 
@@ -52,17 +50,17 @@
   component.requires_network_encryption = false;
   component.crx_format_requirement =
       crx_file::VerifierFormat::CRX3_WITH_PUBLISHER_PROOF;
-  component.pk_hash = pk_hash_;
-  component.name = crx_id_;
+  component.app_id = app_id_;
+  component.name = app_id_;
   component.version = install_info_->version;
   component.fingerprint = install_info_->fingerprint;
   return component;
 }
 
 void Installer::FindInstallOfApp() {
-  VLOG(1) << __func__ << " for " << crx_id_;
+  VLOG(1) << __func__ << " for " << app_id_;
 
-  const base::FilePath app_install_dir = GetAppInstallDir(crx_id_);
+  const base::FilePath app_install_dir = GetAppInstallDir(app_id_);
   if (app_install_dir.empty() || !base::PathExists(app_install_dir)) {
     install_info_ = std::make_unique<InstallInfo>();
     return;
@@ -124,7 +122,7 @@
   if (install_info_->version.CompareTo(manifest_version) > 0)
     return Result(update_client::InstallError::VERSION_NOT_UPGRADED);
 
-  const base::FilePath app_install_dir = GetAppInstallDir(crx_id_);
+  const base::FilePath app_install_dir = GetAppInstallDir(app_id_);
   if (app_install_dir.empty())
     return Result(update_client::InstallError::NO_DIR_COMPONENT_USER);
   if (!base::CreateDirectory(app_install_dir)) {
@@ -162,7 +160,7 @@
 }
 
 void Installer::OnUpdateError(int error) {
-  LOG(ERROR) << "updater error: " << error << " for " << crx_id_;
+  LOG(ERROR) << "updater error: " << error << " for " << app_id_;
 }
 
 void Installer::Install(const base::FilePath& unpack_path,
diff --git a/chrome/updater/installer.h b/chrome/updater/installer.h
index ef97e84..8ddc6bd 100644
--- a/chrome/updater/installer.h
+++ b/chrome/updater/installer.h
@@ -36,9 +36,9 @@
     DISALLOW_COPY_AND_ASSIGN(InstallInfo);
   };
 
-  explicit Installer(const std::vector<uint8_t>& pk_hash);
+  explicit Installer(const std::string& app_id);
 
-  const std::string crx_id() const { return crx_id_; }
+  const std::string app_id() const { return app_id_; }
 
   // Finds the highest version install of the app, and updates the install
   // info for this installer instance.
@@ -62,8 +62,7 @@
 
   Result InstallHelper(const base::FilePath& unpack_path);
 
-  const std::vector<uint8_t> pk_hash_;
-  const std::string crx_id_;
+  const std::string app_id_;
   std::unique_ptr<InstallInfo> install_info_;
 
   DISALLOW_COPY_AND_ASSIGN(Installer);
diff --git a/chrome/updater/updater.cc b/chrome/updater/updater.cc
index 7dd1947..deacefb 100644
--- a/chrome/updater/updater.cc
+++ b/chrome/updater/updater.cc
@@ -59,12 +59,8 @@
 
 namespace {
 
-// For now, use the Flash CRX for testing.
-// CRX id is mimojjlkmoijpicakmndhoigimigcmbb.
-const uint8_t mimo_hash[] = {0xc8, 0xce, 0x99, 0xba, 0xce, 0x89, 0xf8, 0x20,
-                             0xac, 0xd3, 0x7e, 0x86, 0x8c, 0x86, 0x2c, 0x11,
-                             0xb9, 0x40, 0xc5, 0x55, 0xaf, 0x08, 0x63, 0x70,
-                             0x54, 0xf9, 0x56, 0xd3, 0xe7, 0x88, 0xba, 0x8c};
+// For now, use a specific app ID.
+const char kOmaha4AppId[] = "{44FC7FE2-65CE-487C-93F4-EDEE46EEAAAB}";
 
 void ThreadPoolStart() {
   base::ThreadPoolInstance::CreateAndStartWithDefaultParams("Updater");
@@ -152,8 +148,7 @@
 }
 
 int UpdaterUpdateApps() {
-  auto installer = base::MakeRefCounted<Installer>(
-      std::vector<uint8_t>(std::cbegin(mimo_hash), std::cend(mimo_hash)));
+  auto installer = base::MakeRefCounted<Installer>(kOmaha4AppId);
   installer->FindInstallOfApp();
   const auto component = installer->MakeCrxComponent();
 
@@ -170,7 +165,7 @@
     Observer observer(update_client);
     update_client->AddObserver(&observer);
 
-    const std::vector<std::string> ids = {installer->crx_id()};
+    const std::vector<std::string> ids = {installer->app_id()};
     update_client->Update(
         ids,
         base::BindOnce(
diff --git a/chromecast/browser/BUILD.gn b/chromecast/browser/BUILD.gn
index 710f710..dcbde1ae 100644
--- a/chromecast/browser/BUILD.gn
+++ b/chromecast/browser/BUILD.gn
@@ -386,6 +386,8 @@
       "webview/webview_grpc_service.h",
       "webview/webview_layout_manager.cc",
       "webview/webview_layout_manager.h",
+      "webview/webview_window_manager.cc",
+      "webview/webview_window_manager.h",
     ]
     configs += [ "//third_party/grpc:grpc_config" ]
     deps += [
diff --git a/chromecast/browser/webview/webview_grpc_service.cc b/chromecast/browser/webview/webview_grpc_service.cc
index b702725..9c75e52 100644
--- a/chromecast/browser/webview/webview_grpc_service.cc
+++ b/chromecast/browser/webview/webview_grpc_service.cc
@@ -12,8 +12,6 @@
 #include "chromecast/browser/cast_browser_context.h"
 #include "chromecast/browser/cast_browser_process.h"
 #include "chromecast/browser/webview/webview_controller.h"
-#include "components/exo/surface.h"
-#include "components/exo/wm_helper.h"
 #include "third_party/grpc/src/include/grpcpp/grpcpp.h"
 #include "third_party/grpc/src/include/grpcpp/security/server_credentials.h"
 #include "third_party/grpc/src/include/grpcpp/server_builder.h"
@@ -21,17 +19,6 @@
 namespace chromecast {
 namespace {
 
-aura::Window* FindChildWindowWithID(aura::Window* window, int id) {
-  if (window->GetProperty(exo::kClientSurfaceIdKey) == id)
-    return window;
-  for (auto* w : window->children()) {
-    auto* ret = FindChildWindowWithID(w, id);
-    if (ret)
-      return ret;
-  }
-  return nullptr;
-}
-
 typedef base::RepeatingCallback<void(bool)> GrpcCallback;
 
 // Threading model and life cycle.
@@ -40,11 +27,13 @@
 // no other outstanding read or write operations.
 // Deletion bounces off the webview thread to synchronize with request
 // processing.
-class WebviewRpcInstance : public WebviewController::Client {
+class WebviewRpcInstance : public WebviewController::Client,
+                           public WebviewWindowManager::Observer {
  public:
   WebviewRpcInstance(webview::WebviewService::AsyncService* service,
                      grpc::ServerCompletionQueue* cq,
-                     scoped_refptr<base::SingleThreadTaskRunner> task_runner);
+                     scoped_refptr<base::SingleThreadTaskRunner> task_runner,
+                     WebviewWindowManager* window_manager);
   ~WebviewRpcInstance() override;
 
  private:
@@ -60,9 +49,13 @@
   void ProcessRequestOnWebviewThread(
       std::unique_ptr<webview::WebviewRequest> request);
 
+  // WebviewController::Client:
   void EnqueueSend(std::unique_ptr<webview::WebviewResponse> response) override;
   void OnError(const std::string& error_message) override;
 
+  // WebviewWindowManager::Observer:
+  void OnNewWebviewContainerWindow(aura::Window* window, int app_id) override;
+
   GrpcCallback init_callback_;
   GrpcCallback read_callback_;
   GrpcCallback write_callback_;
@@ -87,14 +80,24 @@
   grpc::WriteOptions write_options_;
   scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
 
+  WebviewWindowManager* window_manager_;
+
+  int app_id_ = 0;
+  int window_id_ = 0;
+
   DISALLOW_COPY_AND_ASSIGN(WebviewRpcInstance);
 };
 
 WebviewRpcInstance::WebviewRpcInstance(
     webview::WebviewService::AsyncService* service,
     grpc::ServerCompletionQueue* cq,
-    scoped_refptr<base::SingleThreadTaskRunner> task_runner)
-    : service_(service), cq_(cq), io_(&ctx_), task_runner_(task_runner) {
+    scoped_refptr<base::SingleThreadTaskRunner> task_runner,
+    WebviewWindowManager* window_manager)
+    : service_(service),
+      cq_(cq),
+      io_(&ctx_),
+      task_runner_(task_runner),
+      window_manager_(window_manager) {
   write_options_.clear_buffer_hint();
   write_options_.clear_corked();
 
@@ -108,6 +111,7 @@
                                           base::Unretained(this));
 
   service_->RequestCreateWebview(&ctx_, &io_, cq_, cq_, &init_callback_);
+  window_manager_->AddObserver(this);
 }
 
 WebviewRpcInstance::~WebviewRpcInstance() {
@@ -115,6 +119,8 @@
   if (webview_) {
     webview_.release()->Destroy();
   }
+
+  window_manager_->RemoveObserver(this);
 }
 
 void WebviewRpcInstance::FinishComplete(bool ok) {
@@ -136,7 +142,7 @@
 
   // Create a new instance to handle new requests.
   // Instances of this class delete themselves.
-  new WebviewRpcInstance(service_, cq_, task_runner_);
+  new WebviewRpcInstance(service_, cq_, task_runner_, window_manager_);
 }
 
 void WebviewRpcInstance::ReadComplete(bool ok) {
@@ -173,18 +179,12 @@
 }
 
 void WebviewRpcInstance::CreateWebview(int app_id, int window_id) {
-  auto* root_window =
-      exo::WMHelper::GetInstance()->GetRootWindowForNewWindows();
-  auto* surface_window = FindChildWindowWithID(root_window, app_id);
-  if (!surface_window) {
-    OnError("Failed to find valid surface to display webview on");
-    return;
-  }
+  app_id_ = app_id;
+  window_id_ = window_id;
 
   content::BrowserContext* browser_context =
       shell::CastBrowserProcess::GetInstance()->browser_context();
   webview_ = std::make_unique<WebviewController>(browser_context, this);
-  webview_->AttachTo(surface_window, window_id);
 
   // Begin reading again.
   io_.Read(request_.get(), &read_callback_);
@@ -230,31 +230,31 @@
   send_pending_ = true;
 }
 
+void WebviewRpcInstance::OnNewWebviewContainerWindow(aura::Window* window,
+                                                     int app_id) {
+  if (app_id != app_id_)
+    return;
+
+  webview_->AttachTo(window, window_id_);
+  // The Webview is attached! No reason to keep on listening for window property
+  // updates.
+  window_manager_->RemoveObserver(this);
+}
+
 }  // namespace
 
 WebviewAsyncService::WebviewAsyncService(
-    scoped_refptr<base::SingleThreadTaskRunner> webview_task_runner)
-    : webview_task_runner_(std::move(webview_task_runner)) {}
-
-WebviewAsyncService::~WebviewAsyncService() {
-  if (server_) {
-    server_->Shutdown();
-    cq_->Shutdown();
-
-    base::PlatformThread::Join(rpc_thread_);
-  }
+    std::unique_ptr<webview::WebviewService::AsyncService> service,
+    std::unique_ptr<grpc::ServerCompletionQueue> cq,
+    scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner)
+    : ui_task_runner_(std::move(ui_task_runner)),
+      cq_(std::move(cq)),
+      service_(std::move(service)) {
+  base::PlatformThread::Create(0, this, &rpc_thread_);
 }
 
-void WebviewAsyncService::StartWithSocket(const base::FilePath& socket_path) {
-  DCHECK(!server_.get());
-
-  grpc::ServerBuilder builder;
-  builder.AddListeningPort("unix:" + socket_path.value(),
-                           grpc::InsecureServerCredentials());
-  builder.RegisterService(&service_);
-  cq_ = builder.AddCompletionQueue();
-  server_ = builder.BuildAndStart();
-  base::PlatformThread::Create(0, this, &rpc_thread_);
+WebviewAsyncService::~WebviewAsyncService() {
+  base::PlatformThread::Join(rpc_thread_);
 }
 
 void WebviewAsyncService::ThreadMain() {
@@ -263,7 +263,8 @@
   void* tag;
   bool ok;
   // This self-deletes.
-  new WebviewRpcInstance(&service_, cq_.get(), webview_task_runner_);
+  new WebviewRpcInstance(service_.get(), cq_.get(), ui_task_runner_,
+                         &window_manager_);
   // This thread is joined when this service is destroyed.
   while (cq_->Next(&tag, &ok)) {
     reinterpret_cast<GrpcCallback*>(tag)->Run(ok);
diff --git a/chromecast/browser/webview/webview_grpc_service.h b/chromecast/browser/webview/webview_grpc_service.h
index 2b99784..29d98eaa 100644
--- a/chromecast/browser/webview/webview_grpc_service.h
+++ b/chromecast/browser/webview/webview_grpc_service.h
@@ -11,6 +11,7 @@
 #include "base/threading/platform_thread.h"
 #include "base/threading/thread_task_runner_handle.h"
 #include "chromecast/browser/webview/proto/webview.grpc.pb.h"
+#include "chromecast/browser/webview/webview_window_manager.h"
 #include "third_party/grpc/src/include/grpcpp/server.h"
 
 namespace chromecast {
@@ -19,21 +20,26 @@
 // webviews. See the proto file for commands.
 class WebviewAsyncService : public base::PlatformThread::Delegate {
  public:
-  explicit WebviewAsyncService(
-      scoped_refptr<base::SingleThreadTaskRunner> webview_task_runner);
+  WebviewAsyncService(
+      std::unique_ptr<webview::WebviewService::AsyncService> service,
+      std::unique_ptr<grpc::ServerCompletionQueue> cq,
+      scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner);
   ~WebviewAsyncService() override;
 
-  // Start the server listening on an address, eg "localhost:12345".
-  void StartWithSocket(const base::FilePath& socket_path);
-
  private:
   void ThreadMain() override;
 
+  // Separate thread to run the gRPC completion queue on.
   base::PlatformThreadHandle rpc_thread_;
-  scoped_refptr<base::SingleThreadTaskRunner> webview_task_runner_;
+
+  // Requests need to be posted back to the browser main UI thread to manage
+  // Webview state.
+  scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner_;
+
   std::unique_ptr<grpc::ServerCompletionQueue> cq_;
-  webview::WebviewService::AsyncService service_;
-  std::unique_ptr<grpc::Server> server_;
+  std::unique_ptr<webview::WebviewService::AsyncService> service_;
+
+  WebviewWindowManager window_manager_;
 
   DISALLOW_COPY_AND_ASSIGN(WebviewAsyncService);
 };
diff --git a/chromecast/browser/webview/webview_window_manager.cc b/chromecast/browser/webview/webview_window_manager.cc
new file mode 100644
index 0000000..e3802cb0
--- /dev/null
+++ b/chromecast/browser/webview/webview_window_manager.cc
@@ -0,0 +1,54 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chromecast/browser/webview/webview_window_manager.h"
+
+#include "components/exo/shell_surface_util.h"
+#include "components/exo/surface.h"
+#include "ui/aura/env.h"
+
+namespace chromecast {
+
+WebviewWindowManager::WebviewWindowManager() {
+  aura::Env::GetInstance()->AddObserver(this);
+}
+
+WebviewWindowManager::~WebviewWindowManager() {
+  aura::Env::GetInstance()->RemoveObserver(this);
+}
+
+void WebviewWindowManager::AddObserver(Observer* observer) {
+  observers_.AddObserver(observer);
+}
+
+void WebviewWindowManager::RemoveObserver(Observer* observer) {
+  observers_.RemoveObserver(observer);
+}
+
+void WebviewWindowManager::OnWindowInitialized(aura::Window* window) {
+  observed_windows_.push_back(window);
+  window->AddObserver(this);
+}
+
+void WebviewWindowManager::OnWindowDestroying(aura::Window* window) {
+  window->RemoveObserver(this);
+  auto it =
+      std::find(observed_windows_.begin(), observed_windows_.end(), window);
+  DCHECK(it != observed_windows_.end());
+  observed_windows_.erase(it);
+}
+
+void WebviewWindowManager::OnWindowPropertyChanged(aura::Window* window,
+                                                   const void* key,
+                                                   intptr_t old) {
+  if (key != exo::kClientSurfaceIdKey)
+    return;
+
+  int app_id = window->GetProperty(exo::kClientSurfaceIdKey);
+  LOG(INFO) << "Found window for webview " << app_id;
+  for (auto& observer : observers_)
+    observer.OnNewWebviewContainerWindow(window, app_id);
+}
+
+}  // namespace chromecast
diff --git a/chromecast/browser/webview/webview_window_manager.h b/chromecast/browser/webview/webview_window_manager.h
new file mode 100644
index 0000000..bc2e17c
--- /dev/null
+++ b/chromecast/browser/webview/webview_window_manager.h
@@ -0,0 +1,52 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROMECAST_BROWSER_WEBVIEW_WEBVIEW_WINDOW_MANAGER_H_
+#define CHROMECAST_BROWSER_WEBVIEW_WEBVIEW_WINDOW_MANAGER_H_
+
+#include "base/observer_list.h"
+#include "ui/aura/env_observer.h"
+#include "ui/aura/window_observer.h"
+
+namespace chromecast {
+
+// Keeps track of new aura::Windows and listen for window property events to
+// find Exo windows with the |exo::kClientSurfaceIdKey| property set.
+class WebviewWindowManager : public aura::EnvObserver,
+                             public aura::WindowObserver {
+ public:
+  class Observer {
+   public:
+    virtual ~Observer() = default;
+
+    // Notifies the observer when a window's |exo::kClientSurfaceIdKey| property
+    // is updated.
+    virtual void OnNewWebviewContainerWindow(aura::Window* window,
+                                             int app_id) = 0;
+  };
+
+  WebviewWindowManager();
+  ~WebviewWindowManager() override;
+
+  void AddObserver(Observer* observer);
+  void RemoveObserver(Observer* observer);
+
+ private:
+  void OnWindowInitialized(aura::Window* window) override;
+
+  void OnWindowDestroying(aura::Window* window) override;
+  void OnWindowPropertyChanged(aura::Window* window,
+                               const void* key,
+                               intptr_t old) override;
+
+  std::vector<aura::Window*> observed_windows_;
+
+  base::ObserverList<Observer>::Unchecked observers_;
+
+  DISALLOW_COPY_AND_ASSIGN(WebviewWindowManager);
+};
+
+}  // namespace chromecast
+
+#endif  // CHROMECAST_BROWSER_WEBVIEW_WEBVIEW_WINDOW_MANAGER_H_
diff --git a/chromeos/dbus/shill/fake_shill_device_client.cc b/chromeos/dbus/shill/fake_shill_device_client.cc
index a1d45cb..3ad7ddb3 100644
--- a/chromeos/dbus/shill/fake_shill_device_client.cc
+++ b/chromeos/dbus/shill/fake_shill_device_client.cc
@@ -506,7 +506,7 @@
                     base::Value(base::StringPrintf("Network %d", idx)));
   new_result.SetKey(shill::kTechnologyProperty, base::Value("GSM"));
   new_result.SetKey(shill::kStatusProperty, base::Value("available"));
-  scan_results->GetList().push_back(std::move(new_result));
+  scan_results->Append(std::move(new_result));
   base::ThreadTaskRunnerHandle::Get()->PostTask(
       FROM_HERE,
       base::BindOnce(&FakeShillDeviceClient::NotifyObserversPropertyChanged,
diff --git a/chromeos/dbus/shill/fake_shill_manager_client.cc b/chromeos/dbus/shill/fake_shill_manager_client.cc
index 615ac042..77c01006 100644
--- a/chromeos/dbus/shill/fake_shill_manager_client.cc
+++ b/chromeos/dbus/shill/fake_shill_manager_client.cc
@@ -528,7 +528,7 @@
     list_value = stub_geo_networks_.SetKey(
         technology, base::Value(base::Value::Type::LIST));
   }
-  list_value->GetList().push_back(network.Clone());
+  list_value->Append(network.Clone());
 }
 
 void FakeShillManagerClient::AddProfile(const std::string& profile_path) {
@@ -632,11 +632,11 @@
   complete_path_list->GetList().clear();
   for (const base::Value& dict : complete_dict_list) {
     std::string service_path = GetStringValue(dict, kPathKey);
-    complete_path_list->GetList().push_back(base::Value(service_path));
+    complete_path_list->Append(base::Value(service_path));
   }
   // Append disabled networks to the end of the complete path list.
   for (const std::string& path : disabled_path_list)
-    complete_path_list->GetList().push_back(base::Value(path));
+    complete_path_list->Append(base::Value(path));
 
   // Notify observers if the order changed.
   if (notify && *complete_path_list != prev_complete_path_list)
diff --git a/chromeos/login/auth/challenge_response/known_user_pref_utils.cc b/chromeos/login/auth/challenge_response/known_user_pref_utils.cc
index f7f8628..064469f9 100644
--- a/chromeos/login/auth/challenge_response/known_user_pref_utils.cc
+++ b/chromeos/login/auth/challenge_response/known_user_pref_utils.cc
@@ -26,7 +26,7 @@
     base::Base64Encode(key.public_key_spki_der(), &spki_base64);
     base::Value key_representation(base::Value::Type::DICTIONARY);
     key_representation.SetKey(kPublicKeySpkiKey, base::Value(spki_base64));
-    pref_value.GetList().emplace_back(std::move(key_representation));
+    pref_value.Append(std::move(key_representation));
   }
   return pref_value;
 }
diff --git a/chromeos/network/client_cert_resolver_unittest.cc b/chromeos/network/client_cert_resolver_unittest.cc
index 698c8d9..f7c4132b 100644
--- a/chromeos/network/client_cert_resolver_unittest.cc
+++ b/chromeos/network/client_cert_resolver_unittest.cc
@@ -84,7 +84,7 @@
   onc_certificate.SetKey("Type", base::Value("Client"));
   onc_certificate.SetKey("PKCS12", base::Value(pkcs12_base64_encoded));
   base::Value onc_certificates(base::Value::Type::LIST);
-  onc_certificates.GetList().push_back(std::move(onc_certificate));
+  onc_certificates.Append(std::move(onc_certificate));
   return std::make_unique<onc::OncParsedCertificates>(onc_certificates);
 }
 
diff --git a/chromeos/network/managed_network_configuration_handler_impl.cc b/chromeos/network/managed_network_configuration_handler_impl.cc
index 49d5161..dbd1bab 100644
--- a/chromeos/network/managed_network_configuration_handler_impl.cc
+++ b/chromeos/network/managed_network_configuration_handler_impl.cc
@@ -1015,11 +1015,11 @@
         << "GetDeviceStateProperties: Setting IPv4 properties from network: "
         << service_path;
     if (network->ipv4_config())
-      ip_configs->GetList().push_back(network->ipv4_config()->Clone());
+      ip_configs->Append(network->ipv4_config()->Clone());
   } else {
     // Convert the DeviceState IPConfigs dictionary to a ListValue.
     for (const auto iter : device_state->ip_configs().DictItems())
-      ip_configs->GetList().push_back(iter.second.Clone());
+      ip_configs->Append(iter.second.Clone());
   }
   if (!ip_configs->GetList().empty()) {
     properties->SetWithoutPathExpansion(shill::kIPConfigsProperty,
diff --git a/chromeos/network/managed_network_configuration_handler_unittest.cc b/chromeos/network/managed_network_configuration_handler_unittest.cc
index 5d8cf90..a0dc818 100644
--- a/chromeos/network/managed_network_configuration_handler_unittest.cc
+++ b/chromeos/network/managed_network_configuration_handler_unittest.cc
@@ -186,7 +186,7 @@
           ADD_FAILURE() << "Network configuration invalid.";
           return;
         }
-        validated_network_configs.GetList().push_back(
+        validated_network_configs.Append(
             std::move(*(validated_network_config)));
       }
     }
diff --git a/chromeos/network/onc/onc_translator_onc_to_shill.cc b/chromeos/network/onc/onc_translator_onc_to_shill.cc
index c503ee3..3766c87 100644
--- a/chromeos/network/onc/onc_translator_onc_to_shill.cc
+++ b/chromeos/network/onc/onc_translator_onc_to_shill.cc
@@ -351,7 +351,7 @@
         value_ref = base::Value(kDefaultIpAddr);
     }
     while (name_servers->GetList().size() < 4)
-      name_servers->GetList().push_back(base::Value(kDefaultIpAddr));
+      name_servers->Append(base::Value(kDefaultIpAddr));
   }
 }
 
diff --git a/chromeos/network/onc/onc_utils_unittest.cc b/chromeos/network/onc/onc_utils_unittest.cc
index e079378..9984bb4 100644
--- a/chromeos/network/onc/onc_utils_unittest.cc
+++ b/chromeos/network/onc/onc_utils_unittest.cc
@@ -165,7 +165,7 @@
       ReadTestJson("proxy_config_from_onc.json");
   ASSERT_TRUE(additional_tests->is_list());
   for (const base::Value& value : additional_tests->GetList())
-    list_of_tests->GetList().push_back(value.Clone());
+    list_of_tests->Append(value.Clone());
 
   int index = 0;
   for (const base::Value& test_case : list_of_tests->GetList()) {
diff --git a/chromeos/network/onc/variable_expander_unittest.cc b/chromeos/network/onc/variable_expander_unittest.cc
index 071d240e..9effbbe 100644
--- a/chromeos/network/onc/variable_expander_unittest.cc
+++ b/chromeos/network/onc/variable_expander_unittest.cc
@@ -130,9 +130,9 @@
 TEST(VariableExpanderTest, ExpandValueSucceeds) {
   base::Value root(base::Value::Type::DICTIONARY);
   base::ListValue list;
-  list.GetList().push_back(base::Value(123));
-  list.GetList().push_back(base::Value("${machine_name}"));
-  list.GetList().push_back(base::Value(true));
+  list.Append(base::Value(123));
+  list.Append(base::Value("${machine_name}"));
+  list.Append(base::Value(true));
   root.SetKey("list", std::move(list));
   root.SetKey("str", base::Value("${machine_name}"));
   root.SetKey("double", base::Value(123.45));
diff --git a/chromeos/network/proxy/ui_proxy_config_service.cc b/chromeos/network/proxy/ui_proxy_config_service.cc
index c108736d..eb357ab 100644
--- a/chromeos/network/proxy/ui_proxy_config_service.cc
+++ b/chromeos/network/proxy/ui_proxy_config_service.cc
@@ -131,7 +131,7 @@
 
   base::Value exclude_domains(base::Value::Type::LIST);
   for (const auto& rule : bypass_rules.rules())
-    exclude_domains.GetList().emplace_back(rule->ToString());
+    exclude_domains.Append(rule->ToString());
   result.SetKey(::onc::proxy::kExcludeDomains,
                 CreateEffectiveValue(source, std::move(exclude_domains)));
 
diff --git a/chromeos/services/assistant/utils.cc b/chromeos/services/assistant/utils.cc
index 74123f64..81cb931 100644
--- a/chromeos/services/assistant/utils.cc
+++ b/chromeos/services/assistant/utils.cc
@@ -115,7 +115,7 @@
   dict.SetKey("enable_eraser", Value(features::IsAudioEraserEnabled()));
   dict.SetKey("enable_eraser_toggling",
               Value(features::IsAudioEraserEnabled()));
-  sources.GetList().push_back(std::move(dict));
+  sources.Append(std::move(dict));
   audio_input.SetKey("sources", std::move(sources));
 
   config.SetKey("audio_input", std::move(audio_input));
diff --git a/chromeos/services/network_config/cros_network_config.cc b/chromeos/services/network_config/cros_network_config.cc
index 10d171ce..19bd598 100644
--- a/chromeos/services/network_config/cros_network_config.cc
+++ b/chromeos/services/network_config/cros_network_config.cc
@@ -458,7 +458,7 @@
     return;
   base::Value list(base::Value::Type::LIST);
   for (const std::string& s : *property)
-    list.GetList().push_back(base::Value(s));
+    list.Append(base::Value(s));
   dict->SetKey(key, std::move(list));
 }
 
diff --git a/chromeos/services/network_config/cros_network_config_unittest.cc b/chromeos/services/network_config/cros_network_config_unittest.cc
index 8ed0c6f..2c0906b 100644
--- a/chromeos/services/network_config/cros_network_config_unittest.cc
+++ b/chromeos/services/network_config/cros_network_config_unittest.cc
@@ -95,7 +95,7 @@
             base::HexEncode(user_policy_ssid.c_str(), user_policy_ssid.size())
                 .c_str())));
     base::ListValue user_policy_onc;
-    user_policy_onc.GetList().push_back(std::move(wifi2_onc));
+    user_policy_onc.Append(std::move(wifi2_onc));
     managed_network_configuration_handler_->SetPolicy(
         ::onc::ONC_SOURCE_USER_POLICY, helper().UserHash(), user_policy_onc,
         /*global_network_config=*/base::DictionaryValue());
@@ -832,8 +832,8 @@
   global_config.SetBoolKey(
       ::onc::global_network_config::kAllowOnlyPolicyNetworksToConnect, false);
   base::Value blocked(base::Value::Type::LIST);
-  blocked.GetList().push_back(base::Value("blocked_ssid1"));
-  blocked.GetList().push_back(base::Value("blocked_ssid2"));
+  blocked.Append(base::Value("blocked_ssid1"));
+  blocked.Append(base::Value("blocked_ssid2"));
   global_config.SetKey(::onc::global_network_config::kBlacklistedHexSSIDs,
                        std::move(blocked));
   managed_network_configuration_handler()->SetPolicy(
diff --git a/components/BUILD.gn b/components/BUILD.gn
index a25a222..b3d7779 100644
--- a/components/BUILD.gn
+++ b/components/BUILD.gn
@@ -71,7 +71,6 @@
     "//components/blacklist/opt_out_blacklist/sql:unit_tests",
     "//components/bookmarks/browser:unit_tests",
     "//components/bookmarks/managed:unit_tests",
-    "//components/browser_sync:unit_tests",
     "//components/browsing_data/core:unit_tests",
     "//components/bubble:unit_tests",
     "//components/captive_portal:unit_tests",
@@ -134,7 +133,6 @@
     "//components/search_engines:unit_tests",
     "//components/search_provider_logos:unit_tests",
     "//components/security_state/core:unit_tests",
-    "//components/send_tab_to_self:unit_tests",
     "//components/services/heap_profiling/public/cpp:unit_tests",
     "//components/services/storage:tests",
     "//components/services/unzip:unit_tests",
@@ -151,9 +149,7 @@
     "//components/suggestions:unit_tests",
     "//components/sync:unit_tests",
     "//components/sync_bookmarks:unit_tests",
-    "//components/sync_device_info:unit_tests",
     "//components/sync_preferences:unit_tests",
-    "//components/sync_sessions:unit_tests",
     "//components/sync_user_events:unit_tests",
     "//components/tab_count_metrics:unit_tests",
     "//components/test:run_all_unittests",
@@ -163,7 +159,6 @@
     "//components/ukm:unit_tests",
     "//components/undo:unit_tests",
     "//components/unified_consent:unit_tests",
-    "//components/update_client:unit_tests",
     "//components/upload_list:unit_tests",
     "//components/url_formatter:unit_tests",
     "//components/url_formatter/spoof_checks/top_domains:unit_tests",
@@ -192,6 +187,16 @@
     deps += [ "//components/nacl/browser:unit_tests" ]
   }
 
+  if (!is_fuchsia) {
+    deps += [
+      "//components/browser_sync:unit_tests",
+      "//components/send_tab_to_self:unit_tests",
+      "//components/sync_device_info:unit_tests",
+      "//components/sync_sessions:unit_tests",
+      "//components/update_client:unit_tests",
+    ]
+  }
+
   if (is_ios) {
     deps += [
       "//components/autofill/ios/browser:unit_tests",
@@ -213,13 +218,6 @@
       "//components/certificate_transparency:unit_tests",
       "//components/content_capture/browser:unit_tests",
       "//components/contextual_search/core:unit_tests",
-      "//components/crash/content/app:unit_tests",
-      "//components/crash/content/browser:unit_tests",
-      "//components/data_reduction_proxy/content/browser:unit_tests",
-      "//components/data_reduction_proxy/content/common:unit_tests",
-      "//components/data_reduction_proxy/content/renderer:unit_tests",
-      "//components/data_reduction_proxy/core/browser:unit_tests",
-      "//components/data_reduction_proxy/core/common:unit_tests",
       "//components/data_use_measurement/core:unit_tests",
       "//components/discardable_memory/common:unit_tests",
       "//components/discardable_memory/service:unit_tests",
@@ -268,6 +266,18 @@
       "//components/webcrypto:unit_tests",
     ]
 
+    if (!is_fuchsia) {
+      deps += [
+        "//components/crash/content/app:unit_tests",
+        "//components/crash/content/browser:unit_tests",
+        "//components/data_reduction_proxy/content/browser:unit_tests",
+        "//components/data_reduction_proxy/content/common:unit_tests",
+        "//components/data_reduction_proxy/content/renderer:unit_tests",
+        "//components/data_reduction_proxy/core/browser:unit_tests",
+        "//components/data_reduction_proxy/core/common:unit_tests",
+      ]
+    }
+
     data_deps = [
       ":components_tests_pak",
       "//third_party/mesa_headers",
@@ -480,7 +490,9 @@
   }
 }
 
-if (!is_ios) {
+# TODO(https://crbug.com/961457): components_browsertests no-op build is not a
+# no-op under Fuchsia.
+if (!is_ios && !is_fuchsia) {
   test("components_browsertests") {
     defines = [ "HAS_OUT_OF_PROC_TEST_RUNNER" ]
 
diff --git a/components/autofill/core/browser/autofill_handler.cc b/components/autofill/core/browser/autofill_handler.cc
index 065949c..c4c4ae45 100644
--- a/components/autofill/core/browser/autofill_handler.cc
+++ b/components/autofill/core/browser/autofill_handler.cc
@@ -88,21 +88,14 @@
     // Try to find the FormStructure that corresponds to |form| if the form
     // contains credit card fields only.
     // |cached_form_structure| may still be nullptr after this call.
-    if (base::FeatureList::IsEnabled(features::kAutofillImportDynamicForms)) {
-      ignore_result(FindCachedForm(form, &cached_form_structure));
-      bool only_contains_credit_card_fields = true;
-      if (cached_form_structure) {
-        for (const FormType& form_type :
-             cached_form_structure->GetFormTypes()) {
-          if (form_type != CREDIT_CARD_FORM) {
-            only_contains_credit_card_fields = false;
-            break;
-          }
+    ignore_result(FindCachedForm(form, &cached_form_structure));
+    if (cached_form_structure) {
+      for (const FormType& form_type : cached_form_structure->GetFormTypes()) {
+        if (form_type != CREDIT_CARD_FORM) {
+          cached_form_structure = nullptr;
+          break;
         }
       }
-      if (!only_contains_credit_card_fields) {
-        cached_form_structure = nullptr;
-      }
     }
 
     if (!ParseForm(form, cached_form_structure, &form_structure))
diff --git a/components/autofill/core/browser/form_structure.cc b/components/autofill/core/browser/form_structure.cc
index 22b536c..951a1568 100644
--- a/components/autofill/core/browser/form_structure.cc
+++ b/components/autofill/core/browser/form_structure.cc
@@ -1031,9 +1031,7 @@
         bool is_credit_card_field =
             AutofillType(cached_field->second->Type().GetStorableType())
                 .group() == CREDIT_CARD;
-        if (should_keep_cached_value && is_credit_card_field &&
-            base::FeatureList::IsEnabled(
-                features::kAutofillImportDynamicForms)) {
+        if (should_keep_cached_value && is_credit_card_field) {
           field->value = cached_field->second->value;
           value_from_dynamic_change_form_ = true;
         } else if (field->value == cached_field->second->value) {
diff --git a/components/autofill/core/common/autofill_payments_features.cc b/components/autofill/core/common/autofill_payments_features.cc
index b550fcb..d715e20 100644
--- a/components/autofill/core/common/autofill_payments_features.cc
+++ b/components/autofill/core/common/autofill_payments_features.cc
@@ -77,10 +77,6 @@
 const base::Feature kAutofillEnableToolbarStatusChip{
     "AutofillEnableToolbarStatusChip", base::FEATURE_DISABLED_BY_DEFAULT};
 
-// When enabled, autofill can import credit cards from dynamic change form.
-const base::Feature kAutofillImportDynamicForms{
-    "AutofillImportDynamicForms", base::FEATURE_ENABLED_BY_DEFAULT};
-
 // Controls whether offering to migrate cards will consider data from the
 // Autofill strike database (new version).
 const base::Feature kAutofillLocalCardMigrationUsesStrikeSystemV2{
diff --git a/components/autofill/core/common/autofill_payments_features.h b/components/autofill/core/common/autofill_payments_features.h
index a101acb9..b9bf6ef 100644
--- a/components/autofill/core/common/autofill_payments_features.h
+++ b/components/autofill/core/common/autofill_payments_features.h
@@ -27,7 +27,6 @@
 extern const base::Feature kAutofillDownstreamUseGooglePayBrandingOniOS;
 extern const base::Feature kAutofillEnableLocalCardMigrationForNonSyncUser;
 extern const base::Feature kAutofillEnableToolbarStatusChip;
-extern const base::Feature kAutofillImportDynamicForms;
 extern const base::Feature kAutofillLocalCardMigrationUsesStrikeSystemV2;
 extern const base::Feature kAutofillNoLocalSaveOnUnmaskSuccess;
 extern const base::Feature kAutofillNoLocalSaveOnUploadSuccess;
diff --git a/components/autofill/ios/browser/autofill_agent.mm b/components/autofill/ios/browser/autofill_agent.mm
index 092c784..eaa9cd1 100644
--- a/components/autofill/ios/browser/autofill_agent.mm
+++ b/components/autofill/ios/browser/autofill_agent.mm
@@ -53,7 +53,7 @@
 #import "ios/web/public/js_messaging/web_frames_manager.h"
 #import "ios/web/public/navigation/navigation_context.h"
 #import "ios/web/public/web_state.h"
-#import "ios/web/public/web_state/web_state_observer_bridge.h"
+#import "ios/web/public/web_state_observer_bridge.h"
 #include "ui/gfx/geometry/rect.h"
 #include "url/gurl.h"
 
diff --git a/components/bookmarks/test/test_bookmark_client.cc b/components/bookmarks/test/test_bookmark_client.cc
index 4a42d62..7eab0eb 100644
--- a/components/bookmarks/test/test_bookmark_client.cc
+++ b/components/bookmarks/test/test_bookmark_client.cc
@@ -6,12 +6,12 @@
 
 #include <stddef.h>
 
+#include <memory>
 #include <utility>
 
 #include "base/bind.h"
 #include "base/bind_helpers.h"
 #include "base/logging.h"
-#include "base/memory/ptr_util.h"
 #include "base/stl_util.h"
 #include "components/bookmarks/browser/bookmark_model.h"
 #include "components/bookmarks/browser/bookmark_node.h"
@@ -25,7 +25,7 @@
 
 // static
 std::unique_ptr<BookmarkModel> TestBookmarkClient::CreateModel() {
-  return CreateModelWithClient(base::WrapUnique(new TestBookmarkClient));
+  return CreateModelWithClient(std::make_unique<TestBookmarkClient>());
 }
 
 // static
diff --git a/components/browser_sync/profile_sync_service_bookmark_unittest.cc b/components/browser_sync/profile_sync_service_bookmark_unittest.cc
index afcedb6..1a84dd5 100644
--- a/components/browser_sync/profile_sync_service_bookmark_unittest.cc
+++ b/components/browser_sync/profile_sync_service_bookmark_unittest.cc
@@ -22,7 +22,6 @@
 #include "base/files/scoped_temp_dir.h"
 #include "base/guid.h"
 #include "base/location.h"
-#include "base/memory/ptr_util.h"
 #include "base/run_loop.h"
 #include "base/stl_util.h"
 #include "base/strings/string16.h"
@@ -438,7 +437,7 @@
   std::unique_ptr<BookmarkModel> CreateBookmarkModel(bool delete_bookmarks) {
     const base::FilePath& data_path = data_dir_.GetPath();
     auto model = std::make_unique<BookmarkModel>(
-        base::WrapUnique(new bookmarks::TestBookmarkClient()));
+        std::make_unique<bookmarks::TestBookmarkClient>());
     managed_bookmark_service_->BookmarkModelCreated(model.get());
     int64_t next_id = 0;
     static_cast<bookmarks::TestBookmarkClient*>(model->client())
diff --git a/components/browser_watcher/stability_report_extractor_unittest.cc b/components/browser_watcher/stability_report_extractor_unittest.cc
index cd037fb3..e5a967b 100644
--- a/components/browser_watcher/stability_report_extractor_unittest.cc
+++ b/components/browser_watcher/stability_report_extractor_unittest.cc
@@ -12,7 +12,6 @@
 #include "base/files/file_path.h"
 #include "base/files/memory_mapped_file.h"
 #include "base/files/scoped_temp_dir.h"
-#include "base/memory/ptr_util.h"
 #include "base/metrics/persistent_memory_allocator.h"
 #include "base/stl_util.h"
 #include "base/time/time.h"
@@ -31,7 +30,6 @@
 using base::FilePersistentMemoryAllocator;
 using base::MemoryMappedFile;
 using base::PersistentMemoryAllocator;
-using base::WrapUnique;
 
 namespace {
 
@@ -94,8 +92,8 @@
     // Create a persistent memory allocator.
     if (!FilePersistentMemoryAllocator::IsFileAcceptable(*mmfile, true))
       return nullptr;
-    return WrapUnique(new FilePersistentMemoryAllocator(
-        std::move(mmfile), kFileSize, kAllocatorId, kAllocatorName, false));
+    return std::make_unique<FilePersistentMemoryAllocator>(
+        std::move(mmfile), kFileSize, kAllocatorId, kAllocatorName, false);
   }
 
   std::unique_ptr<ThreadActivityTracker> CreateTracker(
@@ -117,7 +115,7 @@
     // Make the allocation iterable so it can be found by other processes.
     allocator->MakeIterable(mem_reference);
 
-    return WrapUnique(new ThreadActivityTracker(mem_base, tracker_mem_size));
+    return std::make_unique<ThreadActivityTracker>(mem_base, tracker_mem_size);
   }
 
   void PerformBasicReportValidation(const StabilityReport& report) {
diff --git a/components/bubble/bubble_manager_unittest.cc b/components/bubble/bubble_manager_unittest.cc
index a6682434b..0115709 100644
--- a/components/bubble/bubble_manager_unittest.cc
+++ b/components/bubble/bubble_manager_unittest.cc
@@ -8,7 +8,6 @@
 #include <utility>
 
 #include "base/macros.h"
-#include "base/memory/ptr_util.h"
 #include "components/bubble/bubble_controller.h"
 #include "components/bubble/bubble_manager_mocks.h"
 #include "testing/gtest/include/gtest/gtest.h"
@@ -323,8 +322,8 @@
 TEST_F(BubbleManagerTest, AllowBubbleChainingOnClose) {
   BubbleReference chained_bubble;
   BubbleReference ref =
-      manager_->ShowBubble(base::WrapUnique(new ChainShowBubbleDelegate(
-          manager_.get(), MockBubbleDelegate::Default(), &chained_bubble)));
+      manager_->ShowBubble(std::make_unique<ChainShowBubbleDelegate>(
+          manager_.get(), MockBubbleDelegate::Default(), &chained_bubble));
   ASSERT_FALSE(chained_bubble);  // Bubble not yet visible.
   ASSERT_TRUE(manager_->CloseBubble(ref, BUBBLE_CLOSE_FORCED));
   ASSERT_TRUE(chained_bubble);  // Bubble is now visible.
@@ -335,8 +334,8 @@
 TEST_F(BubbleManagerTest, AllowBubbleChainingOnCloseAll) {
   BubbleReference chained_bubble;
   BubbleReference ref =
-      manager_->ShowBubble(base::WrapUnique(new ChainShowBubbleDelegate(
-          manager_.get(), MockBubbleDelegate::Default(), &chained_bubble)));
+      manager_->ShowBubble(std::make_unique<ChainShowBubbleDelegate>(
+          manager_.get(), MockBubbleDelegate::Default(), &chained_bubble));
   ASSERT_FALSE(chained_bubble);  // Bubble not yet visible.
   manager_->CloseAllBubbles(BUBBLE_CLOSE_FORCED);
   ASSERT_TRUE(chained_bubble);  // Bubble is now visible.
@@ -358,8 +357,8 @@
   EXPECT_CALL(*chained_delegate, ShouldClose(testing::_)).Times(0);
   EXPECT_CALL(*chained_delegate, DidClose(testing::_)).Times(0);
 
-  manager_->ShowBubble(base::WrapUnique(new ChainShowBubbleDelegate(
-      manager_.get(), std::move(chained_delegate), nullptr)));
+  manager_->ShowBubble(std::make_unique<ChainShowBubbleDelegate>(
+      manager_.get(), std::move(chained_delegate), nullptr));
   manager_.reset();
 }
 
diff --git a/components/component_updater/component_installer.cc b/components/component_updater/component_installer.cc
index e1e5fd2..2b35165 100644
--- a/components/component_updater/component_installer.cc
+++ b/components/component_updater/component_installer.cc
@@ -398,6 +398,7 @@
 
   update_client::CrxComponent crx;
   installer_policy_->GetHash(&crx.pk_hash);
+  crx.app_id = update_client::GetCrxIdFromPublicKeyHash(crx.pk_hash);
   crx.installer = this;
   crx.version = current_version_;
   crx.fingerprint = current_fingerprint_;
diff --git a/components/component_updater/component_updater_service.cc b/components/component_updater/component_updater_service.cc
index a98f186..41b569a 100644
--- a/components/component_updater/component_updater_service.cc
+++ b/components/component_updater/component_updater_service.cc
@@ -114,30 +114,30 @@
 // it will be replaced.
 bool CrxUpdateService::RegisterComponent(const CrxComponent& component) {
   DCHECK(thread_checker_.CalledOnValidThread());
-  if (component.pk_hash.empty() || !component.version.IsValid() ||
+  if (component.app_id.empty() || !component.version.IsValid() ||
       !component.installer) {
     return false;
   }
 
   // Update the registration data if the component has been registered before.
-  const std::string id(GetCrxComponentID(component));
-  auto it = components_.find(id);
+  auto it = components_.find(component.app_id);
   if (it != components_.end()) {
     it->second = component;
     return true;
   }
 
-  components_.insert(std::make_pair(id, component));
-  components_order_.push_back(id);
+  components_.insert(std::make_pair(component.app_id, component));
+  components_order_.push_back(component.app_id);
   for (const auto& mime_type : component.handled_mime_types)
-    component_ids_by_mime_type_[mime_type] = id;
+    component_ids_by_mime_type_[mime_type] = component.app_id;
 
   // Create an initial state for this component. The state is mutated in
   // response to events from the UpdateClient instance.
   CrxUpdateItem item;
-  item.id = id;
+  item.id = component.app_id;
   item.component = component;
-  const auto inserted = component_states_.insert(std::make_pair(id, item));
+  const auto inserted =
+      component_states_.insert(std::make_pair(component.app_id, item));
   DCHECK(inserted.second);
 
   // Start the timer if this is the first component registered. The first timer
diff --git a/components/component_updater/component_updater_service_unittest.cc b/components/component_updater/component_updater_service_unittest.cc
index d02c62f..b754fc8 100644
--- a/components/component_updater/component_updater_service_unittest.cc
+++ b/components/component_updater/component_updater_service_unittest.cc
@@ -332,11 +332,13 @@
   ids.push_back(id2);
 
   CrxComponent crx_component1;
+  crx_component1.app_id = id1;
   crx_component1.pk_hash.assign(abag_hash, abag_hash + base::size(abag_hash));
   crx_component1.version = base::Version("1.0");
   crx_component1.installer = installer;
 
   CrxComponent crx_component2;
+  crx_component2.app_id = id2;
   crx_component2.pk_hash.assign(jebg_hash, jebg_hash + base::size(jebg_hash));
   crx_component2.version = base::Version("0.9");
   crx_component2.installer = installer;
@@ -427,6 +429,7 @@
   {
     using update_client::jebg_hash;
     CrxComponent crx_component;
+    crx_component.app_id = "jebgalgnebhfojomionfpkfelancnnkf";
     crx_component.pk_hash.assign(jebg_hash, jebg_hash + base::size(jebg_hash));
     crx_component.version = base::Version("0.9");
     crx_component.installer = base::MakeRefCounted<MockInstaller>();
@@ -435,6 +438,7 @@
   {
     using update_client::abag_hash;
     CrxComponent crx_component;
+    crx_component.app_id = "abagagagagagagagagagagagagagagag";
     crx_component.pk_hash.assign(abag_hash, abag_hash + base::size(abag_hash));
     crx_component.version = base::Version("0.9");
     crx_component.installer = base::MakeRefCounted<MockInstaller>();
@@ -486,6 +490,7 @@
 
   using update_client::jebg_hash;
   CrxComponent crx_component;
+  crx_component.app_id = "jebgalgnebhfojomionfpkfelancnnkf";
   crx_component.pk_hash.assign(jebg_hash, jebg_hash + base::size(jebg_hash));
   crx_component.version = base::Version("0.9");
   crx_component.installer = installer;
diff --git a/components/content_settings/core/browser/cookie_settings.h b/components/content_settings/core/browser/cookie_settings.h
index 9754986..f7489216e 100644
--- a/components/content_settings/core/browser/cookie_settings.h
+++ b/components/content_settings/core/browser/cookie_settings.h
@@ -127,7 +127,7 @@
 
   void AddObserver(Observer* obs) { observers_.AddObserver(obs); }
 
-  void RemoveObserver(const Observer* obs) { observers_.RemoveObserver(obs); }
+  void RemoveObserver(Observer* obs) { observers_.RemoveObserver(obs); }
 
   bool IsCookieControlsEnabled();
 
diff --git a/components/content_settings/core/browser/host_content_settings_map.cc b/components/content_settings/core/browser/host_content_settings_map.cc
index 539e841..5b81d5f 100644
--- a/components/content_settings/core/browser/host_content_settings_map.cc
+++ b/components/content_settings/core/browser/host_content_settings_map.cc
@@ -12,7 +12,6 @@
 
 #include "base/command_line.h"
 #include "base/containers/flat_map.h"
-#include "base/memory/ptr_util.h"
 #include "base/metrics/histogram_functions.h"
 #include "base/metrics/histogram_macros.h"
 #include "base/stl_util.h"
@@ -253,22 +252,25 @@
       store_last_modified_(store_last_modified) {
   TRACE_EVENT0("startup", "HostContentSettingsMap::HostContentSettingsMap");
 
-  content_settings::PolicyProvider* policy_provider =
-      new content_settings::PolicyProvider(prefs_);
-  content_settings_providers_[POLICY_PROVIDER] =
-      base::WrapUnique(policy_provider);
+  auto policy_provider_ptr =
+      std::make_unique<content_settings::PolicyProvider>(prefs_);
+  auto* policy_provider = policy_provider_ptr.get();
+  content_settings_providers_[POLICY_PROVIDER] = std::move(policy_provider_ptr);
   policy_provider->AddObserver(this);
 
-  pref_provider_ = new content_settings::PrefProvider(
+  auto pref_provider_ptr = std::make_unique<content_settings::PrefProvider>(
       prefs_, is_off_the_record_, store_last_modified_);
-  content_settings_providers_[PREF_PROVIDER] = base::WrapUnique(pref_provider_);
+  pref_provider_ = pref_provider_ptr.get();
+  content_settings_providers_[PREF_PROVIDER] = std::move(pref_provider_ptr);
   user_modifiable_providers_.push_back(pref_provider_);
   pref_provider_->AddObserver(this);
 
-  content_settings::EphemeralProvider* ephemeral_provider =
-      new content_settings::EphemeralProvider(store_last_modified_);
+  auto ephemeral_provider_ptr =
+      std::make_unique<content_settings::EphemeralProvider>(
+          store_last_modified_);
+  auto* ephemeral_provider = ephemeral_provider_ptr.get();
   content_settings_providers_[EPHEMERAL_PROVIDER] =
-      base::WrapUnique(ephemeral_provider);
+      std::move(ephemeral_provider_ptr);
   user_modifiable_providers_.push_back(ephemeral_provider);
   ephemeral_provider->AddObserver(this);
 
diff --git a/components/cronet/android/cronet_impl_native_proguard.cfg b/components/cronet/android/cronet_impl_native_proguard.cfg
index 99989ff..2d227f7f 100644
--- a/components/cronet/android/cronet_impl_native_proguard.cfg
+++ b/components/cronet/android/cronet_impl_native_proguard.cfg
@@ -5,28 +5,6 @@
     public <init>(android.content.Context);
 }
 
-# Suppress unnecessary warnings.
--dontnote org.chromium.net.ProxyChangeListener$ProxyReceiver
--dontnote org.chromium.net.AndroidKeyStore
-# Needs 'void setTextAppearance(int)' (API level 23).
--dontwarn org.chromium.base.ApiCompatibilityUtils
-# Needs 'boolean onSearchRequested(android.view.SearchEvent)' (API level 23).
--dontwarn org.chromium.base.WindowCallbackWrapper
-
-# Generated for chrome apk and not included into cronet.
--dontwarn org.chromium.base.library_loader.NativeLibraries
--dontwarn org.chromium.base.multidex.ChromiumMultiDexInstaller
--dontwarn org.chromium.base.metrics.CachedMetrics
--dontwarn org.chromium.base.library_loader.LibraryLoader
--dontwarn org.chromium.base.SysUtils
-
-# Objects of this type are passed around by native code, but the class
-# is never used directly by native code. Since the class is not loaded, it does
-# not need to be preserved as an entry point.
--dontnote org.chromium.net.UrlRequest$ResponseHeadersMap
-# https://android.googlesource.com/platform/sdk/+/marshmallow-mr1-release/files/proguard-android.txt#54
--dontwarn android.support.**
-
 # This class should be explicitly kept to avoid failure if
 # class/merging/horizontal proguard optimization is enabled.
 -keep class org.chromium.base.CollectionUtil
diff --git a/components/cronet/android/test/proguard.cfg b/components/cronet/android/test/proguard.cfg
index 23a7900..32e1349 100644
--- a/components/cronet/android/test/proguard.cfg
+++ b/components/cronet/android/test/proguard.cfg
@@ -1,16 +1,12 @@
 # Proguard configuration that is common for all type of tests.
 
 -keepattributes Signature,InnerClasses,SourceFile,LineNumberTable,EnclosingMethod
--dontwarn io.netty.**
 -keep class io.netty.** { *; }
 # Keep ChromiumNativeTestSupport & ChromiumPlatformOnlyTestSupport since they are
 # instantiated through Reflection by the smoke tests.
 -keep class org.chromium.net.smoke.ChromiumNativeTestSupport
 -keep class org.chromium.net.smoke.ChromiumPlatformOnlyTestSupport
 
-# https://android.googlesource.com/platform/sdk/+/marshmallow-mr1-release/files/proguard-android.txt#54
--dontwarn android.support.**
-
 # Do not obfuscate this class for testing since some of the tests check the class
 # name in order to check that an instantiated engine is the Java one.
 -keepnames class org.chromium.net.impl.JavaCronetEngine
@@ -24,6 +20,3 @@
 
 -keep class org.chromium.net.TestFilesInstaller
 -keep class org.chromium.net.MetricsTestUtil
-
-# Generated for chrome apk and not included into cronet.
--dontwarn org.chromium.base.library_loader.NativeLibraries
diff --git a/components/cronet/stale_host_resolver_unittest.cc b/components/cronet/stale_host_resolver_unittest.cc
index 523941f..f489f86 100644
--- a/components/cronet/stale_host_resolver_unittest.cc
+++ b/components/cronet/stale_host_resolver_unittest.cc
@@ -10,7 +10,6 @@
 
 #include "base/bind.h"
 #include "base/logging.h"
-#include "base/memory/ptr_util.h"
 #include "base/memory/ref_counted.h"
 #include "base/optional.h"
 #include "base/run_loop.h"
@@ -692,8 +691,8 @@
   config.ConfigureURLRequestContextBuilder(&builder, &net_log);
   // Set a ProxyConfigService to avoid DCHECK failure when building.
   builder.set_proxy_config_service(
-      base::WrapUnique(new net::ProxyConfigServiceFixed(
-          net::ProxyConfigWithAnnotation::CreateDirect())));
+      std::make_unique<net::ProxyConfigServiceFixed>(
+          net::ProxyConfigWithAnnotation::CreateDirect()));
   std::unique_ptr<net::URLRequestContext> context(builder.Build());
 
   // Experimental options ensure context's resolver is a StaleHostResolver.
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_compression_stats_unittest.cc b/components/data_reduction_proxy/core/browser/data_reduction_proxy_compression_stats_unittest.cc
index 4f30770..4f8446d 100644
--- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_compression_stats_unittest.cc
+++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_compression_stats_unittest.cc
@@ -7,11 +7,11 @@
 #include <stddef.h>
 #include <stdint.h>
 
+#include <memory>
 #include <string>
 #include <utility>
 
 #include "base/bind.h"
-#include "base/memory/ptr_util.h"
 #include "base/memory/ref_counted.h"
 #include "base/run_loop.h"
 #include "base/strings/string_number_conversions.h"
@@ -845,8 +845,8 @@
   RecordDataUsage("https://www.foo.com", 1000, 1250, fifteen_mins_ago);
 
   auto expected_data_usage =
-      base::WrapUnique(new std::vector<data_reduction_proxy::DataUsageBucket>(
-          kNumExpectedBuckets));
+      std::make_unique<std::vector<data_reduction_proxy::DataUsageBucket>>(
+          kNumExpectedBuckets);
   data_reduction_proxy::PerConnectionDataUsage* connection_usage =
       expected_data_usage->at(kNumExpectedBuckets - 2).add_connection_usage();
   data_reduction_proxy::PerSiteDataUsage* site_usage =
diff --git a/components/dom_distiller/core/distillable_page_detector_unittest.cc b/components/dom_distiller/core/distillable_page_detector_unittest.cc
index 60a0a72..3933974 100644
--- a/components/dom_distiller/core/distillable_page_detector_unittest.cc
+++ b/components/dom_distiller/core/distillable_page_detector_unittest.cc
@@ -6,7 +6,6 @@
 
 #include <memory>
 
-#include "base/memory/ptr_util.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
 namespace dom_distiller {
@@ -33,7 +32,7 @@
     proto_.set_num_features(num_features);
     proto_.set_num_stumps(proto_.stump_size());
     return std::make_unique<DistillablePageDetector>(
-        base::WrapUnique(new AdaBoostProto(proto_)));
+        std::make_unique<AdaBoostProto>(proto_));
   }
 
  private:
diff --git a/components/download/internal/common/download_create_info.cc b/components/download/internal/common/download_create_info.cc
index 20881b0..7d45b181 100644
--- a/components/download/internal/common/download_create_info.cc
+++ b/components/download/internal/common/download_create_info.cc
@@ -4,10 +4,10 @@
 
 #include "components/download/public/common/download_create_info.h"
 
+#include <memory>
 #include <string>
 
 #include "base/format_macros.h"
-#include "base/memory/ptr_util.h"
 #include "base/strings/stringprintf.h"
 #include "net/http/http_response_headers.h"
 
@@ -35,8 +35,7 @@
       is_content_initiated(false) {}
 
 DownloadCreateInfo::DownloadCreateInfo()
-    : DownloadCreateInfo(base::Time(), base::WrapUnique(new DownloadSaveInfo)) {
-}
+    : DownloadCreateInfo(base::Time(), std::make_unique<DownloadSaveInfo>()) {}
 
 DownloadCreateInfo::~DownloadCreateInfo() {}
 
diff --git a/components/download/internal/common/download_utils.cc b/components/download/internal/common/download_utils.cc
index bc1fb98..2d4294e 100644
--- a/components/download/internal/common/download_utils.cc
+++ b/components/download/internal/common/download_utils.cc
@@ -243,6 +243,11 @@
   request->method = params->method();
   request->url = params->url();
   request->request_initiator = params->initiator();
+  if (!params->network_isolation_key().IsEmpty()) {
+    request->trusted_params = network::ResourceRequest::TrustedParams();
+    request->trusted_params->network_isolation_key =
+        params->network_isolation_key();
+  }
   request->do_not_prompt_for_login = params->do_not_prompt_for_login();
   request->site_for_cookies = params->url();
   request->referrer = params->referrer();
diff --git a/components/download/public/common/DEPS b/components/download/public/common/DEPS
index cf72027e..9a82ec50 100644
--- a/components/download/public/common/DEPS
+++ b/components/download/public/common/DEPS
@@ -6,6 +6,7 @@
   "+mojo/public/cpp/system",
   "+net/base/io_buffer.h",
   "+net/base/net_errors.h",
+  "+net/base/network_isolation_key.h",
   "+net/cert/cert_status_flags.h",
   "+net/http/http_response_headers.h",
   "+net/http/http_response_info.h",
diff --git a/components/download/public/common/download_url_parameters.h b/components/download/public/common/download_url_parameters.h
index f276edd..5f8d490 100644
--- a/components/download/public/common/download_url_parameters.h
+++ b/components/download/public/common/download_url_parameters.h
@@ -18,6 +18,7 @@
 #include "components/download/public/common/download_interrupt_reasons.h"
 #include "components/download/public/common/download_save_info.h"
 #include "components/download/public/common/download_source.h"
+#include "net/base/network_isolation_key.h"
 #include "net/traffic_annotation/network_traffic_annotation.h"
 #include "net/url_request/url_request.h"
 #include "services/network/public/cpp/resource_request_body.h"
@@ -257,6 +258,11 @@
     require_safety_checks_ = require_safety_checks;
   }
 
+  void set_network_isolation_key(
+      const net::NetworkIsolationKey& network_isolation_key) {
+    network_isolation_key_ = network_isolation_key;
+  }
+
   const OnStartedCallback& callback() const { return callback_; }
   bool content_initiated() const { return content_initiated_; }
   const std::string& last_modified() const { return last_modified_; }
@@ -310,6 +316,9 @@
   bool is_transient() const { return transient_; }
   std::string guid() const { return guid_; }
   bool require_safety_checks() const { return require_safety_checks_; }
+  const net::NetworkIsolationKey& network_isolation_key() const {
+    return network_isolation_key_;
+  }
 
   // STATE CHANGING: All save_info_ sub-objects will be in an indeterminate
   // state following this call.
@@ -357,6 +366,7 @@
   DownloadSource download_source_;
   UploadProgressCallback upload_callback_;
   bool require_safety_checks_;
+  net::NetworkIsolationKey network_isolation_key_;
 
   DISALLOW_COPY_AND_ASSIGN(DownloadUrlParameters);
 };
diff --git a/components/drive/resource_entry_conversion_unittest.cc b/components/drive/resource_entry_conversion_unittest.cc
index d2de2b3..7ca0eba 100644
--- a/components/drive/resource_entry_conversion_unittest.cc
+++ b/components/drive/resource_entry_conversion_unittest.cc
@@ -4,7 +4,8 @@
 
 #include "components/drive/resource_entry_conversion.h"
 
-#include "base/memory/ptr_util.h"
+#include <memory>
+
 #include "base/time/time.h"
 #include "components/drive/drive.pb.h"
 #include "components/drive/drive_api_util.h"
@@ -265,7 +266,7 @@
 TEST(ResourceEntryConversionTest, ConvertChangeResourceToResourceEntry) {
   google_apis::ChangeResource change_resource;
   change_resource.set_type(google_apis::ChangeResource::FILE);
-  change_resource.set_file(base::WrapUnique(new google_apis::FileResource));
+  change_resource.set_file(std::make_unique<google_apis::FileResource>());
   change_resource.set_file_id("resource_id");
   change_resource.set_modification_date(GetTestTime());
 
@@ -295,7 +296,7 @@
      ConvertChangeResourceToResourceEntry_Trashed) {
   google_apis::ChangeResource change_resource;
   change_resource.set_type(google_apis::ChangeResource::FILE);
-  change_resource.set_file(base::WrapUnique(new google_apis::FileResource));
+  change_resource.set_file(std::make_unique<google_apis::FileResource>());
   change_resource.set_file_id("resource_id");
   change_resource.set_modification_date(GetTestTime());
 
@@ -443,7 +444,7 @@
   google_apis::ChangeResource change_resource;
   change_resource.set_type(google_apis::ChangeResource::TEAM_DRIVE);
   change_resource.set_team_drive(
-      base::WrapUnique(new google_apis::TeamDriveResource));
+      std::make_unique<google_apis::TeamDriveResource>());
   change_resource.set_team_drive_id("team_drive_id");
   change_resource.set_modification_date(GetTestTime());
   change_resource.set_deleted(false);
diff --git a/components/exo/display.cc b/components/exo/display.cc
index d9cbf41..bc1fa15 100644
--- a/components/exo/display.cc
+++ b/components/exo/display.cc
@@ -5,10 +5,10 @@
 #include "components/exo/display.h"
 
 #include <iterator>
+#include <memory>
 #include <utility>
 
 #include "base/command_line.h"
-#include "base/memory/ptr_util.h"
 #include "base/trace_event/trace_event.h"
 #include "base/trace_event/traced_value.h"
 #include "build/build_config.h"
@@ -72,7 +72,7 @@
 std::unique_ptr<Surface> Display::CreateSurface() {
   TRACE_EVENT0("exo", "Display::CreateSurface");
 
-  return base::WrapUnique(new Surface);
+  return std::make_unique<Surface>();
 }
 
 std::unique_ptr<SharedMemory> Display::CreateSharedMemory(
diff --git a/components/exo/wayland/wl_compositor.cc b/components/exo/wayland/wl_compositor.cc
index f05ee41..9da8189 100644
--- a/components/exo/wayland/wl_compositor.cc
+++ b/components/exo/wayland/wl_compositor.cc
@@ -6,6 +6,8 @@
 
 #include <wayland-server-protocol-core.h>
 
+#include <memory>
+
 #include "base/bind.h"
 #include "components/exo/buffer.h"
 #include "components/exo/display.h"
@@ -220,7 +222,7 @@
       wl_resource_create(client, &wl_region_interface, 1, id);
 
   SetImplementation(region_resource, &region_implementation,
-                    base::WrapUnique(new SkRegion));
+                    std::make_unique<SkRegion>());
 }
 
 const struct wl_compositor_interface compositor_implementation = {
diff --git a/components/flags_ui/flags_state.cc b/components/flags_ui/flags_state.cc
index 564df9e..e3f194f 100644
--- a/components/flags_ui/flags_state.cc
+++ b/components/flags_ui/flags_state.cc
@@ -102,13 +102,10 @@
   unsigned bit;
   const char* const name;
 } kBitsToOs[] = {
-    {kOsMac, "Mac"},
-    {kOsWin, "Windows"},
-    {kOsLinux, "Linux"},
-    {kOsCrOS, "Chrome OS"},
-    {kOsAndroid, "Android"},
-    {kOsCrOSOwnerOnly, "Chrome OS (owner only)"},
-    {kOsIos, "iOS"},
+    {kOsMac, "Mac"},         {kOsWin, "Windows"},
+    {kOsLinux, "Linux"},     {kOsCrOS, "Chrome OS"},
+    {kOsAndroid, "Android"}, {kOsCrOSOwnerOnly, "Chrome OS (owner only)"},
+    {kOsIos, "iOS"},         {kOsFuchsia, "Fuchsia"},
 };
 
 // Adds a |StringValue| to |list| for each platform where |bitmask| indicates
@@ -694,6 +691,8 @@
   return kOsLinux;
 #elif defined(OS_ANDROID)
   return kOsAndroid;
+#elif defined(OS_FUCHSIA)
+  return kOsFuchsia;
 #else
 #error Unknown platform
 #endif
diff --git a/components/flags_ui/flags_state.h b/components/flags_ui/flags_state.h
index 1a8db5f..d29aafc 100644
--- a/components/flags_ui/flags_state.h
+++ b/components/flags_ui/flags_state.h
@@ -44,6 +44,7 @@
   kOsCrOSOwnerOnly = 1 << 5,
   kOsIos = 1 << 6,
   kDeprecated = 1 << 7,
+  kOsFuchsia = 1 << 8,
 };
 
 // A flag controlling the behavior of the |ConvertFlagsToSwitches| function -
diff --git a/components/gcm_driver/instance_id/instance_id_impl.cc b/components/gcm_driver/instance_id/instance_id_impl.cc
index 064c648..2cf37db 100644
--- a/components/gcm_driver/instance_id/instance_id_impl.cc
+++ b/components/gcm_driver/instance_id/instance_id_impl.cc
@@ -12,7 +12,6 @@
 #include "base/base64.h"
 #include "base/bind.h"
 #include "base/logging.h"
-#include "base/memory/ptr_util.h"
 #include "base/metrics/histogram_macros.h"
 #include "base/stl_util.h"
 #include "base/strings/string_number_conversions.h"
@@ -54,7 +53,7 @@
 std::unique_ptr<InstanceID> InstanceID::CreateInternal(
     const std::string& app_id,
     gcm::GCMDriver* gcm_driver) {
-  return base::WrapUnique(new InstanceIDImpl(app_id, gcm_driver));
+  return std::make_unique<InstanceIDImpl>(app_id, gcm_driver);
 }
 
 InstanceIDImpl::InstanceIDImpl(const std::string& app_id,
diff --git a/components/history/core/browser/browsing_history_service.cc b/components/history/core/browser/browsing_history_service.cc
index 781c5f4..e89c49d 100644
--- a/components/history/core/browser/browsing_history_service.cc
+++ b/components/history/core/browser/browsing_history_service.cc
@@ -20,11 +20,8 @@
 #include "base/time/time.h"
 #include "base/values.h"
 #include "components/history/core/browser/browsing_history_driver.h"
-#include "components/history/core/browser/history_service.h"
 #include "components/history/core/browser/history_types.h"
 #include "components/keyed_service/core/service_access_type.h"
-#include "components/sync/driver/sync_service.h"
-#include "components/sync/driver/sync_service_observer.h"
 #include "components/sync/protocol/history_delete_directive_specifics.pb.h"
 
 namespace history {
@@ -167,9 +164,6 @@
     syncer::SyncService* sync_service,
     std::unique_ptr<base::OneShotTimer> web_history_timer)
     : web_history_timer_(std::move(web_history_timer)),
-      history_service_observer_(this),
-      web_history_service_observer_(this),
-      sync_service_observer_(this),
       driver_(driver),
       local_history_(local_history),
       sync_service_(sync_service),
diff --git a/components/history/core/browser/browsing_history_service.h b/components/history/core/browser/browsing_history_service.h
index 868efb6..f2d32ac 100644
--- a/components/history/core/browser/browsing_history_service.h
+++ b/components/history/core/browser/browsing_history_service.h
@@ -23,24 +23,20 @@
 #include "base/time/clock.h"
 #include "base/timer/timer.h"
 #include "base/values.h"
+#include "components/history/core/browser/history_service.h"
 #include "components/history/core/browser/history_service_observer.h"
 #include "components/history/core/browser/url_row.h"
 #include "components/history/core/browser/web_history_service.h"
 #include "components/history/core/browser/web_history_service_observer.h"
+#include "components/sync/driver/sync_service.h"
 #include "components/sync/driver/sync_service_observer.h"
 #include "url/gurl.h"
 
-namespace syncer {
-class SyncService;
-class SyncServiceObserver;
-}  // namespace syncer
-
 FORWARD_DECLARE_TEST(BrowsingHistoryHandlerTest, ObservingWebHistoryDeletions);
 
 namespace history {
 
 class BrowsingHistoryDriver;
-class HistoryService;
 class QueryResults;
 struct QueryOptions;
 
@@ -232,15 +228,15 @@
 
   // HistoryService (local history) observer.
   ScopedObserver<HistoryService, HistoryServiceObserver>
-      history_service_observer_;
+      history_service_observer_{this};
 
   // WebHistoryService (synced history) observer.
   ScopedObserver<WebHistoryService, WebHistoryServiceObserver>
-      web_history_service_observer_;
+      web_history_service_observer_{this};
 
   // SyncService observer listens to late initialization of history sync.
   ScopedObserver<syncer::SyncService, syncer::SyncServiceObserver>
-      sync_service_observer_;
+      sync_service_observer_{this};
 
   // Whether the last call to Web History returned synced results.
   bool has_synced_results_ = false;
diff --git a/components/history/core/browser/history_backend.cc b/components/history/core/browser/history_backend.cc
index 0a4c7e9..2b39cfc 100644
--- a/components/history/core/browser/history_backend.cc
+++ b/components/history/core/browser/history_backend.cc
@@ -39,6 +39,7 @@
 #include "components/history/core/browser/in_memory_history_backend.h"
 #include "components/history/core/browser/keyword_search_term.h"
 #include "components/history/core/browser/page_usage_data.h"
+#include "components/history/core/browser/sync/typed_url_sync_bridge.h"
 #include "components/history/core/browser/url_utils.h"
 #include "components/sync/model_impl/client_tag_based_model_type_processor.h"
 #include "components/url_formatter/url_formatter.h"
@@ -924,6 +925,11 @@
   ScheduleCommit();
 }
 
+void HistoryBackend::SetTypedURLSyncBridgeForTest(
+    std::unique_ptr<TypedURLSyncBridge> bridge) {
+  typed_url_sync_bridge_ = std::move(bridge);
+}
+
 bool HistoryBackend::IsExpiredVisitTime(const base::Time& time) {
   return time < expirer_.GetCurrentExpirationTime();
 }
diff --git a/components/history/core/browser/history_backend.h b/components/history/core/browser/history_backend.h
index a1301c84..00a8a63 100644
--- a/components/history/core/browser/history_backend.h
+++ b/components/history/core/browser/history_backend.h
@@ -33,7 +33,6 @@
 #include "components/history/core/browser/history_backend_notifier.h"
 #include "components/history/core/browser/history_types.h"
 #include "components/history/core/browser/keyword_id.h"
-#include "components/history/core/browser/sync/typed_url_sync_bridge.h"
 #include "components/history/core/browser/thumbnail_database.h"
 #include "components/history/core/browser/visit_tracker.h"
 #include "sql/init_status.h"
@@ -54,6 +53,7 @@
 class HistoryBackendClient;
 class HistoryBackendDBBaseTest;
 class HistoryBackendObserver;
+class HistoryBackend;
 class HistoryBackendTest;
 class HistoryDatabase;
 struct HistoryDatabaseParams;
@@ -486,13 +486,10 @@
   HistoryDatabase* db() const { return db_.get(); }
 
   ExpireHistoryBackend* expire_backend() { return &expirer_; }
-
-  void SetTypedURLSyncBridgeForTest(
-      std::unique_ptr<TypedURLSyncBridge> bridge) {
-    typed_url_sync_bridge_ = std::move(bridge);
-  }
 #endif
 
+  void SetTypedURLSyncBridgeForTest(std::unique_ptr<TypedURLSyncBridge> bridge);
+
   // Returns true if the passed visit time is already expired (used by the sync
   // code to avoid syncing visits that would immediately be expired).
   virtual bool IsExpiredVisitTime(const base::Time& time);
diff --git a/components/history/core/browser/history_backend_unittest.cc b/components/history/core/browser/history_backend_unittest.cc
index 34bf13b..c8d9d9de 100644
--- a/components/history/core/browser/history_backend_unittest.cc
+++ b/components/history/core/browser/history_backend_unittest.cc
@@ -19,7 +19,6 @@
 #include "base/files/file_path.h"
 #include "base/files/file_util.h"
 #include "base/files/scoped_temp_dir.h"
-#include "base/memory/ptr_util.h"
 #include "base/memory/ref_counted.h"
 #include "base/metrics/histogram_base.h"
 #include "base/metrics/histogram_samples.h"
@@ -42,6 +41,7 @@
 #include "components/history/core/browser/in_memory_database.h"
 #include "components/history/core/browser/in_memory_history_backend.h"
 #include "components/history/core/browser/keyword_search_term.h"
+#include "components/history/core/browser/sync/typed_url_sync_bridge.h"
 #include "components/history/core/browser/visit_delegate.h"
 #include "components/history/core/test/database_test_utils.h"
 #include "components/history/core/test/history_client_fake_bookmarks.h"
@@ -3587,7 +3587,7 @@
   // Add a URL.
   GURL url("http://www.google.com");
   std::unique_ptr<HistoryService> service(
-      new HistoryService(base::WrapUnique(new HistoryClientFakeBookmarks),
+      new HistoryService(std::make_unique<HistoryClientFakeBookmarks>(),
                          std::unique_ptr<history::VisitDelegate>()));
   EXPECT_TRUE(service->Init(
       TestHistoryDatabaseParamsForPath(scoped_temp_dir.GetPath())));
diff --git a/components/history/core/browser/history_types.h b/components/history/core/browser/history_types.h
index cb84ba4..c84ce0b 100644
--- a/components/history/core/browser/history_types.h
+++ b/components/history/core/browser/history_types.h
@@ -31,8 +31,6 @@
 
 namespace history {
 
-// Forward declaration for friend statements.
-class HistoryBackend;
 class PageUsageData;
 
 // Container for a list of URLs.
diff --git a/components/history/core/browser/sync/typed_url_sync_bridge.h b/components/history/core/browser/sync/typed_url_sync_bridge.h
index 6980cbc7b..339584c 100644
--- a/components/history/core/browser/sync/typed_url_sync_bridge.h
+++ b/components/history/core/browser/sync/typed_url_sync_bridge.h
@@ -24,7 +24,7 @@
 namespace history {
 
 class TypedURLSyncBridge : public syncer::ModelTypeSyncBridge,
-                           public history::HistoryBackendObserver {
+                           public HistoryBackendObserver {
  public:
   // |sync_metadata_store| is owned by |history_backend|, and must outlive
   // TypedURLSyncBridge.
@@ -49,7 +49,7 @@
   std::string GetStorageKey(const syncer::EntityData& entity_data) override;
   bool SupportsGetStorageKey() const override;
 
-  // history::HistoryBackendObserver:
+  // HistoryBackendObserver:
   void OnURLVisited(HistoryBackend* history_backend,
                     ui::PageTransition transition,
                     const URLRow& row,
diff --git a/components/invalidation/impl/per_user_topic_registration_request.cc b/components/invalidation/impl/per_user_topic_registration_request.cc
index cc32aef..04412ed 100644
--- a/components/invalidation/impl/per_user_topic_registration_request.cc
+++ b/components/invalidation/impl/per_user_topic_registration_request.cc
@@ -4,10 +4,11 @@
 
 #include "components/invalidation/impl/per_user_topic_registration_request.h"
 
+#include <memory>
+
 #include "base/bind.h"
 #include "base/json/json_reader.h"
 #include "base/json/json_writer.h"
-#include "base/memory/ptr_util.h"
 #include "base/metrics/histogram_functions.h"
 #include "base/metrics/histogram_macros.h"
 #include "base/strings/stringprintf.h"
@@ -200,7 +201,7 @@
 std::unique_ptr<PerUserTopicRegistrationRequest>
 PerUserTopicRegistrationRequest::Builder::Build() const {
   DCHECK(!scope_.empty());
-  auto request = base::WrapUnique(new PerUserTopicRegistrationRequest);
+  auto request = base::WrapUnique(new PerUserTopicRegistrationRequest());
 
   std::string url;
   switch (type_) {
diff --git a/components/invalidation/impl/sync_system_resources_unittest.cc b/components/invalidation/impl/sync_system_resources_unittest.cc
index 979b33eb..632c6dc 100644
--- a/components/invalidation/impl/sync_system_resources_unittest.cc
+++ b/components/invalidation/impl/sync_system_resources_unittest.cc
@@ -4,13 +4,13 @@
 
 #include "components/invalidation/impl/sync_system_resources.h"
 
+#include <memory>
 #include <string>
 
 #include "base/bind.h"
 #include "base/bind_helpers.h"
 #include "base/callback.h"
 #include "base/macros.h"
-#include "base/memory/ptr_util.h"
 #include "base/run_loop.h"
 #include "base/test/task_environment.h"
 #include "components/invalidation/impl/push_client_channel.h"
@@ -52,7 +52,7 @@
 class SyncSystemResourcesTest : public testing::Test {
  protected:
   SyncSystemResourcesTest()
-      : push_client_channel_(base::WrapUnique(new notifier::FakePushClient())),
+      : push_client_channel_(std::make_unique<notifier::FakePushClient>()),
         sync_system_resources_(&push_client_channel_, &mock_state_writer_) {}
 
   ~SyncSystemResourcesTest() override {}
diff --git a/components/invalidation/impl/ticl_invalidation_service_unittest.cc b/components/invalidation/impl/ticl_invalidation_service_unittest.cc
index 52255fc..d83a35d 100644
--- a/components/invalidation/impl/ticl_invalidation_service_unittest.cc
+++ b/components/invalidation/impl/ticl_invalidation_service_unittest.cc
@@ -9,7 +9,6 @@
 #include "base/bind.h"
 #include "base/files/file_path.h"
 #include "base/macros.h"
-#include "base/memory/ptr_util.h"
 #include "base/memory/weak_ptr.h"
 #include "base/test/task_environment.h"
 #include "components/gcm_driver/fake_gcm_driver.h"
@@ -58,7 +57,7 @@
   void InitializeInvalidationService() {
     fake_invalidator_ = new syncer::FakeInvalidator();
     invalidation_service_->InitForTest(
-        base::WrapUnique(new syncer::FakeInvalidationStateTracker),
+        std::make_unique<syncer::FakeInvalidationStateTracker>(),
         fake_invalidator_);
   }
 
diff --git a/components/leveldb_proto/public/proto_database_provider.h b/components/leveldb_proto/public/proto_database_provider.h
index a33452cd5..8798a900 100644
--- a/components/leveldb_proto/public/proto_database_provider.h
+++ b/components/leveldb_proto/public/proto_database_provider.h
@@ -79,10 +79,10 @@
     ProtoDbType db_type,
     const base::FilePath& unique_db_dir,
     const scoped_refptr<base::SequencedTaskRunner>& task_runner) {
-  return base::WrapUnique(new ProtoDatabaseImpl<P, T>(
+  return std::make_unique<ProtoDatabaseImpl<P, T>>(
       db_type, unique_db_dir, task_runner,
       base::WrapUnique(new SharedProtoDatabaseProvider(
-          client_task_runner_, weak_factory_.GetWeakPtr()))));
+          client_task_runner_, weak_factory_.GetWeakPtr())));
 }
 
 }  // namespace leveldb_proto
diff --git a/components/ntp_snippets/reading_list/reading_list_suggestions_provider.cc b/components/ntp_snippets/reading_list/reading_list_suggestions_provider.cc
index ed383e5c..7107eb4 100644
--- a/components/ntp_snippets/reading_list/reading_list_suggestions_provider.cc
+++ b/components/ntp_snippets/reading_list/reading_list_suggestions_provider.cc
@@ -14,7 +14,6 @@
 #include "base/time/time.h"
 #include "components/ntp_snippets/category.h"
 #include "components/reading_list/core/reading_list_entry.h"
-#include "components/reading_list/core/reading_list_model.h"
 #include "components/strings/grit/components_strings.h"
 #include "components/url_formatter/url_formatter.h"
 #include "ui/base/l10n/l10n_util.h"
@@ -38,8 +37,7 @@
       category_status_(CategoryStatus::AVAILABLE_LOADING),
       provided_category_(
           Category::FromKnownCategory(KnownCategories::READING_LIST)),
-      reading_list_model_(reading_list_model),
-      scoped_observer_(this) {
+      reading_list_model_(reading_list_model) {
   observer->OnCategoryStatusChanged(this, provided_category_, category_status_);
 
   // If the ReadingListModel is loaded, this will trigger a call to
diff --git a/components/ntp_snippets/reading_list/reading_list_suggestions_provider.h b/components/ntp_snippets/reading_list/reading_list_suggestions_provider.h
index 1a2aeee..854b7640 100644
--- a/components/ntp_snippets/reading_list/reading_list_suggestions_provider.h
+++ b/components/ntp_snippets/reading_list/reading_list_suggestions_provider.h
@@ -15,10 +15,9 @@
 #include "components/ntp_snippets/category_status.h"
 #include "components/ntp_snippets/content_suggestion.h"
 #include "components/ntp_snippets/content_suggestions_provider.h"
+#include "components/reading_list/core/reading_list_model.h"
 #include "components/reading_list/core/reading_list_model_observer.h"
 
-class ReadingListModel;
-
 namespace ntp_snippets {
 
 // Provides content suggestions from the Reading List.
@@ -75,7 +74,8 @@
   const Category provided_category_;
 
   ReadingListModel* reading_list_model_;
-  ScopedObserver<ReadingListModel, ReadingListModelObserver> scoped_observer_;
+  ScopedObserver<ReadingListModel, ReadingListModelObserver> scoped_observer_{
+      this};
 
   DISALLOW_COPY_AND_ASSIGN(ReadingListSuggestionsProvider);
 };
diff --git a/components/offline_pages/core/prefetch/prefetch_service_test_taco.cc b/components/offline_pages/core/prefetch/prefetch_service_test_taco.cc
index 6759815..ff94385 100644
--- a/components/offline_pages/core/prefetch/prefetch_service_test_taco.cc
+++ b/components/offline_pages/core/prefetch/prefetch_service_test_taco.cc
@@ -4,10 +4,10 @@
 
 #include "components/offline_pages/core/prefetch/prefetch_service_test_taco.h"
 
+#include <memory>
 #include <utility>
 
 #include "base/macros.h"
-#include "base/memory/ptr_util.h"
 #include "base/threading/thread_task_runner_handle.h"
 #include "components/image_fetcher/core/image_fetcher.h"
 #include "components/image_fetcher/core/mock_image_fetcher.h"
@@ -78,8 +78,8 @@
       std::make_unique<PrefetchStore>(base::ThreadTaskRunnerHandle::Get());
 
   download_service_ = std::make_unique<TestDownloadService>();
-  prefetch_downloader_ = base::WrapUnique(new PrefetchDownloaderImpl(
-      download_service_.get(), kTestChannel, pref_service_.get()));
+  prefetch_downloader_ = std::make_unique<PrefetchDownloaderImpl>(
+      download_service_.get(), kTestChannel, pref_service_.get());
   download_client_ =
       std::make_unique<TestDownloadClient>(prefetch_downloader_.get());
   download_service_->SetClient(download_client_.get());
diff --git a/components/omnibox/browser/search_provider.cc b/components/omnibox/browser/search_provider.cc
index c7cb336..c64f6a6a 100644
--- a/components/omnibox/browser/search_provider.cc
+++ b/components/omnibox/browser/search_provider.cc
@@ -35,7 +35,6 @@
 #include "components/omnibox/browser/url_prefix.h"
 #include "components/omnibox/common/omnibox_features.h"
 #include "components/search/search.h"
-#include "components/search_engines/template_url_service.h"
 #include "components/strings/grit/components_strings.h"
 #include "components/url_formatter/url_formatter.h"
 #include "components/variations/net/variations_http_headers.h"
@@ -143,8 +142,7 @@
     : BaseSearchProvider(AutocompleteProvider::TYPE_SEARCH, client),
       listener_(listener),
       providers_(client->GetTemplateURLService()),
-      answers_cache_(10),
-      observer_(this) {
+      answers_cache_(10) {
   TemplateURLService* template_url_service = client->GetTemplateURLService();
 
   // |template_url_service| can be null in tests.
diff --git a/components/omnibox/browser/search_provider.h b/components/omnibox/browser/search_provider.h
index f374dc0..4b4fd61 100644
--- a/components/omnibox/browser/search_provider.h
+++ b/components/omnibox/browser/search_provider.h
@@ -24,6 +24,7 @@
 #include "components/omnibox/browser/answers_cache.h"
 #include "components/omnibox/browser/base_search_provider.h"
 #include "components/search_engines/template_url.h"
+#include "components/search_engines/template_url_service.h"
 #include "components/search_engines/template_url_service_observer.h"
 #include "third_party/metrics_proto/omnibox_input_type.pb.h"
 
@@ -31,7 +32,6 @@
 class AutocompleteProviderListener;
 class AutocompleteResult;
 class SearchProviderTest;
-class TemplateURLService;
 
 namespace history {
 struct KeywordSearchTermVisit;
@@ -437,7 +437,8 @@
   AnswersCache answers_cache_;  // Cache for last answers seen.
   AnswersQueryData prefetch_data_;  // Data to use for query prefetching.
 
-  ScopedObserver<TemplateURLService, TemplateURLServiceObserver> observer_;
+  ScopedObserver<TemplateURLService, TemplateURLServiceObserver> observer_{
+      this};
 
   DISALLOW_COPY_AND_ASSIGN(SearchProvider);
 };
diff --git a/components/omnibox/browser/shortcuts_backend.cc b/components/omnibox/browser/shortcuts_backend.cc
index a81e7e3b..5ee4b063 100644
--- a/components/omnibox/browser/shortcuts_backend.cc
+++ b/components/omnibox/browser/shortcuts_backend.cc
@@ -20,7 +20,6 @@
 #include "base/strings/string_util.h"
 #include "base/task/post_task.h"
 #include "base/threading/thread_task_runner_handle.h"
-#include "components/history/core/browser/history_service.h"
 #include "components/omnibox/browser/autocomplete_input.h"
 #include "components/omnibox/browser/autocomplete_match.h"
 #include "components/omnibox/browser/autocomplete_match_type.h"
@@ -75,7 +74,6 @@
     : template_url_service_(template_url_service),
       search_terms_data_(std::move(search_terms_data)),
       current_state_(NOT_INITIALIZED),
-      history_service_observer_(this),
       main_runner_(base::ThreadTaskRunnerHandle::Get()),
       db_runner_(base::CreateSequencedTaskRunner(
           {base::ThreadPool(), base::MayBlock(),
diff --git a/components/omnibox/browser/shortcuts_backend.h b/components/omnibox/browser/shortcuts_backend.h
index 39eaf475a..9f4e779 100644
--- a/components/omnibox/browser/shortcuts_backend.h
+++ b/components/omnibox/browser/shortcuts_backend.h
@@ -21,6 +21,7 @@
 #include "base/strings/string16.h"
 #include "base/synchronization/lock.h"
 #include "base/time/time.h"
+#include "components/history/core/browser/history_service.h"
 #include "components/history/core/browser/history_service_observer.h"
 #include "components/keyed_service/core/refcounted_keyed_service.h"
 #include "components/omnibox/browser/autocomplete_match.h"
@@ -38,7 +39,6 @@
     size_t db_size);
 
 namespace history {
-class HistoryService;
 class ShortcutsDatabase;
 }  // namespace history
 
@@ -168,7 +168,7 @@
   GuidMap guid_map_;
 
   ScopedObserver<history::HistoryService, history::HistoryServiceObserver>
-      history_service_observer_;
+      history_service_observer_{this};
 
   scoped_refptr<base::SequencedTaskRunner> main_runner_;
   scoped_refptr<base::SequencedTaskRunner> db_runner_;
diff --git a/components/password_manager/core/browser/BUILD.gn b/components/password_manager/core/browser/BUILD.gn
index f42be3ce..d40cc41 100644
--- a/components/password_manager/core/browser/BUILD.gn
+++ b/components/password_manager/core/browser/BUILD.gn
@@ -205,13 +205,9 @@
       "password_reuse_detector.h",
       "password_reuse_detector_consumer.cc",
       "password_reuse_detector_consumer.h",
+      "password_store_signin_notifier.cc",
+      "password_store_signin_notifier.h",
     ]
-    if (is_win || is_mac || is_linux || is_chromeos) {
-      sources += [
-        "password_store_signin_notifier.cc",
-        "password_store_signin_notifier.h",
-      ]
-    }
   }
 
   public_deps = [
@@ -279,7 +275,7 @@
     ]
   }
 
-  if (is_posix && !is_mac && !is_ios) {
+  if ((is_posix && !is_mac && !is_ios) || is_fuchsia) {
     sources += [ "login_database_posix.cc" ]
   }
 
diff --git a/components/password_manager/core/browser/login_database.h b/components/password_manager/core/browser/login_database.h
index dba2f87..7d84ff0ec 100644
--- a/components/password_manager/core/browser/login_database.h
+++ b/components/password_manager/core/browser/login_database.h
@@ -209,7 +209,7 @@
   void enable_encryption() { use_encryption_ = true; }
   // This instance should not encrypt/decrypt password values using OSCrypt.
   void disable_encryption() { use_encryption_ = false; }
-#endif  // defined(OS_POSIX)
+#endif  // defined(OS_POSIX) && !defined(OS_MACOSX)
 
  private:
 #if defined(OS_IOS)
diff --git a/components/password_manager/core/browser/login_database_posix.cc b/components/password_manager/core/browser/login_database_posix.cc
index 241c2d5..57708cc 100644
--- a/components/password_manager/core/browser/login_database_posix.cc
+++ b/components/password_manager/core/browser/login_database_posix.cc
@@ -29,10 +29,12 @@
 LoginDatabase::EncryptionResult LoginDatabase::EncryptedString(
     const base::string16& plain_text,
     std::string* cipher_text) const {
+#if !defined(OS_FUCHSIA)
   if (!use_encryption_) {
     *cipher_text = base::UTF16ToUTF8(plain_text);
     return ENCRYPTION_RESULT_SUCCESS;
   }
+#endif
 
   return OSCrypt::EncryptString16(plain_text, cipher_text)
              ? ENCRYPTION_RESULT_SUCCESS
@@ -42,6 +44,7 @@
 LoginDatabase::EncryptionResult LoginDatabase::DecryptedString(
     const std::string& cipher_text,
     base::string16* plain_text) const {
+#if !defined(OS_FUCHSIA)
 #if defined(OS_ANDROID) || defined(OS_CHROMEOS)
   // On Android and ChromeOS, we have a mix of obfuscated and plain-text
   // passwords. Obfuscated passwords always start with "v10", therefore anything
@@ -59,6 +62,7 @@
         PasswordDecryptionResult::kSucceededBySkipping);
     return ENCRYPTION_RESULT_SUCCESS;
   }
+#endif  // !defined(OS_FUCHSIA)
 
   bool decryption_success = OSCrypt::DecryptString16(cipher_text, plain_text);
 #if defined(OS_ANDROID) || defined(OS_CHROMEOS)
diff --git a/components/password_manager/ios/password_form_helper.h b/components/password_manager/ios/password_form_helper.h
index 81ca0a9b..7e3e039 100644
--- a/components/password_manager/ios/password_form_helper.h
+++ b/components/password_manager/ios/password_form_helper.h
@@ -8,7 +8,7 @@
 #import <Foundation/Foundation.h>
 
 #import "components/autofill/ios/form_util/form_activity_observer_bridge.h"
-#import "ios/web/public/web_state/web_state_observer_bridge.h"
+#import "ios/web/public/web_state_observer_bridge.h"
 #include "url/gurl.h"
 
 NS_ASSUME_NONNULL_BEGIN
diff --git a/components/policy/core/browser/proxy_policy_handler_unittest.cc b/components/policy/core/browser/proxy_policy_handler_unittest.cc
index eb34f84..bb5c6a13 100644
--- a/components/policy/core/browser/proxy_policy_handler_unittest.cc
+++ b/components/policy/core/browser/proxy_policy_handler_unittest.cc
@@ -217,17 +217,16 @@
 TEST_F(ProxyPolicyHandlerTest, PacScriptProxyModeBug78016) {
   PolicyMap policy;
   policy.Set(key::kProxyServer, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
-             POLICY_SOURCE_CLOUD,
-             base::WrapUnique(new base::Value(std::string())), nullptr);
+             POLICY_SOURCE_CLOUD, std::make_unique<base::Value>(std::string()),
+             nullptr);
   policy.Set(key::kProxyPacUrl, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
              POLICY_SOURCE_CLOUD,
-             base::WrapUnique(new base::Value("http://short.org/proxy.pac")),
+             std::make_unique<base::Value>("http://short.org/proxy.pac"),
              nullptr);
-  policy.Set(
-      key::kProxyMode, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
-      POLICY_SOURCE_CLOUD,
-      base::WrapUnique(new base::Value(ProxyPrefs::kPacScriptProxyModeName)),
-      nullptr);
+  policy.Set(key::kProxyMode, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
+             POLICY_SOURCE_CLOUD,
+             std::make_unique<base::Value>(ProxyPrefs::kPacScriptProxyModeName),
+             nullptr);
   UpdateProviderPolicy(policy);
   VerifyProxyPrefs(std::string(),
                    "http://short.org/proxy.pac",
diff --git a/components/policy/core/browser/url_blacklist_policy_handler_unittest.cc b/components/policy/core/browser/url_blacklist_policy_handler_unittest.cc
index a2764fa..f2efc04 100644
--- a/components/policy/core/browser/url_blacklist_policy_handler_unittest.cc
+++ b/components/policy/core/browser/url_blacklist_policy_handler_unittest.cc
@@ -7,7 +7,6 @@
 #include <memory>
 #include <utility>
 
-#include "base/memory/ptr_util.h"
 #include "base/values.h"
 #include "components/policy/core/browser/policy_error_map.h"
 #include "components/policy/core/common/policy_map.h"
@@ -54,14 +53,14 @@
 TEST_F(URLBlacklistPolicyHandlerTest,
        CheckPolicySettings_DisabledSchemesUnspecified) {
   EXPECT_TRUE(
-      CheckPolicy(key::kURLBlacklist, base::WrapUnique(new base::ListValue)));
+      CheckPolicy(key::kURLBlacklist, std::make_unique<base::ListValue>()));
   EXPECT_EQ(0U, errors_.size());
 }
 
 TEST_F(URLBlacklistPolicyHandlerTest,
        CheckPolicySettings_URLBlacklistUnspecified) {
-  EXPECT_TRUE(CheckPolicy(key::kDisabledSchemes,
-                          base::WrapUnique(new base::ListValue)));
+  EXPECT_TRUE(
+      CheckPolicy(key::kDisabledSchemes, std::make_unique<base::ListValue>()));
   EXPECT_EQ(0U, errors_.size());
 }
 
@@ -110,7 +109,7 @@
 
 TEST_F(URLBlacklistPolicyHandlerTest,
        ApplyPolicySettings_DisabledSchemesEmpty) {
-  SetPolicy(key::kDisabledSchemes, base::WrapUnique(new base::ListValue));
+  SetPolicy(key::kDisabledSchemes, std::make_unique<base::ListValue>());
   ApplyPolicies();
   base::Value* out;
   EXPECT_TRUE(prefs_.GetValue(policy_prefs::kUrlBlacklist, &out));
@@ -121,7 +120,7 @@
 
 TEST_F(URLBlacklistPolicyHandlerTest,
        ApplyPolicySettings_URLBlacklistEmpty) {
-  SetPolicy(key::kURLBlacklist, base::WrapUnique(new base::ListValue));
+  SetPolicy(key::kURLBlacklist, std::make_unique<base::ListValue>());
   ApplyPolicies();
   base::Value* out;
   EXPECT_TRUE(prefs_.GetValue(policy_prefs::kUrlBlacklist, &out));
diff --git a/components/policy/core/common/policy_loader_win.cc b/components/policy/core/common/policy_loader_win.cc
index 4b179aa1..e0a63f8 100644
--- a/components/policy/core/common/policy_loader_win.cc
+++ b/components/policy/core/common/policy_loader_win.cc
@@ -24,7 +24,6 @@
 #include "base/json/json_writer.h"
 #include "base/lazy_instance.h"
 #include "base/logging.h"
-#include "base/memory/ptr_util.h"
 #include "base/metrics/histogram.h"
 #include "base/metrics/histogram_functions.h"
 #include "base/metrics/histogram_macros.h"
@@ -338,7 +337,7 @@
 std::unique_ptr<PolicyLoaderWin> PolicyLoaderWin::Create(
     scoped_refptr<base::SequencedTaskRunner> task_runner,
     const base::string16& chrome_policy_key) {
-  return base::WrapUnique(new PolicyLoaderWin(task_runner, chrome_policy_key));
+  return std::make_unique<PolicyLoaderWin>(task_runner, chrome_policy_key);
 }
 
 void PolicyLoaderWin::InitOnBackgroundThread() {
diff --git a/components/safe_browsing/browser/threat_details_history.cc b/components/safe_browsing/browser/threat_details_history.cc
index 3ea0e17..41ee212 100644
--- a/components/safe_browsing/browser/threat_details_history.cc
+++ b/components/safe_browsing/browser/threat_details_history.cc
@@ -11,7 +11,6 @@
 #include "base/bind.h"
 #include "base/bind_helpers.h"
 #include "base/task/post_task.h"
-#include "components/history/core/browser/history_service.h"
 #include "components/safe_browsing/browser/threat_details.h"
 #include "content/public/browser/browser_task_traits.h"
 #include "content/public/browser/browser_thread.h"
@@ -24,9 +23,7 @@
 
 ThreatDetailsRedirectsCollector::ThreatDetailsRedirectsCollector(
     const base::WeakPtr<history::HistoryService>& history_service)
-    : has_started_(false),
-      history_service_(history_service),
-      history_service_observer_(this) {
+    : has_started_(false), history_service_(history_service) {
   DCHECK_CURRENTLY_ON(BrowserThread::UI);
 
   if (history_service) {
diff --git a/components/safe_browsing/browser/threat_details_history.h b/components/safe_browsing/browser/threat_details_history.h
index fcf5c997..64f619e 100644
--- a/components/safe_browsing/browser/threat_details_history.h
+++ b/components/safe_browsing/browser/threat_details_history.h
@@ -16,6 +16,7 @@
 #include "base/scoped_observer.h"
 #include "base/sequenced_task_runner_helpers.h"
 #include "base/task/cancelable_task_tracker.h"
+#include "components/history/core/browser/history_service.h"
 #include "components/history/core/browser/history_service_observer.h"
 #include "content/public/browser/browser_thread.h"
 
@@ -76,7 +77,7 @@
 
   base::WeakPtr<history::HistoryService> history_service_;
   ScopedObserver<history::HistoryService, history::HistoryServiceObserver>
-      history_service_observer_;
+      history_service_observer_{this};
 
   DISALLOW_COPY_AND_ASSIGN(ThreatDetailsRedirectsCollector);
 };
diff --git a/components/safe_browsing/password_protection/password_protection_service.cc b/components/safe_browsing/password_protection/password_protection_service.cc
index b836d99a..116249e5 100644
--- a/components/safe_browsing/password_protection/password_protection_service.cc
+++ b/components/safe_browsing/password_protection/password_protection_service.cc
@@ -19,7 +19,6 @@
 #include "base/strings/string_util.h"
 #include "base/task/post_task.h"
 #include "components/content_settings/core/browser/host_content_settings_map.h"
-#include "components/history/core/browser/history_service.h"
 #include "components/password_manager/core/browser/password_manager_metrics_util.h"
 #include "components/password_manager/core/browser/password_reuse_detector.h"
 #include "components/safe_browsing/common/utils.h"
@@ -60,8 +59,7 @@
     scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory,
     HistoryService* history_service)
     : database_manager_(database_manager),
-      url_loader_factory_(url_loader_factory),
-      history_service_observer_(this) {
+      url_loader_factory_(url_loader_factory) {
   DCHECK_CURRENTLY_ON(BrowserThread::UI);
   if (history_service)
     history_service_observer_.Add(history_service);
diff --git a/components/safe_browsing/password_protection/password_protection_service.h b/components/safe_browsing/password_protection/password_protection_service.h
index 0f681fcf..37b26b87 100644
--- a/components/safe_browsing/password_protection/password_protection_service.h
+++ b/components/safe_browsing/password_protection/password_protection_service.h
@@ -17,6 +17,7 @@
 #include "base/scoped_observer.h"
 #include "base/task/cancelable_task_tracker.h"
 #include "base/values.h"
+#include "components/history/core/browser/history_service.h"
 #include "components/history/core/browser/history_service_observer.h"
 #include "components/password_manager/core/browser/password_manager_metrics_util.h"
 #include "components/safe_browsing/buildflags.h"
@@ -36,10 +37,6 @@
 class NavigationHandle;
 }
 
-namespace history {
-class HistoryService;
-}
-
 namespace policy {
 class BrowserPolicyConnector;
 }
@@ -439,7 +436,7 @@
   std::set<scoped_refptr<PasswordProtectionRequest>> warning_requests_;
 
   ScopedObserver<history::HistoryService, history::HistoryServiceObserver>
-      history_service_observer_;
+      history_service_observer_{this};
 
   // Weakptr can only cancel task if it is posted to the same thread. Therefore,
   // we need CancelableTaskTracker to cancel tasks posted to IO thread.
diff --git a/components/safe_browsing/verdict_cache_manager.cc b/components/safe_browsing/verdict_cache_manager.cc
index fd5ac3d..63ba4a95 100644
--- a/components/safe_browsing/verdict_cache_manager.cc
+++ b/components/safe_browsing/verdict_cache_manager.cc
@@ -9,7 +9,6 @@
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/string_split.h"
 #include "base/task/post_task.h"
-#include "components/history/core/browser/history_service.h"
 #include "components/history/core/browser/history_service_observer.h"
 #include "components/safe_browsing/db/v4_protocol_manager_util.h"
 #include "components/safe_browsing/proto/csd.pb.h"
@@ -148,7 +147,6 @@
     scoped_refptr<HostContentSettingsMap> content_settings)
     : stored_verdict_count_password_on_focus_(base::nullopt),
       stored_verdict_count_password_entry_(base::nullopt),
-      history_service_observer_(this),
       content_settings_(content_settings) {
   if (history_service)
     history_service_observer_.Add(history_service);
diff --git a/components/safe_browsing/verdict_cache_manager.h b/components/safe_browsing/verdict_cache_manager.h
index f4ac829..4c23462 100644
--- a/components/safe_browsing/verdict_cache_manager.h
+++ b/components/safe_browsing/verdict_cache_manager.h
@@ -12,14 +12,11 @@
 #include "base/time/time.h"
 #include "base/values.h"
 #include "components/content_settings/core/browser/host_content_settings_map.h"
+#include "components/history/core/browser/history_service.h"
 #include "components/history/core/browser/history_service_observer.h"
 #include "components/safe_browsing/proto/csd.pb.h"
 #include "url/gurl.h"
 
-namespace history {
-class HistoryService;
-}
-
 class HostContentSettingsMap;
 
 namespace safe_browsing {
@@ -105,7 +102,7 @@
   base::Optional<size_t> stored_verdict_count_password_entry_;
 
   ScopedObserver<history::HistoryService, history::HistoryServiceObserver>
-      history_service_observer_;
+      history_service_observer_{this};
 
   // Content settings maps associated with this instance.
   scoped_refptr<HostContentSettingsMap> content_settings_;
diff --git a/components/search_engines/default_search_policy_handler_unittest.cc b/components/search_engines/default_search_policy_handler_unittest.cc
index a5610ff6..f02f8ba 100644
--- a/components/search_engines/default_search_policy_handler_unittest.cc
+++ b/components/search_engines/default_search_policy_handler_unittest.cc
@@ -133,7 +133,7 @@
   const char bad_search_url[] = "http://test.com/noSearchTerms";
   policy.Set(key::kDefaultSearchProviderSearchURL, POLICY_LEVEL_MANDATORY,
              POLICY_SCOPE_USER, POLICY_SOURCE_CLOUD,
-             base::WrapUnique(new base::Value(bad_search_url)), nullptr);
+             std::make_unique<base::Value>(bad_search_url), nullptr);
   UpdateProviderPolicy(policy);
 
   const base::Value* temp = nullptr;
@@ -249,11 +249,10 @@
   PolicyMap policy;
   policy.Set(key::kDefaultSearchProviderEnabled, POLICY_LEVEL_MANDATORY,
              POLICY_SCOPE_USER, POLICY_SOURCE_CLOUD,
-             base::WrapUnique(new base::Value(false)), nullptr);
+             std::make_unique<base::Value>(false), nullptr);
   policy.Set(key::kDefaultSearchProviderSearchURL, POLICY_LEVEL_MANDATORY,
              POLICY_SCOPE_USER, POLICY_SOURCE_CLOUD,
-             base::WrapUnique(new base::Value("http://a/?{searchTerms}")),
-             nullptr);
+             std::make_unique<base::Value>("http://a/?{searchTerms}"), nullptr);
   UpdateProviderPolicy(policy);
   const base::Value* temp = nullptr;
   // Ignore any other search provider related policy in this case.
@@ -275,8 +274,7 @@
   PolicyMap policy;
   policy.Set(key::kDefaultSearchProviderSearchURL, POLICY_LEVEL_MANDATORY,
              POLICY_SCOPE_USER, POLICY_SOURCE_CLOUD,
-             base::WrapUnique(new base::Value("http://a/?{searchTerms}")),
-             nullptr);
+             std::make_unique<base::Value>("http://a/?{searchTerms}"), nullptr);
   UpdateProviderPolicy(policy);
   const base::Value* temp = nullptr;
   EXPECT_FALSE(store_->GetValue(
@@ -290,10 +288,10 @@
   PolicyMap policy;
   policy.Set(key::kDefaultSearchProviderEnabled, POLICY_LEVEL_MANDATORY,
              POLICY_SCOPE_USER, POLICY_SOURCE_CLOUD,
-             base::WrapUnique(new base::Value(true)), nullptr);
+             std::make_unique<base::Value>(true), nullptr);
   policy.Set(key::kDefaultSearchProviderSearchURL, POLICY_LEVEL_MANDATORY,
              POLICY_SCOPE_USER, POLICY_SOURCE_CLOUD,
-             base::WrapUnique(new base::Value(kSearchURL)), nullptr);
+             std::make_unique<base::Value>(kSearchURL), nullptr);
   UpdateProviderPolicy(policy);
 
   const base::Value* temp = nullptr;
@@ -343,10 +341,10 @@
   PolicyMap policy;
   policy.Set(key::kDefaultSearchProviderEnabled, POLICY_LEVEL_MANDATORY,
              POLICY_SCOPE_USER, POLICY_SOURCE_CLOUD,
-             base::WrapUnique(new base::Value(true)), nullptr);
+             std::make_unique<base::Value>(true), nullptr);
   policy.Set(key::kDefaultSearchProviderSearchURL, POLICY_LEVEL_MANDATORY,
              POLICY_SCOPE_USER, POLICY_SOURCE_CLOUD,
-             base::WrapUnique(new base::Value(kFileSearchURL)), nullptr);
+             std::make_unique<base::Value>(kFileSearchURL), nullptr);
   UpdateProviderPolicy(policy);
 
   const base::Value* temp = nullptr;
diff --git a/components/sessions/content/navigation_task_id.cc b/components/sessions/content/navigation_task_id.cc
index 6bbc546..2792414 100644
--- a/components/sessions/content/navigation_task_id.cc
+++ b/components/sessions/content/navigation_task_id.cc
@@ -4,6 +4,8 @@
 
 #include "components/sessions/content/navigation_task_id.h"
 
+#include <memory>
+
 #include "content/public/browser/navigation_entry.h"
 
 namespace sessions {
@@ -21,14 +23,14 @@
       static_cast<NavigationTaskId*>(entry->GetUserData(kTaskIdKey));
   if (navigation_task_id)
     return navigation_task_id;
-  auto navigation_task_id_ptr = base::WrapUnique(new NavigationTaskId());
+  auto navigation_task_id_ptr = std::make_unique<NavigationTaskId>();
   navigation_task_id = navigation_task_id_ptr.get();
   entry->SetUserData(kTaskIdKey, std::move(navigation_task_id_ptr));
   return navigation_task_id;
 }
 
 std::unique_ptr<base::SupportsUserData::Data> NavigationTaskId::Clone() {
-  return base::WrapUnique(new NavigationTaskId(*this));
+  return std::make_unique<NavigationTaskId>(*this);
 }
 
 }  // namespace sessions
diff --git a/components/storage_monitor/BUILD.gn b/components/storage_monitor/BUILD.gn
index 0003829..fa5d2c0 100644
--- a/components/storage_monitor/BUILD.gn
+++ b/components/storage_monitor/BUILD.gn
@@ -88,6 +88,10 @@
     ]
     deps += [ "//device/udev_linux" ]
   }
+
+  if (is_fuchsia) {
+    sources += [ "storage_monitor_fuchsia.cc" ]
+  }
 }
 
 static_library("test_support") {
diff --git a/components/storage_monitor/storage_monitor_fuchsia.cc b/components/storage_monitor/storage_monitor_fuchsia.cc
new file mode 100644
index 0000000..da11d97
--- /dev/null
+++ b/components/storage_monitor/storage_monitor_fuchsia.cc
@@ -0,0 +1,16 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/storage_monitor/storage_monitor.h"
+
+#include "base/logging.h"
+
+namespace storage_monitor {
+
+StorageMonitor* StorageMonitor::CreateInternal() {
+  NOTIMPLEMENTED();
+  return nullptr;
+}
+
+}  // namespace storage_monitor
diff --git a/components/subresource_filter/content/browser/content_subresource_filter_throttle_manager.cc b/components/subresource_filter/content/browser/content_subresource_filter_throttle_manager.cc
index 41c523f..835e4c4c 100644
--- a/components/subresource_filter/content/browser/content_subresource_filter_throttle_manager.cc
+++ b/components/subresource_filter/content/browser/content_subresource_filter_throttle_manager.cc
@@ -18,7 +18,6 @@
 #include "components/subresource_filter/content/browser/navigation_console_logger.h"
 #include "components/subresource_filter/content/browser/page_load_statistics.h"
 #include "components/subresource_filter/content/browser/subresource_filter_client.h"
-#include "components/subresource_filter/content/browser/subresource_filter_observer_manager.h"
 #include "components/subresource_filter/content/common/subresource_filter_messages.h"
 #include "components/subresource_filter/content/common/subresource_filter_utils.h"
 #include "components/subresource_filter/content/mojom/subresource_filter_agent.mojom.h"
@@ -41,7 +40,6 @@
         content::WebContents* web_contents)
     : content::WebContentsObserver(web_contents),
       binding_(web_contents, this),
-      scoped_observer_(this),
       dealer_handle_(dealer_handle),
       client_(client) {
   SubresourceFilterObserverManager::CreateForWebContents(web_contents);
diff --git a/components/subresource_filter/content/browser/content_subresource_filter_throttle_manager.h b/components/subresource_filter/content/browser/content_subresource_filter_throttle_manager.h
index ec336fa3..202eb5fb 100644
--- a/components/subresource_filter/content/browser/content_subresource_filter_throttle_manager.h
+++ b/components/subresource_filter/content/browser/content_subresource_filter_throttle_manager.h
@@ -16,6 +16,7 @@
 #include "base/stl_util.h"
 #include "components/subresource_filter/content/browser/subframe_navigation_filtering_throttle.h"
 #include "components/subresource_filter/content/browser/subresource_filter_observer.h"
+#include "components/subresource_filter/content/browser/subresource_filter_observer_manager.h"
 #include "components/subresource_filter/content/browser/verified_ruleset_dealer.h"
 #include "components/subresource_filter/core/common/activation_decision.h"
 #include "components/subresource_filter/core/mojom/subresource_filter.mojom.h"
@@ -33,7 +34,6 @@
 class AsyncDocumentSubresourceFilter;
 class ActivationStateComputingNavigationThrottle;
 class PageLoadStatistics;
-class SubresourceFilterObserverManager;
 class SubresourceFilterClient;
 
 // The ContentSubresourceFilterThrottleManager manages NavigationThrottles in
@@ -173,7 +173,7 @@
   content::WebContentsFrameBindingSet<mojom::SubresourceFilterHost> binding_;
 
   ScopedObserver<SubresourceFilterObserverManager, SubresourceFilterObserver>
-      scoped_observer_;
+      scoped_observer_{this};
 
   // Lazily instantiated in EnsureRulesetHandle when the first page level
   // activation is triggered. Will go away when there are no more activated
diff --git a/components/sync/base/pref_names.cc b/components/sync/base/pref_names.cc
index fcaf241..ff801603 100644
--- a/components/sync/base/pref_names.cc
+++ b/components/sync/base/pref_names.cc
@@ -135,9 +135,11 @@
 
 // Stores a "secret" offset that is used to randomize the birth year for metrics
 // reporting. This value should not be logged to UMA directly; instead, it
-// should be summed with the kSyncDemographicsBirthYear. This value is both
-// generated and stored locally on the client and is not known outside of the
-// client. It is not synced.
+// should be summed with the kSyncDemographicsBirthYear. This value is generated
+// locally on the client the first time a user begins to merge birth year data
+// into their UMA reports. The value is synced to the user's other devices so
+// that the user consistently uses the same offset across login/logout events
+// and after clearing their other browser data.
 const char kSyncDemographicsBirthYearOffset[] =
     "sync.demographics_birth_year_offset";
 
diff --git a/components/sync/base/sync_prefs.cc b/components/sync/base/sync_prefs.cc
index 93261734..2d77690f 100644
--- a/components/sync/base/sync_prefs.cc
+++ b/components/sync/base/sync_prefs.cc
@@ -127,7 +127,7 @@
 
 // Gets an offset to add noise to the birth year. If not present in prefs, the
 // offset will be randomly generated within the offset range and cached in
-// prefs.
+// syncable prefs.
 int GetBirthYearOffset(PrefService* pref_service) {
   int offset =
       pref_service->GetInteger(prefs::kSyncDemographicsBirthYearOffset);
@@ -295,7 +295,8 @@
       user_prefs::PrefRegistrySyncable::SYNCABLE_PRIORITY_PREF);
   registry->RegisterIntegerPref(
       prefs::kSyncDemographicsBirthYearOffset,
-      kUserDemographicsBirthYearNoiseOffsetDefaultValue);
+      kUserDemographicsBirthYearNoiseOffsetDefaultValue,
+      user_prefs::PrefRegistrySyncable::SYNCABLE_PREF);
 
   // Obsolete prefs that will be removed after a grace period.
   RegisterObsoleteUserTypePrefs(registry);
diff --git a/components/sync/engine_impl/get_updates_delegate.h b/components/sync/engine_impl/get_updates_delegate.h
index 88e3d601..3438cae5 100644
--- a/components/sync/engine_impl/get_updates_delegate.h
+++ b/components/sync/engine_impl/get_updates_delegate.h
@@ -39,6 +39,9 @@
   virtual std::unique_ptr<ProtocolEvent> GetNetworkRequestEvent(
       base::Time timestamp,
       const sync_pb::ClientToServerMessage& request) const = 0;
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(GetUpdatesDelegate);
 };
 
 // Functionality specific to the normal GetUpdate request.
diff --git a/components/sync/engine_impl/loopback_server/persistent_bookmark_entity.cc b/components/sync/engine_impl/loopback_server/persistent_bookmark_entity.cc
index 7d156bab..3ca35943 100644
--- a/components/sync/engine_impl/loopback_server/persistent_bookmark_entity.cc
+++ b/components/sync/engine_impl/loopback_server/persistent_bookmark_entity.cc
@@ -4,8 +4,9 @@
 
 #include "components/sync/engine_impl/loopback_server/persistent_bookmark_entity.h"
 
+#include <memory>
+
 #include "base/guid.h"
-#include "base/memory/ptr_util.h"
 
 using std::string;
 
@@ -37,11 +38,11 @@
   const string originator_cache_guid = client_guid;
   const string originator_client_item_id = client_entity.id_string();
 
-  return base::WrapUnique(new PersistentBookmarkEntity(
+  return std::make_unique<PersistentBookmarkEntity>(
       id, 0, client_entity.name(), originator_cache_guid,
       originator_client_item_id, client_entity.unique_position(),
       client_entity.specifics(), client_entity.folder(), parent_id,
-      client_entity.ctime(), client_entity.mtime()));
+      client_entity.ctime(), client_entity.mtime());
 }
 
 // static
@@ -68,11 +69,11 @@
 
   // Using a version of 0 is okay here as it'll be updated before this entity is
   // actually saved.
-  return base::WrapUnique(new PersistentBookmarkEntity(
+  return std::make_unique<PersistentBookmarkEntity>(
       client_entity.id_string(), 0, client_entity.name(), originator_cache_guid,
       originator_client_item_id, client_entity.unique_position(),
       client_entity.specifics(), client_entity.folder(), parent_id,
-      client_entity.ctime(), client_entity.mtime()));
+      client_entity.ctime(), client_entity.mtime());
 }
 
 // static
@@ -84,13 +85,13 @@
     return nullptr;
   }
 
-  return base::WrapUnique(new PersistentBookmarkEntity(
+  return std::make_unique<PersistentBookmarkEntity>(
       client_entity.id_string(), client_entity.version(), client_entity.name(),
       client_entity.originator_cache_guid(),
       client_entity.originator_client_item_id(),
       client_entity.unique_position(), client_entity.specifics(),
       client_entity.folder(), client_entity.parent_id_string(),
-      client_entity.ctime(), client_entity.mtime()));
+      client_entity.ctime(), client_entity.mtime());
 }
 PersistentBookmarkEntity::PersistentBookmarkEntity(
     const string& id,
diff --git a/components/sync/engine_impl/loopback_server/persistent_permanent_entity.cc b/components/sync/engine_impl/loopback_server/persistent_permanent_entity.cc
index 54716b2..0797684 100644
--- a/components/sync/engine_impl/loopback_server/persistent_permanent_entity.cc
+++ b/components/sync/engine_impl/loopback_server/persistent_permanent_entity.cc
@@ -4,8 +4,9 @@
 
 #include "components/sync/engine_impl/loopback_server/persistent_permanent_entity.h"
 
+#include <memory>
+
 #include "base/logging.h"
-#include "base/memory/ptr_util.h"
 
 using std::string;
 
@@ -57,8 +58,8 @@
       LoopbackServerEntity::CreateId(model_type, parent_server_tag);
   sync_pb::EntitySpecifics entity_specifics;
   AddDefaultFieldValue(model_type, &entity_specifics);
-  return base::WrapUnique(new PersistentPermanentEntity(
-      id, 0, model_type, name, parent_id, server_tag, entity_specifics));
+  return std::make_unique<PersistentPermanentEntity>(
+      id, 0, model_type, name, parent_id, server_tag, entity_specifics);
 }
 
 // static
@@ -74,8 +75,8 @@
   string id = LoopbackServerEntity::GetTopLevelId(model_type);
   sync_pb::EntitySpecifics entity_specifics;
   AddDefaultFieldValue(model_type, &entity_specifics);
-  return base::WrapUnique(new PersistentPermanentEntity(
-      id, 0, model_type, name, kRootParentTag, server_tag, entity_specifics));
+  return std::make_unique<PersistentPermanentEntity>(
+      id, 0, model_type, name, kRootParentTag, server_tag, entity_specifics);
 }
 
 // static
@@ -89,11 +90,11 @@
     return nullptr;
   }
 
-  return base::WrapUnique(new PersistentPermanentEntity(
+  return std::make_unique<PersistentPermanentEntity>(
       current_server_entity.GetId(), current_server_entity.GetVersion(),
       model_type, current_server_entity.GetName(),
       current_server_entity.GetParentId(),
-      syncer::ModelTypeToRootTag(model_type), client_entity.specifics()));
+      syncer::ModelTypeToRootTag(model_type), client_entity.specifics());
 }
 
 PersistentPermanentEntity::PersistentPermanentEntity(
diff --git a/components/sync/engine_impl/model_type_worker.cc b/components/sync/engine_impl/model_type_worker.cc
index b23b533..1f94082 100644
--- a/components/sync/engine_impl/model_type_worker.cc
+++ b/components/sync/engine_impl/model_type_worker.cc
@@ -379,21 +379,21 @@
 
 void ModelTypeWorker::ApplyUpdates(StatusController* status) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  // This should only ever be called after one PassiveApplyUpdates.
-  DCHECK(model_type_state_.initial_sync_done())
-      << "ApplyUpdates() called without initial sync being done for "
-      << ModelTypeToString(type_);
+  // Indicate to the processor that the initial download is done. The initial
+  // sync technically isn't done yet but by the time this value is persisted to
+  // disk on the model thread it will be.
+  //
+  // This should be mostly relevant for the call from PassiveApplyUpdates(), but
+  // in rare cases we may end up receiving initial updates outside configuration
+  // cycles (e.g. polling cycles).
+  model_type_state_.set_initial_sync_done(true);
   // Download cycle is done, pass all updates to the processor.
   ApplyPendingUpdates();
 }
 
 void ModelTypeWorker::PassiveApplyUpdates(StatusController* status) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  // Indicate to the processor that the initial download is done. The initial
-  // sync technically isn't done yet but by the time this value is persisted to
-  // disk on the model thread it will be.
-  model_type_state_.set_initial_sync_done(true);
-  ApplyPendingUpdates();
+  ApplyUpdates(status);
 }
 
 void ModelTypeWorker::EncryptionAcceptedMaybeApplyUpdates() {
diff --git a/components/sync_bookmarks/bookmark_data_type_controller.cc b/components/sync_bookmarks/bookmark_data_type_controller.cc
index 709c6c6..bac2613 100644
--- a/components/sync_bookmarks/bookmark_data_type_controller.cc
+++ b/components/sync_bookmarks/bookmark_data_type_controller.cc
@@ -7,8 +7,6 @@
 #include <utility>
 
 #include "base/metrics/histogram.h"
-#include "components/bookmarks/browser/bookmark_model.h"
-#include "components/history/core/browser/history_service.h"
 #include "components/sync/driver/model_associator.h"
 #include "components/sync/driver/sync_api_component_factory.h"
 #include "components/sync/driver/sync_service.h"
@@ -29,9 +27,7 @@
                                          sync_service),
       bookmark_model_(bookmark_model),
       history_service_(history_service),
-      component_factory_(component_factory),
-      history_service_observer_(this),
-      bookmark_model_observer_(this) {}
+      component_factory_(component_factory) {}
 
 BookmarkDataTypeController::~BookmarkDataTypeController() {}
 
diff --git a/components/sync_bookmarks/bookmark_data_type_controller.h b/components/sync_bookmarks/bookmark_data_type_controller.h
index febbeec2..3433ef9 100644
--- a/components/sync_bookmarks/bookmark_data_type_controller.h
+++ b/components/sync_bookmarks/bookmark_data_type_controller.h
@@ -10,6 +10,8 @@
 #include "base/macros.h"
 #include "base/scoped_observer.h"
 #include "components/bookmarks/browser/base_bookmark_model_observer.h"
+#include "components/bookmarks/browser/bookmark_model.h"
+#include "components/history/core/browser/history_service.h"
 #include "components/history/core/browser/history_service_observer.h"
 #include "components/sync/driver/frontend_data_type_controller.h"
 
@@ -60,9 +62,9 @@
   syncer::SyncApiComponentFactory* const component_factory_;
 
   ScopedObserver<history::HistoryService, history::HistoryServiceObserver>
-      history_service_observer_;
-  ScopedObserver<bookmarks::BookmarkModel, BaseBookmarkModelObserver>
-      bookmark_model_observer_;
+      history_service_observer_{this};
+  ScopedObserver<bookmarks::BookmarkModel, bookmarks::BookmarkModelObserver>
+      bookmark_model_observer_{this};
 
   DISALLOW_COPY_AND_ASSIGN(BookmarkDataTypeController);
 };
diff --git a/components/sync_sessions/favicon_cache.cc b/components/sync_sessions/favicon_cache.cc
index e1c5f9ec..1b921f0e5 100644
--- a/components/sync_sessions/favicon_cache.cc
+++ b/components/sync_sessions/favicon_cache.cc
@@ -11,7 +11,6 @@
 #include "base/metrics/histogram_macros.h"
 #include "base/stl_util.h"
 #include "components/favicon/core/favicon_service.h"
-#include "components/history/core/browser/history_service.h"
 #include "components/sync/model/sync_change_processor.h"
 #include "components/sync/model/time.h"
 #include "components/sync/protocol/favicon_image_specifics.pb.h"
@@ -227,8 +226,7 @@
                            int max_sync_favicon_limit)
     : favicon_service_(favicon_service),
       history_service_(history_service),
-      max_sync_favicon_limit_(max_sync_favicon_limit),
-      history_service_observer_(this) {
+      max_sync_favicon_limit_(max_sync_favicon_limit) {
   if (history_service)
     history_service_observer_.Add(history_service);
   DVLOG(1) << "Setting favicon limit to " << max_sync_favicon_limit;
diff --git a/components/sync_sessions/favicon_cache.h b/components/sync_sessions/favicon_cache.h
index 46165ef..efee2f7 100644
--- a/components/sync_sessions/favicon_cache.h
+++ b/components/sync_sessions/favicon_cache.h
@@ -23,6 +23,7 @@
 #include "base/scoped_observer.h"
 #include "base/task/cancelable_task_tracker.h"
 #include "components/favicon_base/favicon_types.h"
+#include "components/history/core/browser/history_service.h"
 #include "components/history/core/browser/history_service_observer.h"
 #include "components/history/core/browser/history_types.h"
 #include "components/sessions/core/session_id.h"
@@ -40,10 +41,6 @@
 class FaviconService;
 }
 
-namespace history {
-class HistoryService;
-}
-
 namespace sync_sessions {
 
 enum IconSize {
@@ -240,7 +237,7 @@
   std::vector<base::OnceClosure> wait_until_ready_to_sync_cb_;
 
   ScopedObserver<history::HistoryService, history::HistoryServiceObserver>
-      history_service_observer_;
+      history_service_observer_{this};
 
   // Weak pointer factory for favicon loads.
   base::WeakPtrFactory<FaviconCache> weak_ptr_factory_{this};
diff --git a/components/sync_sessions/favicon_cache_unittest.cc b/components/sync_sessions/favicon_cache_unittest.cc
index 5a86fe8..54245cc0 100644
--- a/components/sync_sessions/favicon_cache_unittest.cc
+++ b/components/sync_sessions/favicon_cache_unittest.cc
@@ -4,9 +4,9 @@
 
 #include "components/sync_sessions/favicon_cache.h"
 
+#include <memory>
 #include <utility>
 
-#include "base/memory/ptr_util.h"
 #include "base/run_loop.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/string_util.h"
@@ -419,7 +419,7 @@
 
 std::unique_ptr<syncer::SyncErrorFactory>
 SyncFaviconCacheTest::CreateAndPassSyncErrorFactory() {
-  return base::WrapUnique(new syncer::SyncErrorFactoryMock);
+  return std::make_unique<syncer::SyncErrorFactoryMock>();
 }
 
 void SyncFaviconCacheTest::PopulateFaviconService(
diff --git a/components/ukm/observers/history_delete_observer.cc b/components/ukm/observers/history_delete_observer.cc
index da42600..bbc71a0 100644
--- a/components/ukm/observers/history_delete_observer.cc
+++ b/components/ukm/observers/history_delete_observer.cc
@@ -4,19 +4,16 @@
 
 #include "components/ukm/observers/history_delete_observer.h"
 
-#include "components/history/core/browser/history_service.h"
-
 namespace ukm {
 
-HistoryDeleteObserver::HistoryDeleteObserver() : history_observer_(this) {}
+HistoryDeleteObserver::HistoryDeleteObserver() {}
 
 HistoryDeleteObserver::~HistoryDeleteObserver() {}
 
 void HistoryDeleteObserver::ObserveServiceForDeletions(
     history::HistoryService* history_service) {
-  if (history_service) {
+  if (history_service)
     history_observer_.Add(history_service);
-  }
 }
 
 void HistoryDeleteObserver::OnURLsDeleted(
diff --git a/components/ukm/observers/history_delete_observer.h b/components/ukm/observers/history_delete_observer.h
index ea48bfc..c27efad 100644
--- a/components/ukm/observers/history_delete_observer.h
+++ b/components/ukm/observers/history_delete_observer.h
@@ -8,6 +8,7 @@
 #include <set>
 
 #include "base/scoped_observer.h"
+#include "components/history/core/browser/history_service.h"
 #include "components/history/core/browser/history_service_observer.h"
 
 namespace ukm {
@@ -34,7 +35,7 @@
  private:
   // Tracks observed history services, for cleanup.
   ScopedObserver<history::HistoryService, history::HistoryServiceObserver>
-      history_observer_;
+      history_observer_{this};
 
   DISALLOW_COPY_AND_ASSIGN(HistoryDeleteObserver);
 };
diff --git a/components/update_client/component_unpacker.cc b/components/update_client/component_unpacker.cc
index a9f34b8..64dc94d 100644
--- a/components/update_client/component_unpacker.cc
+++ b/components/update_client/component_unpacker.cc
@@ -57,11 +57,13 @@
 
 bool ComponentUnpacker::Verify() {
   VLOG(1) << "Verifying component: " << path_.value();
-  if (pk_hash_.empty() || path_.empty()) {
+  if (path_.empty()) {
     error_ = UnpackerError::kInvalidParams;
     return false;
   }
-  const std::vector<std::vector<uint8_t>> required_keys = {pk_hash_};
+  std::vector<std::vector<uint8_t>> required_keys;
+  if (!pk_hash_.empty())
+    required_keys.push_back(pk_hash_);
   const crx_file::VerifierResult result =
       crx_file::Verify(path_, crx_format_, required_keys,
                        std::vector<uint8_t>(), &public_key_, nullptr);
diff --git a/components/update_client/component_unpacker.h b/components/update_client/component_unpacker.h
index 1d79891b..0a3d051 100644
--- a/components/update_client/component_unpacker.h
+++ b/components/update_client/component_unpacker.h
@@ -84,8 +84,9 @@
   using Callback = base::OnceCallback<void(const Result& result)>;
 
   // Constructs an unpacker for a specific component unpacking operation.
-  // |pk_hash| is the expected/ public key SHA256 hash. |path| is the current
-  // location of the CRX.
+  // |pk_hash| is the expected public developer key's SHA256 hash. If empty,
+  // the unpacker accepts any developer key. |path| is the current location
+  // of the CRX.
   ComponentUnpacker(const std::vector<uint8_t>& pk_hash,
                     const base::FilePath& path,
                     scoped_refptr<CrxInstaller> installer,
diff --git a/components/update_client/update_checker_unittest.cc b/components/update_client/update_checker_unittest.cc
index 24fc086fa..001bdd0 100644
--- a/components/update_client/update_checker_unittest.cc
+++ b/components/update_client/update_checker_unittest.cc
@@ -234,6 +234,7 @@
 
 std::unique_ptr<Component> UpdateCheckerTest::MakeComponent() const {
   CrxComponent crx_component;
+  crx_component.app_id = "jebgalgnebhfojomionfpkfelancnnkf";
   crx_component.name = "test_jebg";
   crx_component.pk_hash.assign(jebg_hash, jebg_hash + base::size(jebg_hash));
   crx_component.installer = nullptr;
diff --git a/components/update_client/update_client.h b/components/update_client/update_client.h
index 6d58c59..4b8061c 100644
--- a/components/update_client/update_client.h
+++ b/components/update_client/update_client.h
@@ -220,9 +220,15 @@
   CrxComponent(const CrxComponent& other);
   ~CrxComponent();
 
-  // SHA256 hash of the CRX's public key.
+  // Optional SHA256 hash of the CRX's public key. If not supplied, the
+  // unpacker can accept any CRX for this app, provided that the CRX meets the
+  // VerifierFormat requirements specified by the service's configurator.
+  // Callers that know or need a specific developer signature on acceptable CRX
+  // files must provide this.
   std::vector<uint8_t> pk_hash;
+
   scoped_refptr<CrxInstaller> installer;
+  std::string app_id;
 
   // The current version if the CRX is updated. Otherwise, "0" or "0.0" if
   // the CRX is installed.
diff --git a/components/user_manager/user_image/user_image.cc b/components/user_manager/user_image/user_image.cc
index 55b76866..050f2f0 100644
--- a/components/user_manager/user_image/user_image.cc
+++ b/components/user_manager/user_image/user_image.cc
@@ -4,7 +4,8 @@
 
 #include "components/user_manager/user_image/user_image.h"
 
-#include "base/memory/ptr_util.h"
+#include <memory>
+
 #include "base/trace_event/trace_event.h"
 #include "third_party/skia/include/core/SkBitmap.h"
 #include "ui/gfx/codec/jpeg_codec.h"
@@ -54,7 +55,7 @@
     const gfx::ImageSkia& image,
     ImageFormat image_format) {
   if (image.isNull())
-    return base::WrapUnique(new UserImage);
+    return std::make_unique<UserImage>();
 
   scoped_refptr<base::RefCountedBytes> image_bytes = Encode(*image.bitmap(),
                                                             image_format);
@@ -64,7 +65,7 @@
     result->MarkAsSafe();
     return result;
   }
-  return base::WrapUnique(new UserImage(image));
+  return std::make_unique<UserImage>(image);
 }
 
 // static
diff --git a/components/variations/service/variations_service_unittest.cc b/components/variations/service/variations_service_unittest.cc
index f1a6d488..8d451556 100644
--- a/components/variations/service/variations_service_unittest.cc
+++ b/components/variations/service/variations_service_unittest.cc
@@ -15,7 +15,6 @@
 #include "base/feature_list.h"
 #include "base/json/json_string_value_serializer.h"
 #include "base/macros.h"
-#include "base/memory/ptr_util.h"
 #include "base/run_loop.h"
 #include "base/stl_util.h"
 #include "base/strings/string_number_conversions.h"
@@ -134,7 +133,7 @@
       PrefService* local_state,
       metrics::MetricsStateManager* state_manager,
       bool use_secure_url)
-      : VariationsService(base::WrapUnique(new TestVariationsServiceClient()),
+      : VariationsService(std::make_unique<TestVariationsServiceClient>(),
                           std::move(test_notifier),
                           local_state,
                           state_manager,
diff --git a/components/viz/OWNERS b/components/viz/OWNERS
index 0995ad8..6e8966a 100644
--- a/components/viz/OWNERS
+++ b/components/viz/OWNERS
@@ -47,6 +47,7 @@
 # overlays
 ccameron@chromium.org
 dcastagna@chromium.org
+khushalsagar@chromium.org
 
 # scheduling / begin frames
 sunnyps@chromium.org
diff --git a/components/viz/common/frame_sinks/begin_frame_source_unittest.cc b/components/viz/common/frame_sinks/begin_frame_source_unittest.cc
index 17478bf..6ef808e6 100644
--- a/components/viz/common/frame_sinks/begin_frame_source_unittest.cc
+++ b/components/viz/common/frame_sinks/begin_frame_source_unittest.cc
@@ -6,7 +6,8 @@
 
 #include <stdint.h>
 
-#include "base/memory/ptr_util.h"
+#include <memory>
+
 #include "base/test/test_mock_time_task_runner.h"
 #include "components/viz/test/begin_frame_args_test.h"
 #include "components/viz/test/begin_frame_source_test.h"
@@ -69,7 +70,7 @@
 
     delay_based_time_source_ = time_source.get();
     source_.reset(new BackToBackBeginFrameSource(std::move(time_source)));
-    obs_ = base::WrapUnique(new ::testing::NiceMock<MockBeginFrameObserver>);
+    obs_ = std::make_unique<::testing::NiceMock<MockBeginFrameObserver>>();
   }
 
   void TearDown() override { obs_.reset(); }
diff --git a/components/webcrypto/algorithms/aes_cbc.cc b/components/webcrypto/algorithms/aes_cbc.cc
index a9669a3..89fd33a 100644
--- a/components/webcrypto/algorithms/aes_cbc.cc
+++ b/components/webcrypto/algorithms/aes_cbc.cc
@@ -6,8 +6,9 @@
 #include <stddef.h>
 #include <stdint.h>
 
+#include <memory>
+
 #include "base/logging.h"
-#include "base/memory/ptr_util.h"
 #include "base/numerics/safe_math.h"
 #include "components/webcrypto/algorithms/aes.h"
 #include "components/webcrypto/algorithms/util.h"
@@ -117,7 +118,7 @@
 }  // namespace
 
 std::unique_ptr<AlgorithmImplementation> CreateAesCbcImplementation() {
-  return base::WrapUnique(new AesCbcImplementation);
+  return std::make_unique<AesCbcImplementation>();
 }
 
 }  // namespace webcrypto
diff --git a/components/webcrypto/algorithms/aes_ctr.cc b/components/webcrypto/algorithms/aes_ctr.cc
index 54a83814..e504da2 100644
--- a/components/webcrypto/algorithms/aes_ctr.cc
+++ b/components/webcrypto/algorithms/aes_ctr.cc
@@ -6,9 +6,10 @@
 #include <stdint.h>
 #include <string.h>
 
+#include <memory>
+
 #include "base/logging.h"
 #include "base/macros.h"
-#include "base/memory/ptr_util.h"
 #include "base/numerics/safe_math.h"
 #include "components/webcrypto/algorithms/aes.h"
 #include "components/webcrypto/algorithms/util.h"
@@ -257,7 +258,7 @@
 }  // namespace
 
 std::unique_ptr<AlgorithmImplementation> CreateAesCtrImplementation() {
-  return base::WrapUnique(new AesCtrImplementation);
+  return std::make_unique<AesCtrImplementation>();
 }
 
 }  // namespace webcrypto
diff --git a/components/webcrypto/algorithms/aes_gcm.cc b/components/webcrypto/algorithms/aes_gcm.cc
index 09545a30..dbf1a8f 100644
--- a/components/webcrypto/algorithms/aes_gcm.cc
+++ b/components/webcrypto/algorithms/aes_gcm.cc
@@ -5,10 +5,10 @@
 #include <stddef.h>
 #include <stdint.h>
 
+#include <memory>
 #include <vector>
 
 #include "base/logging.h"
-#include "base/memory/ptr_util.h"
 #include "base/stl_util.h"
 #include "components/webcrypto/algorithms/aes.h"
 #include "components/webcrypto/algorithms/util.h"
@@ -83,7 +83,7 @@
 }  // namespace
 
 std::unique_ptr<AlgorithmImplementation> CreateAesGcmImplementation() {
-  return base::WrapUnique(new AesGcmImplementation);
+  return std::make_unique<AesGcmImplementation>();
 }
 
 }  // namespace webcrypto
diff --git a/components/webcrypto/algorithms/aes_kw.cc b/components/webcrypto/algorithms/aes_kw.cc
index 4a5f9525..fc6e033 100644
--- a/components/webcrypto/algorithms/aes_kw.cc
+++ b/components/webcrypto/algorithms/aes_kw.cc
@@ -5,10 +5,10 @@
 #include <stddef.h>
 #include <stdint.h>
 
+#include <memory>
 #include <vector>
 
 #include "base/location.h"
-#include "base/memory/ptr_util.h"
 #include "base/numerics/safe_math.h"
 #include "components/webcrypto/algorithms/aes.h"
 #include "components/webcrypto/blink_key_handle.h"
@@ -104,7 +104,7 @@
 }  // namespace
 
 std::unique_ptr<AlgorithmImplementation> CreateAesKwImplementation() {
-  return base::WrapUnique(new AesKwImplementation);
+  return std::make_unique<AesKwImplementation>();
 }
 
 }  // namespace webcrypto
diff --git a/components/webcrypto/algorithms/ecdh.cc b/components/webcrypto/algorithms/ecdh.cc
index ca5953b..e7dba88 100644
--- a/components/webcrypto/algorithms/ecdh.cc
+++ b/components/webcrypto/algorithms/ecdh.cc
@@ -5,8 +5,9 @@
 #include <stddef.h>
 #include <stdint.h>
 
+#include <memory>
+
 #include "base/logging.h"
-#include "base/memory/ptr_util.h"
 #include "components/webcrypto/algorithm_implementation.h"
 #include "components/webcrypto/algorithms/ec.h"
 #include "components/webcrypto/algorithms/util.h"
@@ -123,7 +124,7 @@
 }  // namespace
 
 std::unique_ptr<AlgorithmImplementation> CreateEcdhImplementation() {
-  return base::WrapUnique(new EcdhImplementation);
+  return std::make_unique<EcdhImplementation>();
 }
 
 }  // namespace webcrypto
diff --git a/components/webcrypto/algorithms/ecdsa.cc b/components/webcrypto/algorithms/ecdsa.cc
index 49fc2572..023202d 100644
--- a/components/webcrypto/algorithms/ecdsa.cc
+++ b/components/webcrypto/algorithms/ecdsa.cc
@@ -5,8 +5,9 @@
 #include <stddef.h>
 #include <stdint.h>
 
+#include <memory>
+
 #include "base/logging.h"
-#include "base/memory/ptr_util.h"
 #include "components/webcrypto/algorithm_implementation.h"
 #include "components/webcrypto/algorithms/ec.h"
 #include "components/webcrypto/algorithms/util.h"
@@ -256,7 +257,7 @@
 }  // namespace
 
 std::unique_ptr<AlgorithmImplementation> CreateEcdsaImplementation() {
-  return base::WrapUnique(new EcdsaImplementation);
+  return std::make_unique<EcdsaImplementation>();
 }
 
 }  // namespace webcrypto
diff --git a/components/webcrypto/algorithms/hkdf.cc b/components/webcrypto/algorithms/hkdf.cc
index bf8e23b..743bda02 100644
--- a/components/webcrypto/algorithms/hkdf.cc
+++ b/components/webcrypto/algorithms/hkdf.cc
@@ -4,8 +4,9 @@
 
 #include <stdint.h>
 
+#include <memory>
+
 #include "base/logging.h"
-#include "base/memory/ptr_util.h"
 #include "components/webcrypto/algorithm_implementation.h"
 #include "components/webcrypto/algorithms/secret_key_util.h"
 #include "components/webcrypto/algorithms/util.h"
@@ -131,7 +132,7 @@
 }  // namespace
 
 std::unique_ptr<AlgorithmImplementation> CreateHkdfImplementation() {
-  return base::WrapUnique(new HkdfImplementation);
+  return std::make_unique<HkdfImplementation>();
 }
 
 }  // namespace webcrypto
diff --git a/components/webcrypto/algorithms/hmac.cc b/components/webcrypto/algorithms/hmac.cc
index 61e9c0b..027333a 100644
--- a/components/webcrypto/algorithms/hmac.cc
+++ b/components/webcrypto/algorithms/hmac.cc
@@ -5,8 +5,9 @@
 #include <stddef.h>
 #include <stdint.h>
 
+#include <memory>
+
 #include "base/logging.h"
-#include "base/memory/ptr_util.h"
 #include "base/numerics/safe_math.h"
 #include "components/webcrypto/algorithm_implementation.h"
 #include "components/webcrypto/algorithms/secret_key_util.h"
@@ -320,7 +321,7 @@
 }  // namespace
 
 std::unique_ptr<AlgorithmImplementation> CreateHmacImplementation() {
-  return base::WrapUnique(new HmacImplementation);
+  return std::make_unique<HmacImplementation>();
 }
 
 }  // namespace webcrypto
diff --git a/components/webcrypto/algorithms/pbkdf2.cc b/components/webcrypto/algorithms/pbkdf2.cc
index 735e296..3c73173 100644
--- a/components/webcrypto/algorithms/pbkdf2.cc
+++ b/components/webcrypto/algorithms/pbkdf2.cc
@@ -4,7 +4,8 @@
 
 #include <stdint.h>
 
-#include "base/memory/ptr_util.h"
+#include <memory>
+
 #include "base/stl_util.h"
 #include "components/webcrypto/algorithm_implementation.h"
 #include "components/webcrypto/algorithms/secret_key_util.h"
@@ -133,7 +134,7 @@
 }  // namespace
 
 std::unique_ptr<AlgorithmImplementation> CreatePbkdf2Implementation() {
-  return base::WrapUnique(new Pbkdf2Implementation);
+  return std::make_unique<Pbkdf2Implementation>();
 }
 
 }  // namespace webcrypto
diff --git a/components/webcrypto/algorithms/rsa_oaep.cc b/components/webcrypto/algorithms/rsa_oaep.cc
index 1fc15ffba..a6fa77b 100644
--- a/components/webcrypto/algorithms/rsa_oaep.cc
+++ b/components/webcrypto/algorithms/rsa_oaep.cc
@@ -6,7 +6,8 @@
 #include <stdint.h>
 #include <string.h>
 
-#include "base/memory/ptr_util.h"
+#include <memory>
+
 #include "components/webcrypto/algorithms/rsa.h"
 #include "components/webcrypto/algorithms/util.h"
 #include "components/webcrypto/blink_key_handle.h"
@@ -144,7 +145,7 @@
 }  // namespace
 
 std::unique_ptr<AlgorithmImplementation> CreateRsaOaepImplementation() {
-  return base::WrapUnique(new RsaOaepImplementation);
+  return std::make_unique<RsaOaepImplementation>();
 }
 
 }  // namespace webcrypto
diff --git a/components/webcrypto/algorithms/rsa_pss.cc b/components/webcrypto/algorithms/rsa_pss.cc
index 3e5c77d8..1771aea 100644
--- a/components/webcrypto/algorithms/rsa_pss.cc
+++ b/components/webcrypto/algorithms/rsa_pss.cc
@@ -4,7 +4,8 @@
 
 #include <stdint.h>
 
-#include "base/memory/ptr_util.h"
+#include <memory>
+
 #include "components/webcrypto/algorithms/rsa.h"
 #include "components/webcrypto/algorithms/rsa_sign.h"
 #include "components/webcrypto/status.h"
@@ -57,7 +58,7 @@
 }  // namespace
 
 std::unique_ptr<AlgorithmImplementation> CreateRsaPssImplementation() {
-  return base::WrapUnique(new RsaPssImplementation);
+  return std::make_unique<RsaPssImplementation>();
 }
 
 }  // namespace webcrypto
diff --git a/components/webcrypto/algorithms/rsa_ssa.cc b/components/webcrypto/algorithms/rsa_ssa.cc
index c5dae379..2500b3a 100644
--- a/components/webcrypto/algorithms/rsa_ssa.cc
+++ b/components/webcrypto/algorithms/rsa_ssa.cc
@@ -4,7 +4,8 @@
 
 #include <stdint.h>
 
-#include "base/memory/ptr_util.h"
+#include <memory>
+
 #include "components/webcrypto/algorithms/rsa.h"
 #include "components/webcrypto/algorithms/rsa_sign.h"
 #include "components/webcrypto/status.h"
@@ -54,7 +55,7 @@
 }  // namespace
 
 std::unique_ptr<AlgorithmImplementation> CreateRsaSsaImplementation() {
-  return base::WrapUnique(new RsaSsaImplementation);
+  return std::make_unique<RsaSsaImplementation>();
 }
 
 }  // namespace webcrypto
diff --git a/content/browser/accessibility/accessibility_event_recorder_uia_win.cc b/content/browser/accessibility/accessibility_event_recorder_uia_win.cc
index 27a2c8a..5b946a0 100644
--- a/content/browser/accessibility/accessibility_event_recorder_uia_win.cc
+++ b/content/browser/accessibility/accessibility_event_recorder_uia_win.cc
@@ -13,6 +13,7 @@
 #include "base/strings/utf_string_conversions.h"
 #include "base/win/scoped_bstr.h"
 #include "base/win/scoped_com_initializer.h"
+#include "base/win/scoped_safearray.h"
 #include "base/win/scoped_variant.h"
 #include "base/win/windows_version.h"
 #include "content/browser/accessibility/accessibility_tree_formatter_utils_win.h"
@@ -301,14 +302,14 @@
   if (!owner_)
     return S_OK;
 
-  base::win::ScopedBstr id;
-  sender->get_CurrentAutomationId(id.Receive());
-  base::win::ScopedVariant id_variant(id, id.Length());
+  base::win::ScopedSafearray id;
+  sender->GetRuntimeId(id.Receive());
+  base::win::ScopedVariant id_variant(id.Release());
 
   Microsoft::WRL::ComPtr<IUIAutomationElement> element_found;
   Microsoft::WRL::ComPtr<IUIAutomationCondition> condition;
 
-  owner_->uia_->CreatePropertyCondition(UIA_AutomationIdPropertyId, id_variant,
+  owner_->uia_->CreatePropertyCondition(UIA_RuntimeIdPropertyId, id_variant,
                                         &condition);
   CHECK(condition);
   root_->FindFirst(TreeScope::TreeScope_Subtree, condition.Get(),
diff --git a/content/browser/accessibility/browser_accessibility_manager.cc b/content/browser/accessibility/browser_accessibility_manager.cc
index 23c85d7..4f059d6 100644
--- a/content/browser/accessibility/browser_accessibility_manager.cc
+++ b/content/browser/accessibility/browser_accessibility_manager.cc
@@ -11,6 +11,7 @@
 
 #include "base/debug/crash_logging.h"
 #include "base/logging.h"
+#include "base/metrics/user_metrics.h"
 #include "base/no_destructor.h"
 #include "build/build_config.h"
 #include "content/browser/accessibility/browser_accessibility.h"
@@ -634,6 +635,9 @@
   if (!delegate_)
     return;
 
+  base::RecordAction(
+      base::UserMetricsAction("Accessibility.NativeApi.SetFocus"));
+
   ui::AXActionData action_data;
   action_data.action = ax::mojom::Action::kFocus;
   action_data.target_node_id = node.GetId();
@@ -690,6 +694,9 @@
   if (!delegate_)
     return;
 
+  base::RecordAction(
+      base::UserMetricsAction("Accessibility.NativeApi.DoDefault"));
+
   ui::AXActionData action_data;
   action_data.action = ax::mojom::Action::kDoDefault;
   action_data.target_node_id = node.GetId();
@@ -746,6 +753,9 @@
   if (!delegate_)
     return;
 
+  base::RecordAction(
+      base::UserMetricsAction("Accessibility.NativeApi.ScrollToMakeVisible"));
+
   ui::AXActionData action_data;
   action_data.target_node_id = node.GetId();
   action_data.action = ax::mojom::Action::kScrollToMakeVisible;
@@ -851,6 +861,9 @@
   if (!delegate_)
     return;
 
+  base::RecordAction(
+      base::UserMetricsAction("Accessibility.NativeApi.HitTest"));
+
   ui::AXActionData action_data;
   action_data.action = ax::mojom::Action::kHitTest;
   action_data.target_point = point;
diff --git a/content/browser/android/web_contents_observer_proxy.cc b/content/browser/android/web_contents_observer_proxy.cc
index 1359ea2..4c86986 100644
--- a/content/browser/android/web_contents_observer_proxy.cc
+++ b/content/browser/android/web_contents_observer_proxy.cc
@@ -14,7 +14,7 @@
 #include "base/strings/utf_string_conversions.h"
 #include "base/trace_event/trace_event.h"
 #include "content/browser/android/navigation_handle_proxy.h"
-#include "content/browser/frame_host/navigation_handle_impl.h"
+#include "content/browser/frame_host/navigation_request.h"
 #include "content/browser/renderer_host/render_widget_host_impl.h"
 #include "content/browser/web_contents/web_contents_impl.h"
 #include "content/public/android/content_jni_headers/WebContentsObserverProxy_jni.h"
@@ -131,18 +131,14 @@
     NavigationHandle* navigation_handle) {
   Java_WebContentsObserverProxy_didStartNavigation(
       AttachCurrentThread(), java_observer_,
-      static_cast<NavigationHandleImpl*>(navigation_handle)
-          ->navigation_request()
-          ->java_navigation_handle());
+      NavigationRequest::From(navigation_handle)->java_navigation_handle());
 }
 
 void WebContentsObserverProxy::DidRedirectNavigation(
     NavigationHandle* navigation_handle) {
   Java_WebContentsObserverProxy_didRedirectNavigation(
       AttachCurrentThread(), java_observer_,
-      static_cast<NavigationHandleImpl*>(navigation_handle)
-          ->navigation_request()
-          ->java_navigation_handle());
+      NavigationRequest::From(navigation_handle)->java_navigation_handle());
 }
 
 void WebContentsObserverProxy::DidFinishNavigation(
@@ -152,9 +148,7 @@
 
   Java_WebContentsObserverProxy_didFinishNavigation(
       AttachCurrentThread(), java_observer_,
-      static_cast<NavigationHandleImpl*>(navigation_handle)
-          ->navigation_request()
-          ->java_navigation_handle());
+      NavigationRequest::From(navigation_handle)->java_navigation_handle());
 }
 
 void WebContentsObserverProxy::DidFinishLoad(RenderFrameHost* render_frame_host,
diff --git a/content/browser/child_process_task_port_provider_mac_unittest.cc b/content/browser/child_process_task_port_provider_mac_unittest.cc
index 9c5be36..49bbadef 100644
--- a/content/browser/child_process_task_port_provider_mac_unittest.cc
+++ b/content/browser/child_process_task_port_provider_mac_unittest.cc
@@ -12,6 +12,7 @@
 #include "base/synchronization/waitable_event.h"
 #include "base/task/post_task.h"
 #include "base/test/task_environment.h"
+#include "base/test/test_timeouts.h"
 #include "content/common/child_process.mojom.h"
 #include "mojo/public/cpp/system/platform_handle.h"
 #include "testing/gmock/include/gmock/gmock.h"
@@ -49,7 +50,6 @@
   ChildProcessTaskPortProviderTest()
       : event_(base::WaitableEvent::ResetPolicy::AUTOMATIC) {
     provider_.AddObserver(this);
-    last_seqno_ = GetNotificationPortSequenceNumber();
   }
   ~ChildProcessTaskPortProviderTest() override {
     provider_.RemoveObserver(this);
@@ -57,14 +57,15 @@
 
   void WaitForTaskPort() { event_.Wait(); }
 
-  // There is no observer callback for when a process dies, so use the kernel's
-  // sequence number on the notification port receive right to determine if the
-  // DEAD_NAME notification has been delivered. If the seqno is different, then
-  // assume it is.
-  void WaitForNotificationPortSeqnoChange() {
-    base::RunLoop run_loop;
-    CheckSequenceNumberAndQuitIfChanged(run_loop.QuitWhenIdleClosure());
-    run_loop.Run();
+  // There is no observer callback for when a process dies, so spin the run loop
+  // until the desired exit |condition| is met.
+  void WaitForCondition(base::RepeatingCallback<bool(void)> condition) {
+    base::TimeTicks start = base::TimeTicks::Now();
+    do {
+      base::RunLoop().RunUntilIdle();
+      if (condition.Run())
+        break;
+    } while ((base::TimeTicks::Now() - start) < TestTimeouts::action_timeout());
   }
 
   mach_port_urefs_t GetSendRightRefCount(mach_port_t send_right) {
@@ -95,37 +96,10 @@
   }
 
  private:
-  mach_port_seqno_t GetNotificationPortSequenceNumber() {
-    mach_port_status_t status;
-    mach_msg_type_number_t count = sizeof(status);
-    kern_return_t kr = mach_port_get_attributes(
-        mach_task_self(), provider_.notification_port_.get(),
-        MACH_PORT_RECEIVE_STATUS, reinterpret_cast<mach_port_info_t>(&status),
-        &count);
-    EXPECT_EQ(KERN_SUCCESS, kr);
-    return status.mps_seqno;
-  }
-
-  void CheckSequenceNumberAndQuitIfChanged(base::OnceClosure quit_closure) {
-    mach_port_seqno_t seqno = GetNotificationPortSequenceNumber();
-    if (seqno == last_seqno_) {
-      task_environment_.GetMainThreadTaskRunner()->PostDelayedTask(
-          FROM_HERE,
-          base::BindOnce(&ChildProcessTaskPortProviderTest::
-                             CheckSequenceNumberAndQuitIfChanged,
-                         base::Unretained(this), std::move(quit_closure)),
-          base::TimeDelta::FromMilliseconds(10));
-    } else {
-      last_seqno_ = seqno;
-      std::move(quit_closure).Run();
-    }
-  }
-
   base::test::TaskEnvironment task_environment_;
   ChildProcessTaskPortProvider provider_;
   base::WaitableEvent event_;
   std::vector<base::ProcessHandle> received_processes_;
-  mach_port_seqno_t last_seqno_;
 };
 
 static constexpr mach_port_t kMachPortNull = MACH_PORT_NULL;
@@ -167,7 +141,11 @@
   // "Kill" the process and verify that the association is deleted.
   receive_right.reset();
 
-  WaitForNotificationPortSeqnoChange();
+  WaitForCondition(base::BindRepeating(
+      [](ChildProcessTaskPortProvider* provider) -> bool {
+        return provider->TaskForPid(99) == MACH_PORT_NULL;
+      },
+      base::Unretained(provider())));
 
   EXPECT_EQ(kMachPortNull, provider()->TaskForPid(99));
 
@@ -176,8 +154,7 @@
   EXPECT_EQ(1u, GetDeadNameRefCount(send_right.get()));
 }
 
-// Test is flaky. See https://crbug.com/986288.
-TEST_F(ChildProcessTaskPortProviderTest, DISABLED_DeadTaskPort) {
+TEST_F(ChildProcessTaskPortProviderTest, DeadTaskPort) {
   EXPECT_EQ(kMachPortNull, provider()->TaskForPid(6));
 
   // Create a fake task port for the fake process.
@@ -237,7 +214,11 @@
 
   // Clean up the second receive right.
   receive_right2.reset();
-  WaitForNotificationPortSeqnoChange();
+  WaitForCondition(base::BindRepeating(
+      [](ChildProcessTaskPortProvider* provider) -> bool {
+        return provider->TaskForPid(123) == MACH_PORT_NULL;
+      },
+      base::Unretained(provider())));
   EXPECT_EQ(kMachPortNull, provider()->TaskForPid(123));
 }
 
diff --git a/content/browser/devtools/devtools_instrumentation.cc b/content/browser/devtools/devtools_instrumentation.cc
index 87f23d7..d0817ac 100644
--- a/content/browser/devtools/devtools_instrumentation.cc
+++ b/content/browser/devtools/devtools_instrumentation.cc
@@ -13,7 +13,6 @@
 #include "content/browser/devtools/render_frame_devtools_agent_host.h"
 #include "content/browser/devtools/service_worker_devtools_agent_host.h"
 #include "content/browser/frame_host/frame_tree_node.h"
-#include "content/browser/frame_host/navigation_handle_impl.h"
 #include "content/browser/frame_host/navigation_request.h"
 #include "content/browser/web_contents/web_contents_impl.h"
 #include "content/browser/web_package/signed_exchange_envelope.h"
@@ -182,9 +181,10 @@
 }
 
 std::vector<std::unique_ptr<NavigationThrottle>> CreateNavigationThrottles(
-    NavigationHandleImpl* navigation_handle) {
+    NavigationHandle* navigation_handle) {
   std::vector<std::unique_ptr<NavigationThrottle>> result;
-  FrameTreeNode* frame_tree_node = navigation_handle->frame_tree_node();
+  FrameTreeNode* frame_tree_node =
+      NavigationRequest::From(navigation_handle)->frame_tree_node();
 
   DevToolsAgentHostImpl* agent_host =
       RenderFrameDevToolsAgentHost::GetFor(frame_tree_node);
diff --git a/content/browser/devtools/devtools_instrumentation.h b/content/browser/devtools/devtools_instrumentation.h
index 2207045..0825bf7 100644
--- a/content/browser/devtools/devtools_instrumentation.h
+++ b/content/browser/devtools/devtools_instrumentation.h
@@ -37,7 +37,7 @@
 class SignedExchangeEnvelope;
 class FrameTreeNode;
 class FileSelectListener;
-class NavigationHandleImpl;
+class NavigationHandle;
 class NavigationRequest;
 class NavigationThrottle;
 class RenderFrameHostImpl;
@@ -129,7 +129,7 @@
     const base::Optional<std::string>& response_headers_text);
 
 std::vector<std::unique_ptr<NavigationThrottle>> CreateNavigationThrottles(
-    NavigationHandleImpl* navigation_handle);
+    NavigationHandle* navigation_handle);
 
 // Asks any interested agents to handle the given certificate error. Returns
 // |true| if the error was handled, |false| otherwise.
diff --git a/content/browser/devtools/devtools_url_loader_interceptor.cc b/content/browser/devtools/devtools_url_loader_interceptor.cc
index a532aaf..701378d 100644
--- a/content/browser/devtools/devtools_url_loader_interceptor.cc
+++ b/content/browser/devtools/devtools_url_loader_interceptor.cc
@@ -1069,10 +1069,9 @@
 
   response_metadata_->redirect_info = std::make_unique<net::RedirectInfo>(
       net::RedirectInfo::ComputeRedirectInfo(
-          request.method, request.url, request.request_initiator,
-          request.site_for_cookies, first_party_url_policy,
-          request.referrer_policy, request.referrer.spec(),
-          headers.response_code(), redirect_url,
+          request.method, request.url, request.site_for_cookies,
+          first_party_url_policy, request.referrer_policy,
+          request.referrer.spec(), headers.response_code(), redirect_url,
           net::RedirectUtil::GetReferrerPolicyHeader(&headers),
           false /* insecure_scheme_was_upgraded */, true /* copy_fragment */));
 
diff --git a/content/browser/devtools/protocol/target_auto_attacher.cc b/content/browser/devtools/protocol/target_auto_attacher.cc
index 1f80794..8a80f23a 100644
--- a/content/browser/devtools/protocol/target_auto_attacher.cc
+++ b/content/browser/devtools/protocol/target_auto_attacher.cc
@@ -10,7 +10,6 @@
 #include "content/browser/devtools/service_worker_devtools_agent_host.h"
 #include "content/browser/frame_host/frame_tree.h"
 #include "content/browser/frame_host/frame_tree_node.h"
-#include "content/browser/frame_host/navigation_handle_impl.h"
 #include "content/browser/frame_host/navigation_request.h"
 #include "content/browser/frame_host/render_frame_host_impl.h"
 #include "content/browser/web_contents/web_contents_impl.h"
@@ -208,12 +207,12 @@
 }
 
 DevToolsAgentHost* TargetAutoAttacher::AutoAttachToFrame(
-    NavigationHandleImpl* navigation_handle) {
+    NavigationRequest* navigation_request) {
   if (!ShouldThrottleFramesNavigation())
     return nullptr;
 
-  FrameTreeNode* frame_tree_node = navigation_handle->frame_tree_node();
-  RenderFrameHostImpl* new_host = navigation_handle->GetRenderFrameHost();
+  FrameTreeNode* frame_tree_node = navigation_request->frame_tree_node();
+  RenderFrameHostImpl* new_host = navigation_request->GetRenderFrameHost();
 
   // |new_host| can be nullptr for navigation that doesn't commmit
   // (e.g. download). Skip possibly detaching the old agent host so the DevTools
@@ -237,7 +236,7 @@
 
   if (new_cross_process) {
     agent_host = RenderFrameDevToolsAgentHost::CreateForCrossProcessNavigation(
-        navigation_handle);
+        navigation_request);
     DCHECK(auto_attached_hosts_.find(agent_host) == auto_attached_hosts_.end());
     attach_callback_.Run(agent_host.get(), wait_for_debugger_on_start_);
     auto_attached_hosts_.insert(agent_host);
diff --git a/content/browser/devtools/protocol/target_auto_attacher.h b/content/browser/devtools/protocol/target_auto_attacher.h
index e958bc0..ed03537b 100644
--- a/content/browser/devtools/protocol/target_auto_attacher.h
+++ b/content/browser/devtools/protocol/target_auto_attacher.h
@@ -13,7 +13,7 @@
 
 class DevToolsAgentHostImpl;
 class DevToolsRendererChannel;
-class NavigationHandleImpl;
+class NavigationRequest;
 class RenderFrameHostImpl;
 
 namespace protocol {
@@ -40,7 +40,7 @@
   void AgentHostClosed(DevToolsAgentHost* host);
 
   bool ShouldThrottleFramesNavigation();
-  DevToolsAgentHost* AutoAttachToFrame(NavigationHandleImpl* navigation_handle);
+  DevToolsAgentHost* AutoAttachToFrame(NavigationRequest* navigation_request);
   void ChildWorkerCreated(DevToolsAgentHostImpl* agent_host,
                           bool waiting_for_debugger);
 
diff --git a/content/browser/devtools/protocol/target_handler.cc b/content/browser/devtools/protocol/target_handler.cc
index 693edd13..ed5f730 100644
--- a/content/browser/devtools/protocol/target_handler.cc
+++ b/content/browser/devtools/protocol/target_handler.cc
@@ -17,7 +17,7 @@
 #include "content/browser/devtools/browser_devtools_agent_host.h"
 #include "content/browser/devtools/devtools_agent_host_impl.h"
 #include "content/browser/devtools/devtools_manager.h"
-#include "content/browser/frame_host/navigation_handle_impl.h"
+#include "content/browser/frame_host/navigation_request.h"
 #include "content/public/browser/browser_context.h"
 #include "content/public/browser/devtools_agent_host_client.h"
 #include "content/public/browser/navigation_throttle.h"
@@ -417,7 +417,7 @@
   if (!target_handler_)
     return PROCEED;
   agent_host_ = target_handler_->auto_attacher_.AutoAttachToFrame(
-      static_cast<NavigationHandleImpl*>(navigation_handle()));
+      NavigationRequest::From(navigation_handle()));
   if (!agent_host_.get())
     return PROCEED;
   target_handler_->auto_attached_sessions_[agent_host_.get()]->SetThrottle(
diff --git a/content/browser/devtools/protocol/tracing_handler.cc b/content/browser/devtools/protocol/tracing_handler.cc
index dbfab95..51069f5 100644
--- a/content/browser/devtools/protocol/tracing_handler.cc
+++ b/content/browser/devtools/protocol/tracing_handler.cc
@@ -35,7 +35,7 @@
 #include "content/browser/devtools/devtools_video_consumer.h"
 #include "content/browser/frame_host/frame_tree.h"
 #include "content/browser/frame_host/frame_tree_node.h"
-#include "content/browser/frame_host/navigation_handle_impl.h"
+#include "content/browser/frame_host/navigation_request.h"
 #include "content/browser/frame_host/render_frame_host_impl.h"
 #include "content/browser/gpu/gpu_process_host.h"
 #include "content/browser/renderer_host/render_widget_host_impl.h"
@@ -1081,19 +1081,19 @@
 }
 
 void TracingHandler::ReadyToCommitNavigation(
-    NavigationHandleImpl* navigation_handle) {
+    NavigationRequest* navigation_request) {
   if (!did_initiate_recording_)
     return;
   auto data = std::make_unique<base::trace_event::TracedValue>();
-  FillFrameData(data.get(), navigation_handle->frame_tree_node(),
-                navigation_handle->GetRenderFrameHost(),
-                navigation_handle->GetURL());
+  FillFrameData(data.get(), navigation_request->frame_tree_node(),
+                navigation_request->GetRenderFrameHost(),
+                navigation_request->GetURL());
   TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"),
                        "FrameCommittedInBrowser", TRACE_EVENT_SCOPE_THREAD,
                        "data", std::move(data));
 
   SetupProcessFilter(base::kNullProcessId,
-                     navigation_handle->GetRenderFrameHost());
+                     navigation_request->GetRenderFrameHost());
   session_->ChangeTraceConfig(trace_config_);
 }
 
diff --git a/content/browser/devtools/protocol/tracing_handler.h b/content/browser/devtools/protocol/tracing_handler.h
index 34ebb5dc..c83b585 100644
--- a/content/browser/devtools/protocol/tracing_handler.h
+++ b/content/browser/devtools/protocol/tracing_handler.h
@@ -37,7 +37,7 @@
 class DevToolsVideoConsumer;
 class DevToolsIOContext;
 class FrameTreeNode;
-class NavigationHandleImpl;
+class NavigationRequest;
 class RenderFrameHost;
 class RenderProcessHost;
 
@@ -77,7 +77,7 @@
   Response RecordClockSyncMarker(const std::string& sync_id) override;
 
   bool did_initiate_recording() { return did_initiate_recording_; }
-  void ReadyToCommitNavigation(NavigationHandleImpl* navigation_handle);
+  void ReadyToCommitNavigation(NavigationRequest* navigation_request);
   void FrameDeleted(RenderFrameHostImpl* frame_host);
 
  private:
diff --git a/content/browser/devtools/render_frame_devtools_agent_host.cc b/content/browser/devtools/render_frame_devtools_agent_host.cc
index cb520b7..2622dea6 100644
--- a/content/browser/devtools/render_frame_devtools_agent_host.cc
+++ b/content/browser/devtools/render_frame_devtools_agent_host.cc
@@ -41,7 +41,6 @@
 #include "content/browser/devtools/protocol/storage_handler.h"
 #include "content/browser/devtools/protocol/target_handler.h"
 #include "content/browser/devtools/protocol/tracing_handler.h"
-#include "content/browser/frame_host/navigation_handle_impl.h"
 #include "content/browser/frame_host/navigation_request.h"
 #include "content/browser/frame_host/render_frame_host_impl.h"
 #include "content/browser/renderer_host/render_process_host_impl.h"
@@ -143,16 +142,16 @@
 // static
 scoped_refptr<DevToolsAgentHost>
 RenderFrameDevToolsAgentHost::CreateForCrossProcessNavigation(
-    NavigationHandleImpl* handle) {
+    NavigationRequest* request) {
   // Note that this method does not use FrameTreeNode::current_frame_host(),
   // since it is used while the frame host may not be set as current yet,
   // for example right before commit time. Instead target frame from the
   // navigation handle is used. When this method is invoked it's already known
   // that the navigation will commit to the new frame host.
-  FrameTreeNode* frame_tree_node = handle->frame_tree_node();
+  FrameTreeNode* frame_tree_node = request->frame_tree_node();
   DCHECK(!FindAgentHost(frame_tree_node));
   return new RenderFrameDevToolsAgentHost(frame_tree_node,
-                                          handle->GetRenderFrameHost());
+                                          request->GetRenderFrameHost());
 }
 
 // static
@@ -389,17 +388,16 @@
 
 void RenderFrameDevToolsAgentHost::ReadyToCommitNavigation(
     NavigationHandle* navigation_handle) {
-  NavigationHandleImpl* handle =
-      static_cast<NavigationHandleImpl*>(navigation_handle);
+  NavigationRequest* request = NavigationRequest::From(navigation_handle);
   for (auto* tracing : protocol::TracingHandler::ForAgentHost(this))
-    tracing->ReadyToCommitNavigation(handle);
+    tracing->ReadyToCommitNavigation(request);
 
-  if (handle->frame_tree_node() != frame_tree_node_) {
-    if (ShouldForceCreation() && handle->GetRenderFrameHost() &&
-        handle->GetRenderFrameHost()->IsCrossProcessSubframe()) {
+  if (request->frame_tree_node() != frame_tree_node_) {
+    if (ShouldForceCreation() && request->GetRenderFrameHost() &&
+        request->GetRenderFrameHost()->IsCrossProcessSubframe()) {
       // An agent may have been created earlier if auto attach is on.
-      if (!FindAgentHost(handle->frame_tree_node()))
-        CreateForCrossProcessNavigation(handle);
+      if (!FindAgentHost(request->frame_tree_node()))
+        CreateForCrossProcessNavigation(request);
     }
     return;
   }
@@ -408,25 +406,24 @@
   // renderer process. To ensure consistent view over protocol, disconnect them
   // right now.
   GetRendererChannel()->ForceDetachWorkerSessions();
-  UpdateFrameHost(handle->GetRenderFrameHost());
+  UpdateFrameHost(request->GetRenderFrameHost());
   // UpdateFrameHost may destruct |this|.
 }
 
 void RenderFrameDevToolsAgentHost::DidFinishNavigation(
     NavigationHandle* navigation_handle) {
-  NavigationHandleImpl* handle =
-      static_cast<NavigationHandleImpl*>(navigation_handle);
-  if (handle->frame_tree_node() != frame_tree_node_)
+  NavigationRequest* request = NavigationRequest::From(navigation_handle);
+  if (request->frame_tree_node() != frame_tree_node_)
     return;
-  navigation_handles_.erase(handle);
-  if (handle->HasCommitted())
+  navigation_requests_.erase(request);
+  if (request->HasCommitted())
     NotifyNavigated();
 
   // UpdateFrameHost may destruct |this|.
   scoped_refptr<RenderFrameDevToolsAgentHost> protect(this);
   UpdateFrameHost(frame_tree_node_->current_frame_host());
 
-  if (navigation_handles_.empty()) {
+  if (navigation_requests_.empty()) {
     for (DevToolsSession* session : sessions())
       session->ResumeSendingMessagesToAgent();
   }
@@ -476,15 +473,14 @@
 
 void RenderFrameDevToolsAgentHost::DidStartNavigation(
     NavigationHandle* navigation_handle) {
-  NavigationHandleImpl* handle =
-      static_cast<NavigationHandleImpl*>(navigation_handle);
-  if (handle->frame_tree_node() != frame_tree_node_)
+  NavigationRequest* request = NavigationRequest::From(navigation_handle);
+  if (request->frame_tree_node() != frame_tree_node_)
     return;
-  if (navigation_handles_.empty()) {
+  if (navigation_requests_.empty()) {
     for (DevToolsSession* session : sessions())
       session->SuspendSendingMessagesToAgent();
   }
-  navigation_handles_.insert(handle);
+  navigation_requests_.insert(request);
 }
 
 void RenderFrameDevToolsAgentHost::RenderFrameHostChanged(
@@ -598,7 +594,7 @@
 }
 
 void RenderFrameDevToolsAgentHost::DisconnectWebContents() {
-  navigation_handles_.clear();
+  navigation_requests_.clear();
   SetFrameTreeNode(nullptr);
   // UpdateFrameHost may destruct |this|.
   scoped_refptr<RenderFrameDevToolsAgentHost> protect(this);
diff --git a/content/browser/devtools/render_frame_devtools_agent_host.h b/content/browser/devtools/render_frame_devtools_agent_host.h
index 4fbdf6a7..7fb6d56 100644
--- a/content/browser/devtools/render_frame_devtools_agent_host.h
+++ b/content/browser/devtools/render_frame_devtools_agent_host.h
@@ -33,7 +33,7 @@
 class BrowserContext;
 class DevToolsFrameTraceRecorder;
 class FrameTreeNode;
-class NavigationHandleImpl;
+class NavigationRequest;
 class RenderFrameHostImpl;
 struct DevToolsFrameMetadata;
 
@@ -59,7 +59,7 @@
   // This method is called when new frame is created during cross process
   // navigation.
   static scoped_refptr<DevToolsAgentHost> CreateForCrossProcessNavigation(
-      NavigationHandleImpl* handle);
+      NavigationRequest* request);
   static scoped_refptr<DevToolsAgentHost> FindForDangling(
       FrameTreeNode* frame_tree_node);
 
@@ -142,7 +142,7 @@
 
   // The active host we are talking to.
   RenderFrameHostImpl* frame_host_ = nullptr;
-  base::flat_set<NavigationHandleImpl*> navigation_handles_;
+  base::flat_set<NavigationRequest*> navigation_requests_;
   bool render_frame_alive_ = false;
   void* active_file_chooser_interceptor_ = nullptr;
 
diff --git a/content/browser/download/download_browsertest.cc b/content/browser/download/download_browsertest.cc
index 28fad47..568594c 100644
--- a/content/browser/download/download_browsertest.cc
+++ b/content/browser/download/download_browsertest.cc
@@ -3684,6 +3684,42 @@
             downloads[0]->GetTargetFilePath().BaseName().value());
 }
 
+// Test that the network isolation key is populated for <a download> triggered
+// download request that doesn't go through the navigation path.
+IN_PROC_BROWSER_TEST_F(DownloadContentTest,
+                       DownloadAttributeNetworkIsolationKeyPopulated) {
+  GURL frame_url = embedded_test_server()->GetURL(
+      "/download/download-attribute.html?noclick=/download/download-test.lib");
+  GURL document_url = embedded_test_server()->GetURL(
+      "/download/iframe-host.html?target=" + frame_url.spec());
+
+  // Load a page that contains a same-origin iframe, where the iframe contains
+  // a <a download> link same-origin to the iframe's origin.
+  TestNavigationObserver same_tab_observer(shell()->web_contents(), 1);
+  shell()->LoadURL(document_url);
+  same_tab_observer.Wait();
+
+  FetchHistogramsFromChildProcesses();
+  base::HistogramTester histogram_tester;
+  histogram_tester.ExpectTotalCount("HttpCache.NetworkIsolationKeyPresent", 0);
+
+  std::unique_ptr<DownloadCreateObserver> observer(
+      new DownloadCreateObserver(DownloadManagerForShell(shell())));
+
+  // click the <a download> link in the child frame
+  EXPECT_TRUE(
+      ExecJs(shell()->web_contents()->GetAllFrames()[1],
+             "var anchorElement = document.querySelector('a[download]'); "
+             "anchorElement.click();"));
+  download::DownloadItem* download = observer->WaitForFinished();
+  WaitForCompletion(download);
+
+  FetchHistogramsFromChildProcesses();
+  // Assert that the NIK for the download request is populated.
+  histogram_tester.ExpectUniqueSample("HttpCache.NetworkIsolationKeyPresent",
+                                      true /*sample*/, 1 /*count*/);
+}
+
 IN_PROC_BROWSER_TEST_F(DownloadContentTest, DownloadAttributeSameOriginIFrame) {
   GURL frame_url = embedded_test_server()->GetURL(
       "/download/download-attribute.html?target=/download/download-test.lib");
diff --git a/content/browser/download/download_manager_impl.cc b/content/browser/download/download_manager_impl.cc
index 56dde3f..9d5e2589 100644
--- a/content/browser/download/download_manager_impl.cc
+++ b/content/browser/download/download_manager_impl.cc
@@ -1196,6 +1196,11 @@
       tab_url = entry->GetURL();
       tab_referrer_url = entry->GetReferrer().url;
     }
+    RenderFrameHost* top_frame = web_contents->GetMainFrame();
+    if (top_frame) {
+      params->set_network_isolation_key(net::NetworkIsolationKey(
+          top_frame->GetLastCommittedOrigin(), rfh->GetLastCommittedOrigin()));
+    }
   }
 
   DCHECK_EQ(params->url().SchemeIsBlob(), bool{blob_url_loader_factory});
diff --git a/content/browser/frame_host/navigation_controller_impl.cc b/content/browser/frame_host/navigation_controller_impl.cc
index 8235e056..c8c28a5 100644
--- a/content/browser/frame_host/navigation_controller_impl.cc
+++ b/content/browser/frame_host/navigation_controller_impl.cc
@@ -56,7 +56,7 @@
 #include "content/browser/frame_host/debug_urls.h"
 #include "content/browser/frame_host/interstitial_page_impl.h"
 #include "content/browser/frame_host/navigation_entry_impl.h"
-#include "content/browser/frame_host/navigation_handle_impl.h"
+#include "content/browser/frame_host/navigation_request.h"
 #include "content/browser/frame_host/navigator.h"
 #include "content/browser/renderer_host/render_view_host_impl.h"  // Temporary
 #include "content/browser/site_instance_impl.h"
@@ -960,10 +960,10 @@
   NavigateWithoutEntry(params);
 }
 
-bool NavigationControllerImpl::PendingEntryMatchesHandle(
-    NavigationHandleImpl* handle) const {
+bool NavigationControllerImpl::PendingEntryMatchesRequest(
+    NavigationRequest* request) const {
   return pending_entry_ &&
-         pending_entry_->GetUniqueID() == handle->pending_nav_entry_id();
+         pending_entry_->GetUniqueID() == request->nav_entry_id();
 }
 
 bool NavigationControllerImpl::RendererDidNavigate(
@@ -1049,35 +1049,33 @@
   // renderer.  Limit this to a very narrow set of conditions to avoid risks to
   // other navigation types. See https://crbug.com/900036.
   // TODO(crbug.com/926009): Handle history.pushState() as well.
-  NavigationHandleImpl* navigation_handle =
-      navigation_request->navigation_handle();
   bool keep_pending_entry = is_same_document_navigation &&
                             details->type == NAVIGATION_TYPE_EXISTING_PAGE &&
                             pending_entry_ &&
-                            !PendingEntryMatchesHandle(navigation_handle);
+                            !PendingEntryMatchesRequest(navigation_request);
 
   switch (details->type) {
     case NAVIGATION_TYPE_NEW_PAGE:
       RendererDidNavigateToNewPage(
           rfh, params, details->is_same_document, details->did_replace_entry,
-          previous_document_was_activated, navigation_handle);
+          previous_document_was_activated, navigation_request);
       break;
     case NAVIGATION_TYPE_EXISTING_PAGE:
       RendererDidNavigateToExistingPage(rfh, params, details->is_same_document,
-                                        was_restored, navigation_handle,
+                                        was_restored, navigation_request,
                                         keep_pending_entry);
       break;
     case NAVIGATION_TYPE_SAME_PAGE:
       RendererDidNavigateToSamePage(rfh, params, details->is_same_document,
-                                    navigation_handle);
+                                    navigation_request);
       break;
     case NAVIGATION_TYPE_NEW_SUBFRAME:
       RendererDidNavigateNewSubframe(
           rfh, params, details->is_same_document, details->did_replace_entry,
-          previous_document_was_activated, navigation_handle);
+          previous_document_was_activated, navigation_request);
       break;
     case NAVIGATION_TYPE_AUTO_SUBFRAME:
-      if (!RendererDidNavigateAutoSubframe(rfh, params, navigation_handle)) {
+      if (!RendererDidNavigateAutoSubframe(rfh, params, navigation_request)) {
         // We don't send a notification about auto-subframe PageState during
         // UpdateStateForFrame, since it looks like nothing has changed.  Send
         // it here at commit time instead.
@@ -1129,8 +1127,8 @@
         std::move(back_forward_cache_metrics));
   }
   active_entry->back_forward_cache_metrics()->DidCommitNavigation(
-      navigation_request->navigation_handle()->GetNavigationId(),
-      active_entry->GetUniqueID(), rfh->frame_tree_node()->IsMainFrame());
+      navigation_request->GetNavigationId(), active_entry->GetUniqueID(),
+      rfh->frame_tree_node()->IsMainFrame());
 
   // Grab the corresponding FrameNavigationEntry for a few updates, but only if
   // the SiteInstance matches (to avoid updating the wrong entry by mistake).
@@ -1173,7 +1171,7 @@
   NotifyNavigationEntryCommitted(details);
 
   if (active_entry->GetURL().SchemeIs(url::kHttpsScheme) && !rfh->GetParent() &&
-      navigation_handle->GetNetErrorCode() == net::OK) {
+      navigation_request->GetNetErrorCode() == net::OK) {
     UMA_HISTOGRAM_BOOLEAN("Navigation.SecureSchemeHasSSLStatus",
                           !!active_entry->GetSSL().certificate);
   }
@@ -1321,12 +1319,12 @@
     bool is_same_document,
     bool replace_entry,
     bool previous_document_was_activated,
-    NavigationHandleImpl* handle) {
+    NavigationRequest* request) {
   std::unique_ptr<NavigationEntryImpl> new_entry;
   bool update_virtual_url = false;
 
   const base::Optional<url::Origin>& initiator_origin =
-      handle->navigation_request()->common_params().initiator_origin;
+      request->common_params().initiator_origin;
 
   // First check if this is an in-page navigation.  If so, clone the current
   // entry instead of looking at the pending entry, because the pending entry
@@ -1349,7 +1347,7 @@
       new_entry->GetSSL() = SSLStatus();
 
       if (params.url.SchemeIs(url::kHttpsScheme) && !rfh->GetParent() &&
-          handle->GetNetErrorCode() == net::OK) {
+          request->GetNetErrorCode() == net::OK) {
         UMA_HISTOGRAM_BOOLEAN(
             "Navigation.SecureSchemeHasSSLStatus.NewPageInPageOriginMismatch",
             !!new_entry->GetSSL().certificate);
@@ -1365,7 +1363,7 @@
     update_virtual_url = new_entry->update_virtual_url_with_url();
 
     if (params.url.SchemeIs(url::kHttpsScheme) && !rfh->GetParent() &&
-        handle->GetNetErrorCode() == net::OK) {
+        request->GetNetErrorCode() == net::OK) {
       UMA_HISTOGRAM_BOOLEAN("Navigation.SecureSchemeHasSSLStatus.NewPageInPage",
                             !!new_entry->GetSSL().certificate);
     }
@@ -1373,25 +1371,25 @@
 
   // Only make a copy of the pending entry if it is appropriate for the new page
   // that was just loaded. Verify this by checking if the entry corresponds
-  // to the given navigation handle. Additionally, coarsely check that:
+  // to the given NavigationRequest. Additionally, coarsely check that:
   // 1. The SiteInstance hasn't been assigned to something else.
   // 2. The pending entry was intended as a new entry, rather than being a
   // history navigation that was interrupted by an unrelated,
   // renderer-initiated navigation.
   // TODO(csharrison): Investigate whether we can remove some of the coarser
   // checks.
-  if (!new_entry &&
-      PendingEntryMatchesHandle(handle) && pending_entry_index_ == -1 &&
+  if (!new_entry && PendingEntryMatchesRequest(request) &&
+      pending_entry_index_ == -1 &&
       (!pending_entry_->site_instance() ||
        pending_entry_->site_instance() == rfh->GetSiteInstance())) {
     new_entry = pending_entry_->Clone();
 
     update_virtual_url = new_entry->update_virtual_url_with_url();
     new_entry->GetSSL() =
-        SSLStatus(handle->GetSSLInfo().value_or(net::SSLInfo()));
+        SSLStatus(request->GetSSLInfo().value_or(net::SSLInfo()));
 
     if (params.url.SchemeIs(url::kHttpsScheme) && !rfh->GetParent() &&
-        handle->GetNetErrorCode() == net::OK) {
+        request->GetNetErrorCode() == net::OK) {
       UMA_HISTOGRAM_BOOLEAN(
           "Navigation.SecureSchemeHasSSLStatus.NewPagePendingEntryMatches",
           !!new_entry->GetSSL().certificate);
@@ -1403,7 +1401,7 @@
     new_entry = std::make_unique<NavigationEntryImpl>(
         rfh->GetSiteInstance(), params.url, params.referrer, initiator_origin,
         base::string16(),  // title
-        params.transition, handle->IsRendererInitiated(),
+        params.transition, request->IsRendererInitiated(),
         nullptr);  // blob_url_loader_factory
 
     // Find out whether the new entry needs to update its virtual URL on URL
@@ -1421,10 +1419,10 @@
     // the URL.
     update_virtual_url = needs_update;
     new_entry->GetSSL() =
-        SSLStatus(handle->GetSSLInfo().value_or(net::SSLInfo()));
+        SSLStatus(request->GetSSLInfo().value_or(net::SSLInfo()));
 
     if (params.url.SchemeIs(url::kHttpsScheme) && !rfh->GetParent() &&
-        handle->GetNetErrorCode() == net::OK) {
+        request->GetNetErrorCode() == net::OK) {
       UMA_HISTOGRAM_BOOLEAN(
           "Navigation.SecureSchemeHasSSLStatus.NewPageNoMatchingEntry",
           !!new_entry->GetSSL().certificate);
@@ -1488,7 +1486,7 @@
 
   SetShouldSkipOnBackForwardUIIfNeeded(rfh, replace_entry,
                                        previous_document_was_activated,
-                                       handle->IsRendererInitiated());
+                                       request->IsRendererInitiated());
 
   InsertOrReplaceEntry(std::move(new_entry), replace_entry);
 }
@@ -1498,7 +1496,7 @@
     const FrameHostMsg_DidCommitProvisionalLoad_Params& params,
     bool is_same_document,
     bool was_restored,
-    NavigationHandleImpl* handle,
+    NavigationRequest* request,
     bool keep_pending_entry) {
   DCHECK(GetLastCommittedEntry()) << "ClassifyNavigation should guarantee "
                                   << "that a last committed entry exists.";
@@ -1513,13 +1511,13 @@
     // entry.
     entry = GetLastCommittedEntry();
     // If this is a same document navigation, then there's no SSLStatus in the
-    // NavigationHandle so don't overwrite the existing entry's SSLStatus.
+    // NavigationRequest so don't overwrite the existing entry's SSLStatus.
     if (!is_same_document)
       entry->GetSSL() =
-          SSLStatus(handle->GetSSLInfo().value_or(net::SSLInfo()));
+          SSLStatus(request->GetSSLInfo().value_or(net::SSLInfo()));
 
     if (params.url.SchemeIs(url::kHttpsScheme) && !rfh->GetParent() &&
-        handle->GetNetErrorCode() == net::OK) {
+        request->GetNetErrorCode() == net::OK) {
       bool has_cert = !!entry->GetSSL().certificate;
       if (is_same_document) {
         UMA_HISTOGRAM_BOOLEAN(
@@ -1538,7 +1536,7 @@
     entry = GetEntryWithUniqueID(params.nav_entry_id);
 
     if (is_same_document) {
-      // There's no SSLStatus in the NavigationHandle for same document
+      // There's no SSLStatus in the NavigationRequest for same document
       // navigations, so normally we leave |entry|'s SSLStatus as is. However if
       // this was a restored same document navigation entry, then it won't have
       // an SSLStatus. So we need to copy over the SSLStatus from the entry that
@@ -1550,19 +1548,19 @@
         entry->GetSSL() = last_entry->GetSSL();
       }
     } else {
-      // In rapid back/forward navigations |handle| sometimes won't have a cert
-      // (http://crbug.com/727892). So we use the handle's cert if it exists,
+      // In rapid back/forward navigations |request| sometimes won't have a cert
+      // (http://crbug.com/727892). So we use the request's cert if it exists,
       // otherwise we only reuse the existing cert if the origins match.
-      if (handle->GetSSLInfo().has_value() &&
-          handle->GetSSLInfo()->is_valid()) {
-        entry->GetSSL() = SSLStatus(*(handle->GetSSLInfo()));
-      } else if (entry->GetURL().GetOrigin() != handle->GetURL().GetOrigin()) {
+      if (request->GetSSLInfo().has_value() &&
+          request->GetSSLInfo()->is_valid()) {
+        entry->GetSSL() = SSLStatus(*(request->GetSSLInfo()));
+      } else if (entry->GetURL().GetOrigin() != request->GetURL().GetOrigin()) {
         entry->GetSSL() = SSLStatus();
       }
     }
 
     if (params.url.SchemeIs(url::kHttpsScheme) && !rfh->GetParent() &&
-        handle->GetNetErrorCode() == net::OK) {
+        request->GetNetErrorCode() == net::OK) {
       bool has_cert = !!entry->GetSSL().certificate;
       if (is_same_document && was_restored) {
         UMA_HISTOGRAM_BOOLEAN(
@@ -1600,13 +1598,13 @@
     CopyReplacedNavigationEntryDataIfPreviouslyEmpty(entry, entry);
 
     // If this is a same document navigation, then there's no SSLStatus in the
-    // NavigationHandle so don't overwrite the existing entry's SSLStatus.
+    // NavigationRequest so don't overwrite the existing entry's SSLStatus.
     if (!is_same_document)
       entry->GetSSL() =
-          SSLStatus(handle->GetSSLInfo().value_or(net::SSLInfo()));
+          SSLStatus(request->GetSSLInfo().value_or(net::SSLInfo()));
 
     if (params.url.SchemeIs(url::kHttpsScheme) && !rfh->GetParent() &&
-        handle->GetNetErrorCode() == net::OK) {
+        request->GetNetErrorCode() == net::OK) {
       bool has_cert = !!entry->GetSSL().certificate;
       if (is_same_document) {
         UMA_HISTOGRAM_BOOLEAN(
@@ -1641,7 +1639,7 @@
   // Update the existing FrameNavigationEntry to ensure all of its members
   // reflect the parameters coming from the renderer process.
   const base::Optional<url::Origin>& initiator_origin =
-      handle->navigation_request()->common_params().initiator_origin;
+      request->common_params().initiator_origin;
   entry->AddOrUpdateFrameEntry(
       rfh->frame_tree_node(), params.item_sequence_number,
       params.document_sequence_number, rfh->GetSiteInstance(), nullptr,
@@ -1674,7 +1672,7 @@
     RenderFrameHostImpl* rfh,
     const FrameHostMsg_DidCommitProvisionalLoad_Params& params,
     bool is_same_document,
-    NavigationHandleImpl* handle) {
+    NavigationRequest* request) {
   // This classification says that we have a pending entry that's the same as
   // the last committed entry. This entry is guaranteed to exist by
   // ClassifyNavigation. All we need to do is update the existing entry.
@@ -1704,10 +1702,10 @@
   // change, the previous SSLStatus is still valid.
   if (!is_same_document)
     existing_entry->GetSSL() =
-        SSLStatus(handle->GetSSLInfo().value_or(net::SSLInfo()));
+        SSLStatus(request->GetSSLInfo().value_or(net::SSLInfo()));
 
   if (existing_entry->GetURL().SchemeIs(url::kHttpsScheme) &&
-      !rfh->GetParent() && handle->GetNetErrorCode() == net::OK) {
+      !rfh->GetParent() && request->GetNetErrorCode() == net::OK) {
     UMA_HISTOGRAM_BOOLEAN("Navigation.SecureSchemeHasSSLStatus.SamePage",
                           !!existing_entry->GetSSL().certificate);
   }
@@ -1718,7 +1716,7 @@
   // Update the existing FrameNavigationEntry to ensure all of its members
   // reflect the parameters coming from the renderer process.
   const base::Optional<url::Origin>& initiator_origin =
-      handle->navigation_request()->common_params().initiator_origin;
+      request->common_params().initiator_origin;
   existing_entry->AddOrUpdateFrameEntry(
       rfh->frame_tree_node(), params.item_sequence_number,
       params.document_sequence_number, rfh->GetSiteInstance(), nullptr,
@@ -1735,7 +1733,7 @@
     bool is_same_document,
     bool replace_entry,
     bool previous_document_was_activated,
-    NavigationHandleImpl* handle) {
+    NavigationRequest* request) {
   DCHECK(ui::PageTransitionCoreTypeIs(params.transition,
                                       ui::PAGE_TRANSITION_MANUAL_SUBFRAME));
 
@@ -1755,7 +1753,7 @@
   // This FrameNavigationEntry might not end up being used in the
   // CloneAndReplace() call below, if a spot can't be found for it in the tree.
   const base::Optional<url::Origin>& initiator_origin =
-      handle->navigation_request()->common_params().initiator_origin;
+      request->common_params().initiator_origin;
   auto frame_entry = base::MakeRefCounted<FrameNavigationEntry>(
       rfh->frame_tree_node()->unique_name(), params.item_sequence_number,
       params.document_sequence_number, rfh->GetSiteInstance(), nullptr,
@@ -1770,7 +1768,7 @@
 
   SetShouldSkipOnBackForwardUIIfNeeded(rfh, replace_entry,
                                        previous_document_was_activated,
-                                       handle->IsRendererInitiated());
+                                       request->IsRendererInitiated());
 
   // TODO(creis): Update this to add the frame_entry if we can't find the one
   // to replace, which can happen due to a unique name change. See
@@ -1783,7 +1781,7 @@
 bool NavigationControllerImpl::RendererDidNavigateAutoSubframe(
     RenderFrameHostImpl* rfh,
     const FrameHostMsg_DidCommitProvisionalLoad_Params& params,
-    NavigationHandleImpl* handle) {
+    NavigationRequest* request) {
   DCHECK(ui::PageTransitionCoreTypeIs(params.transition,
                                       ui::PAGE_TRANSITION_AUTO_SUBFRAME));
 
@@ -1833,7 +1831,7 @@
   // it may be a "history auto" case where we update an existing one.
   NavigationEntryImpl* last_committed = GetLastCommittedEntry();
   const base::Optional<url::Origin>& initiator_origin =
-      handle->navigation_request()->common_params().initiator_origin;
+      request->common_params().initiator_origin;
   last_committed->AddOrUpdateFrameEntry(
       rfh->frame_tree_node(), params.item_sequence_number,
       params.document_sequence_number, rfh->GetSiteInstance(), nullptr,
diff --git a/content/browser/frame_host/navigation_controller_impl.h b/content/browser/frame_host/navigation_controller_impl.h
index 48075d6..19733b1 100644
--- a/content/browser/frame_host/navigation_controller_impl.h
+++ b/content/browser/frame_host/navigation_controller_impl.h
@@ -30,6 +30,7 @@
 
 namespace content {
 class FrameTreeNode;
+class NavigationRequest;
 class RenderFrameHostImpl;
 class SiteInstance;
 struct LoadCommittedDetails;
@@ -368,8 +369,8 @@
       bool is_history_navigation_in_new_child_frame);
 
   // Returns whether there is a pending NavigationEntry whose unique ID matches
-  // the given NavigationHandle's pending_nav_entry_id.
-  bool PendingEntryMatchesHandle(NavigationHandleImpl* handle) const;
+  // the given NavigationRequest's pending_nav_entry_id.
+  bool PendingEntryMatchesRequest(NavigationRequest* request) const;
 
   // Classifies the given renderer navigation (see the NavigationType enum).
   NavigationType ClassifyNavigation(
@@ -396,30 +397,30 @@
       bool is_same_document,
       bool replace_entry,
       bool previous_document_was_activated,
-      NavigationHandleImpl* handle);
+      NavigationRequest* request);
   void RendererDidNavigateToExistingPage(
       RenderFrameHostImpl* rfh,
       const FrameHostMsg_DidCommitProvisionalLoad_Params& params,
       bool is_same_document,
       bool was_restored,
-      NavigationHandleImpl* handle,
+      NavigationRequest* request,
       bool keep_pending_entry);
   void RendererDidNavigateToSamePage(
       RenderFrameHostImpl* rfh,
       const FrameHostMsg_DidCommitProvisionalLoad_Params& params,
       bool is_same_document,
-      NavigationHandleImpl* handle);
+      NavigationRequest* request);
   void RendererDidNavigateNewSubframe(
       RenderFrameHostImpl* rfh,
       const FrameHostMsg_DidCommitProvisionalLoad_Params& params,
       bool is_same_document,
       bool replace_entry,
       bool previous_document_was_activated,
-      NavigationHandleImpl* handle);
+      NavigationRequest* request);
   bool RendererDidNavigateAutoSubframe(
       RenderFrameHostImpl* rfh,
       const FrameHostMsg_DidCommitProvisionalLoad_Params& params,
-      NavigationHandleImpl* handle);
+      NavigationRequest* request);
 
   // 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_request.cc b/content/browser/frame_host/navigation_request.cc
index bc1e047..8a4eb96 100644
--- a/content/browser/frame_host/navigation_request.cc
+++ b/content/browser/frame_host/navigation_request.cc
@@ -467,6 +467,14 @@
   UMA_HISTOGRAM_BOOLEAN("Navigation.IsSameBrowsingInstance",
                         is_same_browsing_instance);
 
+  UMA_HISTOGRAM_BOOLEAN("Navigation.RequiresDedicatedProcess",
+                        new_rfh->GetSiteInstance()->RequiresDedicatedProcess());
+
+  ChildProcessSecurityPolicyImpl* policy =
+      ChildProcessSecurityPolicyImpl::GetInstance();
+  GURL process_lock = policy->GetOriginLock(new_rfh->GetProcess()->GetID());
+  UMA_HISTOGRAM_BOOLEAN("Navigation.IsLockedProcess", !process_lock.is_empty());
+
   if (common_params.transition & ui::PAGE_TRANSITION_FORWARD_BACK) {
     UMA_HISTOGRAM_BOOLEAN("Navigation.IsSameProcess.BackForward",
                           is_same_process);
@@ -3612,4 +3620,9 @@
   return previous_render_frame_host_id_;
 }
 
+// static
+NavigationRequest* NavigationRequest::From(NavigationHandle* handle) {
+  return static_cast<NavigationHandleImpl*>(handle)->navigation_request();
+}
+
 }  // namespace content
diff --git a/content/browser/frame_host/navigation_request.h b/content/browser/frame_host/navigation_request.h
index 6809d0dc..a852c2b 100644
--- a/content/browser/frame_host/navigation_request.h
+++ b/content/browser/frame_host/navigation_request.h
@@ -179,6 +179,8 @@
       bool is_renderer_initiated,
       bool is_same_document);
 
+  static NavigationRequest* From(NavigationHandle* handle);
+
   ~NavigationRequest() override;
 
   // NavigationHandle implementation:
diff --git a/content/browser/frame_host/navigation_throttle_runner.cc b/content/browser/frame_host/navigation_throttle_runner.cc
index a6a3ced..8727dc0 100644
--- a/content/browser/frame_host/navigation_throttle_runner.cc
+++ b/content/browser/frame_host/navigation_throttle_runner.cc
@@ -10,10 +10,11 @@
 #include "content/browser/frame_host/form_submission_throttle.h"
 #include "content/browser/frame_host/history_navigation_ablation_study_navigation_throttle.h"
 #include "content/browser/frame_host/mixed_content_navigation_throttle.h"
-#include "content/browser/frame_host/navigation_handle_impl.h"
+#include "content/browser/frame_host/navigation_request.h"
 #include "content/browser/frame_host/navigator_delegate.h"
 #include "content/browser/frame_host/origin_policy_throttle.h"
 #include "content/browser/frame_host/webui_navigation_throttle.h"
+#include "content/public/browser/navigation_handle.h"
 
 namespace content {
 
@@ -89,41 +90,40 @@
   std::vector<std::unique_ptr<NavigationThrottle>> testing_throttles =
       std::move(throttles_);
 
-  NavigationHandleImpl* handle = static_cast<NavigationHandleImpl*>(handle_);
-  throttles_ =
-      handle->navigation_request()->GetDelegate()->CreateThrottlesForNavigation(
-          handle);
+  throttles_ = NavigationRequest::From(handle_)
+                   ->GetDelegate()
+                   ->CreateThrottlesForNavigation(handle_);
 
   // Enforce rules for WebUI navigations.
-  AddThrottle(WebUINavigationThrottle::CreateThrottleForNavigation(handle));
+  AddThrottle(WebUINavigationThrottle::CreateThrottleForNavigation(handle_));
 
   // Check for renderer-inititated main frame navigations to blocked URL schemes
   // (data, filesystem). This is done early as it may block the main frame
   // navigation altogether.
   AddThrottle(
-      BlockedSchemeNavigationThrottle::CreateThrottleForNavigation(handle));
+      BlockedSchemeNavigationThrottle::CreateThrottleForNavigation(handle_));
 
-  AddThrottle(AncestorThrottle::MaybeCreateThrottleFor(handle));
-  AddThrottle(FormSubmissionThrottle::MaybeCreateThrottleFor(handle));
+  AddThrottle(AncestorThrottle::MaybeCreateThrottleFor(handle_));
+  AddThrottle(FormSubmissionThrottle::MaybeCreateThrottleFor(handle_));
 
   // Check for mixed content. This is done after the AncestorThrottle and the
   // FormSubmissionThrottle so that when folks block mixed content with a CSP
   // policy, they don't get a warning. They'll still get a warning in the
   // console about CSP blocking the load.
   AddThrottle(
-      MixedContentNavigationThrottle::CreateThrottleForNavigation(handle));
+      MixedContentNavigationThrottle::CreateThrottleForNavigation(handle_));
 
   // Handle Origin Policy (if enabled)
-  AddThrottle(OriginPolicyThrottle::MaybeCreateThrottleFor(handle));
+  AddThrottle(OriginPolicyThrottle::MaybeCreateThrottleFor(handle_));
 
   for (auto& throttle :
-       devtools_instrumentation::CreateNavigationThrottles(handle)) {
+       devtools_instrumentation::CreateNavigationThrottles(handle_)) {
     AddThrottle(std::move(throttle));
   }
 
   // Delay navigation for an ablation study (if needed).
   AddThrottle(HistoryNavigationAblationStudyNavigationThrottle::
-                  MaybeCreateForNavigation(handle));
+                  MaybeCreateForNavigation(handle_));
 
   // Insert all testing NavigationThrottles last.
   throttles_.insert(throttles_.end(),
diff --git a/content/browser/frame_host/navigation_throttle_runner.h b/content/browser/frame_host/navigation_throttle_runner.h
index 916bb85d..572d28f4 100644
--- a/content/browser/frame_host/navigation_throttle_runner.h
+++ b/content/browser/frame_host/navigation_throttle_runner.h
@@ -12,8 +12,6 @@
 
 namespace content {
 
-class NavigationHandleImpl;
-
 // This class owns the set of NavigationThrottles added to a NavigationHandle.
 // It is responsible for calling the various sets of events on its
 // NavigationThrottle, and notifying its delegate of the results of said events.
diff --git a/content/browser/media/session/media_session_impl_browsertest.cc b/content/browser/media/session/media_session_impl_browsertest.cc
index cdb48b2..df1c6e8 100644
--- a/content/browser/media/session/media_session_impl_browsertest.cc
+++ b/content/browser/media/session/media_session_impl_browsertest.cc
@@ -16,6 +16,7 @@
 #include "base/strings/utf_string_conversions.h"
 #include "base/test/metrics/histogram_tester.h"
 #include "base/test/simple_test_tick_clock.h"
+#include "build/build_config.h"
 #include "content/browser/media/session/audio_focus_delegate.h"
 #include "content/browser/media/session/mock_media_session_player_observer.h"
 #include "content/browser/media/session/mock_media_session_service_impl.h"
@@ -2702,7 +2703,7 @@
   }
 }
 
-#if defined(OS_CHROMEOS)
+#if defined(OS_CHROMEOS) || defined(OS_ANDROID)
 // TODO(https://crbug.com/1000400): Re-enable this test.
 #define MAYBE_PositionStateRouteWithOnePlayer \
   DISABLED_PositionStateRouteWithOnePlayer
diff --git a/content/browser/portal/portal.cc b/content/browser/portal/portal.cc
index 5480e45e..bf977af 100644
--- a/content/browser/portal/portal.cc
+++ b/content/browser/portal/portal.cc
@@ -78,6 +78,13 @@
     RenderFrameHostImpl* owner_render_frame_host,
     mojo::PendingAssociatedReceiver<blink::mojom::Portal> receiver,
     mojo::PendingAssociatedRemote<blink::mojom::PortalClient> client) {
+  if (!IsEnabled()) {
+    mojo::ReportBadMessage(
+        "blink.mojom.Portal can only be used if the Portals feature is "
+        "enabled.");
+    return nullptr;
+  }
+
   auto portal_ptr = base::WrapUnique(new Portal(owner_render_frame_host));
   Portal* portal = portal_ptr.get();
   portal->binding_ = mojo::MakeStrongAssociatedBinding<blink::mojom::Portal>(
@@ -97,6 +104,13 @@
     RenderFrameHostImpl* frame,
     mojo::PendingAssociatedReceiver<blink::mojom::PortalHost>
         pending_receiver) {
+  if (!IsEnabled()) {
+    mojo::ReportBadMessage(
+        "blink.mojom.PortalHost can only be used if the Portals feature is "
+        "enabled.");
+    return;
+  }
+
   WebContentsImpl* web_contents =
       static_cast<WebContentsImpl*>(WebContents::FromRenderFrameHost(frame));
 
diff --git a/content/browser/tracing/cast_tracing_agent.cc b/content/browser/tracing/cast_tracing_agent.cc
index dcf5107..b9c3767 100644
--- a/content/browser/tracing/cast_tracing_agent.cc
+++ b/content/browser/tracing/cast_tracing_agent.cc
@@ -285,12 +285,13 @@
                              base::Unretained(this), std::move(callback)));
 }
 
-void CastTracingAgent::StopAndFlush(tracing::mojom::RecorderPtr recorder) {
+void CastTracingAgent::StopAndFlush(
+    mojo::PendingRemote<tracing::mojom::Recorder> recorder) {
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
   // This may be called even if we are not tracing.
   if (!session_)
     return;
-  recorder_ = std::move(recorder);
+  recorder_.Bind(std::move(recorder));
   session_->StopTracing(base::BindRepeating(&CastTracingAgent::HandleTraceData,
                                             base::Unretained(this)));
 }
diff --git a/content/browser/tracing/cast_tracing_agent.h b/content/browser/tracing/cast_tracing_agent.h
index 7b90f2a..cb6ea1ad 100644
--- a/content/browser/tracing/cast_tracing_agent.h
+++ b/content/browser/tracing/cast_tracing_agent.h
@@ -9,6 +9,7 @@
 #include <string>
 
 #include "chromecast/tracing/system_tracer.h"
+#include "mojo/public/cpp/bindings/remote.h"
 #include "services/tracing/public/cpp/base_agent.h"
 #include "services/tracing/public/mojom/tracing.mojom.h"
 
@@ -35,14 +36,15 @@
   void StartTracing(const std::string& config,
                     base::TimeTicks coordinator_time,
                     Agent::StartTracingCallback callback) override;
-  void StopAndFlush(tracing::mojom::RecorderPtr recorder) override;
+  void StopAndFlush(
+      mojo::PendingRemote<tracing::mojom::Recorder> recorder) override;
 
   void StartTracingCallbackProxy(Agent::StartTracingCallback callback,
                                  bool success);
   void HandleTraceData(chromecast::SystemTracer::Status status,
                        std::string trace_data);
 
-  tracing::mojom::RecorderPtr recorder_;
+  mojo::Remote<tracing::mojom::Recorder> recorder_;
 
   // Task runner for collecting traces in a worker thread.
   scoped_refptr<base::SequencedTaskRunner> worker_task_runner_;
diff --git a/content/browser/tracing/cros_tracing_agent.cc b/content/browser/tracing/cros_tracing_agent.cc
index b8c22b8..ed2b988 100644
--- a/content/browser/tracing/cros_tracing_agent.cc
+++ b/content/browser/tracing/cros_tracing_agent.cc
@@ -244,11 +244,12 @@
                              base::Unretained(this), std::move(callback)));
 }
 
-void CrOSTracingAgent::StopAndFlush(tracing::mojom::RecorderPtr recorder) {
+void CrOSTracingAgent::StopAndFlush(
+    mojo::PendingRemote<tracing::mojom::Recorder> recorder) {
   // This may be called even if we are not tracing.
   if (!session_)
     return;
-  recorder_ = std::move(recorder);
+  recorder_.Bind(std::move(recorder));
   session_->StopTracing(
       base::BindOnce(&CrOSTracingAgent::RecorderProxy, base::Unretained(this)));
 }
diff --git a/content/browser/tracing/cros_tracing_agent.h b/content/browser/tracing/cros_tracing_agent.h
index 289db7c..edb0c96 100644
--- a/content/browser/tracing/cros_tracing_agent.h
+++ b/content/browser/tracing/cros_tracing_agent.h
@@ -8,6 +8,7 @@
 #include <memory>
 #include <string>
 
+#include "mojo/public/cpp/bindings/remote.h"
 #include "services/tracing/public/cpp/base_agent.h"
 #include "services/tracing/public/mojom/tracing.mojom.h"
 
@@ -34,14 +35,15 @@
   void StartTracing(const std::string& config,
                     base::TimeTicks coordinator_time,
                     Agent::StartTracingCallback callback) override;
-  void StopAndFlush(tracing::mojom::RecorderPtr recorder) override;
+  void StopAndFlush(
+      mojo::PendingRemote<tracing::mojom::Recorder> recorder) override;
 
   void StartTracingCallbackProxy(Agent::StartTracingCallback callback,
                                  bool success);
   void RecorderProxy(const scoped_refptr<base::RefCountedString>& events);
 
   std::unique_ptr<CrOSSystemTracingSession> session_;
-  tracing::mojom::RecorderPtr recorder_;
+  mojo::Remote<tracing::mojom::Recorder> recorder_;
 
   DISALLOW_COPY_AND_ASSIGN(CrOSTracingAgent);
 };
diff --git a/content/browser/web_package/bundled_exchanges_handle.cc b/content/browser/web_package/bundled_exchanges_handle.cc
index dd88c96..0dd7b0a 100644
--- a/content/browser/web_package/bundled_exchanges_handle.cc
+++ b/content/browser/web_package/bundled_exchanges_handle.cc
@@ -73,8 +73,7 @@
             base::StringPrintf("HTTP/1.1 %d %s\r\n", 303, "See Other")));
 
     net::RedirectInfo redirect_info = net::RedirectInfo::ComputeRedirectInfo(
-        "GET", resource_request.url, resource_request.request_initiator,
-        resource_request.site_for_cookies,
+        "GET", resource_request.url, resource_request.site_for_cookies,
         resource_request.update_first_party_url_on_redirect
             ? net::URLRequest::FirstPartyURLPolicy::
                   UPDATE_FIRST_PARTY_URL_ON_REDIRECT
diff --git a/content/browser/web_package/signed_exchange_utils.cc b/content/browser/web_package/signed_exchange_utils.cc
index f692760..153d2a7 100644
--- a/content/browser/web_package/signed_exchange_utils.cc
+++ b/content/browser/web_package/signed_exchange_utils.cc
@@ -207,8 +207,7 @@
   // https://wicg.github.io/webpackage/loading.html#mp-http-fetch
   // Step 3. Set actualResponse's status to 303. [spec text]
   return net::RedirectInfo::ComputeRedirectInfo(
-      "GET", outer_request.url, outer_request.request_initiator,
-      outer_request.site_for_cookies,
+      "GET", outer_request.url, outer_request.site_for_cookies,
       outer_request.update_first_party_url_on_redirect
           ? net::URLRequest::FirstPartyURLPolicy::
                 UPDATE_FIRST_PARTY_URL_ON_REDIRECT
diff --git a/content/common/service_worker/service_worker_loader_helpers.cc b/content/common/service_worker/service_worker_loader_helpers.cc
index 1b025c3..649fee9 100644
--- a/content/common/service_worker/service_worker_loader_helpers.cc
+++ b/content/common/service_worker/service_worker_loader_helpers.cc
@@ -128,8 +128,8 @@
           : net::URLRequest::NEVER_CHANGE_FIRST_PARTY_URL;
   return net::RedirectInfo::ComputeRedirectInfo(
       original_request.method, original_request.url,
-      original_request.request_initiator, original_request.site_for_cookies,
-      first_party_url_policy, original_request.referrer_policy,
+      original_request.site_for_cookies, first_party_url_policy,
+      original_request.referrer_policy,
       network::ComputeReferrer(original_request.referrer),
       response_head.headers->response_code(),
       original_request.url.Resolve(new_location),
diff --git a/content/common/throttling_url_loader.cc b/content/common/throttling_url_loader.cc
index e71e8a68..41f1ab32c 100644
--- a/content/common/throttling_url_loader.cc
+++ b/content/common/throttling_url_loader.cc
@@ -392,7 +392,6 @@
 
     net::RedirectInfo redirect_info = net::RedirectInfo::ComputeRedirectInfo(
         start_info_->url_request.method, start_info_->url_request.url,
-        start_info_->url_request.request_initiator,
         start_info_->url_request.site_for_cookies, first_party_url_policy,
         start_info_->url_request.referrer_policy,
         start_info_->url_request.referrer.spec(),
diff --git a/content/renderer/render_frame_impl.cc b/content/renderer/render_frame_impl.cc
index 9d22c67..4966798 100644
--- a/content/renderer/render_frame_impl.cc
+++ b/content/renderer/render_frame_impl.cc
@@ -453,9 +453,8 @@
   navigation_params->ip_address_space = commit_params.ip_address_space;
 
   if (common_params.referrer->url.is_valid()) {
-    url::Origin origin = common_params.initiator_origin.value_or(url::Origin());
     WebString referrer = WebSecurityPolicy::GenerateReferrerHeader(
-        common_params.referrer->policy, origin, common_params.url,
+        common_params.referrer->policy, common_params.url,
         WebString::FromUTF8(common_params.referrer->url.spec()));
     navigation_params->referrer = referrer;
     navigation_params->referrer_policy = common_params.referrer->policy;
@@ -502,7 +501,7 @@
       WebURLLoaderImpl::PopulateURLResponse(
           exchange->inner_url,
           network::ResourceResponseHead(exchange->inner_response),
-          &web_response, false /* report_security_info */, -1 /* request_id */);
+          &web_response, false /* report_security_info*/, -1 /* request_id */);
       navigation_params->prefetched_signed_exchanges.emplace_back(
           std::make_unique<
               blink::WebNavigationParams::PrefetchedSignedExchange>(
diff --git a/content/renderer/render_widget.cc b/content/renderer/render_widget.cc
index a579d9c..928f3d91 100644
--- a/content/renderer/render_widget.cc
+++ b/content/renderer/render_widget.cc
@@ -604,12 +604,6 @@
                              emulator->original_screen_info());
 }
 
-gfx::Rect RenderWidget::AdjustValidationMessageAnchor(const gfx::Rect& anchor) {
-  if (screen_metrics_emulator_)
-    return screen_metrics_emulator_->AdjustValidationMessageAnchor(anchor);
-  return anchor;
-}
-
 #if BUILDFLAG(USE_EXTERNAL_POPUP_MENU)
 void RenderWidget::SetExternalPopupOriginAdjustmentsForEmulation(
     ExternalPopupMenu* popup) {
@@ -624,6 +618,14 @@
 }
 
 bool RenderWidget::OnMessageReceived(const IPC::Message& message) {
+  // TODO(https://crbug.com/1000502): Don't process IPC messages on undead
+  // RenderWidgets. We would like to eventually remove them altogether, so they
+  // won't be able to process IPC messages. An undead widget may become
+  // provisional again, so we must check for that too. Provisional frames don't
+  // receive messages until swapped in.
+  if (is_undead_)
+    return false;
+
   bool handled = false;
   IPC_BEGIN_MESSAGE_MAP(RenderWidget, message)
     IPC_MESSAGE_HANDLER(WidgetMsg_EnableDeviceEmulation,
@@ -634,13 +636,11 @@
   if (handled)
     return true;
 
-  // TODO(https://crbug.com/1000502): Don't process IPC messages on undead
-  // RenderWidgets. We would like to eventually remove them altogether, so they
-  // won't be able to process IPC messages. An undead widget may become
-  // provisional again, so we must check for that too. Provisional frames don't
-  // receive messages until swapped in.
-  if (IsUndeadOrProvisional())
+  // TODO(https://crbug.com/1000502): We shouldn't process IPC messages on
+  // provisional frames.
+  if (IsForProvisionalFrame())
     return false;
+
 #if defined(OS_MACOSX)
   if (IPC_MESSAGE_CLASS(message) == TextInputClientMsgStart)
     return text_input_client_observer_->OnMessageReceived(message);
diff --git a/content/renderer/render_widget.h b/content/renderer/render_widget.h
index 82b2c2d..c7d05a1 100644
--- a/content/renderer/render_widget.h
+++ b/content/renderer/render_widget.h
@@ -559,8 +559,6 @@
 
   void ApplyEmulatedScreenMetricsForPopupWidget(RenderWidget* origin_widget);
 
-  gfx::Rect AdjustValidationMessageAnchor(const gfx::Rect& anchor);
-
   // Checks if the selection bounds have been changed. If they are changed,
   // the new value will be sent to the browser process.
   void UpdateSelectionBounds();
diff --git a/content/renderer/render_widget_screen_metrics_emulator.cc b/content/renderer/render_widget_screen_metrics_emulator.cc
index 29d798d..68fb7b7 100644
--- a/content/renderer/render_widget_screen_metrics_emulator.cc
+++ b/content/renderer/render_widget_screen_metrics_emulator.cc
@@ -158,9 +158,4 @@
   params->y *= scale_;
 }
 
-gfx::Rect RenderWidgetScreenMetricsEmulator::AdjustValidationMessageAnchor(
-    const gfx::Rect& anchor) {
-  return gfx::ScaleToEnclosedRect(anchor, scale_);
-}
-
 }  // namespace content
diff --git a/content/renderer/render_widget_screen_metrics_emulator.h b/content/renderer/render_widget_screen_metrics_emulator.h
index 4a98f3e..85381232 100644
--- a/content/renderer/render_widget_screen_metrics_emulator.h
+++ b/content/renderer/render_widget_screen_metrics_emulator.h
@@ -56,7 +56,6 @@
   void OnUpdateScreenRects(const gfx::Rect& view_screen_rect,
                            const gfx::Rect& window_screen_rect);
   void OnShowContextMenu(ContextMenuParams* params);
-  gfx::Rect AdjustValidationMessageAnchor(const gfx::Rect& anchor);
 
   // Apply parameters to the render widget.
   void Apply();
diff --git a/device/gamepad/gamepad_standard_mappings_linux.cc b/device/gamepad/gamepad_standard_mappings_linux.cc
index 538a0ee..245b46f 100644
--- a/device/gamepad/gamepad_standard_mappings_linux.cc
+++ b/device/gamepad/gamepad_standard_mappings_linux.cc
@@ -101,7 +101,19 @@
   mapped->buttons[BUTTON_INDEX_DPAD_LEFT] = AxisNegativeAsButton(input.axes[6]);
   mapped->buttons[BUTTON_INDEX_DPAD_RIGHT] =
       AxisPositiveAsButton(input.axes[6]);
-  mapped->buttons[BUTTON_INDEX_META] = input.buttons[15];
+
+  // Xbox Wireless Controller (045e:02fd) received a firmware update in 2019
+  // that changed which field is populated with the Xbox button state. Check
+  // both fields and combine the results.
+  auto& xbox_old = input.buttons[15];
+  auto& xbox_new = input.buttons[12];
+  mapped->buttons[BUTTON_INDEX_META].pressed =
+      (xbox_old.pressed || xbox_new.pressed);
+  mapped->buttons[BUTTON_INDEX_META].touched =
+      (xbox_old.touched || xbox_new.touched);
+  mapped->buttons[BUTTON_INDEX_META].value =
+      std::max(xbox_old.value, xbox_new.value);
+
   mapped->axes[AXIS_INDEX_RIGHT_STICK_Y] = input.axes[3];
 
   mapped->buttons_length = BUTTON_INDEX_COUNT;
diff --git a/device/gamepad/gamepad_standard_mappings_mac.mm b/device/gamepad/gamepad_standard_mappings_mac.mm
index 77f348e..266deec1 100644
--- a/device/gamepad/gamepad_standard_mappings_mac.mm
+++ b/device/gamepad/gamepad_standard_mappings_mac.mm
@@ -83,7 +83,19 @@
   mapped->buttons[BUTTON_INDEX_START] = input.buttons[11];
   mapped->buttons[BUTTON_INDEX_LEFT_THUMBSTICK] = input.buttons[13];
   mapped->buttons[BUTTON_INDEX_RIGHT_THUMBSTICK] = input.buttons[14];
-  mapped->buttons[BUTTON_INDEX_META] = input.buttons[15];
+
+  // Xbox Wireless Controller (045e:02fd) received a firmware update in 2019
+  // that changed which field is populated with the Xbox button state. Check
+  // both fields and combine the results.
+  auto& xbox_old = input.buttons[15];
+  auto& xbox_new = input.buttons[12];
+  mapped->buttons[BUTTON_INDEX_META].pressed =
+      (xbox_old.pressed || xbox_new.pressed);
+  mapped->buttons[BUTTON_INDEX_META].touched =
+      (xbox_old.touched || xbox_new.touched);
+  mapped->buttons[BUTTON_INDEX_META].value =
+      std::max(xbox_old.value, xbox_new.value);
+
   mapped->axes[AXIS_INDEX_RIGHT_STICK_Y] = input.axes[5];
   DpadFromAxis(mapped, input.axes[9]);
 
diff --git a/docs/windows_build_instructions.md b/docs/windows_build_instructions.md
index 3490c0a..c24f222 100644
--- a/docs/windows_build_instructions.md
+++ b/docs/windows_build_instructions.md
@@ -283,8 +283,8 @@
 slower than expected for your machine's specifications?
 
 The next step is to gather some data. If you set the ``NINJA_SUMMARIZE_BUILD``
-environment variable to 1 then ``autoninja`` will do a couple of things. First,
-it will set the [NINJA_STATUS](https://ninja-build.org/manual.html#_environment_variables)
+environment variable to 1 then ``autoninja`` will do three things. First, it
+will set the [NINJA_STATUS](https://ninja-build.org/manual.html#_environment_variables)
 environment variable so that ninja will print additional information while
 building Chrome. It will show how many build processes are running at any given
 time, how many build steps have completed, how many build steps have completed
@@ -325,20 +325,16 @@
 $ python depot_tools\post_build_ninja_summary.py -C out\Default
 ```
 
-You can also get a visual report of the build performance with
-[ninjatracing](https://github.com/nico/ninjatracing). This converts the
-.ninja_log file into a .json file which can be loaded into chrome://tracing:
+Finally, setting ``NINJA_SUMMARIZE_BUILD=1`` tells autoninja to tell Ninja to
+report on its own overhead by passing "-d stats". This can be helpful if, for
+instance, process creation (which shows up in the StartEdge metric) is making
+builds slow, perhaps due to antivirus interference due to clang-cl not being in
+an excluded directory:
 
 ```shell
-$ python ninjatracing out\Default\.ninja_log >build.json
-```
-
-Finally, Ninja can report on its own overhead which can be helpful if, for
-instance, process creation is making builds slow, perhaps due to antivirus
-interference due to clang-cl not being in an excluded directory:
-
-```shell
-$ autoninja -d stats -C out\Default base
+$ set NINJA_SUMMARIZE_BUILD=1
+$ autoninja -C out\Default base
+"c:\src\depot_tools\ninja.exe" -C out\Default base -j 10 -d stats
 metric                  count   avg (us)        total (ms)
 .ninja parse            3555    1539.4          5472.6
 canonicalize str        1383032 0.0             12.7
@@ -353,6 +349,14 @@
 CLParser::Parse         45      1889.1          85.0
 ```
 
+You can also get a visual report of the build performance with
+[ninjatracing](https://github.com/nico/ninjatracing). This converts the
+.ninja_log file into a .json file which can be loaded into chrome://tracing:
+
+```shell
+$ python ninjatracing out\Default\.ninja_log >build.json
+```
+
 ## Build Chromium
 
 Build Chromium (the "chrome" target) with Ninja using the command:
diff --git a/extensions/browser/updater/update_data_provider.cc b/extensions/browser/updater/update_data_provider.cc
index 46ab1056..7e2a36b7 100644
--- a/extensions/browser/updater/update_data_provider.cc
+++ b/extensions/browser/updater/update_data_provider.cc
@@ -99,6 +99,8 @@
     crx_component->pk_hash.resize(crypto::kSHA256Length, 0);
     crypto::SHA256HashString(pubkey_bytes, crx_component->pk_hash.data(),
                              crx_component->pk_hash.size());
+    crx_component->app_id =
+        update_client::GetCrxIdFromPublicKeyHash(crx_component->pk_hash);
     crx_component->version = extension_data.is_corrupt_reinstall
                                  ? base::Version("0.0.0.0")
                                  : extension->version();
diff --git a/headless/test/test_network_interceptor.cc b/headless/test/test_network_interceptor.cc
index 62f0df0..30f5df5 100644
--- a/headless/test/test_network_interceptor.cc
+++ b/headless/test/test_network_interceptor.cc
@@ -49,8 +49,7 @@
  private:
   void NotifyRedirect(const std::string& location) {
     auto redirect_info = net::RedirectInfo::ComputeRedirectInfo(
-        url_request_.method, url_request_.url, url_request_.request_initiator,
-        url_request_.site_for_cookies,
+        url_request_.method, url_request_.url, url_request_.site_for_cookies,
         net::URLRequest::FirstPartyURLPolicy::
             UPDATE_FIRST_PARTY_URL_ON_REDIRECT,
         url_request_.referrer_policy, url_request_.referrer.spec(),
diff --git a/ios/chrome/app/chrome_overlay_window.mm b/ios/chrome/app/chrome_overlay_window.mm
index d1d7ea0..64d55b6 100644
--- a/ios/chrome/app/chrome_overlay_window.mm
+++ b/ios/chrome/app/chrome_overlay_window.mm
@@ -68,6 +68,8 @@
 - (void)updateBreakpad {
   breakpad_helper::SetCurrentHorizontalSizeClass(
       self.traitCollection.horizontalSizeClass);
+  breakpad_helper::SetCurrentUserInterfaceStyle(
+      self.traitCollection.userInterfaceStyle);
 }
 
 #pragma mark - UITraitEnvironment
@@ -87,6 +89,7 @@
       [self.userInterfaceStyleRecorder
           userInterfaceStyleDidChange:self.traitCollection.userInterfaceStyle];
     }
+    [self updateBreakpad];
   }
 }
 
diff --git a/ios/chrome/app/startup/BUILD.gn b/ios/chrome/app/startup/BUILD.gn
index f4f7b1e..02e8dde 100644
--- a/ios/chrome/app/startup/BUILD.gn
+++ b/ios/chrome/app/startup/BUILD.gn
@@ -23,6 +23,7 @@
 
   deps = [
     "//base",
+    "//components/component_updater",
     "//components/crash/core/common",
     "//ios/chrome/browser:chrome_paths",
     "//ios/web/public/init",
diff --git a/ios/chrome/app/startup/ios_chrome_main_delegate.mm b/ios/chrome/app/startup/ios_chrome_main_delegate.mm
index 2d2f023..e7b3c02 100644
--- a/ios/chrome/app/startup/ios_chrome_main_delegate.mm
+++ b/ios/chrome/app/startup/ios_chrome_main_delegate.mm
@@ -5,6 +5,7 @@
 #include "ios/chrome/app/startup/ios_chrome_main_delegate.h"
 
 #include "base/logging.h"
+#include "components/component_updater/component_updater_paths.h"
 #include "ios/chrome/browser/chrome_paths.h"
 #include "third_party/skia/include/core/SkGraphics.h"
 
@@ -25,6 +26,12 @@
   // Initialize the Chrome path provider.
   ios::RegisterPathProvider();
 
+  // Register the component updater path provider.
+  // Bundled components are not supported on ios, so DIR_USER_DATA is passed
+  // for all three arguments.
+  component_updater::RegisterPathProvider(
+      ios::DIR_USER_DATA, ios::DIR_USER_DATA, ios::DIR_USER_DATA);
+
   // Upstream wires up log file handling here based on flags; for now that's
   // not supported, and this is called just to handle vlog levels and patterns.
   // If redirecting to a file is ever needed, add it here (see
diff --git a/ios/chrome/app/strings/ios_strings.grd b/ios/chrome/app/strings/ios_strings.grd
index 3f82640..f225f43 100644
--- a/ios/chrome/app/strings/ios_strings.grd
+++ b/ios/chrome/app/strings/ios_strings.grd
@@ -1108,6 +1108,9 @@
       <message name="IDS_IOS_OPTIONS_WEB_SERVICES_LABEL" desc="Title for group of web services items in Privacy settings table, including Show Suggestions, Preload Webpages, and Send Usage Data. [Length: 10em] [iOS only]">
         Web Services
       </message>
+      <message name="IDS_IOS_OVERFLOW_BADGE_HINT" desc="Button displayed when there is more than one badge to show [iOS only]">
+        Show available page actions
+      </message>
       <message name="IDS_IOS_OVERSCROLL_NEW_TAB_LABEL" desc="The text to use for the tooltip for the overscroll new tab action. [Length: 20em] [iOS only]">
         New Tab
       </message>
diff --git a/ios/chrome/browser/autofill/form_suggestion_controller.h b/ios/chrome/browser/autofill/form_suggestion_controller.h
index 4c91bf8..41e0889 100644
--- a/ios/chrome/browser/autofill/form_suggestion_controller.h
+++ b/ios/chrome/browser/autofill/form_suggestion_controller.h
@@ -13,7 +13,7 @@
 #import "ios/chrome/browser/autofill/form_input_suggestions_provider.h"
 #import "ios/chrome/browser/autofill/form_suggestion_client.h"
 #import "ios/chrome/browser/autofill/form_suggestion_view.h"
-#import "ios/web/public/web_state/web_state_observer_bridge.h"
+#import "ios/web/public/web_state_observer_bridge.h"
 
 namespace autofill {
 struct FormActivityParams;
diff --git a/ios/chrome/browser/crash_report/breakpad_helper.h b/ios/chrome/browser/crash_report/breakpad_helper.h
index dc727b7..5225381 100644
--- a/ios/chrome/browser/crash_report/breakpad_helper.h
+++ b/ios/chrome/browser/crash_report/breakpad_helper.h
@@ -97,6 +97,11 @@
 // values from 0 to 2).
 void SetCurrentHorizontalSizeClass(int horizontalSizeClass);
 
+// Sets a key in browser_state dictionary to store the device user interface
+// style. The values are from the UIKit UIUserInterfaceStyle enum (decimal
+// values from 0 to 2).
+void SetCurrentUserInterfaceStyle(int userInterfaceStyle);
+
 // Sets a key in browser_state dictionary to store the count of regular tabs.
 void SetRegularTabCount(int tabCount);
 
diff --git a/ios/chrome/browser/crash_report/breakpad_helper.mm b/ios/chrome/browser/crash_report/breakpad_helper.mm
index 9437acc9..9ba5321b 100644
--- a/ios/chrome/browser/crash_report/breakpad_helper.mm
+++ b/ios/chrome/browser/crash_report/breakpad_helper.mm
@@ -57,6 +57,7 @@
 // These are the values grouped in the user_application_state parameter.
 NSString* const kOrientationState = @"orient";
 NSString* const kHorizontalSizeClass = @"sizeclass";
+NSString* const kUserInterfaceStyle = @"user_interface_style";
 NSString* const kSignedIn = @"signIn";
 NSString* const kIsShowingPDF = @"pdf";
 NSString* const kVideoPlaying = @"avplay";
@@ -319,6 +320,12 @@
       withValue:horizontalSizeClass];
 }
 
+void SetCurrentUserInterfaceStyle(int userInterfaceStyle) {
+  [[CrashReportUserApplicationState sharedInstance]
+       setValue:kUserInterfaceStyle
+      withValue:userInterfaceStyle];
+}
+
 void SetCurrentlySignedIn(bool signedIn) {
   if (signedIn) {
     [[CrashReportUserApplicationState sharedInstance] setValue:kSignedIn
diff --git a/ios/chrome/browser/crash_report/breakpad_helper_unittest.mm b/ios/chrome/browser/crash_report/breakpad_helper_unittest.mm
index 8cd8b0b..c76c190 100644
--- a/ios/chrome/browser/crash_report/breakpad_helper_unittest.mm
+++ b/ios/chrome/browser/crash_report/breakpad_helper_unittest.mm
@@ -60,6 +60,7 @@
   // single breakpad record.
   breakpad_helper::SetCurrentOrientation(3, 7);
   breakpad_helper::SetCurrentHorizontalSizeClass(2);
+  breakpad_helper::SetCurrentUserInterfaceStyle(2);
   breakpad_helper::SetRegularTabCount(999);
   breakpad_helper::SetIncognitoTabCount(999);
   breakpad_helper::SetDestroyingAndRebuildingIncognitoBrowserState(true);
diff --git a/ios/chrome/browser/crash_report/crash_report_helper.mm b/ios/chrome/browser/crash_report/crash_report_helper.mm
index 6b13845..a21fcd23 100644
--- a/ios/chrome/browser/crash_report/crash_report_helper.mm
+++ b/ios/chrome/browser/crash_report/crash_report_helper.mm
@@ -29,7 +29,7 @@
 #import "ios/web/public/navigation/navigation_manager.h"
 #include "ios/web/public/thread/web_thread.h"
 #import "ios/web/public/web_state.h"
-#import "ios/web/public/web_state/web_state_observer_bridge.h"
+#import "ios/web/public/web_state_observer_bridge.h"
 #import "net/base/mac/url_conversions.h"
 
 #if !defined(__has_feature) || !__has_feature(objc_arc)
diff --git a/ios/chrome/browser/find_in_page/find_in_page_controller.mm b/ios/chrome/browser/find_in_page/find_in_page_controller.mm
index 9af4c97..36c2571 100644
--- a/ios/chrome/browser/find_in_page/find_in_page_controller.mm
+++ b/ios/chrome/browser/find_in_page/find_in_page_controller.mm
@@ -23,7 +23,7 @@
 #import "ios/web/public/ui/crw_web_view_proxy.h"
 #import "ios/web/public/ui/crw_web_view_scroll_view_proxy.h"
 #import "ios/web/public/web_state.h"
-#import "ios/web/public/web_state/web_state_observer_bridge.h"
+#import "ios/web/public/web_state_observer_bridge.h"
 #include "services/metrics/public/cpp/ukm_builders.h"
 
 #if !defined(__has_feature) || !__has_feature(objc_arc)
diff --git a/ios/chrome/browser/flags/about_flags.mm b/ios/chrome/browser/flags/about_flags.mm
index 8e81ea0..758414ec 100644
--- a/ios/chrome/browser/flags/about_flags.mm
+++ b/ios/chrome/browser/flags/about_flags.mm
@@ -494,11 +494,6 @@
      flag_descriptions::kOmniboxUseDefaultSearchEngineFaviconDescription,
      flags_ui::kOsIos,
      FEATURE_VALUE_TYPE(kOmniboxUseDefaultSearchEngineFavicon)},
-    {"enable-autofill-import-dynamic-forms",
-     flag_descriptions::kEnableAutofillImportDynamicFormsName,
-     flag_descriptions::kEnableAutofillImportDynamicFormsDescription,
-     flags_ui::kOsIos,
-     FEATURE_VALUE_TYPE(autofill::features::kAutofillImportDynamicForms)},
     {"enable-send-tab-to-self-broadcast",
      flag_descriptions::kSendTabToSelfBroadcastName,
      flag_descriptions::kSendTabToSelfBroadcastDescription, flags_ui::kOsIos,
diff --git a/ios/chrome/browser/flags/ios_chrome_flag_descriptions.cc b/ios/chrome/browser/flags/ios_chrome_flag_descriptions.cc
index 83d6af3..bd218e5 100644
--- a/ios/chrome/browser/flags/ios_chrome_flag_descriptions.cc
+++ b/ios/chrome/browser/flags/ios_chrome_flag_descriptions.cc
@@ -178,12 +178,6 @@
 const char kEnableAutofillSaveCardShowNoThanksDescription[] =
     "If enabled, adds a [No thanks] button to credit card save prompts.";
 
-const char kEnableAutofillImportDynamicFormsName[] =
-    "Allow credit card import from dynamic forms after entry";
-const char kEnableAutofillImportDynamicFormsDescription[] =
-    "If enabled, offers credit card save for dynamic forms from the page after "
-    "information has been entered into them.";
-
 const char kEnableClipboardProviderImageSuggestionsName[] =
     "Enable copied image provider";
 const char kEnableClipboardProviderImageSuggestionsDescription[] =
diff --git a/ios/chrome/browser/flags/ios_chrome_flag_descriptions.h b/ios/chrome/browser/flags/ios_chrome_flag_descriptions.h
index 17ee6947..aad43902 100644
--- a/ios/chrome/browser/flags/ios_chrome_flag_descriptions.h
+++ b/ios/chrome/browser/flags/ios_chrome_flag_descriptions.h
@@ -144,11 +144,6 @@
 extern const char kEnableAutofillSaveCardShowNoThanksName[];
 extern const char kEnableAutofillSaveCardShowNoThanksDescription[];
 
-// Title and description for the flag to control the credit card import from
-// dynamic forms.
-extern const char kEnableAutofillImportDynamicFormsName[];
-extern const char kEnableAutofillImportDynamicFormsDescription[];
-
 // Title and description for the flag to enable the clipboard provider to
 // suggest searchihng for copied imagse
 extern const char kEnableClipboardProviderImageSuggestionsName[];
diff --git a/ios/chrome/browser/geolocation/omnibox_geolocation_controller.mm b/ios/chrome/browser/geolocation/omnibox_geolocation_controller.mm
index c6ca8454..b81140ce 100644
--- a/ios/chrome/browser/geolocation/omnibox_geolocation_controller.mm
+++ b/ios/chrome/browser/geolocation/omnibox_geolocation_controller.mm
@@ -26,7 +26,7 @@
 #include "ios/web/public/navigation/navigation_item.h"
 #import "ios/web/public/navigation/navigation_manager.h"
 #import "ios/web/public/web_state.h"
-#import "ios/web/public/web_state/web_state_observer_bridge.h"
+#import "ios/web/public/web_state_observer_bridge.h"
 #include "url/gurl.h"
 
 #if !defined(__has_feature) || !__has_feature(objc_arc)
diff --git a/ios/chrome/browser/infobars/infobar_metrics_recorder.h b/ios/chrome/browser/infobars/infobar_metrics_recorder.h
index 97089bc..7a25fbb4 100644
--- a/ios/chrome/browser/infobars/infobar_metrics_recorder.h
+++ b/ios/chrome/browser/infobars/infobar_metrics_recorder.h
@@ -35,8 +35,9 @@
   TimedOut = 0,
   // Infobar Banner was dismissed by being swiped up.
   SwipedUp = 1,
-  // Infobar Banner was dismissed by being dragged into an Infobar Modal.
-  ExpandedToModal = 2,
+  // *DEPRECATED* Infobar Banner was dismissed by being dragged into an Infobar
+  // Modal.
+  ExpandedToModal_DEPRECATED = 2,
   // Infobar Banner was dismissed by being tapped into an Infobar Modal.
   TappedToModal = 3,
   // Highest enumerator. Recommended by Histogram metrics best practices.
diff --git a/ios/chrome/browser/passwords/password_controller.h b/ios/chrome/browser/passwords/password_controller.h
index 389c6f0..0bc9c0c 100644
--- a/ios/chrome/browser/passwords/password_controller.h
+++ b/ios/chrome/browser/passwords/password_controller.h
@@ -12,7 +12,7 @@
 #import "components/password_manager/ios/password_form_helper.h"
 #import "ios/chrome/browser/passwords/ios_chrome_password_manager_client.h"
 #import "ios/chrome/browser/passwords/ios_chrome_password_manager_driver.h"
-#import "ios/web/public/web_state/web_state_observer_bridge.h"
+#import "ios/web/public/web_state_observer_bridge.h"
 
 @protocol ApplicationCommands;
 @class NotifyUserAutoSigninViewController;
diff --git a/ios/chrome/browser/prerender/preload_controller.mm b/ios/chrome/browser/prerender/preload_controller.mm
index 5d4f52f..898e0907 100644
--- a/ios/chrome/browser/prerender/preload_controller.mm
+++ b/ios/chrome/browser/prerender/preload_controller.mm
@@ -32,7 +32,7 @@
 #import "ios/web/public/navigation/web_state_policy_decider_bridge.h"
 #include "ios/web/public/thread/web_thread.h"
 #import "ios/web/public/web_state.h"
-#include "ios/web/public/web_state/web_state_observer_bridge.h"
+#import "ios/web/public/web_state_observer_bridge.h"
 #import "ios/web/web_state/ui/crw_web_controller.h"
 #import "net/base/mac/url_conversions.h"
 #include "ui/base/page_transition_types.h"
diff --git a/ios/chrome/browser/snapshots/snapshot_generator.mm b/ios/chrome/browser/snapshots/snapshot_generator.mm
index 209f501..f6c61f5b 100644
--- a/ios/chrome/browser/snapshots/snapshot_generator.mm
+++ b/ios/chrome/browser/snapshots/snapshot_generator.mm
@@ -24,7 +24,7 @@
 #include "ios/web/public/thread/web_thread.h"
 #import "ios/web/public/web_client.h"
 #import "ios/web/public/web_state.h"
-#import "ios/web/public/web_state/web_state_observer_bridge.h"
+#import "ios/web/public/web_state_observer_bridge.h"
 #include "ui/gfx/geometry/rect_f.h"
 #include "ui/gfx/image/image.h"
 
diff --git a/ios/chrome/browser/tabs/tab_model.mm b/ios/chrome/browser/tabs/tab_model.mm
index 402a1081..a351dde8 100644
--- a/ios/chrome/browser/tabs/tab_model.mm
+++ b/ios/chrome/browser/tabs/tab_model.mm
@@ -63,7 +63,7 @@
 #include "ios/web/public/session/session_certificate_policy_cache.h"
 #include "ios/web/public/thread/web_task_traits.h"
 #include "ios/web/public/thread/web_thread.h"
-#import "ios/web/public/web_state/web_state_observer_bridge.h"
+#import "ios/web/public/web_state_observer_bridge.h"
 #include "url/gurl.h"
 
 #if !defined(__has_feature) || !__has_feature(objc_arc)
diff --git a/ios/chrome/browser/ui/activity_services/chrome_activity_item_thumbnail_generator.mm b/ios/chrome/browser/ui/activity_services/chrome_activity_item_thumbnail_generator.mm
index 614a3c3b..4628764 100644
--- a/ios/chrome/browser/ui/activity_services/chrome_activity_item_thumbnail_generator.mm
+++ b/ios/chrome/browser/ui/activity_services/chrome_activity_item_thumbnail_generator.mm
@@ -8,8 +8,8 @@
 #import "ios/chrome/browser/snapshots/snapshot_tab_helper.h"
 #import "ios/chrome/browser/ui/util/uikit_ui_util.h"
 #import "ios/web/public/web_state.h"
-#import "ios/web/public/web_state/web_state_observer_bridge.h"
 #include "ios/web/public/web_state_observer.h"
+#import "ios/web/public/web_state_observer_bridge.h"
 
 #if !defined(__has_feature) || !__has_feature(objc_arc)
 #error "This file requires ARC support."
diff --git a/ios/chrome/browser/ui/autofill/form_input_accessory/form_input_accessory_coordinator.h b/ios/chrome/browser/ui/autofill/form_input_accessory/form_input_accessory_coordinator.h
index a46ff7e..c00f4dbe 100644
--- a/ios/chrome/browser/ui/autofill/form_input_accessory/form_input_accessory_coordinator.h
+++ b/ios/chrome/browser/ui/autofill/form_input_accessory/form_input_accessory_coordinator.h
@@ -7,7 +7,7 @@
 
 #import "ios/chrome/browser/ui/coordinators/chrome_coordinator.h"
 
-#import "ios/web/public/web_state/web_state_observer_bridge.h"
+#import "ios/web/public/web_state_observer_bridge.h"
 
 @protocol BrowserCoordinatorCommands;
 @class ManualFillInjectionHandler;
diff --git a/ios/chrome/browser/ui/autofill/form_input_accessory/form_input_accessory_mediator.h b/ios/chrome/browser/ui/autofill/form_input_accessory/form_input_accessory_mediator.h
index 259468c..c769e96 100644
--- a/ios/chrome/browser/ui/autofill/form_input_accessory/form_input_accessory_mediator.h
+++ b/ios/chrome/browser/ui/autofill/form_input_accessory/form_input_accessory_mediator.h
@@ -10,7 +10,7 @@
 #include "components/password_manager/core/browser/password_store.h"
 #import "ios/chrome/browser/autofill/form_input_navigator.h"
 #import "ios/chrome/browser/web_state_list/web_state_list_observer_bridge.h"
-#import "ios/web/public/web_state/web_state_observer_bridge.h"
+#import "ios/web/public/web_state_observer_bridge.h"
 
 @class ChromeCoordinator;
 @protocol FormInputAccessoryConsumer;
diff --git a/ios/chrome/browser/ui/badges/BUILD.gn b/ios/chrome/browser/ui/badges/BUILD.gn
index b3dc390d..8504ade 100644
--- a/ios/chrome/browser/ui/badges/BUILD.gn
+++ b/ios/chrome/browser/ui/badges/BUILD.gn
@@ -22,10 +22,13 @@
     "badge_button_factory.h",
     "badge_button_factory.mm",
     "badge_consumer.h",
+    "badge_delegate.h",
     "badge_mediator.h",
     "badge_mediator.mm",
     "badge_static_item.h",
     "badge_static_item.mm",
+    "badge_tappable_item.h",
+    "badge_tappable_item.mm",
     "badge_view_controller.h",
     "badge_view_controller.mm",
   ]
@@ -33,6 +36,7 @@
     ":public",
     "resources:incognito_badge",
     "resources:incognito_small_badge",
+    "resources:wrench_badge",
     "//base:base",
     "//ios/chrome/app/strings:ios_strings_grit",
     "//ios/chrome/browser/infobars:badge",
@@ -42,6 +46,7 @@
     "//ios/chrome/browser/ui/elements",
     "//ios/chrome/browser/ui/fullscreen:ui",
     "//ios/chrome/browser/ui/infobars:feature_flags",
+    "//ios/chrome/browser/ui/list_model",
     "//ios/chrome/browser/ui/util",
     "//ios/chrome/browser/web",
     "//ios/chrome/browser/web_state_list",
diff --git a/ios/chrome/browser/ui/badges/badge_button_action_handler.h b/ios/chrome/browser/ui/badges/badge_button_action_handler.h
index ed2ec0ac..96f7446 100644
--- a/ios/chrome/browser/ui/badges/badge_button_action_handler.h
+++ b/ios/chrome/browser/ui/badges/badge_button_action_handler.h
@@ -8,6 +8,7 @@
 #import <UIKit/UIKit.h>
 
 @protocol InfobarCommands;
+@protocol BadgeDelegate;
 
 // Handler for the actions associated with the different badge buttons.
 @interface BadgeButtonActionHandler : NSObject
@@ -15,9 +16,15 @@
 // The dispatcher for badge button actions.
 @property(nonatomic, weak) id<InfobarCommands> dispatcher;
 
+// The command handler.
+@property(nonatomic, weak) id<BadgeDelegate> buttonActionDelegate;
+
 // Action when a Passwords badge is tapped.
 - (void)passwordsBadgeButtonTapped:(id)sender;
 
+// Action when the overflow badge is tapped.
+- (void)overflowBadgeButtonTapped:(id)sender;
+
 @end
 
 #endif  // IOS_CHROME_BROWSER_UI_BADGES_BADGE_BUTTON_ACTION_HANDLER_H_
diff --git a/ios/chrome/browser/ui/badges/badge_button_action_handler.mm b/ios/chrome/browser/ui/badges/badge_button_action_handler.mm
index 7b05e6c..5324e26 100644
--- a/ios/chrome/browser/ui/badges/badge_button_action_handler.mm
+++ b/ios/chrome/browser/ui/badges/badge_button_action_handler.mm
@@ -9,6 +9,7 @@
 #include "ios/chrome/browser/infobars/infobar_metrics_recorder.h"
 #import "ios/chrome/browser/infobars/infobar_type.h"
 #import "ios/chrome/browser/ui/badges/badge_button.h"
+#import "ios/chrome/browser/ui/badges/badge_delegate.h"
 #import "ios/chrome/browser/ui/commands/infobar_commands.h"
 
 #if !defined(__has_feature) || !__has_feature(objc_arc)
@@ -43,4 +44,9 @@
   [metricsRecorder recordBadgeTappedInState:state];
 }
 
+- (void)overflowBadgeButtonTapped:(id)sender {
+  [self.buttonActionDelegate showOverflowMenu];
+  // TODO(crbug.com/976901): Add metric for this action.
+}
+
 @end
diff --git a/ios/chrome/browser/ui/badges/badge_button_factory.mm b/ios/chrome/browser/ui/badges/badge_button_factory.mm
index ecea4cd6..d8a37aef 100644
--- a/ios/chrome/browser/ui/badges/badge_button_factory.mm
+++ b/ios/chrome/browser/ui/badges/badge_button_factory.mm
@@ -42,6 +42,8 @@
       return [self passwordsUpdateBadgeButton];
     case BadgeType::kBadgeTypeIncognito:
       return [self incognitoBadgeButton];
+    case BadgeType::kBadgeTypeOverflow:
+      return [self overflowBadgeButton];
     case BadgeType::kBadgeTypeNone:
       NOTREACHED() << "A badge should not have kBadgeTypeNone";
       return nil;
@@ -96,6 +98,20 @@
   return button;
 }
 
+- (BadgeButton*)overflowBadgeButton {
+  BadgeButton* button =
+      [self createButtonForType:BadgeType::kBadgeTypeOverflow
+                     imageNamed:@"wrench_badge"
+                  renderingMode:UIImageRenderingModeAlwaysTemplate];
+  [button addTarget:self.actionHandler
+                action:@selector(overflowBadgeButtonTapped:)
+      forControlEvents:UIControlEventTouchUpInside];
+  button.accessibilityIdentifier = kBadgeButtonOverflowAccessibilityIdentifier;
+  button.accessibilityLabel =
+      l10n_util::GetNSString(IDS_IOS_OVERFLOW_BADGE_HINT);
+  return button;
+}
+
 - (BadgeButton*)createButtonForType:(BadgeType)badgeType
                          imageNamed:(NSString*)imageName
                       renderingMode:(UIImageRenderingMode)renderingMode {
diff --git a/ios/chrome/browser/ui/badges/badge_constants.h b/ios/chrome/browser/ui/badges/badge_constants.h
index 31c072a..85fcac6 100644
--- a/ios/chrome/browser/ui/badges/badge_constants.h
+++ b/ios/chrome/browser/ui/badges/badge_constants.h
@@ -11,5 +11,6 @@
 extern NSString* const kBadgeButtonSavePasswordAccessibilityIdentifier;
 extern NSString* const kBadgeButtonUpdatePasswordAccessibilityIdentifier;
 extern NSString* const kBadgeButtonIncognitoAccessibilityIdentifier;
+extern NSString* const kBadgeButtonOverflowAccessibilityIdentifier;
 
 #endif  // IOS_CHROME_BROWSER_UI_BADGES_BADGE_CONSTANTS_H_
diff --git a/ios/chrome/browser/ui/badges/badge_constants.mm b/ios/chrome/browser/ui/badges/badge_constants.mm
index 32abe3a8..1a917cac 100644
--- a/ios/chrome/browser/ui/badges/badge_constants.mm
+++ b/ios/chrome/browser/ui/badges/badge_constants.mm
@@ -16,3 +16,6 @@
 
 NSString* const kBadgeButtonIncognitoAccessibilityIdentifier =
     @"badgeButtonIncognitoAXID";
+
+NSString* const kBadgeButtonOverflowAccessibilityIdentifier =
+    @"badgeButtonOverflowAXID";
diff --git a/ios/chrome/browser/ui/badges/badge_delegate.h b/ios/chrome/browser/ui/badges/badge_delegate.h
new file mode 100644
index 0000000..9c71a7e
--- /dev/null
+++ b/ios/chrome/browser/ui/badges/badge_delegate.h
@@ -0,0 +1,14 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef IOS_CHROME_BROWSER_UI_BADGES_BADGE_DELEGATE_H_
+#define IOS_CHROME_BROWSER_UI_BADGES_BADGE_DELEGATE_H_
+
+// Protocol to communicate Badge actions to the coordinator.
+@protocol BadgeDelegate
+// Shows the badge overflow menu.
+- (void)showOverflowMenu;
+@end
+
+#endif  // IOS_CHROME_BROWSER_UI_BADGES_BADGE_DELEGATE_H_
diff --git a/ios/chrome/browser/ui/badges/badge_tappable_item.h b/ios/chrome/browser/ui/badges/badge_tappable_item.h
new file mode 100644
index 0000000..2e7e550c
--- /dev/null
+++ b/ios/chrome/browser/ui/badges/badge_tappable_item.h
@@ -0,0 +1,20 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef IOS_CHROME_BROWSER_UI_BADGES_BADGE_TAPPABLE_ITEM_H_
+#define IOS_CHROME_BROWSER_UI_BADGES_BADGE_TAPPABLE_ITEM_H_
+
+#import "ios/chrome/browser/ui/badges/badge_item.h"
+
+// Holds properties and values needed to configure a BadgeButton that is
+// tappable.
+@interface BadgeTappableItem : NSObject <BadgeItem>
+
+- (instancetype)initWithBadgeType:(BadgeType)badgeType
+    NS_DESIGNATED_INITIALIZER;
+- (instancetype)init NS_UNAVAILABLE;
+
+@end
+
+#endif  // IOS_CHROME_BROWSER_UI_BADGES_BADGE_TAPPABLE_ITEM_H_
diff --git a/ios/chrome/browser/ui/badges/badge_tappable_item.mm b/ios/chrome/browser/ui/badges/badge_tappable_item.mm
new file mode 100644
index 0000000..2ba50f697
--- /dev/null
+++ b/ios/chrome/browser/ui/badges/badge_tappable_item.mm
@@ -0,0 +1,42 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#import "ios/chrome/browser/ui/badges/badge_tappable_item.h"
+
+#import "ios/chrome/browser/ui/badges/badge_type.h"
+
+#if !defined(__has_feature) || !__has_feature(objc_arc)
+#error "This file requires ARC support."
+#endif
+
+@interface BadgeTappableItem ()
+
+// The BadgeType of this item.
+@property(nonatomic, assign) BadgeType badgeType;
+
+@end
+
+@implementation BadgeTappableItem
+// Synthesized from protocol.
+@synthesize tappable = _tappable;
+// Synthesized from protocol.
+@synthesize accepted = _accepted;
+
+- (instancetype)initWithBadgeType:(BadgeType)badgeType {
+  self = [super init];
+  if (self) {
+    _badgeType = badgeType;
+    _tappable = YES;
+    _accepted = NO;
+  }
+  return self;
+}
+
+#pragma mark - BadgeItem
+
+- (BOOL)isFullScreen {
+  return NO;
+}
+
+@end
diff --git a/ios/chrome/browser/ui/badges/badge_type.h b/ios/chrome/browser/ui/badges/badge_type.h
index 1bca959..4f3a1139 100644
--- a/ios/chrome/browser/ui/badges/badge_type.h
+++ b/ios/chrome/browser/ui/badges/badge_type.h
@@ -17,6 +17,8 @@
   kBadgeTypePasswordUpdate = 2,
   // Badge type for the Incognito Badge.
   kBadgeTypeIncognito = 3,
+  // Badge type for when there are more than one badge to be displayed.
+  kBadgeTypeOverflow = 4,
 };
 
 #endif  // IOS_CHROME_BROWSER_UI_BADGES_BADGE_TYPE_H_
diff --git a/ios/chrome/browser/ui/badges/resources/BUILD.gn b/ios/chrome/browser/ui/badges/resources/BUILD.gn
index 21e3d8b..e57f829 100644
--- a/ios/chrome/browser/ui/badges/resources/BUILD.gn
+++ b/ios/chrome/browser/ui/badges/resources/BUILD.gn
@@ -19,3 +19,11 @@
     "incognito_small_badge.imageset/incognito_small_badge@3x.png",
   ]
 }
+
+imageset("wrench_badge") {
+  sources = [
+    "wrench_badge.imageset/Contents.json",
+    "wrench_badge.imageset/wrench_badge@2x.png",
+    "wrench_badge.imageset/wrench_badge@3x.png",
+  ]
+}
diff --git a/ios/chrome/browser/ui/badges/resources/wrench_badge.imageset/Contents.json b/ios/chrome/browser/ui/badges/resources/wrench_badge.imageset/Contents.json
new file mode 100644
index 0000000..237f28c
--- /dev/null
+++ b/ios/chrome/browser/ui/badges/resources/wrench_badge.imageset/Contents.json
@@ -0,0 +1,18 @@
+{
+    "images": [
+        {
+            "idiom": "universal",
+            "scale": "2x",
+            "filename": "wrench_badge@2x.png"
+        },
+        {
+            "idiom": "universal",
+            "scale": "3x",
+            "filename": "wrench_badge@3x.png"
+        }
+    ],
+    "info": {
+        "version": 1,
+        "author": "xcode"
+    }
+}
diff --git a/ios/chrome/browser/ui/badges/resources/wrench_badge.imageset/wrench_badge@2x.png b/ios/chrome/browser/ui/badges/resources/wrench_badge.imageset/wrench_badge@2x.png
new file mode 100644
index 0000000..0e9bdd7
--- /dev/null
+++ b/ios/chrome/browser/ui/badges/resources/wrench_badge.imageset/wrench_badge@2x.png
Binary files differ
diff --git a/ios/chrome/browser/ui/badges/resources/wrench_badge.imageset/wrench_badge@3x.png b/ios/chrome/browser/ui/badges/resources/wrench_badge.imageset/wrench_badge@3x.png
new file mode 100644
index 0000000..c69d3888
--- /dev/null
+++ b/ios/chrome/browser/ui/badges/resources/wrench_badge.imageset/wrench_badge@3x.png
Binary files differ
diff --git a/ios/chrome/browser/ui/browser_view/browser_view_controller.mm b/ios/chrome/browser/ui/browser_view/browser_view_controller.mm
index 24dc7fd..2216f51 100644
--- a/ios/chrome/browser/ui/browser_view/browser_view_controller.mm
+++ b/ios/chrome/browser/ui/browser_view/browser_view_controller.mm
@@ -193,7 +193,7 @@
 #import "ios/web/public/ui/crw_web_view_proxy.h"
 #include "ios/web/public/web_client.h"
 #import "ios/web/public/web_state/web_state_delegate_bridge.h"
-#include "ios/web/public/web_state/web_state_observer_bridge.h"
+#import "ios/web/public/web_state_observer_bridge.h"
 #import "ios/web/web_state/ui/crw_web_controller.h"
 #include "ui/base/l10n/l10n_util.h"
 
diff --git a/ios/chrome/browser/ui/content_suggestions/ntp_home_mediator.mm b/ios/chrome/browser/ui/content_suggestions/ntp_home_mediator.mm
index 34e840a4..7fd32db8 100644
--- a/ios/chrome/browser/ui/content_suggestions/ntp_home_mediator.mm
+++ b/ios/chrome/browser/ui/content_suggestions/ntp_home_mediator.mm
@@ -54,7 +54,7 @@
 #import "ios/web/public/navigation/navigation_manager.h"
 #include "ios/web/public/navigation/referrer.h"
 #import "ios/web/public/web_state.h"
-#import "ios/web/public/web_state/web_state_observer_bridge.h"
+#import "ios/web/public/web_state_observer_bridge.h"
 #include "ui/base/l10n/l10n_util.h"
 #include "url/gurl.h"
 
diff --git a/ios/chrome/browser/ui/dialogs/dialog_presenter.mm b/ios/chrome/browser/ui/dialogs/dialog_presenter.mm
index b5fb951..02dce26a 100644
--- a/ios/chrome/browser/ui/dialogs/dialog_presenter.mm
+++ b/ios/chrome/browser/ui/dialogs/dialog_presenter.mm
@@ -21,7 +21,7 @@
 #include "ios/chrome/grit/ios_strings.h"
 #import "ios/web/public/navigation/navigation_context.h"
 #import "ios/web/public/web_state.h"
-#import "ios/web/public/web_state/web_state_observer_bridge.h"
+#import "ios/web/public/web_state_observer_bridge.h"
 #include "ui/base/l10n/l10n_util.h"
 #include "url/gurl.h"
 
diff --git a/ios/chrome/browser/ui/download/pass_kit_coordinator.mm b/ios/chrome/browser/ui/download/pass_kit_coordinator.mm
index d88f639..734597f 100644
--- a/ios/chrome/browser/ui/download/pass_kit_coordinator.mm
+++ b/ios/chrome/browser/ui/download/pass_kit_coordinator.mm
@@ -11,7 +11,7 @@
 #include "components/infobars/core/simple_alert_infobar_delegate.h"
 #include "ios/chrome/browser/infobars/infobar_manager_impl.h"
 #include "ios/chrome/grit/ios_strings.h"
-#import "ios/web/public/web_state/web_state_observer_bridge.h"
+#import "ios/web/public/web_state_observer_bridge.h"
 #include "ui/base/l10n/l10n_util.h"
 
 #if !defined(__has_feature) || !__has_feature(objc_arc)
diff --git a/ios/chrome/browser/ui/infobars/banners/infobar_banner_view_controller.mm b/ios/chrome/browser/ui/infobars/banners/infobar_banner_view_controller.mm
index ac7e5e2..753135c6 100644
--- a/ios/chrome/browser/ui/infobars/banners/infobar_banner_view_controller.mm
+++ b/ios/chrome/browser/ui/infobars/banners/infobar_banner_view_controller.mm
@@ -51,7 +51,6 @@
 const CGFloat kIconWidth = 25.0;
 
 // Gesture constants.
-const CGFloat kChangeInPositionForTransition = 100.0;
 const CGFloat kChangeInPositionForDismissal = -15.0;
 const CGFloat kLongPressTimeDurationInSeconds = 0.4;
 }  // namespace
@@ -313,27 +312,11 @@
     self.startingTouch = touchLocation;
     [self animateBannerToScaleUpState];
   } else if (gesture.state == UIGestureRecognizerStateChanged) {
-    self.view.center =
-        CGPointMake(self.view.center.x, self.view.center.y + touchLocation.y -
-                                            self.startingTouch.y);
-    // If dragged down by more than kChangeInPositionForTransition, present
-    // the InfobarModal.
-    BOOL dragDownExceededThreshold =
-        (self.view.center.y - self.originalCenter.y >
-         kChangeInPositionForTransition);
-    if (dragDownExceededThreshold) {
-      base::RecordAction(
-          base::UserMetricsAction("MobileMessagesBannerDraggedDown"));
-      [self.metricsRecorder
-          recordBannerDismissType:MobileMessagesBannerDismissType::
-                                      ExpandedToModal];
-      [self recordBannerOnScreenTime];
-      [self.delegate presentInfobarModalFromBanner];
-      // Since the modal has now been presented prevent any external dismissal.
-      self.shouldDismissAfterTouchesEnded = NO;
-      // Cancel the gesture since the modal has now been presented.
-      gesture.state = UIGestureRecognizerStateCancelled;
-      return;
+    // Don't allow the banner to be dragged down past its original position.
+    CGFloat newYPosition =
+        self.view.center.y + touchLocation.y - self.startingTouch.y;
+    if (newYPosition < self.originalCenter.y) {
+      self.view.center = CGPointMake(self.view.center.x, newYPosition);
     }
   }
 
diff --git a/ios/chrome/browser/ui/location_bar/location_bar_coordinator.mm b/ios/chrome/browser/ui/location_bar/location_bar_coordinator.mm
index fd68b01..2340b53 100644
--- a/ios/chrome/browser/ui/location_bar/location_bar_coordinator.mm
+++ b/ios/chrome/browser/ui/location_bar/location_bar_coordinator.mm
@@ -25,6 +25,7 @@
 #include "ios/chrome/browser/search_engines/template_url_service_factory.h"
 #import "ios/chrome/browser/ui/badges/badge_button_action_handler.h"
 #import "ios/chrome/browser/ui/badges/badge_button_factory.h"
+#import "ios/chrome/browser/ui/badges/badge_delegate.h"
 #import "ios/chrome/browser/ui/badges/badge_mediator.h"
 #import "ios/chrome/browser/ui/badges/badge_view_controller.h"
 #include "ios/chrome/browser/ui/commands/browser_commands.h"
@@ -72,10 +73,11 @@
 const int kLocationAuthorizationStatusCount = 5;
 }  // namespace
 
-@interface LocationBarCoordinator ()<LoadQueryCommands,
-                                     LocationBarDelegate,
-                                     LocationBarViewControllerDelegate,
-                                     LocationBarConsumer> {
+@interface LocationBarCoordinator () <BadgeDelegate,
+                                      LoadQueryCommands,
+                                      LocationBarDelegate,
+                                      LocationBarViewControllerDelegate,
+                                      LocationBarConsumer> {
   // API endpoint for omnibox.
   std::unique_ptr<WebOmniboxEditControllerImpl> _editController;
   // Observer that updates |viewController| for fullscreen events.
@@ -173,10 +175,14 @@
   self.omniboxPopupCoordinator.webStateList = self.webStateList;
   [self.omniboxPopupCoordinator start];
 
-  // Create BadgeMediator and set the viewController as its consumer.
+  // Create an action handler that will handle the action to take for button
+  // taps.
   BadgeButtonActionHandler* actionHandler =
       [[BadgeButtonActionHandler alloc] init];
   actionHandler.dispatcher = static_cast<id<InfobarCommands>>(self.dispatcher);
+  actionHandler.buttonActionDelegate = self;
+  // Create button factory that wil be used by the ViewController to get
+  // BadgeButtons for a BadgeType.
   BadgeButtonFactory* buttonFactory =
       [[BadgeButtonFactory alloc] initWithActionHandler:actionHandler];
   self.badgeViewController =
@@ -184,6 +190,7 @@
   [self.viewController addChildViewController:self.badgeViewController];
   [self.viewController setBadgeView:self.badgeViewController.view];
   [self.badgeViewController didMoveToParentViewController:self.viewController];
+  // Create BadgeMediator and set the viewController as its consumer.
   self.badgeMediator =
       [[BadgeMediator alloc] initWithConsumer:self.badgeViewController
                                  webStateList:self.webStateList];
@@ -254,6 +261,13 @@
   return self.omniboxCoordinator.animatee;
 }
 
+#pragma mark - BadgeDelegate
+
+- (void)showOverflowMenu {
+  // TODO(crbug.com/976901): Retrieve badges to show in overflow menu and send
+  // signal to BVC.
+}
+
 #pragma mark - LoadQueryCommands
 
 - (void)loadQuery:(NSString*)query immediately:(BOOL)immediately {
diff --git a/ios/chrome/browser/ui/location_bar/location_bar_mediator.mm b/ios/chrome/browser/ui/location_bar/location_bar_mediator.mm
index 7e4d7a7..4b7fb18a 100644
--- a/ios/chrome/browser/ui/location_bar/location_bar_mediator.mm
+++ b/ios/chrome/browser/ui/location_bar/location_bar_mediator.mm
@@ -29,7 +29,7 @@
 #include "ios/web/public/security/ssl_status.h"
 #import "ios/web/public/web_client.h"
 #import "ios/web/public/web_state.h"
-#import "ios/web/public/web_state/web_state_observer_bridge.h"
+#import "ios/web/public/web_state_observer_bridge.h"
 #include "skia/ext/skia_utils_ios.h"
 #include "ui/base/l10n/l10n_util.h"
 
diff --git a/ios/chrome/browser/ui/main/browser_view_wrangler.mm b/ios/chrome/browser/ui/main/browser_view_wrangler.mm
index ac7119fb..c615f1a 100644
--- a/ios/chrome/browser/ui/main/browser_view_wrangler.mm
+++ b/ios/chrome/browser/ui/main/browser_view_wrangler.mm
@@ -24,7 +24,7 @@
 #import "ios/chrome/browser/web_state_list/web_state_list_observer_bridge.h"
 #include "ios/public/provider/chrome/browser/chrome_browser_provider.h"
 #import "ios/web/public/web_state.h"
-#import "ios/web/public/web_state/web_state_observer_bridge.h"
+#import "ios/web/public/web_state_observer_bridge.h"
 
 #if !defined(__has_feature) || !__has_feature(objc_arc)
 #error "This file requires ARC support."
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 fe3d1b1c..edd281d4 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
@@ -14,7 +14,7 @@
 #import "ios/web/public/ui/crw_web_view_proxy.h"
 #import "ios/web/public/ui/crw_web_view_scroll_view_proxy.h"
 #import "ios/web/public/web_state.h"
-#import "ios/web/public/web_state/web_state_observer_bridge.h"
+#import "ios/web/public/web_state_observer_bridge.h"
 
 #if !defined(__has_feature) || !__has_feature(objc_arc)
 #error "This file requires ARC support."
diff --git a/ios/chrome/browser/ui/ntp/new_tab_page_coordinator.mm b/ios/chrome/browser/ui/ntp/new_tab_page_coordinator.mm
index 2812389..9bc71c6 100644
--- a/ios/chrome/browser/ui/ntp/new_tab_page_coordinator.mm
+++ b/ios/chrome/browser/ui/ntp/new_tab_page_coordinator.mm
@@ -14,7 +14,7 @@
 #import "ios/web/public/navigation/navigation_context.h"
 #import "ios/web/public/navigation/navigation_item.h"
 #import "ios/web/public/navigation/navigation_manager.h"
-#import "ios/web/public/web_state/web_state_observer_bridge.h"
+#import "ios/web/public/web_state_observer_bridge.h"
 
 #if !defined(__has_feature) || !__has_feature(objc_arc)
 #error "This file requires ARC support."
diff --git a/ios/chrome/browser/ui/payments/payment_request_manager.mm b/ios/chrome/browser/ui/payments/payment_request_manager.mm
index e40bf96..82bbc5b 100644
--- a/ios/chrome/browser/ui/payments/payment_request_manager.mm
+++ b/ios/chrome/browser/ui/payments/payment_request_manager.mm
@@ -69,7 +69,7 @@
 #include "ios/web/public/security/ssl_status.h"
 #import "ios/web/public/ui/crw_web_view_proxy.h"
 #import "ios/web/public/web_state.h"
-#import "ios/web/public/web_state/web_state_observer_bridge.h"
+#import "ios/web/public/web_state_observer_bridge.h"
 #include "third_party/libaddressinput/chromium/chrome_metadata_source.h"
 #include "third_party/libaddressinput/chromium/chrome_storage_impl.h"
 #include "url/gurl.h"
diff --git a/ios/chrome/browser/ui/popup_menu/popup_menu_mediator.mm b/ios/chrome/browser/ui/popup_menu/popup_menu_mediator.mm
index a700c78..04a7feb8f 100644
--- a/ios/chrome/browser/ui/popup_menu/popup_menu_mediator.mm
+++ b/ios/chrome/browser/ui/popup_menu/popup_menu_mediator.mm
@@ -51,7 +51,7 @@
 #include "ios/web/public/navigation/navigation_manager.h"
 #include "ios/web/public/web_client.h"
 #import "ios/web/public/web_state.h"
-#import "ios/web/public/web_state/web_state_observer_bridge.h"
+#import "ios/web/public/web_state_observer_bridge.h"
 #include "ui/base/l10n/l10n_util.h"
 #include "ui/gfx/image/image.h"
 
diff --git a/ios/chrome/browser/ui/popup_menu/popup_menu_mediator_unittest.mm b/ios/chrome/browser/ui/popup_menu/popup_menu_mediator_unittest.mm
index 9ec214c..01b1eb3d 100644
--- a/ios/chrome/browser/ui/popup_menu/popup_menu_mediator_unittest.mm
+++ b/ios/chrome/browser/ui/popup_menu/popup_menu_mediator_unittest.mm
@@ -34,7 +34,7 @@
 #import "ios/web/public/test/fakes/test_navigation_manager.h"
 #import "ios/web/public/test/fakes/test_web_state.h"
 #include "ios/web/public/test/web_task_environment.h"
-#import "ios/web/public/web_state/web_state_observer_bridge.h"
+#import "ios/web/public/web_state_observer_bridge.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/platform_test.h"
 #import "third_party/ocmock/OCMock/OCMock.h"
diff --git a/ios/chrome/browser/ui/settings/settings_navigation_controller.mm b/ios/chrome/browser/ui/settings/settings_navigation_controller.mm
index 765b1f7..0aabe7d 100644
--- a/ios/chrome/browser/ui/settings/settings_navigation_controller.mm
+++ b/ios/chrome/browser/ui/settings/settings_navigation_controller.mm
@@ -47,7 +47,9 @@
 @property(nonatomic, strong)
     GoogleServicesSettingsCoordinator* googleServicesSettingsCoordinator;
 
-// Current ViewController being presented by this Navigation Controller.
+// Current SettingsViewController being presented by this Navigation Controller.
+// If nil it means the Navigation Controller is not presenting anything, or the
+// VC being presented is not a SettingsRootTableViewController.
 @property(nonatomic, weak)
     SettingsRootTableViewController* currentPresentedSettingsViewController;
 
@@ -404,8 +406,7 @@
       willShowViewController:(UIViewController*)viewController
                     animated:(BOOL)animated {
   self.currentPresentedSettingsViewController =
-      base::mac::ObjCCastStrict<SettingsRootTableViewController>(
-          viewController);
+      base::mac::ObjCCast<SettingsRootTableViewController>(viewController);
 }
 
 #pragma mark - UIResponder
diff --git a/ios/chrome/browser/ui/side_swipe/side_swipe_controller.mm b/ios/chrome/browser/ui/side_swipe/side_swipe_controller.mm
index c76f9077..e8cdd6f 100644
--- a/ios/chrome/browser/ui/side_swipe/side_swipe_controller.mm
+++ b/ios/chrome/browser/ui/side_swipe/side_swipe_controller.mm
@@ -31,7 +31,7 @@
 #import "ios/chrome/browser/web_state_list/web_state_list_observer_bridge.h"
 #import "ios/web/public/navigation/navigation_item.h"
 #import "ios/web/public/web_client.h"
-#import "ios/web/public/web_state/web_state_observer_bridge.h"
+#import "ios/web/public/web_state_observer_bridge.h"
 
 #if !defined(__has_feature) || !__has_feature(objc_arc)
 #error "This file requires ARC support."
diff --git a/ios/chrome/browser/ui/tab_grid/tab_grid_mediator.mm b/ios/chrome/browser/ui/tab_grid/tab_grid_mediator.mm
index 2a013d0..4ad14fa 100644
--- a/ios/chrome/browser/ui/tab_grid/tab_grid_mediator.mm
+++ b/ios/chrome/browser/ui/tab_grid/tab_grid_mediator.mm
@@ -32,7 +32,7 @@
 #import "ios/chrome/browser/web_state_list/web_usage_enabler/web_state_list_web_usage_enabler_factory.h"
 #import "ios/web/public/navigation/navigation_manager.h"
 #import "ios/web/public/web_state.h"
-#import "ios/web/public/web_state/web_state_observer_bridge.h"
+#import "ios/web/public/web_state_observer_bridge.h"
 #include "ui/gfx/image/image.h"
 
 #if !defined(__has_feature) || !__has_feature(objc_arc)
diff --git a/ios/chrome/browser/ui/table_view/cells/table_view_text_edit_item.mm b/ios/chrome/browser/ui/table_view/cells/table_view_text_edit_item.mm
index eb68f1b3..d6a6323 100644
--- a/ios/chrome/browser/ui/table_view/cells/table_view_text_edit_item.mm
+++ b/ios/chrome/browser/ui/table_view/cells/table_view_text_edit_item.mm
@@ -166,7 +166,7 @@
     UIImage* editImage = [[UIImage imageNamed:@"table_view_cell_edit_icon"]
         imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
     _editIconView = [[UIImageView alloc] initWithImage:editImage];
-    _editIconView.tintColor = UIColor.cr_secondaryLabelColor;
+    _editIconView.tintColor = [UIColor colorNamed:kGrey400Color];
     _editIconView.translatesAutoresizingMaskIntoConstraints = NO;
     [contentView addSubview:_editIconView];
 
diff --git a/ios/chrome/browser/ui/tabs/tab_strip_controller.mm b/ios/chrome/browser/ui/tabs/tab_strip_controller.mm
index b9dd1cf0..c7e0bf4 100644
--- a/ios/chrome/browser/ui/tabs/tab_strip_controller.mm
+++ b/ios/chrome/browser/ui/tabs/tab_strip_controller.mm
@@ -47,7 +47,7 @@
 #import "ios/chrome/browser/web_state_list/web_state_list_observer_bridge.h"
 #include "ios/chrome/grit/ios_strings.h"
 #import "ios/web/public/web_state.h"
-#import "ios/web/public/web_state/web_state_observer_bridge.h"
+#import "ios/web/public/web_state_observer_bridge.h"
 #include "third_party/google_toolbox_for_mac/src/iPhone/GTMFadeTruncatingLabel.h"
 #include "ui/gfx/image/image.h"
 
diff --git a/ios/chrome/browser/ui/toolbar/fullscreen/legacy_toolbar_ui_updater.mm b/ios/chrome/browser/ui/toolbar/fullscreen/legacy_toolbar_ui_updater.mm
index b20c189e..bd0613b5 100644
--- a/ios/chrome/browser/ui/toolbar/fullscreen/legacy_toolbar_ui_updater.mm
+++ b/ios/chrome/browser/ui/toolbar/fullscreen/legacy_toolbar_ui_updater.mm
@@ -12,7 +12,7 @@
 #import "ios/chrome/browser/web_state_list/web_state_list_observer_bridge.h"
 #import "ios/web/public/navigation/navigation_context.h"
 #import "ios/web/public/web_state.h"
-#import "ios/web/public/web_state/web_state_observer_bridge.h"
+#import "ios/web/public/web_state_observer_bridge.h"
 
 #if !defined(__has_feature) || !__has_feature(objc_arc)
 #error "This file requires ARC support."
diff --git a/ios/chrome/browser/ui/toolbar/toolbar_mediator.mm b/ios/chrome/browser/ui/toolbar/toolbar_mediator.mm
index 324fe3f6..653fa55d 100644
--- a/ios/chrome/browser/ui/toolbar/toolbar_mediator.mm
+++ b/ios/chrome/browser/ui/toolbar/toolbar_mediator.mm
@@ -21,7 +21,7 @@
 #import "ios/web/public/navigation/navigation_manager.h"
 #import "ios/web/public/web_client.h"
 #import "ios/web/public/web_state.h"
-#import "ios/web/public/web_state/web_state_observer_bridge.h"
+#import "ios/web/public/web_state_observer_bridge.h"
 
 #if !defined(__has_feature) || !__has_feature(objc_arc)
 #error "This file requires ARC support."
diff --git a/ios/chrome/browser/ui/toolbar/toolbar_mediator_unittest.mm b/ios/chrome/browser/ui/toolbar/toolbar_mediator_unittest.mm
index 39a7dc7..99d5eb9 100644
--- a/ios/chrome/browser/ui/toolbar/toolbar_mediator_unittest.mm
+++ b/ios/chrome/browser/ui/toolbar/toolbar_mediator_unittest.mm
@@ -28,7 +28,7 @@
 #import "ios/web/public/test/fakes/test_navigation_manager.h"
 #import "ios/web/public/test/fakes/test_web_state.h"
 #include "ios/web/public/test/web_task_environment.h"
-#import "ios/web/public/web_state/web_state_observer_bridge.h"
+#import "ios/web/public/web_state_observer_bridge.h"
 #include "testing/platform_test.h"
 #import "third_party/ocmock/OCMock/OCMock.h"
 #include "third_party/ocmock/gtest_support.h"
diff --git a/ios/chrome/browser/voice/text_to_speech_listener.mm b/ios/chrome/browser/voice/text_to_speech_listener.mm
index 1b2ac1d..c829904 100644
--- a/ios/chrome/browser/voice/text_to_speech_listener.mm
+++ b/ios/chrome/browser/voice/text_to_speech_listener.mm
@@ -11,8 +11,8 @@
 #import "ios/chrome/browser/voice/voice_search_url_rewriter.h"
 #include "ios/web/public/navigation/navigation_manager.h"
 #import "ios/web/public/web_state.h"
-#import "ios/web/public/web_state/web_state_observer_bridge.h"
 #include "ios/web/public/web_state_observer.h"
+#import "ios/web/public/web_state_observer_bridge.h"
 #include "url/gurl.h"
 
 #if !defined(__has_feature) || !__has_feature(objc_arc)
diff --git a/ios/showcase/infobars/sc_infobar_banner_coordinator_egtest.mm b/ios/showcase/infobars/sc_infobar_banner_coordinator_egtest.mm
index 3f04a7f..794f173 100644
--- a/ios/showcase/infobars/sc_infobar_banner_coordinator_egtest.mm
+++ b/ios/showcase/infobars/sc_infobar_banner_coordinator_egtest.mm
@@ -89,8 +89,8 @@
       assertWithMatcher:grey_nil()];
 }
 
-// Tests that the InfobarModal is presented when the Banner its swiped down.
-- (void)testInfobarBannerSwipeDown {
+// Tests that the InfobarModal is not presented when the Banner its swiped down.
+- (void)testInfobarBannerCantSwipeDown {
   // Check Banner was presented.
   [[EarlGrey selectElementWithMatcher:grey_accessibilityID(
                                           kInfobarBannerViewIdentifier)]
@@ -99,20 +99,17 @@
   [[EarlGrey selectElementWithMatcher:grey_accessibilityID(
                                           kInfobarBannerViewIdentifier)]
       performAction:grey_swipeFastInDirection(kGREYDirectionDown)];
-  // Check Modal was presented.
+  // Check the Modal is not presented.
   [[EarlGrey selectElementWithMatcher:grey_accessibilityID(
                                           kInfobarBannerPresentedModalLabel)]
-      assertWithMatcher:grey_notNil()];
-  // Dismiss Modal.
-  [[EarlGrey
-      selectElementWithMatcher:grey_accessibilityID(kInfobarModalCancelButton)]
-      performAction:grey_tap()];
-  // Check neither the Banner nor Modal are presented.
+      assertWithMatcher:grey_nil()];
+  // Check the banner is still interactable by swiping it up.
   [[EarlGrey selectElementWithMatcher:grey_accessibilityID(
                                           kInfobarBannerViewIdentifier)]
-      assertWithMatcher:grey_nil()];
+      performAction:grey_swipeFastInDirection(kGREYDirectionUp)];
+  // Check Banner was dismissed.
   [[EarlGrey selectElementWithMatcher:grey_accessibilityID(
-                                          kInfobarBannerPresentedModalLabel)]
+                                          kInfobarBannerViewIdentifier)]
       assertWithMatcher:grey_nil()];
 }
 
diff --git a/ios/web/public/BUILD.gn b/ios/web/public/BUILD.gn
index f1f759f..32d1cd3 100644
--- a/ios/web/public/BUILD.gn
+++ b/ios/web/public/BUILD.gn
@@ -28,7 +28,7 @@
     "web_state.h",
     "web_state/web_state_delegate.h",
     "web_state/web_state_delegate_bridge.h",
-    "web_state/web_state_observer_bridge.h",
+    "web_state_observer_bridge.h",
     "web_state_user_data.h",
   ]
 
diff --git a/ios/web/public/test/fakes/crw_test_web_state_observer.h b/ios/web/public/test/fakes/crw_test_web_state_observer.h
index 2d14884f..82a85f8 100644
--- a/ios/web/public/test/fakes/crw_test_web_state_observer.h
+++ b/ios/web/public/test/fakes/crw_test_web_state_observer.h
@@ -6,7 +6,7 @@
 #define IOS_WEB_PUBLIC_TEST_FAKES_CRW_TEST_WEB_STATE_OBSERVER_H_
 
 #include "ios/web/public/test/fakes/test_web_state_observer_util.h"
-#import "ios/web/public/web_state/web_state_observer_bridge.h"
+#import "ios/web/public/web_state_observer_bridge.h"
 
 // Test implementation of CRWWebStateObserver protocol.
 @interface CRWTestWebStateObserver : NSObject<CRWWebStateObserver>
diff --git a/ios/web/public/web_state/web_state_observer_bridge.h b/ios/web/public/web_state_observer_bridge.h
similarity index 95%
rename from ios/web/public/web_state/web_state_observer_bridge.h
rename to ios/web/public/web_state_observer_bridge.h
index e96e685..eca7354 100644
--- a/ios/web/public/web_state/web_state_observer_bridge.h
+++ b/ios/web/public/web_state_observer_bridge.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 IOS_WEB_PUBLIC_WEB_STATE_WEB_STATE_OBSERVER_BRIDGE_H_
-#define IOS_WEB_PUBLIC_WEB_STATE_WEB_STATE_OBSERVER_BRIDGE_H_
+#ifndef IOS_WEB_PUBLIC_WEB_STATE_OBSERVER_BRIDGE_H_
+#define IOS_WEB_PUBLIC_WEB_STATE_OBSERVER_BRIDGE_H_
 
 #import <Foundation/Foundation.h>
 
@@ -14,7 +14,7 @@
 
 // Observes page lifecyle events from Objective-C. To use as a
 // web::WebStateObserver, wrap in a web::WebStateObserverBridge.
-@protocol CRWWebStateObserver<NSObject>
+@protocol CRWWebStateObserver <NSObject>
 @optional
 
 // Invoked by WebStateObserverBridge::WasShown.
@@ -123,4 +123,4 @@
 
 }  // namespace web
 
-#endif  // IOS_WEB_PUBLIC_WEB_STATE_WEB_STATE_OBSERVER_BRIDGE_H_
+#endif  // IOS_WEB_PUBLIC_WEB_STATE_OBSERVER_BRIDGE_H_
diff --git a/ios/web/shell/view_controller.mm b/ios/web/shell/view_controller.mm
index 2c8348b..9c358e9 100644
--- a/ios/web/shell/view_controller.mm
+++ b/ios/web/shell/view_controller.mm
@@ -17,7 +17,7 @@
 #import "ios/web/public/ui/context_menu_params.h"
 #import "ios/web/public/web_state.h"
 #import "ios/web/public/web_state/web_state_delegate_bridge.h"
-#import "ios/web/public/web_state/web_state_observer_bridge.h"
+#import "ios/web/public/web_state_observer_bridge.h"
 #import "net/base/mac/url_conversions.h"
 #include "ui/base/page_transition_types.h"
 
diff --git a/ios/web/web_state/ui/crw_context_menu_controller.mm b/ios/web/web_state/ui/crw_context_menu_controller.mm
index a1eb74de..2b5645c 100644
--- a/ios/web/web_state/ui/crw_context_menu_controller.mm
+++ b/ios/web/web_state/ui/crw_context_menu_controller.mm
@@ -18,7 +18,7 @@
 #import "ios/web/public/navigation/navigation_context.h"
 #import "ios/web/public/ui/context_menu_params.h"
 #import "ios/web/public/web_state.h"
-#import "ios/web/public/web_state/web_state_observer_bridge.h"
+#import "ios/web/public/web_state_observer_bridge.h"
 #import "ios/web/web_state/context_menu_constants.h"
 #import "ios/web/web_state/context_menu_params_utils.h"
 #import "ios/web/web_state/ui/html_element_fetch_request.h"
diff --git a/ios/web/web_state/ui/crw_web_controller.mm b/ios/web/web_state/ui/crw_web_controller.mm
index 44cd194..34d2ad9 100644
--- a/ios/web/web_state/ui/crw_web_controller.mm
+++ b/ios/web/web_state/ui/crw_web_controller.mm
@@ -424,6 +424,7 @@
   for (NSString* keyPath in self.WKWebViewObservers) {
     [_webView removeObserver:self forKeyPath:keyPath];
   }
+  self.webViewNavigationObserver.webView = nil;
 
   CRWWKScriptMessageRouter* messageRouter =
       [self webViewConfigurationProvider].GetScriptMessageRouter();
diff --git a/ios/web/web_state/web_state_observer_bridge.mm b/ios/web/web_state/web_state_observer_bridge.mm
index baa86280..82bd19a 100644
--- a/ios/web/web_state/web_state_observer_bridge.mm
+++ b/ios/web/web_state/web_state_observer_bridge.mm
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#import "ios/web/public/web_state/web_state_observer_bridge.h"
+#import "ios/web/public/web_state_observer_bridge.h"
 
 #if !defined(__has_feature) || !__has_feature(objc_arc)
 #error "This file requires ARC support."
diff --git a/ios/web/web_state/web_state_observer_bridge_unittest.mm b/ios/web/web_state/web_state_observer_bridge_unittest.mm
index b6b109c..e55cd139 100644
--- a/ios/web/web_state/web_state_observer_bridge_unittest.mm
+++ b/ios/web/web_state/web_state_observer_bridge_unittest.mm
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#import "ios/web/public/web_state/web_state_observer_bridge.h"
+#import "ios/web/public/web_state_observer_bridge.h"
 
 #include "base/memory/ptr_util.h"
 #include "base/scoped_observer.h"
@@ -10,7 +10,6 @@
 #include "ios/web/public/favicon/favicon_url.h"
 #import "ios/web/public/test/fakes/crw_test_web_state_observer.h"
 #import "ios/web/public/test/fakes/test_web_state.h"
-#import "ios/web/public/web_state/web_state_observer_bridge.h"
 #include "net/http/http_response_headers.h"
 #include "testing/platform_test.h"
 
diff --git a/ios/web_view/internal/autofill/cwv_autofill_controller.mm b/ios/web_view/internal/autofill/cwv_autofill_controller.mm
index 178cf21..52bc26a3 100644
--- a/ios/web_view/internal/autofill/cwv_autofill_controller.mm
+++ b/ios/web_view/internal/autofill/cwv_autofill_controller.mm
@@ -31,7 +31,7 @@
 #include "ios/web/public/js_messaging/web_frame_util.h"
 #import "ios/web/public/js_messaging/web_frames_manager.h"
 #import "ios/web/public/web_state.h"
-#import "ios/web/public/web_state/web_state_observer_bridge.h"
+#import "ios/web/public/web_state_observer_bridge.h"
 #include "ios/web_view/internal/app/application_context.h"
 #import "ios/web_view/internal/autofill/cwv_autofill_client_ios_bridge.h"
 #import "ios/web_view/internal/autofill/cwv_autofill_form_internal.h"
diff --git a/ios/web_view/internal/cwv_web_view.mm b/ios/web_view/internal/cwv_web_view.mm
index c0d3a4b3..e019770b 100644
--- a/ios/web_view/internal/cwv_web_view.mm
+++ b/ios/web_view/internal/cwv_web_view.mm
@@ -33,7 +33,7 @@
 #import "ios/web/public/web_client.h"
 #import "ios/web/public/web_state.h"
 #import "ios/web/public/web_state/web_state_delegate_bridge.h"
-#import "ios/web/public/web_state/web_state_observer_bridge.h"
+#import "ios/web/public/web_state_observer_bridge.h"
 #include "ios/web_view/cwv_web_view_buildflags.h"
 #import "ios/web_view/internal/autofill/cwv_autofill_controller_internal.h"
 #import "ios/web_view/internal/cwv_favicon_internal.h"
diff --git a/ios/web_view/internal/passwords/cwv_password_controller.mm b/ios/web_view/internal/passwords/cwv_password_controller.mm
index d6b14d2..263ec23 100644
--- a/ios/web_view/internal/passwords/cwv_password_controller.mm
+++ b/ios/web_view/internal/passwords/cwv_password_controller.mm
@@ -21,7 +21,7 @@
 #include "ios/web/public/js_messaging/web_frame.h"
 #include "ios/web/public/js_messaging/web_frame_util.h"
 #import "ios/web/public/web_state.h"
-#import "ios/web/public/web_state/web_state_observer_bridge.h"
+#import "ios/web/public/web_state_observer_bridge.h"
 #import "ios/web_view/internal/autofill/cwv_autofill_suggestion_internal.h"
 #import "ios/web_view/internal/passwords/web_view_password_manager_client.h"
 #import "ios/web_view/internal/passwords/web_view_password_manager_driver.h"
diff --git a/media/filters/BUILD.gn b/media/filters/BUILD.gn
index c66febd..9022a76 100644
--- a/media/filters/BUILD.gn
+++ b/media/filters/BUILD.gn
@@ -212,6 +212,7 @@
       "//gpu/command_buffer/client",
       "//gpu/command_buffer/common",
       "//gpu/ipc/common",
+      "//media/fuchsia/common",
       "//third_party/fuchsia-sdk/sdk:media",
       "//third_party/fuchsia-sdk/sdk:mediacodec",
       "//third_party/fuchsia-sdk/sdk:sys_cpp",
diff --git a/media/filters/fuchsia/fuchsia_video_decoder.cc b/media/filters/fuchsia/fuchsia_video_decoder.cc
index aff8c405..2c8e526 100644
--- a/media/filters/fuchsia/fuchsia_video_decoder.cc
+++ b/media/filters/fuchsia/fuchsia_video_decoder.cc
@@ -33,6 +33,9 @@
 #include "media/base/video_decoder_config.h"
 #include "media/base/video_frame.h"
 #include "media/base/video_util.h"
+#include "media/fuchsia/common/stream_processor_helper.h"
+#include "media/fuchsia/common/sysmem_buffer_pool.h"
+#include "media/fuchsia/common/sysmem_buffer_writer_queue.h"
 #include "third_party/libyuv/include/libyuv/video_common.h"
 #include "ui/gfx/buffer_types.h"
 #include "ui/gfx/client_native_pixmap_factory.h"
@@ -50,141 +53,6 @@
 // works properly when the client holds to more than that.
 const uint32_t kMaxUsedOutputFrames = 8;
 
-class PendingDecode {
- public:
-  PendingDecode(scoped_refptr<DecoderBuffer> buffer,
-                VideoDecoder::DecodeCB decode_cb)
-      : buffer_(buffer), decode_cb_(std::move(decode_cb)) {
-    DCHECK(buffer_);
-  }
-  ~PendingDecode() {
-    if (decode_cb_) {
-      std::move(decode_cb_).Run(DecodeStatus::ABORTED);
-    }
-  }
-
-  PendingDecode(PendingDecode&& other) = default;
-  PendingDecode& operator=(PendingDecode&& other) = default;
-
-  const DecoderBuffer& buffer() { return *buffer_; }
-
-  const uint8_t* data() const { return buffer_->data() + buffer_pos_; }
-  size_t bytes_left() const { return buffer_->data_size() - buffer_pos_; }
-  void AdvanceCurrentPos(size_t bytes) {
-    DCHECK_LE(bytes, bytes_left());
-    buffer_pos_ += bytes;
-  }
-  VideoDecoder::DecodeCB TakeDecodeCallback() { return std::move(decode_cb_); }
-
- private:
-  scoped_refptr<DecoderBuffer> buffer_;
-  size_t buffer_pos_ = 0;
-  VideoDecoder::DecodeCB decode_cb_;
-
-  DISALLOW_COPY_AND_ASSIGN(PendingDecode);
-};
-
-class InputBuffer {
- public:
-  InputBuffer() {}
-
-  ~InputBuffer() {
-    if (base_address_) {
-      size_t mapped_bytes =
-          base::bits::Align(offset_ + size_, base::GetPageSize());
-      zx_status_t status = zx::vmar::root_self()->unmap(
-          reinterpret_cast<uintptr_t>(base_address_), mapped_bytes);
-      ZX_DCHECK(status == ZX_OK, status) << "zx_vmar_unmap";
-    }
-
-    CallDecodeCallbackIfAny(DecodeStatus::ABORTED);
-  }
-
-  InputBuffer(InputBuffer&&) = default;
-  InputBuffer& operator=(InputBuffer&&) = default;
-
-  bool Initialize(zx::vmo vmo,
-                  size_t offset,
-                  size_t size,
-                  fuchsia::sysmem::CoherencyDomain coherency_domain) {
-    DCHECK(!base_address_);
-    DCHECK(vmo);
-
-    // zx_vmo_write() doesn't work for sysmem-allocated VMOs (see ZX-4854), so
-    // the VMOs have to be mapped.
-    size_t bytes_to_map = base::bits::Align(offset + size, base::GetPageSize());
-    uintptr_t addr;
-    zx_status_t status = zx::vmar::root_self()->map(
-        /*vmar_offset=*/0, vmo, /*vmo_offset=*/0, bytes_to_map,
-        ZX_VM_PERM_READ | ZX_VM_PERM_WRITE, &addr);
-    if (status != ZX_OK) {
-      ZX_DLOG(ERROR, status) << "zx_vmar_map";
-      return false;
-    }
-
-    base_address_ = reinterpret_cast<uint8_t*>(addr);
-    offset_ = offset;
-    size_ = size;
-    coherency_domain_ = coherency_domain;
-
-    return true;
-  }
-
-  bool is_used() const { return is_used_; }
-
-  // Copies as much data as possible from |pending_decode| to this input buffer.
-  size_t FillFromDecodeBuffer(PendingDecode* pending_decode) {
-    DCHECK(!is_used_);
-    is_used_ = true;
-
-    size_t bytes_to_fill = std::min(size_, pending_decode->bytes_left());
-    memcpy(base_address_ + offset_, pending_decode->data(), bytes_to_fill);
-
-    // Flush CPU cache if the codec reads from RAM.
-    if (coherency_domain_ == fuchsia::sysmem::CoherencyDomain::RAM) {
-      zx_status_t status = zx_cache_flush(base_address_ + offset_,
-                                          bytes_to_fill, ZX_CACHE_FLUSH_DATA);
-      ZX_DCHECK(status == ZX_OK, status) << "zx_cache_flush";
-    }
-
-    pending_decode->AdvanceCurrentPos(bytes_to_fill);
-
-    if (pending_decode->bytes_left() == 0) {
-      DCHECK(!decode_cb_);
-      decode_cb_ = pending_decode->TakeDecodeCallback();
-    }
-
-    return bytes_to_fill;
-  }
-
-  void CallDecodeCallbackIfAny(DecodeStatus status) {
-    if (decode_cb_) {
-      std::move(decode_cb_).Run(status);
-    }
-  }
-
-  void OnDoneDecoding(DecodeStatus status) {
-    DCHECK(is_used_);
-    is_used_ = false;
-    CallDecodeCallbackIfAny(status);
-  }
-
- private:
-  uint8_t* base_address_ = nullptr;
-
-  // Buffer settings provided by sysmem.
-  size_t offset_ = 0;
-  size_t size_ = 0;
-  fuchsia::sysmem::CoherencyDomain coherency_domain_;
-
-  // Set to true when this buffer is being used by the codec.
-  bool is_used_ = false;
-
-  // Decode callback for the DecodeBuffer of which this InputBuffer is a part.
-  // This is only set on the final InputBuffer in each DecodeBuffer.
-  VideoDecoder::DecodeCB decode_cb_;
-};
-
 // Helper used to hold mailboxes for the output textures. OutputMailbox may
 // outlive FuchsiaVideoDecoder if is referenced by a VideoFrame.
 class OutputMailbox {
@@ -324,19 +192,17 @@
   // Called on errors to shutdown the decoder and notify the client.
   void OnError();
 
-  // Called by OnInputConstraints() to initialize input buffers.
-  void InitializeInputBufferCollection(
-      fuchsia::media::StreamBufferConstraints constraints,
-      fuchsia::sysmem::BufferCollectionTokenPtr sysmem_token);
+  // Callback for |input_buffer_collection_creator_->Create()|.
+  void OnInputBufferPoolCreated(fuchsia::media::StreamBufferConstraints,
+                                std::unique_ptr<SysmemBufferPool> pool);
 
-  // Callback for BufferCollection::WaitForBuffersAllocated() when initializing
-  // input buffer collection.
-  void OnInputBuffersAllocated(
-      zx_status_t status,
-      fuchsia::sysmem::BufferCollectionInfo_2 buffer_collection_info);
+  // Callback for |input_buffer_collection_->CreateWriter()|.
+  void OnWriterCreated(std::unique_ptr<SysmemBufferWriter> writer);
 
-  // Pumps |pending_decodes_| to the decoder.
-  void PumpInput();
+  // Callbacks for |input_writer_|.
+  void SendInputPacket(const DecoderBuffer* buffer,
+                       StreamProcessorHelper::IoPacket packet);
+  void ProcessEndOfStream();
 
   // Called by OnOutputConstraints() to initialize input buffers.
   void InitializeOutputBufferCollection(
@@ -361,8 +227,9 @@
   // value is used only if the aspect ratio is not specified in the bitstream.
   float container_pixel_aspect_ratio_ = 1.0;
 
+  // TODO(sergeyu): Use StreamProcessorHelper.
   fuchsia::media::StreamProcessorPtr codec_;
-  fuchsia::sysmem::AllocatorPtr sysmem_allocator_;
+  BufferAllocator sysmem_allocator_;
   std::unique_ptr<gfx::ClientNativePixmapFactory> client_native_pixmap_factory_;
 
   uint64_t stream_lifetime_ordinal_ = 1;
@@ -372,11 +239,13 @@
   bool active_stream_ = false;
 
   // Input buffers.
-  std::list<PendingDecode> pending_decodes_;
   uint64_t input_buffer_lifetime_ordinal_ = 1;
-  fuchsia::sysmem::BufferCollectionPtr input_buffer_collection_;
-  std::vector<InputBuffer> input_buffers_;
-  int num_used_input_buffers_ = 0;
+  SysmemBufferWriterQueue input_writer_queue_;
+  std::unique_ptr<SysmemBufferPool::Creator> input_buffer_collection_creator_;
+  std::unique_ptr<SysmemBufferPool> input_buffer_collection_;
+  base::flat_map<size_t, StreamProcessorHelper::IoPacket>
+      in_flight_input_packets_;
+  std::deque<DecodeCB> decode_callbacks_;
 
   // Output buffers.
   fuchsia::media::VideoUncompressedFormat output_format_;
@@ -448,15 +317,6 @@
   output_cb_ = output_cb;
   container_pixel_aspect_ratio_ = config.GetPixelAspectRatio();
 
-  sysmem_allocator_ = base::fuchsia::ComponentContextForCurrentProcess()
-                          ->svc()
-                          ->Connect<fuchsia::sysmem::Allocator>();
-  sysmem_allocator_.set_error_handler([](zx_status_t status) {
-    // Just log a warning. We will handle BufferCollection the failure when
-    // trying to create a new BufferCollection.
-    ZX_DLOG(WARNING, status) << "fuchsia.sysmem.Allocator disconnected.";
-  });
-
   fuchsia::mediacodec::CreateDecoder_Params codec_params;
   codec_params.mutable_input_details()->set_format_details_version_ordinal(0);
 
@@ -517,9 +377,6 @@
 
 void FuchsiaVideoDecoder::Decode(scoped_refptr<DecoderBuffer> buffer,
                                  DecodeCB decode_cb) {
-  DCHECK_LT(static_cast<int>(pending_decodes_.size()) + num_used_input_buffers_,
-            GetMaxDecodeRequests());
-
   if (!codec_) {
     // Post the callback to the current sequence as DecoderStream doesn't expect
     // Decode() to complete synchronously.
@@ -529,18 +386,17 @@
     return;
   }
 
-  pending_decodes_.push_back(PendingDecode(buffer, std::move(decode_cb)));
-  PumpInput();
+  decode_callbacks_.push_back(std::move(decode_cb));
+  input_writer_queue_.EnqueueBuffer(buffer);
 }
 
 void FuchsiaVideoDecoder::Reset(base::OnceClosure closure) {
-  // Call DecodeCB(ABORTED) for all active decode requests.
-  for (auto& buffer : input_buffers_) {
-    buffer.CallDecodeCallbackIfAny(DecodeStatus::ABORTED);
+  // Call DecodeCB(ABORTED) for all pending decode requests.
+  for (auto& cb : decode_callbacks_) {
+    std::move(cb).Run(DecodeStatus::ABORTED);
   }
 
-  // Will call DecodeCB(ABORTED) for all pending decode requests.
-  pending_decodes_.clear();
+  input_writer_queue_.ResetQueue();
 
   if (active_stream_) {
     codec_->CloseCurrentStream(stream_lifetime_ordinal_,
@@ -564,7 +420,7 @@
 int FuchsiaVideoDecoder::GetMaxDecodeRequests() const {
   // Add one extra request to be able to send new InputBuffer immediately after
   // OnFreeInputPacket().
-  return input_buffers_.size() + 1;
+  return input_writer_queue_.num_buffers() + 1;
 }
 
 void FuchsiaVideoDecoder::OnStreamFailed(uint64_t stream_lifetime_ordinal,
@@ -577,49 +433,107 @@
 }
 
 void FuchsiaVideoDecoder::OnInputConstraints(
-    fuchsia::media::StreamBufferConstraints constraints) {
+    fuchsia::media::StreamBufferConstraints stream_constraints) {
   // Buffer lifetime ordinal is an odd number incremented by 2 for each buffer
   // generation as required by StreamProcessor.
   input_buffer_lifetime_ordinal_ += 2;
 
-  if (!constraints.has_default_settings() ||
-      !constraints.default_settings().has_packet_count_for_server() ||
-      !constraints.default_settings().has_packet_count_for_client()) {
-    DLOG(ERROR)
-        << "Received OnInputConstraints() with missing required fields.";
+  input_buffer_collection_.reset();
+  input_writer_queue_.ResetBuffers();
+
+  // Create buffer constrains for the input buffer collection.
+  base::Optional<fuchsia::sysmem::BufferCollectionConstraints>
+      buffer_constraints =
+          SysmemBufferWriter::GetRecommendedConstraints(stream_constraints);
+  if (!buffer_constraints.has_value()) {
     OnError();
     return;
   }
 
-  input_buffer_collection_.Unbind();
-  input_buffers_.clear();
+  // Request SysmemBufferPool with one token to share with the codec.
+  input_buffer_collection_creator_ =
+      sysmem_allocator_.MakeBufferPoolCreator(1 /* num_shared_token */);
+  input_buffer_collection_creator_->Create(
+      std::move(buffer_constraints).value(),
+      base::BindOnce(&FuchsiaVideoDecoder::OnInputBufferPoolCreated,
+                     base::Unretained(this), std::move(stream_constraints)));
+}
 
-  // Create a new sysmem buffer collection token for the input buffers.
-  fuchsia::sysmem::BufferCollectionTokenPtr collection_token;
-  sysmem_allocator_->AllocateSharedCollection(collection_token.NewRequest());
-
-  // Create collection token for the codec.
-  fuchsia::sysmem::BufferCollectionTokenPtr collection_token_for_codec;
-  collection_token->Duplicate(ZX_RIGHT_SAME_RIGHTS,
-                              collection_token_for_codec.NewRequest());
-
-  // Convert the token to a BufferCollection connection.
-  sysmem_allocator_->BindSharedCollection(
-      std::move(collection_token), input_buffer_collection_.NewRequest());
-  input_buffer_collection_.set_error_handler([this](zx_status_t status) {
-    ZX_LOG(ERROR, status) << "fuchsia.sysmem.BufferCollection disconnected.";
+void FuchsiaVideoDecoder::OnInputBufferPoolCreated(
+    fuchsia::media::StreamBufferConstraints constraints,
+    std::unique_ptr<SysmemBufferPool> pool) {
+  if (!pool) {
+    DLOG(ERROR) << "Fail to allocate input buffers for the codec.";
     OnError();
-  });
+    return;
+  }
 
-  // BufferCollection needs to be synchronized to ensure that all token
-  // duplicate requests have been processed and sysmem knows about all clients
-  // that will be using this buffer collection.
-  input_buffer_collection_->Sync([this, constraints = std::move(constraints),
-                                  collection_token_for_codec = std::move(
-                                      collection_token_for_codec)]() mutable {
-    InitializeInputBufferCollection(std::move(constraints),
-                                    std::move(collection_token_for_codec));
-  });
+  input_buffer_collection_ = std::move(pool);
+
+  fuchsia::media::StreamBufferPartialSettings settings;
+  settings.set_buffer_lifetime_ordinal(input_buffer_lifetime_ordinal_);
+  settings.set_buffer_constraints_version_ordinal(
+      constraints.buffer_constraints_version_ordinal());
+  settings.set_single_buffer_mode(false);
+  settings.set_packet_count_for_server(
+      constraints.default_settings().packet_count_for_server());
+  settings.set_packet_count_for_client(
+      constraints.default_settings().packet_count_for_client());
+  settings.set_sysmem_token(std::move(input_buffer_collection_->TakeToken()));
+  codec_->SetInputBufferPartialSettings(std::move(settings));
+
+  input_buffer_collection_->CreateWriter(base::BindOnce(
+      &FuchsiaVideoDecoder::OnWriterCreated, base::Unretained(this)));
+}
+
+void FuchsiaVideoDecoder::OnWriterCreated(
+    std::unique_ptr<SysmemBufferWriter> writer) {
+  if (!writer) {
+    OnError();
+    return;
+  }
+
+  input_writer_queue_.Start(
+      std::move(writer),
+      base::BindRepeating(&FuchsiaVideoDecoder::SendInputPacket,
+                          base::Unretained(this)),
+      base::BindRepeating(&FuchsiaVideoDecoder::ProcessEndOfStream,
+                          base::Unretained(this)));
+}
+
+void FuchsiaVideoDecoder::SendInputPacket(
+    const DecoderBuffer* buffer,
+    StreamProcessorHelper::IoPacket packet) {
+  fuchsia::media::Packet media_packet;
+  media_packet.mutable_header()->set_buffer_lifetime_ordinal(
+      input_buffer_lifetime_ordinal_);
+  media_packet.mutable_header()->set_packet_index(packet.index());
+  media_packet.set_buffer_index(packet.index());
+  media_packet.set_timestamp_ish(packet.timestamp().InNanoseconds());
+  media_packet.set_stream_lifetime_ordinal(stream_lifetime_ordinal_);
+  media_packet.set_start_offset(packet.offset());
+  media_packet.set_valid_length_bytes(packet.size());
+  media_packet.set_known_end_access_unit(packet.unit_end());
+  codec_->QueueInputPacket(std::move(media_packet));
+
+  active_stream_ = true;
+
+  DCHECK(in_flight_input_packets_.find(packet.index()) ==
+         in_flight_input_packets_.end());
+  in_flight_input_packets_.insert_or_assign(packet.index(), std::move(packet));
+}
+
+void FuchsiaVideoDecoder::ProcessEndOfStream() {
+  active_stream_ = true;
+  codec_->QueueInputEndOfStream(stream_lifetime_ordinal_);
+  codec_->FlushEndOfStreamAndCloseStream(stream_lifetime_ordinal_);
+
+  DCHECK(!decode_callbacks_.empty());
+  pending_flush_cb_ = std::move(decode_callbacks_.front());
+  decode_callbacks_.pop_front();
+
+  // Decode() is not supposed to be called after EOF.
+  DCHECK(decode_callbacks_.empty());
 }
 
 void FuchsiaVideoDecoder::OnFreeInputPacket(
@@ -636,7 +550,7 @@
     return;
   }
 
-  if (free_input_packet.packet_index() >= input_buffers_.size()) {
+  if (free_input_packet.packet_index() >= input_writer_queue_.num_buffers()) {
     DLOG(ERROR) << "fuchsia.mediacodec sent OnFreeInputPacket() for an unknown "
                    "packet: buffer_lifetime_ordinal="
                 << free_input_packet.buffer_lifetime_ordinal()
@@ -645,13 +559,30 @@
     return;
   }
 
-  DCHECK_GT(num_used_input_buffers_, 0);
-  num_used_input_buffers_--;
-  input_buffers_[free_input_packet.packet_index()].OnDoneDecoding(
-      DecodeStatus::OK);
+  auto it = in_flight_input_packets_.find(free_input_packet.packet_index());
+  if (it == in_flight_input_packets_.end()) {
+    DLOG(ERROR) << "Received OnFreeInputPacket() with invalid packet index.";
+    OnError();
+    return;
+  }
 
-  // Try to pump input in case it was blocked.
-  PumpInput();
+  // Call DecodeCB if this was a last packet for a Decode request.
+  bool call_decode_callback = it->second.unit_end();
+
+  {
+    // The packet should be destroyed only after it's removed from
+    // |in_flight_input_packets_|. Otherwise SysmemBufferWriter may call
+    // SendInputPacket() while the packet is still in
+    // |in_flight_input_packets_|.
+    auto packet = std::move(it->second);
+    in_flight_input_packets_.erase(it);
+  }
+
+  if (call_decode_callback) {
+    DCHECK(!decode_callbacks_.empty());
+    std::move(decode_callbacks_.front()).Run(DecodeStatus::OK);
+    decode_callbacks_.pop_front();
+  }
 }
 
 void FuchsiaVideoDecoder::OnOutputConstraints(
@@ -704,7 +635,8 @@
 
   // Create a new sysmem buffer collection token for the output buffers.
   fuchsia::sysmem::BufferCollectionTokenPtr collection_token;
-  sysmem_allocator_->AllocateSharedCollection(collection_token.NewRequest());
+  sysmem_allocator_.raw()->AllocateSharedCollection(
+      collection_token.NewRequest());
 
   // Create sysmem tokens for the gpu process and the codec.
   fuchsia::sysmem::BufferCollectionTokenPtr collection_token_for_codec;
@@ -715,7 +647,7 @@
                               collection_token_for_gpu.NewRequest());
 
   // Convert the token to a BufferCollection connection.
-  sysmem_allocator_->BindSharedCollection(
+  sysmem_allocator_.raw()->BindSharedCollection(
       std::move(collection_token), output_buffer_collection_.NewRequest());
   output_buffer_collection_.set_error_handler([this](zx_status_t status) {
     ZX_LOG(ERROR, status) << "fuchsia.sysmem.BufferCollection disconnected.";
@@ -886,156 +818,25 @@
 
   auto weak_this = weak_this_;
 
-  // Call all decode callback with DECODE_ERROR before clearing input_buffers_
-  // and pending_decodes_. Otherwise PendingDecode and InputBuffer destructors
-  // would the callbacks with ABORTED.
-  for (auto& buffer : input_buffers_) {
-    if (buffer.is_used()) {
-      buffer.OnDoneDecoding(DecodeStatus::DECODE_ERROR);
+  // Call all decode callback with DECODE_ERROR.
+  for (auto& cb : decode_callbacks_) {
+    std::move(cb).Run(DecodeStatus::DECODE_ERROR);
 
-      // DecodeCB(DECODE_ERROR) may destroy |this|.
-      if (!weak_this) {
-        return;
-      }
-    }
-  }
-
-  for (auto& pending_decode : pending_decodes_) {
-    pending_decode.TakeDecodeCallback().Run(DecodeStatus::DECODE_ERROR);
-    if (!weak_this) {
+    // DecodeCB(DECODE_ERROR) may destroy |this|.
+    if (!weak_this)
       return;
-    }
   }
+  decode_callbacks_.clear();
 
-  pending_decodes_.clear();
+  input_writer_queue_.ResetBuffers();
+  input_writer_queue_.ResetQueue();
 
-  input_buffer_collection_.Unbind();
-  num_used_input_buffers_ = 0;
-  input_buffers_.clear();
+  input_buffer_collection_.reset();
+  input_buffer_collection_creator_.reset();
 
   ReleaseOutputBuffers();
 }
 
-void FuchsiaVideoDecoder::InitializeInputBufferCollection(
-    fuchsia::media::StreamBufferConstraints constraints,
-    fuchsia::sysmem::BufferCollectionTokenPtr sysmem_token) {
-  fuchsia::media::StreamBufferPartialSettings settings;
-  settings.set_buffer_lifetime_ordinal(input_buffer_lifetime_ordinal_);
-  settings.set_buffer_constraints_version_ordinal(
-      constraints.buffer_constraints_version_ordinal());
-  settings.set_single_buffer_mode(false);
-  settings.set_packet_count_for_server(
-      constraints.default_settings().packet_count_for_server());
-  settings.set_packet_count_for_client(
-      constraints.default_settings().packet_count_for_client());
-  settings.set_sysmem_token(std::move(sysmem_token));
-  codec_->SetInputBufferPartialSettings(std::move(settings));
-
-  fuchsia::sysmem::BufferCollectionConstraints buffer_constraints;
-
-  // Currently we have to map buffers VMOs to write to them (see ZX-4854) and
-  // memory cannot be mapped as write-only (see ZX-4872), so request RW access
-  // even though we will never need to read from these buffers.
-  buffer_constraints.usage.cpu =
-      fuchsia::sysmem::cpuUsageRead | fuchsia::sysmem::cpuUsageWrite;
-
-  buffer_constraints.min_buffer_count_for_camping =
-      settings.packet_count_for_client();
-  buffer_constraints.has_buffer_memory_constraints = true;
-  buffer_constraints.buffer_memory_constraints.min_size_bytes =
-      constraints.has_per_packet_buffer_bytes_recommended();
-  buffer_constraints.buffer_memory_constraints.ram_domain_supported = true;
-  buffer_constraints.buffer_memory_constraints.cpu_domain_supported = true;
-  input_buffer_collection_->SetConstraints(
-      /*has_constraints=*/true, std::move(buffer_constraints));
-
-  input_buffer_collection_->WaitForBuffersAllocated(
-      fit::bind_member(this, &FuchsiaVideoDecoder::OnInputBuffersAllocated));
-}
-
-void FuchsiaVideoDecoder::OnInputBuffersAllocated(
-    zx_status_t status,
-    fuchsia::sysmem::BufferCollectionInfo_2 buffer_collection_info) {
-  if (status != ZX_OK) {
-    ZX_DLOG(ERROR, status) << "Failed to allocate buffer collection for input.";
-    OnError();
-    return;
-  }
-
-  std::vector<InputBuffer> new_buffers;
-  new_buffers.resize(buffer_collection_info.buffer_count);
-  fuchsia::sysmem::BufferMemorySettings& settings =
-      buffer_collection_info.settings.buffer_settings;
-  for (size_t i = 0; i < buffer_collection_info.buffer_count; ++i) {
-    fuchsia::sysmem::VmoBuffer& buffer = buffer_collection_info.buffers[i];
-    if (!new_buffers[i].Initialize(std::move(buffer.vmo),
-                                   buffer.vmo_usable_start, settings.size_bytes,
-                                   settings.coherency_domain)) {
-      OnError();
-      return;
-    }
-  }
-  num_used_input_buffers_ = 0;
-  input_buffers_ = std::move(new_buffers);
-
-  PumpInput();
-}
-
-void FuchsiaVideoDecoder::PumpInput() {
-  // Nothing to do if a codec error has occurred or input buffers have not been
-  // initialized (which happens in response to OnInputConstraints() event).
-  if (!codec_ || input_buffers_.empty())
-    return;
-
-  while (!pending_decodes_.empty()) {
-    // Decode() is not supposed to be called while Decode(EOS) is pending.
-    DCHECK(!pending_flush_cb_);
-
-    if (pending_decodes_.front().buffer().end_of_stream()) {
-      active_stream_ = true;
-      codec_->QueueInputEndOfStream(stream_lifetime_ordinal_);
-      codec_->FlushEndOfStreamAndCloseStream(stream_lifetime_ordinal_);
-      pending_flush_cb_ = pending_decodes_.front().TakeDecodeCallback();
-      pending_decodes_.pop_front();
-      continue;
-    }
-
-    DCHECK_LE(num_used_input_buffers_, static_cast<int>(input_buffers_.size()));
-    if (num_used_input_buffers_ == static_cast<int>(input_buffers_.size())) {
-      // No input buffer available.
-      return;
-    }
-
-    auto input_buffer =
-        std::find_if(input_buffers_.begin(), input_buffers_.end(),
-                     [](const InputBuffer& buf) { return !buf.is_used(); });
-    CHECK(input_buffer != input_buffers_.end());
-
-    num_used_input_buffers_++;
-    size_t bytes_filled =
-        input_buffer->FillFromDecodeBuffer(&pending_decodes_.front());
-
-    fuchsia::media::Packet packet;
-    packet.mutable_header()->set_buffer_lifetime_ordinal(
-        input_buffer_lifetime_ordinal_);
-    packet.mutable_header()->set_packet_index(input_buffer -
-                                              input_buffers_.begin());
-    packet.set_buffer_index(packet.header().packet_index());
-    packet.set_timestamp_ish(
-        pending_decodes_.front().buffer().timestamp().InNanoseconds());
-    packet.set_stream_lifetime_ordinal(stream_lifetime_ordinal_);
-    packet.set_start_offset(0);
-    packet.set_valid_length_bytes(bytes_filled);
-
-    active_stream_ = true;
-    codec_->QueueInputPacket(std::move(packet));
-
-    if (pending_decodes_.front().bytes_left() == 0) {
-      pending_decodes_.pop_front();
-    }
-  }
-}
-
 void FuchsiaVideoDecoder::InitializeOutputBufferCollection(
     fuchsia::media::StreamBufferConstraints constraints,
     fuchsia::sysmem::BufferCollectionTokenPtr collection_token_for_codec,
diff --git a/media/fuchsia/cdm/fuchsia_stream_decryptor.cc b/media/fuchsia/cdm/fuchsia_stream_decryptor.cc
index 88fdca3..3eb847b3 100644
--- a/media/fuchsia/cdm/fuchsia_stream_decryptor.cc
+++ b/media/fuchsia/cdm/fuchsia_stream_decryptor.cc
@@ -22,7 +22,7 @@
 
 // FuchsiaClearStreamDecryptor copies decrypted data immediately once it's
 // available, so it doesn't need more than one output buffer.
-const size_t kMinOutputAudioOutputFrames = 1;
+const size_t kMinClearStreamOutputFrames = 1;
 
 std::string GetEncryptionMode(EncryptionMode mode) {
   switch (mode) {
@@ -96,55 +96,14 @@
 void FuchsiaStreamDecryptorBase::DecryptInternal(
     scoped_refptr<DecoderBuffer> encrypted) {
   DCHECK(!encrypted->end_of_stream()) << "EOS frame is always clear.";
-  DCHECK(!pending_encrypted_buffer_);
-
-  // Input buffer writer is not available. Wait.
-  if (!input_writer_) {
-    pending_encrypted_buffer_ = std::move(encrypted);
-    return;
-  }
-
-  // Decryptor can only process one buffer at a time, which means there
-  // should be always enough unused buffers.
-  base::Optional<size_t> buf_index = input_writer_->Acquire();
-
-  // No available input buffer. Just wait for the next available one.
-  if (!buf_index.has_value()) {
-    pending_encrypted_buffer_ = std::move(encrypted);
-    return;
-  }
-
-  size_t index = buf_index.value();
-
-  size_t bytes = input_writer_->Write(
-      index, base::make_span(encrypted->data(), encrypted->data_size()));
-  if (bytes < encrypted->data_size()) {
-    // The encrypted data size is too big. Decryptor should consider
-    // splitting the buffer and update the IV and subsample entries.
-    // TODO(yucliu): Handle large encrypted buffer correctly. For now, just
-    // reject the decryption.
-    DLOG(ERROR) << "Encrypted data size is too big.";
-    OnError();
-    return;
-  }
-
-  const DecryptConfig* decrypt_config = encrypted->decrypt_config();
-  DCHECK(decrypt_config);
-
-  auto input_packet = StreamProcessorHelper::IoPacket::CreateInput(
-      index, encrypted->data_size(), encrypted->timestamp(),
-      GetFormatDetails(decrypt_config),
-      base::BindOnce(&FuchsiaStreamDecryptorBase::OnInputPacketReleased,
-                     base::Unretained(this), index));
-
-  processor_.Process(std::move(input_packet));
+  input_writer_queue_.EnqueueBuffer(std::move(encrypted));
 }
 
 void FuchsiaStreamDecryptorBase::ResetStream() {
   // Close current stream and drop all the cached decoder buffers.
   // Keep input and output buffers to avoid buffer re-allocation.
   processor_.Reset();
-  pending_encrypted_buffer_ = nullptr;
+  input_writer_queue_.ResetQueue();
 }
 
 // StreamProcessorHelper::Client implementation:
@@ -168,17 +127,6 @@
                      base::Unretained(this)));
 }
 
-void FuchsiaStreamDecryptorBase::OnInputPacketReleased(size_t index) {
-  input_writer_->Release(index);
-
-  if (!pending_encrypted_buffer_)
-    return;
-
-  // If there are pending decryption request, handle it now since we have
-  // available input buffers.
-  DecryptInternal(std::move(pending_encrypted_buffer_));
-}
-
 void FuchsiaStreamDecryptorBase::OnInputBufferPoolCreated(
     std::unique_ptr<SysmemBufferPool> pool) {
   if (!pool) {
@@ -194,24 +142,38 @@
   processor_.CompleteInputBuffersAllocation(input_pool_->TakeToken());
 
   input_pool_->CreateWriter(base::BindOnce(
-      &FuchsiaStreamDecryptorBase::OnInputBufferPoolWriterCreated,
-      base::Unretained(this)));
+      &FuchsiaStreamDecryptorBase::OnWriterCreated, base::Unretained(this)));
 }
 
-void FuchsiaStreamDecryptorBase::OnInputBufferPoolWriterCreated(
+void FuchsiaStreamDecryptorBase::OnWriterCreated(
     std::unique_ptr<SysmemBufferWriter> writer) {
   if (!writer) {
-    LOG(ERROR) << "Fail to enable input buffer writer";
     OnError();
     return;
   }
 
-  DCHECK(!input_writer_);
-  input_writer_ = std::move(writer);
+  input_writer_queue_.Start(
+      std::move(writer),
+      base::BindRepeating(&FuchsiaStreamDecryptorBase::SendInputPacket,
+                          base::Unretained(this)),
+      SysmemBufferWriterQueue::EndOfStreamCB());
+}
 
-  if (pending_encrypted_buffer_) {
-    DecryptInternal(std::move(pending_encrypted_buffer_));
+void FuchsiaStreamDecryptorBase::SendInputPacket(
+    const DecoderBuffer* buffer,
+    StreamProcessorHelper::IoPacket packet) {
+  if (!packet.unit_end()) {
+    // The encrypted data size is too big. Decryptor should consider
+    // splitting the buffer and update the IV and subsample entries.
+    // TODO(crbug.com/1003651): Handle large encrypted buffer correctly. For
+    // now, just reject the decryption.
+    LOG(ERROR) << "DecoderBuffer doesn't fit in one packet.";
+    OnError();
+    return;
   }
+
+  packet.set_format(GetFormatDetails(buffer->decrypt_config()));
+  processor_.Process(std::move(packet));
 }
 
 std::unique_ptr<FuchsiaClearStreamDecryptor>
@@ -240,7 +202,7 @@
     Decryptor::DecryptCB decrypt_cb) {
   DCHECK(!decrypt_cb_);
   decrypt_cb_ = std::move(decrypt_cb);
-
+  current_status_ = Decryptor::kSuccess;
   DecryptInternal(std::move(encrypted));
 }
 
@@ -262,7 +224,7 @@
   }
 
   size_t max_used_output_buffers = std::max(
-      kMinOutputAudioOutputFrames,
+      kMinClearStreamOutputFrames,
       static_cast<size_t>(stream_constraints.packet_count_for_client_min()));
 
   output_pool_creator_ =
@@ -283,28 +245,63 @@
     fuchsia::media::StreamOutputFormat format) {}
 
 void FuchsiaClearStreamDecryptor::OnOutputPacket(
-    std::unique_ptr<StreamProcessorHelper::IoPacket> packet) {
+    StreamProcessorHelper::IoPacket packet) {
+  DCHECK(decrypt_cb_);
+
   DCHECK(output_reader_);
   if (!output_pool_->is_live()) {
     DLOG(ERROR) << "Output buffer pool is dead.";
     return;
   }
 
-  auto clear_buffer = base::MakeRefCounted<DecoderBuffer>(packet->size());
-  clear_buffer->set_timestamp(packet->timestamp());
+  // If that's not the last packet for the current Decrypt() request then just
+  // store the output and wait for the next packet.
+  if (!packet.unit_end()) {
+    size_t pos = output_data_.size();
+    output_data_.resize(pos + packet.size());
 
-  bool read_success =
-      output_reader_->Read(packet->index(), packet->offset(),
-                           base::make_span(clear_buffer->writable_data(),
-                                           clear_buffer->data_size()));
+    bool read_success = output_reader_->Read(
+        packet.index(), packet.offset(),
+        base::make_span(output_data_.data() + pos, packet.size()));
 
-  if (!read_success) {
-    DLOG(ERROR) << "Fail to get decrypted result.";
-    std::move(decrypt_cb_).Run(Decryptor::kError, nullptr);
+    if (!read_success) {
+      // If we've failed to read a partial packet then delay reporting the error
+      // until we've received the last packet to make sure we consume all output
+      // packets generated by the last Decrypt() call.
+      DLOG(ERROR) << "Fail to get decrypted result.";
+      current_status_ = Decryptor::kError;
+      output_data_.clear();
+    }
+
     return;
   }
 
-  std::move(decrypt_cb_).Run(Decryptor::kSuccess, std::move(clear_buffer));
+  // We've received the last packet. Assemble DecoderBuffer and pass it to the
+  // DecryptCB.
+  auto clear_buffer =
+      base::MakeRefCounted<DecoderBuffer>(output_data_.size() + packet.size());
+  clear_buffer->set_timestamp(packet.timestamp());
+
+  // Copy data received in the previous packets.
+  memcpy(clear_buffer->writable_data(), output_data_.data(),
+         output_data_.size());
+  output_data_.clear();
+
+  // Copy data received in the last packet
+  bool read_success = output_reader_->Read(
+      packet.index(), packet.offset(),
+      base::make_span(clear_buffer->writable_data() + output_data_.size(),
+                      packet.size()));
+
+  if (!read_success) {
+    DLOG(ERROR) << "Fail to get decrypted result.";
+    current_status_ = Decryptor::kError;
+  }
+
+  std::move(decrypt_cb_)
+      .Run(current_status_, current_status_ == Decryptor::kSuccess
+                                ? std::move(clear_buffer)
+                                : nullptr);
 }
 
 void FuchsiaClearStreamDecryptor::OnNoKey() {
diff --git a/media/fuchsia/cdm/fuchsia_stream_decryptor.h b/media/fuchsia/cdm/fuchsia_stream_decryptor.h
index 323062c..8679521 100644
--- a/media/fuchsia/cdm/fuchsia_stream_decryptor.h
+++ b/media/fuchsia/cdm/fuchsia_stream_decryptor.h
@@ -12,10 +12,10 @@
 #include "media/base/decryptor.h"
 #include "media/fuchsia/common/stream_processor_helper.h"
 #include "media/fuchsia/common/sysmem_buffer_pool.h"
+#include "media/fuchsia/common/sysmem_buffer_writer_queue.h"
 
 namespace media {
 class SysmemBufferReader;
-class SysmemBufferWriter;
 
 // Base class for media stream decryptor implementations.
 class FuchsiaStreamDecryptorBase : public StreamProcessorHelper::Client {
@@ -37,17 +37,14 @@
   BufferAllocator allocator_;
 
  private:
-  void OnInputPacketReleased(size_t index);
   void OnInputBufferPoolCreated(std::unique_ptr<SysmemBufferPool> pool);
-  void OnInputBufferPoolWriterCreated(
-      std::unique_ptr<SysmemBufferWriter> writer);
+  void OnWriterCreated(std::unique_ptr<SysmemBufferWriter> writer);
+  void SendInputPacket(const DecoderBuffer* buffer,
+                       StreamProcessorHelper::IoPacket packet);
 
-  // Pending buffers due to input buffer pool not available.
-  scoped_refptr<DecoderBuffer> pending_encrypted_buffer_;
-
+  SysmemBufferWriterQueue input_writer_queue_;
   std::unique_ptr<SysmemBufferPool::Creator> input_pool_creator_;
   std::unique_ptr<SysmemBufferPool> input_pool_;
-  std::unique_ptr<SysmemBufferWriter> input_writer_;
 
   DISALLOW_COPY_AND_ASSIGN(FuchsiaStreamDecryptorBase);
 };
@@ -72,8 +69,7 @@
                                  stream_constraints) override;
   void OnProcessEos() override;
   void OnOutputFormat(fuchsia::media::StreamOutputFormat format) override;
-  void OnOutputPacket(
-      std::unique_ptr<StreamProcessorHelper::IoPacket> packet) override;
+  void OnOutputPacket(StreamProcessorHelper::IoPacket packet) override;
   void OnNoKey() override;
   void OnError() override;
 
@@ -88,7 +84,10 @@
   std::unique_ptr<SysmemBufferPool> output_pool_;
   std::unique_ptr<SysmemBufferReader> output_reader_;
 
-  scoped_refptr<DecoderBuffer> clear_buffer_;
+  // Used to re-assemble decrypted output that was split between multiple sysmem
+  // buffers.
+  Decryptor::Status current_status_ = Decryptor::kSuccess;
+  std::vector<uint8_t> output_data_;
 
   DISALLOW_COPY_AND_ASSIGN(FuchsiaClearStreamDecryptor);
 };
diff --git a/media/fuchsia/common/BUILD.gn b/media/fuchsia/common/BUILD.gn
index 5919a04..578edf6e 100644
--- a/media/fuchsia/common/BUILD.gn
+++ b/media/fuchsia/common/BUILD.gn
@@ -14,10 +14,13 @@
     "sysmem_buffer_reader.h",
     "sysmem_buffer_writer.cc",
     "sysmem_buffer_writer.h",
+    "sysmem_buffer_writer_queue.cc",
+    "sysmem_buffer_writer_queue.h",
   ]
 
   deps = [
     "//base",
+    "//media/base",
     "//third_party/fuchsia-sdk/sdk:media",
     "//third_party/fuchsia-sdk/sdk:sysmem",
   ]
diff --git a/media/fuchsia/common/stream_processor_helper.cc b/media/fuchsia/common/stream_processor_helper.cc
index dbc81af3..c403017 100644
--- a/media/fuchsia/common/stream_processor_helper.cc
+++ b/media/fuchsia/common/stream_processor_helper.cc
@@ -13,39 +13,42 @@
                                           size_t offset,
                                           size_t size,
                                           base::TimeDelta timestamp,
-                                          fuchsia::media::FormatDetails format,
+                                          bool unit_end,
                                           base::OnceClosure destroy_cb)
     : index_(index),
       offset_(offset),
       size_(size),
       timestamp_(timestamp),
-      format_(std::move(format)),
+      unit_end_(unit_end),
       destroy_cb_(std::move(destroy_cb)) {}
 
 StreamProcessorHelper::IoPacket::~IoPacket() = default;
 
+StreamProcessorHelper::IoPacket::IoPacket(IoPacket&&) = default;
+StreamProcessorHelper::IoPacket& StreamProcessorHelper::IoPacket::operator=(
+    IoPacket&&) = default;
+
 // static
-std::unique_ptr<StreamProcessorHelper::IoPacket>
-StreamProcessorHelper::IoPacket::CreateInput(
+StreamProcessorHelper::IoPacket StreamProcessorHelper::IoPacket::CreateInput(
     size_t index,
     size_t size,
     base::TimeDelta timestamp,
-    fuchsia::media::FormatDetails format,
+    bool unit_end,
     base::OnceClosure destroy_cb) {
-  return std::make_unique<IoPacket>(index, 0 /* offset */, size, timestamp,
-                                    std::move(format), std::move(destroy_cb));
+  return IoPacket(index, 0 /* offset */, size, timestamp, unit_end,
+                  std::move(destroy_cb));
 }
 
 // static
-std::unique_ptr<StreamProcessorHelper::IoPacket>
-StreamProcessorHelper::IoPacket::CreateOutput(size_t index,
-                                              size_t offset,
-                                              size_t size,
-                                              base::TimeDelta timestamp,
-                                              base::OnceClosure destroy_cb) {
-  return std::make_unique<IoPacket>(index, offset, size, timestamp,
-                                    fuchsia::media::FormatDetails(),
-                                    std::move(destroy_cb));
+StreamProcessorHelper::IoPacket StreamProcessorHelper::IoPacket::CreateOutput(
+    size_t index,
+    size_t offset,
+    size_t size,
+    base::TimeDelta timestamp,
+    bool unit_end,
+    base::OnceClosure destroy_cb) {
+  return IoPacket(index, offset, size, timestamp, unit_end,
+                  std::move(destroy_cb));
 }
 
 StreamProcessorHelper::StreamProcessorHelper(
@@ -83,29 +86,29 @@
 
 StreamProcessorHelper::~StreamProcessorHelper() = default;
 
-void StreamProcessorHelper::Process(std::unique_ptr<IoPacket> input) {
-  DCHECK(input);
+void StreamProcessorHelper::Process(IoPacket input) {
   DCHECK(processor_);
 
   fuchsia::media::Packet packet;
   packet.mutable_header()->set_buffer_lifetime_ordinal(
       input_buffer_lifetime_ordinal_);
-  packet.mutable_header()->set_packet_index(input->index());
+  packet.mutable_header()->set_packet_index(input.index());
   packet.set_buffer_index(packet.header().packet_index());
-  packet.set_timestamp_ish(input->timestamp().InNanoseconds());
+  packet.set_timestamp_ish(input.timestamp().InNanoseconds());
   packet.set_stream_lifetime_ordinal(stream_lifetime_ordinal_);
-  packet.set_start_offset(input->offset());
-  packet.set_valid_length_bytes(input->size());
+  packet.set_start_offset(input.offset());
+  packet.set_valid_length_bytes(input.size());
+  packet.set_known_end_access_unit(input.unit_end());
 
   active_stream_ = true;
 
-  if (!input->format().IsEmpty()) {
+  if (!input.format().IsEmpty()) {
     processor_->QueueInputFormatDetails(stream_lifetime_ordinal_,
-                                        fidl::Clone(input->format()));
+                                        fidl::Clone(input.format()));
   }
 
-  DCHECK(input_packets_.find(input->index()) == input_packets_.end());
-  input_packets_[input->index()] = std::move(input);
+  DCHECK(input_packets_.find(input.index()) == input_packets_.end());
+  input_packets_.insert_or_assign(input.index(), std::move(input));
   processor_->QueueInputPacket(std::move(packet));
 }
 
@@ -183,10 +186,15 @@
 
   auto it = input_packets_.find(free_input_packet.packet_index());
   if (it == input_packets_.end()) {
-    DLOG(WARNING) << "Received OnFreeInputPacket() with invalid packet index.";
+    DLOG(ERROR) << "Received OnFreeInputPacket() with invalid packet index.";
+    OnError();
     return;
   }
 
+  // The packet should be destroyed only after it's removed from
+  // |input_packets_|. Otherwise packet destruction observer may call Process()
+  // for the next packet while the current packet is still in |input_packets_|.
+  auto packet = std::move(it->second);
   input_packets_.erase(it);
 }
 
@@ -269,6 +277,7 @@
   client_->OnOutputPacket(IoPacket::CreateOutput(
       buffer_index, output_packet.start_offset(),
       output_packet.valid_length_bytes(), timestamp,
+      output_packet.known_end_access_unit(),
       base::BindOnce(&StreamProcessorHelper::OnRecycleOutputBuffer, weak_this_,
                      output_buffer_lifetime_ordinal_, packet_index)));
 }
diff --git a/media/fuchsia/common/stream_processor_helper.h b/media/fuchsia/common/stream_processor_helper.h
index 64fe8a5..babbaac6 100644
--- a/media/fuchsia/common/stream_processor_helper.h
+++ b/media/fuchsia/common/stream_processor_helper.h
@@ -26,35 +26,38 @@
  public:
   class IoPacket {
    public:
-    static std::unique_ptr<IoPacket> CreateInput(
-        size_t index,
-        size_t size,
-        base::TimeDelta timestamp,
-        fuchsia::media::FormatDetails format,
-        base::OnceClosure destroy_cb);
+    static IoPacket CreateInput(size_t index,
+                                size_t size,
+                                base::TimeDelta timestamp,
+                                bool unit_end,
+                                base::OnceClosure destroy_cb);
 
-    static std::unique_ptr<IoPacket> CreateOutput(size_t index,
-                                                  size_t offset,
-                                                  size_t size,
-                                                  base::TimeDelta timestamp,
-                                                  base::OnceClosure destroy_cb);
+    static IoPacket CreateOutput(size_t index,
+                                 size_t offset,
+                                 size_t size,
+                                 base::TimeDelta timestamp,
+                                 bool unit_end,
+                                 base::OnceClosure destroy_cb);
 
     IoPacket(size_t index,
              size_t offset,
              size_t size,
              base::TimeDelta timestamp,
-             fuchsia::media::FormatDetails format,
+             bool unit_end,
              base::OnceClosure destroy_cb);
     ~IoPacket();
 
+    IoPacket(IoPacket&&);
+    IoPacket& operator=(IoPacket&&);
+
     size_t index() const { return index_; }
-
     size_t offset() const { return offset_; }
-
     size_t size() const { return size_; }
-
     base::TimeDelta timestamp() const { return timestamp_; }
-
+    bool unit_end() const { return unit_end_; }
+    void set_format(fuchsia::media::FormatDetails format) {
+      format_ = std::move(format);
+    }
     const fuchsia::media::FormatDetails& format() const { return format_; }
 
    private:
@@ -62,8 +65,11 @@
     size_t offset_;
     size_t size_;
     base::TimeDelta timestamp_;
+    bool unit_end_;
     fuchsia::media::FormatDetails format_;
     base::ScopedClosureRunner destroy_cb_;
+
+    DISALLOW_COPY_AND_ASSIGN(IoPacket);
   };
 
   class Client {
@@ -83,9 +89,9 @@
     virtual void OnOutputFormat(fuchsia::media::StreamOutputFormat format) = 0;
 
     // Called when output packet is available. Deleting |packet| will notify
-    // StreamProcessor the output buffer is available to be re-used.
-    // Client should delete |packet| on the same thread as this function.
-    virtual void OnOutputPacket(std::unique_ptr<IoPacket> packet) = 0;
+    // StreamProcessor the output buffer is available to be re-used. Client
+    // should delete |packet| on the same thread as this function.
+    virtual void OnOutputPacket(IoPacket packet) = 0;
 
     // Only available for decryption, which indicates currently the
     // StreamProcessor doesn't have the content key to process.
@@ -102,9 +108,9 @@
                         Client* client);
   ~StreamProcessorHelper();
 
-  // Process one packet. |packet| is owned by this class until the buffer
-  // represented by |packet| is released.
-  void Process(std::unique_ptr<IoPacket> packet);
+  // Process one packet. Caller can reuse the underlying buffer when the
+  // |packet| is destroyed.
+  void Process(IoPacket packet);
 
   // Push End-Of-Stream to StreamProcessor. No more data should be sent to
   // StreamProcessor without calling Reset.
@@ -153,7 +159,7 @@
 
   // Map from packet index to corresponding input IoPacket. IoPacket should be
   // owned by this class until StreamProcessor released the buffer.
-  base::flat_map<size_t, std::unique_ptr<IoPacket>> input_packets_;
+  base::flat_map<size_t, IoPacket> input_packets_;
 
   // Output buffers.
   uint64_t output_buffer_lifetime_ordinal_ = 1;
diff --git a/media/fuchsia/common/sysmem_buffer_pool.h b/media/fuchsia/common/sysmem_buffer_pool.h
index b7f4bc3c..a3fcf74 100644
--- a/media/fuchsia/common/sysmem_buffer_pool.h
+++ b/media/fuchsia/common/sysmem_buffer_pool.h
@@ -95,6 +95,10 @@
   std::unique_ptr<SysmemBufferPool::Creator> MakeBufferPoolCreator(
       size_t num_shared_token);
 
+  // TODO(sergeyu): Update FuchsiaVideoDecoder to use SysmemBufferPool and
+  // remove this function.
+  fuchsia::sysmem::Allocator* raw() { return allocator_.get(); }
+
  private:
   fuchsia::sysmem::AllocatorPtr allocator_;
 
diff --git a/media/fuchsia/common/sysmem_buffer_writer.cc b/media/fuchsia/common/sysmem_buffer_writer.cc
index e355d345..82346ec2 100644
--- a/media/fuchsia/common/sysmem_buffer_writer.cc
+++ b/media/fuchsia/common/sysmem_buffer_writer.cc
@@ -122,6 +122,16 @@
   buffers_[index].Release();
 }
 
+void SysmemBufferWriter::ReleaseAll() {
+  for (auto& buf : buffers_) {
+    buf.Release();
+  }
+}
+
+size_t SysmemBufferWriter::num_buffers() const {
+  return buffers_.size();
+}
+
 // static
 std::unique_ptr<SysmemBufferWriter> SysmemBufferWriter::Create(
     fuchsia::sysmem::BufferCollectionInfo_2 info) {
diff --git a/media/fuchsia/common/sysmem_buffer_writer.h b/media/fuchsia/common/sysmem_buffer_writer.h
index b7746af..9aed936 100644
--- a/media/fuchsia/common/sysmem_buffer_writer.h
+++ b/media/fuchsia/common/sysmem_buffer_writer.h
@@ -43,6 +43,11 @@
   // Notify the pool buffer at |index| is free to write new data.
   void Release(size_t index);
 
+  // Mark all buffers as unused.
+  void ReleaseAll();
+
+  size_t num_buffers() const;
+
  private:
   std::vector<Buffer> buffers_;
 
diff --git a/media/fuchsia/common/sysmem_buffer_writer_queue.cc b/media/fuchsia/common/sysmem_buffer_writer_queue.cc
new file mode 100644
index 0000000..d04e378
--- /dev/null
+++ b/media/fuchsia/common/sysmem_buffer_writer_queue.cc
@@ -0,0 +1,132 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "media/fuchsia/common/sysmem_buffer_writer_queue.h"
+
+#include <zircon/rights.h>
+#include <algorithm>
+
+#include "base/bits.h"
+#include "base/fuchsia/fuchsia_logging.h"
+#include "base/process/process_metrics.h"
+#include "media/base/decoder_buffer.h"
+
+namespace media {
+
+class SysmemBufferWriterQueue::PendingBuffer {
+ public:
+  PendingBuffer(scoped_refptr<DecoderBuffer> buffer) : buffer_(buffer) {
+    DCHECK(buffer_);
+  }
+  ~PendingBuffer() = default;
+
+  PendingBuffer(PendingBuffer&& other) = default;
+  PendingBuffer& operator=(PendingBuffer&& other) = default;
+
+  const DecoderBuffer* buffer() { return buffer_.get(); }
+
+  const uint8_t* data() const { return buffer_->data() + buffer_pos_; }
+  size_t bytes_left() const { return buffer_->data_size() - buffer_pos_; }
+  void AdvanceCurrentPos(size_t bytes) {
+    DCHECK_LE(bytes, bytes_left());
+    buffer_pos_ += bytes;
+  }
+
+ private:
+  scoped_refptr<DecoderBuffer> buffer_;
+  size_t buffer_pos_ = 0;
+
+  DISALLOW_COPY_AND_ASSIGN(PendingBuffer);
+};
+
+SysmemBufferWriterQueue::SysmemBufferWriterQueue() = default;
+SysmemBufferWriterQueue::~SysmemBufferWriterQueue() = default;
+
+void SysmemBufferWriterQueue::EnqueueBuffer(
+    scoped_refptr<DecoderBuffer> buffer) {
+  pending_buffers_.push_back(PendingBuffer(buffer));
+  PumpPackets();
+}
+
+void SysmemBufferWriterQueue::Start(std::unique_ptr<SysmemBufferWriter> writer,
+                                    SendPacketCB send_packet_cb,
+                                    EndOfStreamCB end_of_stream_cb) {
+  DCHECK(!writer_);
+
+  writer_ = std::move(writer);
+  send_packet_cb_ = std::move(send_packet_cb);
+  end_of_stream_cb_ = std::move(end_of_stream_cb);
+
+  PumpPackets();
+}
+
+void SysmemBufferWriterQueue::PumpPackets() {
+  auto weak_this = weak_factory_.GetWeakPtr();
+
+  while (writer_ && !pending_buffers_.empty()) {
+    if (pending_buffers_.front().buffer()->end_of_stream()) {
+      pending_buffers_.pop_front();
+      end_of_stream_cb_.Run();
+      if (!weak_this)
+        return;
+      continue;
+    }
+
+    base::Optional<size_t> index_opt = writer_->Acquire();
+
+    if (!index_opt.has_value()) {
+      // No input buffer available.
+      return;
+    }
+
+    size_t buffer_index = index_opt.value();
+
+    size_t bytes_filled = writer_->Write(
+        buffer_index, base::make_span(pending_buffers_.front().data(),
+                                      pending_buffers_.front().bytes_left()));
+    pending_buffers_.front().AdvanceCurrentPos(bytes_filled);
+
+    bool buffer_end = pending_buffers_.front().bytes_left() == 0;
+
+    auto packet = StreamProcessorHelper::IoPacket::CreateInput(
+        buffer_index, bytes_filled,
+        pending_buffers_.front().buffer()->timestamp(), buffer_end,
+        base::BindOnce(&SysmemBufferWriterQueue::ReleaseBuffer,
+                       weak_factory_.GetWeakPtr(), buffer_index));
+
+    send_packet_cb_.Run(pending_buffers_.front().buffer(), std::move(packet));
+    if (!weak_this)
+      return;
+
+    if (buffer_end)
+      pending_buffers_.pop_front();
+  }
+}
+
+void SysmemBufferWriterQueue::ResetQueue() {
+  // Invalidate weak pointers to drop all ReleaseBuffer() callbacks.
+  weak_factory_.InvalidateWeakPtrs();
+
+  pending_buffers_.clear();
+  if (writer_)
+    writer_->ReleaseAll();
+}
+
+void SysmemBufferWriterQueue::ResetBuffers() {
+  writer_.reset();
+  send_packet_cb_ = SendPacketCB();
+  end_of_stream_cb_ = EndOfStreamCB();
+}
+
+void SysmemBufferWriterQueue::ReleaseBuffer(size_t buffer_index) {
+  DCHECK(writer_);
+  writer_->Release(buffer_index);
+  PumpPackets();
+}
+
+size_t SysmemBufferWriterQueue::num_buffers() const {
+  return writer_ ? writer_->num_buffers() : 0;
+}
+
+}  // namespace media
diff --git a/media/fuchsia/common/sysmem_buffer_writer_queue.h b/media/fuchsia/common/sysmem_buffer_writer_queue.h
new file mode 100644
index 0000000..4d5f2de
--- /dev/null
+++ b/media/fuchsia/common/sysmem_buffer_writer_queue.h
@@ -0,0 +1,87 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef MEDIA_FUCHSIA_COMMON_SYSMEM_BUFFER_WRITER_QUEUE_H_
+#define MEDIA_FUCHSIA_COMMON_SYSMEM_BUFFER_WRITER_QUEUE_H_
+
+#include <fuchsia/media/cpp/fidl.h>
+#include <fuchsia/sysmem/cpp/fidl.h>
+
+#include <memory>
+
+#include "base/containers/span.h"
+#include "base/memory/weak_ptr.h"
+#include "base/optional.h"
+#include "media/fuchsia/common/stream_processor_helper.h"
+#include "media/fuchsia/common/sysmem_buffer_writer.h"
+
+namespace media {
+
+class DecoderBuffer;
+
+// A SysmemBufferWriter wrapper that keeps a queue of pending DecodeBuffers,
+// writes them to sysmem buffers and generates StreamProcessor packets.
+class SysmemBufferWriterQueue {
+ public:
+  // Callback passed to StartSender(). |buffer| corresponds to the original
+  // buffer from which the |packet| was generated.
+  using SendPacketCB =
+      base::RepeatingCallback<void(const DecoderBuffer* buffer,
+                                   StreamProcessorHelper::IoPacket packet)>;
+
+  // Called when processing DecoderBuffer that's marked as end-of-stream.
+  using EndOfStreamCB = base::RepeatingClosure;
+
+  SysmemBufferWriterQueue();
+  ~SysmemBufferWriterQueue();
+
+  // Enqueues buffer to the queue.
+  void EnqueueBuffer(scoped_refptr<DecoderBuffer> buffer);
+
+  // Sets the buffer writer to use and starts sending outgoing packets using
+  // |send_packet_cb|. |end_of_stream_cb| will be called when processing each
+  // end-of-stream buffer.
+  void Start(std::unique_ptr<SysmemBufferWriter> writer,
+             SendPacketCB send_packet_cb,
+             EndOfStreamCB end_of_stream_cb);
+
+  // Resets all pending buffers. Keeps the underlying sysmem buffers.
+  void ResetQueue();
+
+  // Resets the buffers. Keeps the current pending buffers, so they will still
+  // be sent once the new collection is allocated and passed to Start().
+  void ResetBuffers();
+
+  // Number of buffers in the sysmem collection or 0 if sysmem buffers has not
+  // been allocated (i.e. before Start()).
+  size_t num_buffers() const;
+
+ private:
+  class PendingBuffer;
+  class SysmemBuffer;
+
+  // Pumps pending buffers to SendPacketCB.
+  void PumpPackets();
+
+  // Callback called when a packet is destroyed. It marks the buffer as unused
+  // and tries to reuse it for other buffers if any.
+  void ReleaseBuffer(size_t buffer_index);
+
+  // Buffers that are waiting to be sent.
+  std::deque<PendingBuffer> pending_buffers_;
+
+  // Buffers for sysmem buffer collection. Not set until Start() is called.
+  std::unique_ptr<SysmemBufferWriter> writer_;
+
+  SendPacketCB send_packet_cb_;
+  EndOfStreamCB end_of_stream_cb_;
+
+  base::WeakPtrFactory<SysmemBufferWriterQueue> weak_factory_{this};
+
+  DISALLOW_COPY_AND_ASSIGN(SysmemBufferWriterQueue);
+};
+
+}  // namespace media
+
+#endif  // MEDIA_FUCHSIA_COMMON_SYSMEM_BUFFER_WRITER_QUEUE_H_
diff --git a/media/media_options.gni b/media/media_options.gni
index 6a507193..b2105c6 100644
--- a/media/media_options.gni
+++ b/media/media_options.gni
@@ -30,7 +30,10 @@
 ]
 
 if (is_fuchsia) {
-  media_subcomponent_deps += [ "//media/fuchsia/cdm" ]
+  media_subcomponent_deps += [
+    "//media/fuchsia/cdm",
+    "//media/fuchsia/common",
+  ]
 }
 
 declare_args() {
diff --git a/media/renderers/paint_canvas_video_renderer.cc b/media/renderers/paint_canvas_video_renderer.cc
index 2a2f051a..6636834 100644
--- a/media/renderers/paint_canvas_video_renderer.cc
+++ b/media/renderers/paint_canvas_video_renderer.cc
@@ -648,7 +648,23 @@
                 .set_image(std::move(non_texture_image), image.content_id())
                 .TakePaintImage();
   }
-  canvas->drawImage(image, 0, 0, &video_flags);
+
+  SkImageInfo info;
+  size_t row_bytes;
+  SkIPoint origin;
+  void* pixels = nullptr;
+  if (!need_transform && video_frame->IsMappable() &&
+      flags.getAlpha() == SK_AlphaOPAQUE &&
+      flags.getBlendMode() == SkBlendMode::kSrc &&
+      flags.getFilterQuality() == kLow_SkFilterQuality &&
+      (pixels = canvas->accessTopLayerPixels(&info, &row_bytes, &origin)) &&
+      info.colorType() == kBGRA_8888_SkColorType) {
+    const size_t offset = info.computeOffset(origin.x(), origin.y(), row_bytes);
+    void* const pixels_offset = reinterpret_cast<char*>(pixels) + offset;
+    ConvertVideoFrameToRGBPixels(video_frame.get(), pixels_offset, row_bytes);
+  } else {
+    canvas->drawImage(image, 0, 0, &video_flags);
+  }
 
   if (need_transform)
     canvas->restore();
diff --git a/net/dns/dns_transaction.cc b/net/dns/dns_transaction.cc
index af57285..2ec718b 100644
--- a/net/dns/dns_transaction.cc
+++ b/net/dns/dns_transaction.cc
@@ -865,7 +865,8 @@
     session_->SetProbeSuccess(doh_server_index, false /* success */);
     ContinueProbe(doh_server_index, context,
                   probe_stats_[doh_server_index]->weak_factory.GetWeakPtr(),
-                  network_change, base::TimeTicks::Now());
+                  network_change,
+                  base::TimeTicks::Now() /* sequence_start_time */);
   }
 
  private:
@@ -883,7 +884,7 @@
                      URLRequestContext* context,
                      base::WeakPtr<ProbeStats> probe_stats,
                      bool network_change,
-                     base::TimeTicks start_time) {
+                     base::TimeTicks sequence_start_time) {
     // If the ProbeStats for which this probe was scheduled has been deleted,
     // don't continue to send probes.
     if (!probe_stats)
@@ -900,7 +901,7 @@
         FROM_HERE,
         base::BindOnce(&DnsOverHttpsProbeRunner::ContinueProbe,
                        base::Unretained(this), doh_server_index, context,
-                       probe_stats, network_change, start_time),
+                       probe_stats, network_change, sequence_start_time),
         probe_stats->backoff_entry->GetTimeUntilRelease());
 
     unsigned attempt_number = probe_stats->probe_attempts.size();
@@ -910,17 +911,19 @@
                             &probe_stats->probe_attempts, context,
                             RequestPriority::DEFAULT_PRIORITY);
 
-    probe_stats->probe_attempts.back()->Start(
-        base::BindOnce(&DnsOverHttpsProbeRunner::ProbeComplete,
-                       base::Unretained(this), attempt_number, doh_server_index,
-                       std::move(probe_stats), network_change, start_time));
+    probe_stats->probe_attempts.back()->Start(base::BindOnce(
+        &DnsOverHttpsProbeRunner::ProbeComplete, base::Unretained(this),
+        attempt_number, doh_server_index, std::move(probe_stats),
+        network_change, sequence_start_time,
+        base::TimeTicks::Now() /* query_start_time */));
   }
 
   void ProbeComplete(unsigned attempt_number,
                      int doh_server_index,
                      base::WeakPtr<ProbeStats> probe_stats,
                      bool network_change,
-                     base::TimeTicks start,
+                     base::TimeTicks sequence_start_time,
+                     base::TimeTicks query_start_time,
                      int rv) {
     bool success = false;
     if (rv == OK && probe_stats) {
@@ -941,7 +944,7 @@
         session_->RecordServerSuccess(doh_server_index,
                                       true /* is_doh_server */);
         session_->RecordRTT(doh_server_index, true /* is_doh_server */,
-                            base::TimeTicks::Now() - start, rv);
+                            base::TimeTicks::Now() - query_start_time, rv);
         session_->SetProbeSuccess(doh_server_index, true /* success */);
         probe_stats_[doh_server_index] = nullptr;
         success = true;
@@ -952,7 +955,7 @@
         base::StringPrintf("Net.DNS.ProbeSequence.%s.%s.AttemptTime",
                            network_change ? "NetworkChange" : "ConfigChange",
                            success ? "Success" : "Failure"),
-        base::TimeTicks::Now() - start);
+        base::TimeTicks::Now() - sequence_start_time);
   }
 
   DnsSession* session_;
diff --git a/net/dns/dns_util.cc b/net/dns/dns_util.cc
index d83ff7c..14997c4 100644
--- a/net/dns/dns_util.cc
+++ b/net/dns/dns_util.cc
@@ -139,11 +139,11 @@
   const DnsConfig::DnsOverHttpsServerConfig dns_over_https_config;
 };
 
-const std::vector<const DohUpgradeEntry>& GetDohUpgradeList() {
+const std::vector<DohUpgradeEntry>& GetDohUpgradeList() {
   // The provider names in these entries should be kept in sync with the
   // DohProviderId histogram suffix list in
   // tools/metrics/histograms/histograms.xml.
-  static const base::NoDestructor<std::vector<const DohUpgradeEntry>>
+  static const base::NoDestructor<std::vector<DohUpgradeEntry>>
       upgradable_servers({
           DohUpgradeEntry(
               "CleanBrowsingAdult",
@@ -222,8 +222,7 @@
 std::vector<const DohUpgradeEntry*> GetDohUpgradeEntriesFromNameservers(
     const std::vector<IPEndPoint>& dns_servers,
     const std::vector<std::string>& excluded_providers) {
-  const std::vector<const DohUpgradeEntry>& upgradable_servers =
-      GetDohUpgradeList();
+  const std::vector<DohUpgradeEntry>& upgradable_servers = GetDohUpgradeList();
   std::vector<const DohUpgradeEntry*> entries;
 
   for (const auto& server : dns_servers) {
@@ -417,8 +416,7 @@
 GetDohUpgradeServersFromDotHostname(
     const std::string& dot_server,
     const std::vector<std::string>& excluded_providers) {
-  const std::vector<const DohUpgradeEntry>& upgradable_servers =
-      GetDohUpgradeList();
+  const std::vector<DohUpgradeEntry>& upgradable_servers = GetDohUpgradeList();
   std::vector<DnsConfig::DnsOverHttpsServerConfig> doh_servers;
 
   if (dot_server.empty())
@@ -451,8 +449,7 @@
 
 std::string GetDohProviderIdForHistogramFromDohConfig(
     const DnsConfig::DnsOverHttpsServerConfig& doh_server) {
-  const std::vector<const DohUpgradeEntry>& upgradable_servers =
-      GetDohUpgradeList();
+  const std::vector<DohUpgradeEntry>& upgradable_servers = GetDohUpgradeList();
   for (const auto& upgrade_entry : upgradable_servers) {
     if (doh_server.server_template ==
         upgrade_entry.dns_over_https_config.server_template) {
diff --git a/net/url_request/redirect_info.cc b/net/url_request/redirect_info.cc
index dbdbc008..d716a0c1 100644
--- a/net/url_request/redirect_info.cc
+++ b/net/url_request/redirect_info.cc
@@ -117,7 +117,6 @@
 RedirectInfo RedirectInfo::ComputeRedirectInfo(
     const std::string& original_method,
     const GURL& original_url,
-    const base::Optional<url::Origin>& initiator,
     const GURL& original_site_for_cookies,
     URLRequest::FirstPartyURLPolicy original_first_party_url_policy,
     URLRequest::ReferrerPolicy original_referrer_policy,
@@ -167,9 +166,9 @@
 
   // Alter the referrer if redirecting cross-origin (especially HTTP->HTTPS).
   redirect_info.new_referrer =
-      URLRequestJob::ComputeReferrerForPolicy(
-          redirect_info.new_referrer_policy, GURL(original_referrer),
-          initiator.value_or(url::Origin()), redirect_info.new_url)
+      URLRequestJob::ComputeReferrerForPolicy(redirect_info.new_referrer_policy,
+                                              GURL(original_referrer),
+                                              redirect_info.new_url)
           .spec();
 
   return redirect_info;
diff --git a/net/url_request/redirect_info.h b/net/url_request/redirect_info.h
index ea8febe7..3e4699fc 100644
--- a/net/url_request/redirect_info.h
+++ b/net/url_request/redirect_info.h
@@ -27,7 +27,6 @@
       // request.
       const std::string& original_method,
       const GURL& original_url,
-      const base::Optional<url::Origin>& initiator,
       const GURL& original_site_for_cookies,
       URLRequest::FirstPartyURLPolicy original_first_party_url_policy,
       URLRequest::ReferrerPolicy original_referrer_policy,
diff --git a/net/url_request/redirect_info_unittest.cc b/net/url_request/redirect_info_unittest.cc
index f9d4538..d92e688 100644
--- a/net/url_request/redirect_info_unittest.cc
+++ b/net/url_request/redirect_info_unittest.cc
@@ -47,8 +47,7 @@
                  << " http_status_code: " << test.http_status_code);
 
     RedirectInfo redirect_info = RedirectInfo::ComputeRedirectInfo(
-        test.original_method, kOriginalUrl,
-        url::Origin::Create(kOriginalSiteForCookies), kOriginalSiteForCookies,
+        test.original_method, kOriginalUrl, kOriginalSiteForCookies,
         kOriginalFirstPartyUrlPolicy, kOriginalReferrerPolicy,
         kOriginalReferrer, test.http_status_code, kNewLocation,
         base::nullopt /* referrer_policy_header */, kInsecureSchemeWasUpgraded,
@@ -99,8 +98,7 @@
                  << " new_location: " << test.new_location);
 
     RedirectInfo redirect_info = RedirectInfo::ComputeRedirectInfo(
-        KOriginalMethod, GURL(test.original_url),
-        url::Origin::Create(kOriginalSiteForCookies), kOriginalSiteForCookies,
+        KOriginalMethod, GURL(test.original_url), kOriginalSiteForCookies,
         kOriginalFirstPartyUrlPolicy, kOriginalReferrerPolicy,
         kOriginalReferrer, kHttpStatusCode, GURL(test.new_location),
         base::nullopt /* referrer_policy_header */, kInsecureSchemeWasUpgraded,
@@ -138,8 +136,7 @@
                  << static_cast<int>(test.original_first_party_url_policy));
 
     RedirectInfo redirect_info = RedirectInfo::ComputeRedirectInfo(
-        KOriginalMethod, kOriginalUrl,
-        url::Origin::Create(kOriginalSiteForCookies), kOriginalSiteForCookies,
+        KOriginalMethod, kOriginalUrl, kOriginalSiteForCookies,
         test.original_first_party_url_policy, kOriginalReferrerPolicy,
         kOriginalReferrer, kHttpStatusCode, kNewLocation,
         base::nullopt /* referrer_policy_header */, kInsecureSchemeWasUpgraded,
@@ -240,8 +237,7 @@
            ORIGIN_ONLY_ON_TRANSITION_CROSS_ORIGIN /* expected new policy */,
        "https://foo.test/referrer" /* expected new referrer */},
 
-      // ... but should be stripped to the origin for a cross-origin redirect
-      // ...
+      // ... but should be stripped to the origin for a cross-origin redirect.
       {"https://foo.test/one" /* original url */,
        "https://foo.test/one" /* original referrer */,
        "Location: https://bar.test/two\n"
@@ -251,16 +247,6 @@
            ORIGIN_ONLY_ON_TRANSITION_CROSS_ORIGIN /* expected new policy */,
        "https://foo.test/" /* expected new referrer */},
 
-      // ... even when the referrer is same-origin with the redirect.
-      {"https://foo.test/one" /* original url */,
-       "https://bar.test/one" /* original referrer */,
-       "Location: https://bar.test/two\n"
-       "Referrer-Policy: origin-when-cross-origin\n",
-       URLRequest::NEVER_CLEAR_REFERRER /* original policy */,
-       URLRequest::
-           ORIGIN_ONLY_ON_TRANSITION_CROSS_ORIGIN /* expected new policy */,
-       "https://bar.test/" /* expected new referrer */},
-
       // If a redirect serves 'Referrer-Policy: same-origin', then the referrer
       // should be untouched for a same-origin redirect,
       {"https://foo.test/one" /* original url */,
@@ -272,7 +258,7 @@
        ,
        "https://foo.test/referrer" /* expected new referrer */},
 
-      // ... but should be cleared for a cross-origin redirect ...
+      // ... but should be cleared for a cross-origin redirect.
       {"https://foo.test/one" /* original url */,
        "https://foo.test/referrer" /* original referrer */,
        "Location: https://bar.test/two\n"
@@ -281,15 +267,6 @@
        URLRequest::CLEAR_REFERRER_ON_TRANSITION_CROSS_ORIGIN,
        "" /* expected new referrer */},
 
-      // ... even when the referrer is same-origin with the redirect ...
-      {"https://foo.test/one" /* original url */,
-       "https://bar.test/referrer" /* original referrer */,
-       "Location: https://bar.test/two\n"
-       "Referrer-Policy: same-origin\n",
-       URLRequest::NEVER_CLEAR_REFERRER /* original policy */,
-       URLRequest::CLEAR_REFERRER_ON_TRANSITION_CROSS_ORIGIN,
-       "" /* expected new referrer */},
-
       // If a redirect serves 'Referrer-Policy: strict-origin', then the
       // referrer should be the origin only for a cross-origin non-downgrading
       // redirect,
@@ -308,22 +285,6 @@
        URLRequest::ORIGIN_CLEAR_ON_TRANSITION_FROM_SECURE_TO_INSECURE,
        "http://foo.test/" /* expected new referrer */},
 
-      // even when the referrer is same-origin with the redirect ...
-      {"https://foo.test/one" /* original url */,
-       "https://bar.test/referrer" /* original referrer */,
-       "Location: https://bar.test/two\n"
-       "Referrer-Policy: strict-origin\n",
-       URLRequest::NEVER_CLEAR_REFERRER /* original policy */,
-       URLRequest::ORIGIN_CLEAR_ON_TRANSITION_FROM_SECURE_TO_INSECURE,
-       "https://bar.test/" /* expected new referrer */},
-      {"http://foo.test/one" /* original url */,
-       "http://bar.test/referrer" /* original referrer */,
-       "Location: http://bar.test/two\n"
-       "Referrer-Policy: strict-origin\n",
-       URLRequest::NEVER_CLEAR_REFERRER /* original policy */,
-       URLRequest::ORIGIN_CLEAR_ON_TRANSITION_FROM_SECURE_TO_INSECURE,
-       "http://bar.test/" /* expected new referrer */},
-
       // ... but should be cleared for a downgrading redirect.
       {"https://foo.test/one" /* original url */,
        "https://foo.test/referrer" /* original referrer */,
@@ -368,22 +329,6 @@
        URLRequest::REDUCE_REFERRER_GRANULARITY_ON_TRANSITION_CROSS_ORIGIN,
        "http://foo.test/" /* expected new referrer */},
 
-      // ... even when the referrer is same-origin with the redirect ...
-      {"https://foo.test/one" /* original url */,
-       "https://bar.test/referrer" /* original referrer */,
-       "Location: https://bar.test/two\n"
-       "Referrer-Policy: strict-origin-when-cross-origin\n",
-       URLRequest::NEVER_CLEAR_REFERRER /* original policy */,
-       URLRequest::REDUCE_REFERRER_GRANULARITY_ON_TRANSITION_CROSS_ORIGIN,
-       "https://bar.test/" /* expected new referrer */},
-      {"http://foo.test/one" /* original url */,
-       "http://bar.test/referrer" /* original referrer */,
-       "Location: http://bar.test/two\n"
-       "Referrer-Policy: strict-origin-when-cross-origin\n",
-       URLRequest::NEVER_CLEAR_REFERRER /* original policy */,
-       URLRequest::REDUCE_REFERRER_GRANULARITY_ON_TRANSITION_CROSS_ORIGIN,
-       "http://bar.test/" /* expected new referrer */},
-
       // ... and should be cleared for a downgrading redirect.
       {"https://foo.test/one" /* original url */,
        "https://foo.test/referrer" /* original referrer */,
@@ -452,14 +397,6 @@
        URLRequest::ORIGIN_ONLY_ON_TRANSITION_CROSS_ORIGIN /* original policy */,
        URLRequest::ORIGIN /* expected new policy */,
        "https://foo.test/" /* expected new referrer */},
-      {"https://foo.test/one" /* original url */,
-       "https://bar.test/one" /* original referrer */,
-       "Location: https://bar.test/two\n"
-       "Referrer-Policy: unsafe-url\n"
-       "Referrer-Policy: origin\n",
-       URLRequest::ORIGIN_ONLY_ON_TRANSITION_CROSS_ORIGIN /* original policy */,
-       URLRequest::ORIGIN /* expected new policy */,
-       "https://bar.test/" /* expected new referrer */},
 
       // An empty header should not affect the request.
       {"https://foo.test/one" /* original url */,
@@ -512,10 +449,9 @@
     const GURL new_location = original_url.Resolve(location_string);
 
     RedirectInfo redirect_info = RedirectInfo::ComputeRedirectInfo(
-        KOriginalMethod, original_url, url::Origin::Create(original_url),
-        kOriginalSiteForCookies, kOriginalFirstPartyUrlPolicy,
-        test.original_referrer_policy, test.original_referrer,
-        response_headers->response_code(), new_location,
+        KOriginalMethod, original_url, kOriginalSiteForCookies,
+        kOriginalFirstPartyUrlPolicy, test.original_referrer_policy,
+        test.original_referrer, response_headers->response_code(), new_location,
         RedirectUtil::GetReferrerPolicyHeader(response_headers.get()),
         kInsecureSchemeWasUpgraded, kCopyFragment);
 
diff --git a/net/url_request/url_request.cc b/net/url_request/url_request.cc
index 57baa4c..127d2a5 100644
--- a/net/url_request/url_request.cc
+++ b/net/url_request/url_request.cc
@@ -677,8 +677,7 @@
 
   GURL referrer_url(referrer_);
   if (referrer_url != URLRequestJob::ComputeReferrerForPolicy(
-                          referrer_policy_, referrer_url,
-                          initiator_.value_or(url::Origin()), url())) {
+                          referrer_policy_, referrer_url, url())) {
     if (!network_delegate_ ||
         !network_delegate_->CancelURLRequestWithPolicyViolatingReferrerHeader(
             *this, url(), referrer_url)) {
diff --git a/net/url_request/url_request_job.cc b/net/url_request/url_request_job.cc
index b7c41cc..957a601 100644
--- a/net/url_request/url_request_job.cc
+++ b/net/url_request/url_request_job.cc
@@ -269,19 +269,16 @@
   out->clear();
 }
 
-// When making changes to this method that affect the returned referrer value,
-// also update blink::SecurityPolicy::GenerateReferrer accordingly.
 // static
 GURL URLRequestJob::ComputeReferrerForPolicy(URLRequest::ReferrerPolicy policy,
                                              const GURL& original_referrer,
-                                             const url::Origin& initiator,
                                              const GURL& destination) {
   bool secure_referrer_but_insecure_destination =
       original_referrer.SchemeIsCryptographic() &&
       !destination.SchemeIsCryptographic();
   url::Origin referrer_origin = url::Origin::Create(original_referrer);
   bool same_origin =
-      initiator.IsSameOriginWith(url::Origin::Create(destination));
+      referrer_origin.IsSameOriginWith(url::Origin::Create(destination));
   switch (policy) {
     case URLRequest::CLEAR_REFERRER_ON_TRANSITION_FROM_SECURE_TO_INSECURE:
       return secure_referrer_but_insecure_destination ? GURL()
@@ -387,10 +384,9 @@
     base::WeakPtr<URLRequestJob> weak_this(weak_factory_.GetWeakPtr());
 
     RedirectInfo redirect_info = RedirectInfo::ComputeRedirectInfo(
-        request_->method(), request_->url(), request_->initiator(),
-        request_->site_for_cookies(), request_->first_party_url_policy(),
-        request_->referrer_policy(), request_->referrer(), http_status_code,
-        new_location,
+        request_->method(), request_->url(), request_->site_for_cookies(),
+        request_->first_party_url_policy(), request_->referrer_policy(),
+        request_->referrer(), http_status_code, new_location,
         net::RedirectUtil::GetReferrerPolicyHeader(
             request_->response_headers()),
         insecure_scheme_was_upgraded, CopyFragmentOnRedirect(new_location));
diff --git a/net/url_request/url_request_job.h b/net/url_request/url_request_job.h
index c1c7424..ebab2dd 100644
--- a/net/url_request/url_request_job.h
+++ b/net/url_request/url_request_job.h
@@ -242,11 +242,10 @@
   // from the remote party with the actual response headers recieved.
   virtual void SetResponseHeadersCallback(ResponseHeadersCallback callback) {}
 
-  // Given |policy|, |referrer|, |initiator|, and |destination|, returns the
+  // Given |policy|, |referrer|, and |destination|, returns the
   // referrer URL mandated by |request|'s referrer policy.
   static GURL ComputeReferrerForPolicy(URLRequest::ReferrerPolicy policy,
                                        const GURL& original_referrer,
-                                       const url::Origin& initiator,
                                        const GURL& destination);
 
  protected:
diff --git a/net/url_request/url_request_unittest.cc b/net/url_request/url_request_unittest.cc
index d1de14f2..c298347 100644
--- a/net/url_request/url_request_unittest.cc
+++ b/net/url_request/url_request_unittest.cc
@@ -8173,7 +8173,6 @@
     TestDelegate d;
     std::unique_ptr<URLRequest> req(default_context().CreateRequest(
         origin_url, DEFAULT_PRIORITY, &d, TRAFFIC_ANNOTATION_FOR_TESTS));
-    req->set_initiator(url::Origin::Create(origin_url));
     req->set_referrer_policy(policy);
     req->SetReferrer(referrer.spec());
     req->Start();
@@ -8193,9 +8192,6 @@
   }
 
   EmbeddedTestServer* origin_server() const { return origin_server_.get(); }
-  EmbeddedTestServer* destination_server() const {
-    return destination_server_.get();
-  }
 
  private:
   std::unique_ptr<EmbeddedTestServer> origin_server_;
@@ -8445,88 +8441,6 @@
   VerifyReferrerAfterRedirect(URLRequest::NO_REFERRER, GURL(), GURL());
 }
 
-TEST_F(URLRequestTestReferrerPolicy,
-       HTTPSToHTTPSSameOriginRequestCrossOrginReferrer) {
-  InstantiateSameOriginServers(net::EmbeddedTestServer::TYPE_HTTPS);
-  // The request is same-origin, however its referrer is cross-origin.
-  GURL referrer("https://foo.test/some/path.html");
-
-  VerifyReferrerAfterRedirect(
-      URLRequest::CLEAR_REFERRER_ON_TRANSITION_FROM_SECURE_TO_INSECURE,
-      referrer, referrer);
-
-  VerifyReferrerAfterRedirect(
-      URLRequest::REDUCE_REFERRER_GRANULARITY_ON_TRANSITION_CROSS_ORIGIN,
-      referrer, referrer);
-
-  VerifyReferrerAfterRedirect(
-      URLRequest::ORIGIN_ONLY_ON_TRANSITION_CROSS_ORIGIN, referrer, referrer);
-
-  VerifyReferrerAfterRedirect(URLRequest::NEVER_CLEAR_REFERRER, referrer,
-                              referrer);
-
-  // The original referrer set on the request is expected to obey the referrer
-  // policy and already be stripped to the origin; thus this test case just
-  // checks that this policy doesn't cause the referrer to change when following
-  // a redirect.
-  VerifyReferrerAfterRedirect(URLRequest::ORIGIN, referrer.GetOrigin(),
-                              referrer.GetOrigin());
-
-  VerifyReferrerAfterRedirect(
-      URLRequest::CLEAR_REFERRER_ON_TRANSITION_CROSS_ORIGIN, referrer,
-      referrer);
-
-  // The original referrer set on the request is expected to obey the referrer
-  // policy and already be stripped to the origin, though it should be
-  // subsequently cleared during the downgrading redirect.
-  VerifyReferrerAfterRedirect(
-      URLRequest::ORIGIN_CLEAR_ON_TRANSITION_FROM_SECURE_TO_INSECURE,
-      referrer.GetOrigin(), referrer.GetOrigin());
-  VerifyReferrerAfterRedirect(URLRequest::NO_REFERRER, GURL(), GURL());
-}
-
-TEST_F(URLRequestTestReferrerPolicy,
-       HTTPSToHTTPSCrossOriginRequestCrossOrginReferrer) {
-  InstantiateCrossOriginServers(net::EmbeddedTestServer::TYPE_HTTPS,
-                                net::EmbeddedTestServer::TYPE_HTTPS);
-  // The request is cross-origin, and so is its referrer.
-  GURL referrer = destination_server()->GetURL("/path/to/file.html");
-
-  VerifyReferrerAfterRedirect(
-      URLRequest::CLEAR_REFERRER_ON_TRANSITION_FROM_SECURE_TO_INSECURE,
-      referrer, referrer);
-
-  VerifyReferrerAfterRedirect(
-      URLRequest::REDUCE_REFERRER_GRANULARITY_ON_TRANSITION_CROSS_ORIGIN,
-      referrer, referrer.GetOrigin());
-
-  VerifyReferrerAfterRedirect(
-      URLRequest::ORIGIN_ONLY_ON_TRANSITION_CROSS_ORIGIN, referrer,
-      referrer.GetOrigin());
-
-  VerifyReferrerAfterRedirect(URLRequest::NEVER_CLEAR_REFERRER, referrer,
-                              referrer);
-
-  // The original referrer set on the request is expected to obey the referrer
-  // policy and already be stripped to the origin; thus this test case just
-  // checks that this policy doesn't cause the referrer to change when following
-  // a redirect.
-  VerifyReferrerAfterRedirect(URLRequest::ORIGIN, referrer.GetOrigin(),
-                              referrer.GetOrigin());
-
-  VerifyReferrerAfterRedirect(
-      URLRequest::CLEAR_REFERRER_ON_TRANSITION_CROSS_ORIGIN, referrer, GURL());
-
-  // The original referrer set on the request is expected to obey the referrer
-  // policy and already be stripped to the origin, though it should be
-  // subsequently cleared during the downgrading redirect.
-  VerifyReferrerAfterRedirect(
-      URLRequest::ORIGIN_CLEAR_ON_TRANSITION_FROM_SECURE_TO_INSECURE,
-      referrer.GetOrigin(), referrer.GetOrigin());
-
-  VerifyReferrerAfterRedirect(URLRequest::NO_REFERRER, GURL(), GURL());
-}
-
 class HTTPSRequestTest : public TestWithTaskEnvironment {
  public:
   HTTPSRequestTest() : default_context_(true) {
diff --git a/ppapi/proxy/pdf_resource.cc b/ppapi/proxy/pdf_resource.cc
index d96c845..cb225c5 100644
--- a/ppapi/proxy/pdf_resource.cc
+++ b/ppapi/proxy/pdf_resource.cc
@@ -226,14 +226,12 @@
   std::vector<ppapi::PdfAccessibilityLinkInfo> link_vector;
   link_vector.reserve(page_info->link_count);
   for (size_t i = 0; i < page_info->link_count; i++) {
-    ppapi::PdfAccessibilityLinkInfo link(links[i]);
-    link_vector.emplace_back(link);
+    link_vector.emplace_back(links[i]);
   }
   std::vector<ppapi::PdfAccessibilityImageInfo> image_vector;
   image_vector.reserve(page_info->image_count);
   for (size_t i = 0; i < page_info->image_count; i++) {
-    ppapi::PdfAccessibilityImageInfo image(images[i]);
-    image_vector.emplace_back(image);
+    image_vector.emplace_back(images[i]);
   }
   Post(RENDERER, PpapiHostMsg_PDF_SetAccessibilityPageInfo(
                      *page_info, text_run_vector, char_vector, link_vector,
diff --git a/services/device/generic_sensor/platform_sensor_and_provider_unittest_win.cc b/services/device/generic_sensor/platform_sensor_and_provider_unittest_win.cc
index 303f65e..d28748f 100644
--- a/services/device/generic_sensor/platform_sensor_and_provider_unittest_win.cc
+++ b/services/device/generic_sensor/platform_sensor_and_provider_unittest_win.cc
@@ -313,13 +313,16 @@
   }
 
   // Sets minimal reporting frequency for the mock sensor.
-  void SetSupportedReportingFrequency(double frequency) {
+  void SetSupportedReportingFrequency(int frequency) {
     ON_CALL(*sensor_, GetProperty(SENSOR_PROPERTY_MIN_REPORT_INTERVAL, _))
         .WillByDefault(
             Invoke([frequency](REFPROPERTYKEY key, PROPVARIANT* pProperty) {
               pProperty->vt = VT_UI4;
-              pProperty->ulVal =
-                  (1 / frequency) * base::Time::kMillisecondsPerSecond;
+              pProperty->ulVal = 0;
+              if (frequency != 0) {
+                pProperty->ulVal =
+                    (1.0 / frequency) * base::Time::kMillisecondsPerSecond;
+              }
               return S_OK;
             }));
   }
diff --git a/services/tracing/coordinator.cc b/services/tracing/coordinator.cc
index cdf9d51..225026b 100644
--- a/services/tracing/coordinator.cc
+++ b/services/tracing/coordinator.cc
@@ -23,6 +23,7 @@
 #include "base/threading/thread_task_runner_handle.h"
 #include "base/time/time.h"
 #include "base/trace_event/trace_event.h"
+#include "mojo/public/cpp/bindings/remote.h"
 #include "mojo/public/cpp/system/data_pipe_utils.h"
 #include "services/service_manager/public/cpp/bind_source_info.h"
 #include "services/service_manager/public/cpp/service_context_ref.h"
@@ -72,11 +73,12 @@
       const std::string& label,
       mojom::TraceDataType type,
       base::WeakPtr<AgentRegistry::AgentEntry> agent_entry) {
-    mojom::RecorderPtr ptr;
-    mojom::RecorderRequest request = MakeRequest(&ptr);
+    mojo::PendingRemote<mojom::Recorder> remote;
+    mojo::PendingReceiver<mojom::Recorder> receiver =
+        remote.InitWithNewPipeAndPassReceiver();
     if (processed_labels_.count(label) == 0) {
       auto recorder = std::make_unique<Recorder>(
-          std::move(request), type,
+          std::move(receiver), type,
           base::BindRepeating(&Coordinator::TraceStreamer::OnRecorderDataChange,
                               AsWeakPtr(), label));
       recorders_[label].insert(std::move(recorder));
@@ -88,7 +90,7 @@
     // from the main thread.
     main_task_runner_->PostTask(
         FROM_HERE, base::BindOnce(&Coordinator::SendRecorder, coordinator_,
-                                  agent_entry, std::move(ptr)));
+                                  agent_entry, std::move(remote)));
   }
 
   // Called from |main_task_runner_| either after flushing is complete or at
@@ -521,14 +523,15 @@
 
 void Coordinator::SendRecorder(
     base::WeakPtr<AgentRegistry::AgentEntry> agent_entry,
-    mojom::RecorderPtr recorder) {
+    mojo::PendingRemote<mojom::Recorder> recorder) {
   if (agent_entry) {
     agent_entry->agent()->StopAndFlush(std::move(recorder));
   } else {
     // Recorders are created and closed on |backend_task_runner_|.
+    mojo::Remote<mojom::Recorder> remote_recorder(std::move(recorder));
     backend_task_runner_->PostTask(
-        FROM_HERE,
-        base::BindOnce([](mojom::RecorderPtr ptr) {}, std::move(recorder)));
+        FROM_HERE, base::BindOnce([](mojo::Remote<mojom::Recorder> ptr) {},
+                                  std::move(remote_recorder)));
   }
 }
 
@@ -545,14 +548,14 @@
 
 void Coordinator::SendStopTracingWithNoOpRecorderToAgent(
     AgentRegistry::AgentEntry* agent_entry) {
-  mojom::RecorderPtr ptr;
-  // We need to create a message pipe and bind |ptr| to one end of it before
-  // sending |ptr| to the agent; otherwise, the agent will fail as soon as it
-  // tries to invoke a method on |ptr|. We do not have to bind the
-  // implementation end of the message pipe since we are going to ignore the
-  // messages.
-  MakeRequest(&ptr);
-  agent_entry->agent()->StopAndFlush(std::move(ptr));
+  mojo::PendingRemote<mojom::Recorder> pending_remote;
+  // We need to create a message pipe and bind |pending_remote| to one end of it
+  // before sending |pending_remote| to the agent; otherwise, the agent will
+  // fail as soon as it tries to invoke a method on |pending_remote|. We do not
+  // have to bind the implementation end of the message pipe since we are going
+  // to ignore the messages.
+  auto receiver = pending_remote.InitWithNewPipeAndPassReceiver();
+  agent_entry->agent()->StopAndFlush(std::move(pending_remote));
 }
 
 void Coordinator::IsTracing(IsTracingCallback callback) {
diff --git a/services/tracing/coordinator.h b/services/tracing/coordinator.h
index 5b6e42a..f0e9d7a 100644
--- a/services/tracing/coordinator.h
+++ b/services/tracing/coordinator.h
@@ -99,7 +99,7 @@
   void SendStopTracingWithNoOpRecorderToAgent(
       AgentRegistry::AgentEntry* agent_entry);
   void SendRecorder(base::WeakPtr<AgentRegistry::AgentEntry> agent_entry,
-                    mojom::RecorderPtr recorder);
+                    mojo::PendingRemote<mojom::Recorder> recorder);
   void OnFlushDone();
 
   void OnRequestBufferStatusResponse(AgentRegistry::AgentEntry* agent_entry,
diff --git a/services/tracing/public/cpp/base_agent.cc b/services/tracing/public/cpp/base_agent.cc
index 8250ead..1a2a05b 100644
--- a/services/tracing/public/cpp/base_agent.cc
+++ b/services/tracing/public/cpp/base_agent.cc
@@ -52,7 +52,8 @@
   std::move(callback).Run(true /* success */);
 }
 
-void BaseAgent::StopAndFlush(tracing::mojom::RecorderPtr recorder) {}
+void BaseAgent::StopAndFlush(
+    mojo::PendingRemote<tracing::mojom::Recorder> recorder) {}
 
 void BaseAgent::RequestBufferStatus(
     Agent::RequestBufferStatusCallback callback) {
diff --git a/services/tracing/public/cpp/base_agent.h b/services/tracing/public/cpp/base_agent.h
index 4aa86b4..81b0283e 100644
--- a/services/tracing/public/cpp/base_agent.h
+++ b/services/tracing/public/cpp/base_agent.h
@@ -39,7 +39,8 @@
   void StartTracing(const std::string& config,
                     base::TimeTicks coordinator_time,
                     Agent::StartTracingCallback callback) override;
-  void StopAndFlush(tracing::mojom::RecorderPtr recorder) override;
+  void StopAndFlush(
+      mojo::PendingRemote<tracing::mojom::Recorder> recorder) override;
   void RequestBufferStatus(
       Agent::RequestBufferStatusCallback callback) override;
 
diff --git a/services/tracing/public/cpp/trace_event_agent.cc b/services/tracing/public/cpp/trace_event_agent.cc
index d0082726..53ee5d0 100644
--- a/services/tracing/public/cpp/trace_event_agent.cc
+++ b/services/tracing/public/cpp/trace_event_agent.cc
@@ -99,11 +99,12 @@
   std::move(callback).Run(true);
 }
 
-void TraceEventAgent::StopAndFlush(mojom::RecorderPtr recorder) {
+void TraceEventAgent::StopAndFlush(
+    mojo::PendingRemote<mojom::Recorder> recorder) {
   DCHECK(!IsBoundForTesting() || !TracingUsesPerfettoBackend());
   DCHECK(!recorder_);
 
-  recorder_ = std::move(recorder);
+  recorder_.Bind(std::move(recorder));
   base::trace_event::TraceLog::GetInstance()->SetDisabled(
       enabled_tracing_modes_);
   enabled_tracing_modes_ = 0;
diff --git a/services/tracing/public/cpp/trace_event_agent.h b/services/tracing/public/cpp/trace_event_agent.h
index 0a269203..8ade16e 100644
--- a/services/tracing/public/cpp/trace_event_agent.h
+++ b/services/tracing/public/cpp/trace_event_agent.h
@@ -16,6 +16,7 @@
 #include "base/memory/weak_ptr.h"
 #include "base/threading/thread_checker.h"
 #include "base/values.h"
+#include "mojo/public/cpp/bindings/remote.h"
 #include "services/tracing/public/cpp/base_agent.h"
 #include "services/tracing/public/mojom/tracing.mojom.h"
 
@@ -52,7 +53,7 @@
   void StartTracing(const std::string& config,
                     base::TimeTicks coordinator_time,
                     StartTracingCallback callback) override;
-  void StopAndFlush(mojom::RecorderPtr recorder) override;
+  void StopAndFlush(mojo::PendingRemote<mojom::Recorder> recorder) override;
 
   void RequestBufferStatus(RequestBufferStatusCallback callback) override;
 
@@ -60,7 +61,7 @@
                        bool has_more_events);
 
   uint8_t enabled_tracing_modes_;
-  mojom::RecorderPtr recorder_;
+  mojo::Remote<mojom::Recorder> recorder_;
   std::vector<MetadataGeneratorFunction> metadata_generator_functions_;
 
   THREAD_CHECKER(thread_checker_);
diff --git a/services/tracing/public/cpp/trace_event_agent_unittest.cc b/services/tracing/public/cpp/trace_event_agent_unittest.cc
index 38c1be99..b04ec2b 100644
--- a/services/tracing/public/cpp/trace_event_agent_unittest.cc
+++ b/services/tracing/public/cpp/trace_event_agent_unittest.cc
@@ -30,9 +30,9 @@
 
 class MockRecorder : public mojom::Recorder {
  public:
-  explicit MockRecorder(mojom::RecorderRequest request)
-      : binding_(this, std::move(request)) {
-    binding_.set_connection_error_handler(base::BindRepeating(
+  explicit MockRecorder(mojo::PendingReceiver<mojom::Recorder> receiver)
+      : receiver_(this, std::move(receiver)) {
+    receiver_.set_disconnect_handler(base::BindRepeating(
         &MockRecorder::OnConnectionError, base::Unretained(this)));
   }
 
@@ -75,7 +75,7 @@
       quit_closure_.Run();
   }
 
-  mojo::Binding<mojom::Recorder> binding_;
+  mojo::Receiver<mojom::Recorder> receiver_;
   std::string events_;
   std::string metadata_;
   base::Closure quit_closure_;
@@ -98,10 +98,11 @@
   }
 
   void StopAndFlush(base::Closure quit_closure) {
-    mojom::RecorderPtr recorder_ptr;
-    recorder_.reset(new MockRecorder(MakeRequest(&recorder_ptr)));
+    mojo::PendingRemote<mojom::Recorder> recorder;
+    recorder_.reset(
+        new MockRecorder(recorder.InitWithNewPipeAndPassReceiver()));
     recorder_->set_quit_closure(quit_closure);
-    TraceEventAgent::GetInstance()->StopAndFlush(std::move(recorder_ptr));
+    TraceEventAgent::GetInstance()->StopAndFlush(std::move(recorder));
   }
 
   void AddMetadataGeneratorFunction(
diff --git a/services/tracing/public/mojom/tracing.mojom b/services/tracing/public/mojom/tracing.mojom
index c846c62..83205b3 100644
--- a/services/tracing/public/mojom/tracing.mojom
+++ b/services/tracing/public/mojom/tracing.mojom
@@ -41,7 +41,7 @@
 interface Agent {
   StartTracing(string config, mojo_base.mojom.TimeTicks coordinator_time)
       => (bool success);
-  StopAndFlush(Recorder recorder);
+  StopAndFlush(pending_remote<Recorder> recorder);
   RequestBufferStatus() => (uint32 capacity, uint32 count);
 };
 
diff --git a/services/tracing/recorder_unittest.cc b/services/tracing/recorder_unittest.cc
index 311677e7..2059673 100644
--- a/services/tracing/recorder_unittest.cc
+++ b/services/tracing/recorder_unittest.cc
@@ -25,15 +25,15 @@
     message_loop_.reset();
   }
 
-  void CreateRecorder(mojom::RecorderRequest request,
+  void CreateRecorder(mojo::PendingReceiver<mojom::Recorder> receiver,
                       mojom::TraceDataType data_type,
                       const base::Closure& callback) {
-    recorder_.reset(new Recorder(std::move(request), data_type, callback));
+    recorder_.reset(new Recorder(std::move(receiver), data_type, callback));
   }
 
   void CreateRecorder(mojom::TraceDataType data_type,
                       const base::Closure& callback) {
-    CreateRecorder(nullptr, data_type, callback);
+    CreateRecorder(mojo::NullReceiver(), data_type, callback);
   }
 
   void AddChunk(const std::string& chunk) { recorder_->AddChunk(chunk); }
@@ -116,9 +116,9 @@
   base::RunLoop run_loop;
   size_t num_calls = 0;
   {
-    mojom::RecorderPtr ptr;
-    auto request = MakeRequest(&ptr);
-    CreateRecorder(std::move(request), mojom::TraceDataType::STRING,
+    mojo::PendingRemote<mojom::Recorder> remote;
+    auto receiver = remote.InitWithNewPipeAndPassReceiver();
+    CreateRecorder(std::move(receiver), mojom::TraceDataType::STRING,
                    base::BindRepeating(
                        [](size_t* num_calls, base::Closure quit_closure) {
                          (*num_calls)++;
@@ -126,7 +126,7 @@
                        },
                        base::Unretained(&num_calls), run_loop.QuitClosure()));
   }
-  // |ptr| is deleted at this point and so the recorder should notify us that
+  // |remote| is deleted at this point and so the recorder should notify us that
   // the client is not going to send any more data by running the callback.
   run_loop.Run();
   EXPECT_EQ(1u, num_calls);
diff --git a/services/tracing/test_util.cc b/services/tracing/test_util.cc
index 94dd4c1..50e38c1106 100644
--- a/services/tracing/test_util.cc
+++ b/services/tracing/test_util.cc
@@ -7,6 +7,7 @@
 #include <string>
 #include <utility>
 
+#include "mojo/public/cpp/bindings/remote.h"
 #include "services/tracing/public/mojom/tracing.mojom.h"
 
 namespace tracing {
@@ -28,7 +29,9 @@
   std::move(cb).Run(true);
 }
 
-void MockAgent::StopAndFlush(mojom::RecorderPtr recorder) {
+void MockAgent::StopAndFlush(
+    mojo::PendingRemote<mojom::Recorder> pending_recorder) {
+  mojo::Remote<mojom::Recorder> recorder(std::move(pending_recorder));
   call_stat_.push_back("StopAndFlush");
   if (!metadata_.empty())
     recorder->AddMetadata(metadata_.Clone());
diff --git a/services/tracing/test_util.h b/services/tracing/test_util.h
index e43e051..9a0732f 100644
--- a/services/tracing/test_util.h
+++ b/services/tracing/test_util.h
@@ -40,7 +40,7 @@
   void StartTracing(const std::string& config,
                     base::TimeTicks coordinator_time,
                     StartTracingCallback cb) override;
-  void StopAndFlush(mojom::RecorderPtr recorder) override;
+  void StopAndFlush(mojo::PendingRemote<mojom::Recorder> recorder) override;
   void RequestBufferStatus(RequestBufferStatusCallback cb) override;
 
   mojo::Receiver<mojom::Agent> receiver_{this};
diff --git a/testing/buildbot/chrome.json b/testing/buildbot/chrome.json
index 897f5aca..564235f4 100644
--- a/testing/buildbot/chrome.json
+++ b/testing/buildbot/chrome.json
@@ -526,6 +526,522 @@
       }
     ]
   },
+  "chromeos-betty-pi-arc-google-rel": {
+    "additional_compile_targets": [
+      "chromiumos_preflight"
+    ],
+    "gtest_tests": [
+      {
+        "args": [
+          "--ozone-platform=headless"
+        ],
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_gtest_merge.py"
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "kvm": "1",
+              "os": "Ubuntu-16.04",
+              "pool": "chrome.tests.cros-vm"
+            }
+          ]
+        },
+        "test": "aura_unittests"
+      },
+      {
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_gtest_merge.py"
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "kvm": "1",
+              "os": "Ubuntu-16.04",
+              "pool": "chrome.tests.cros-vm"
+            }
+          ]
+        },
+        "test": "base_unittests"
+      },
+      {
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_gtest_merge.py"
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "kvm": "1",
+              "os": "Ubuntu-16.04",
+              "pool": "chrome.tests.cros-vm"
+            }
+          ]
+        },
+        "test": "cacheinvalidation_unittests"
+      },
+      {
+        "args": [
+          "--test-launcher-jobs=1",
+          "--gtest_filter=-*UsingRealWebcam_CaptureMjpeg*"
+        ],
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_gtest_merge.py"
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "kvm": "1",
+              "os": "Ubuntu-16.04",
+              "pool": "chrome.tests.cros-vm"
+            }
+          ]
+        },
+        "test": "capture_unittests"
+      },
+      {
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_gtest_merge.py"
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "kvm": "1",
+              "os": "Ubuntu-16.04",
+              "pool": "chrome.tests.cros-vm"
+            }
+          ]
+        },
+        "test": "cc_unittests"
+      },
+      {
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_gtest_merge.py"
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "kvm": "1",
+              "os": "Ubuntu-16.04",
+              "pool": "chrome.tests.cros-vm"
+            }
+          ],
+          "idempotent": false
+        },
+        "test": "chrome_all_tast_tests"
+      },
+      {
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_gtest_merge.py"
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "kvm": "1",
+              "os": "Ubuntu-16.04",
+              "pool": "chrome.tests.cros-vm"
+            }
+          ]
+        },
+        "test": "cros_browser_sanity_test"
+      },
+      {
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_gtest_merge.py"
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "kvm": "1",
+              "os": "Ubuntu-16.04",
+              "pool": "chrome.tests.cros-vm"
+            }
+          ]
+        },
+        "test": "crypto_unittests"
+      },
+      {
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_gtest_merge.py"
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "kvm": "1",
+              "os": "Ubuntu-16.04",
+              "pool": "chrome.tests.cros-vm"
+            }
+          ]
+        },
+        "test": "display_unittests"
+      },
+      {
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_gtest_merge.py"
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "kvm": "1",
+              "os": "Ubuntu-16.04",
+              "pool": "chrome.tests.cros-vm"
+            }
+          ]
+        },
+        "test": "google_apis_unittests"
+      },
+      {
+        "args": [
+          "--stop-ui",
+          "--dbus-stub",
+          "--gtest_filter=SplitViewTest.SplitViewResize"
+        ],
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_gtest_merge.py"
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "kvm": "1",
+              "os": "Ubuntu-16.04",
+              "pool": "chrome.tests.cros-vm"
+            }
+          ]
+        },
+        "test": "interactive_ui_tests"
+      },
+      {
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_gtest_merge.py"
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "kvm": "1",
+              "os": "Ubuntu-16.04",
+              "pool": "chrome.tests.cros-vm"
+            }
+          ]
+        },
+        "test": "ipc_tests"
+      },
+      {
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_gtest_merge.py"
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "kvm": "1",
+              "os": "Ubuntu-16.04",
+              "pool": "chrome.tests.cros-vm"
+            }
+          ]
+        },
+        "test": "jingle_unittests"
+      },
+      {
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_gtest_merge.py"
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "kvm": "1",
+              "os": "Ubuntu-16.04",
+              "pool": "chrome.tests.cros-vm"
+            }
+          ]
+        },
+        "test": "latency_unittests"
+      },
+      {
+        "args": [
+          "--test-launcher-filter-file=../../testing/buildbot/filters/chromeos.media_unittests.filter"
+        ],
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_gtest_merge.py"
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "kvm": "1",
+              "os": "Ubuntu-16.04",
+              "pool": "chrome.tests.cros-vm"
+            }
+          ]
+        },
+        "test": "media_unittests"
+      },
+      {
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_gtest_merge.py"
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "kvm": "1",
+              "os": "Ubuntu-16.04",
+              "pool": "chrome.tests.cros-vm"
+            }
+          ]
+        },
+        "test": "midi_unittests"
+      },
+      {
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_gtest_merge.py"
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "kvm": "1",
+              "os": "Ubuntu-16.04",
+              "pool": "chrome.tests.cros-vm"
+            }
+          ]
+        },
+        "test": "mojo_unittests"
+      },
+      {
+        "args": [
+          "--vpython-dir=../../vpython_dir_linux_amd64"
+        ],
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_gtest_merge.py"
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/luci/vpython/linux-amd64",
+              "location": "vpython_dir_linux_amd64",
+              "revision": "git_revision:9a931a5307c46b16b1c12e01e8239d4a73830b89"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "kvm": "1",
+              "os": "Ubuntu-16.04",
+              "pool": "chrome.tests.cros-vm"
+            }
+          ],
+          "shards": 3
+        },
+        "test": "net_unittests"
+      },
+      {
+        "args": [
+          "--stop-ui"
+        ],
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_gtest_merge.py"
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "kvm": "1",
+              "os": "Ubuntu-16.04",
+              "pool": "chrome.tests.cros-vm"
+            }
+          ]
+        },
+        "test": "ozone_gl_unittests"
+      },
+      {
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_gtest_merge.py"
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "kvm": "1",
+              "os": "Ubuntu-16.04",
+              "pool": "chrome.tests.cros-vm"
+            }
+          ]
+        },
+        "test": "ozone_unittests"
+      },
+      {
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_gtest_merge.py"
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "kvm": "1",
+              "os": "Ubuntu-16.04",
+              "pool": "chrome.tests.cros-vm"
+            }
+          ]
+        },
+        "test": "pdf_unittests"
+      },
+      {
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_gtest_merge.py"
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "kvm": "1",
+              "os": "Ubuntu-16.04",
+              "pool": "chrome.tests.cros-vm"
+            }
+          ]
+        },
+        "test": "printing_unittests"
+      },
+      {
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_gtest_merge.py"
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "kvm": "1",
+              "os": "Ubuntu-16.04",
+              "pool": "chrome.tests.cros-vm"
+            }
+          ]
+        },
+        "test": "sandbox_linux_unittests"
+      },
+      {
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_gtest_merge.py"
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "kvm": "1",
+              "os": "Ubuntu-16.04",
+              "pool": "chrome.tests.cros-vm"
+            }
+          ]
+        },
+        "test": "sql_unittests"
+      },
+      {
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_gtest_merge.py"
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "kvm": "1",
+              "os": "Ubuntu-16.04",
+              "pool": "chrome.tests.cros-vm"
+            }
+          ]
+        },
+        "test": "url_unittests"
+      }
+    ],
+    "isolated_scripts": [
+      {
+        "args": [
+          "--browser=cros-chrome",
+          "--remote=127.0.0.1",
+          "--remote-ssh-port=9222",
+          "--xvfb"
+        ],
+        "isolate_name": "telemetry_perf_unittests",
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
+        "name": "telemetry_perf_unittests",
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "kvm": "1",
+              "os": "Ubuntu-16.04",
+              "pool": "chrome.tests.cros-vm"
+            }
+          ],
+          "idempotent": false,
+          "shards": 6
+        }
+      },
+      {
+        "args": [
+          "--jobs=1",
+          "--browser=cros-chrome",
+          "--remote=127.0.0.1",
+          "--remote-ssh-port=9222"
+        ],
+        "isolate_name": "telemetry_unittests",
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
+        "name": "telemetry_unittests",
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "kvm": "1",
+              "os": "Ubuntu-16.04",
+              "pool": "chrome.tests.cros-vm"
+            }
+          ],
+          "idempotent": false,
+          "shards": 24
+        }
+      }
+    ]
+  },
   "chromeos-kevin-google-rel": {
     "additional_compile_targets": [
       "chromiumos_preflight"
diff --git a/testing/buildbot/chromium.clang.json b/testing/buildbot/chromium.clang.json
index ec4ab2f72..b52c9e3 100644
--- a/testing/buildbot/chromium.clang.json
+++ b/testing/buildbot/chromium.clang.json
@@ -11105,7 +11105,7 @@
       },
       {
         "args": [
-          "--enable-features=VizDisplayCompositor,UseSkiaRenderer",
+          "--enable-features=UseSkiaRenderer",
           "--test-launcher-filter-file=../../testing/buildbot/filters/skia_renderer.content_browsertests.filter"
         ],
         "merge": {
@@ -12582,7 +12582,7 @@
       },
       {
         "args": [
-          "--enable-features=VizDisplayCompositor,UseSkiaRenderer",
+          "--enable-features=UseSkiaRenderer",
           "--test-launcher-filter-file=../../testing/buildbot/filters/skia_renderer.content_browsertests.filter",
           "--test-launcher-print-test-stdio=always"
         ],
@@ -14157,7 +14157,7 @@
       },
       {
         "args": [
-          "--enable-features=VizDisplayCompositor,UseSkiaRenderer",
+          "--enable-features=UseSkiaRenderer",
           "--test-launcher-filter-file=../../testing/buildbot/filters/skia_renderer.content_browsertests.filter"
         ],
         "merge": {
@@ -15539,7 +15539,7 @@
       },
       {
         "args": [
-          "--enable-features=VizDisplayCompositor,UseSkiaRenderer",
+          "--enable-features=UseSkiaRenderer",
           "--test-launcher-filter-file=../../testing/buildbot/filters/skia_renderer.content_browsertests.filter"
         ],
         "merge": {
@@ -16923,7 +16923,7 @@
       },
       {
         "args": [
-          "--enable-features=VizDisplayCompositor,UseSkiaRenderer",
+          "--enable-features=UseSkiaRenderer",
           "--test-launcher-filter-file=../../testing/buildbot/filters/skia_renderer.content_browsertests.filter"
         ],
         "merge": {
@@ -18307,7 +18307,7 @@
       },
       {
         "args": [
-          "--enable-features=VizDisplayCompositor,UseSkiaRenderer",
+          "--enable-features=UseSkiaRenderer",
           "--test-launcher-filter-file=../../testing/buildbot/filters/skia_renderer.content_browsertests.filter"
         ],
         "merge": {
@@ -19707,7 +19707,7 @@
       },
       {
         "args": [
-          "--enable-features=VizDisplayCompositor,UseSkiaRenderer",
+          "--enable-features=UseSkiaRenderer",
           "--test-launcher-filter-file=../../testing/buildbot/filters/skia_renderer.content_browsertests.filter"
         ],
         "merge": {
@@ -37425,7 +37425,7 @@
       },
       {
         "args": [
-          "--enable-features=VizDisplayCompositor,UseSkiaRenderer",
+          "--enable-features=UseSkiaRenderer",
           "--test-launcher-filter-file=../../testing/buildbot/filters/skia_renderer.content_browsertests.filter"
         ],
         "merge": {
diff --git a/testing/buildbot/chromium.fyi.json b/testing/buildbot/chromium.fyi.json
index 9be031ce..efa27148 100644
--- a/testing/buildbot/chromium.fyi.json
+++ b/testing/buildbot/chromium.fyi.json
@@ -60,7 +60,7 @@
     "gtest_tests": [
       {
         "args": [
-          "--enable-features=VizDisplayCompositor,UseSkiaRenderer",
+          "--enable-features=UseSkiaRenderer",
           "--test-launcher-filter-file=../../testing/buildbot/filters/skia_renderer.browser_tests.filter"
         ],
         "merge": {
@@ -81,7 +81,7 @@
       },
       {
         "args": [
-          "--enable-features=VizDisplayCompositor,UseSkiaRenderer"
+          "--enable-features=UseSkiaRenderer"
         ],
         "merge": {
           "args": [],
@@ -105,7 +105,7 @@
           "--test-launcher-bot-mode",
           "--test-launcher-jobs=1",
           "--test-launcher-filter-file=../../testing/buildbot/filters/vulkan.content_browsertests.filter",
-          "--enable-features=VizDisplayCompositor,UseSkiaRenderer,UiGpuRasterization",
+          "--enable-features=UseSkiaRenderer,UiGpuRasterization",
           "--use-vulkan=swiftshader",
           "--enable-oop-rasterization",
           "--enable-gpu-rasterization",
@@ -135,7 +135,7 @@
         "args": [
           "--num-retries=3",
           "--additional-driver-flag=--enable-gpu-rasterization",
-          "--additional-driver-flag=--enable-features=VizDisplayCompositor,UseSkiaRenderer",
+          "--additional-driver-flag=--enable-features=UseSkiaRenderer",
           "--additional-driver-flag=--use-gl=swiftshader",
           "--additional-driver-flag=--force-gpu-rasterization",
           "--additional-driver-flag=--enable-oop-rasterization",
@@ -168,7 +168,7 @@
         "args": [
           "--num-retries=3",
           "--additional-driver-flag=--enable-gpu-rasterization",
-          "--additional-driver-flag=--enable-features=VizDisplayCompositor,UseSkiaRenderer",
+          "--additional-driver-flag=--enable-features=UseSkiaRenderer",
           "--additional-driver-flag=--force-gpu-rasterization",
           "--additional-driver-flag=--enable-oop-rasterization",
           "--additional-driver-flag=--use-vulkan=swiftshader",
@@ -508,6 +508,51 @@
       },
       {
         "args": [
+          "--gs-results-bucket=chromium-result-details",
+          "--recover-devices"
+        ],
+        "merge": {
+          "args": [
+            "--bucket",
+            "chromium-result-details",
+            "--test-name",
+            "weblayer_instrumentation_test_apk"
+          ],
+          "script": "//build/android/pylib/results/presentation/test_results_presentation.py"
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
+              "location": "bin",
+              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "device_os": "MMB29Q",
+              "device_os_type": "userdebug",
+              "device_type": "bullhead",
+              "os": "Android"
+            }
+          ],
+          "hard_timeout": 3600,
+          "output_links": [
+            {
+              "link": [
+                "https://luci-logdog.appspot.com/v/?s",
+                "=android%2Fswarming%2Flogcats%2F",
+                "${TASK_ID}%2F%2B%2Funified_logcats"
+              ],
+              "name": "shard #${SHARD_INDEX} logcats"
+            }
+          ]
+        },
+        "test": "weblayer_instrumentation_test_apk"
+      },
+      {
+        "args": [
           "--enable-features=NetworkService,NetworkServiceInProcess",
           "--test-launcher-filter-file=../../testing/buildbot/filters/mojo.fyi.network_webview_instrumentation_test_apk.filter",
           "--gs-results-bucket=chromium-result-details",
@@ -7708,6 +7753,50 @@
       },
       {
         "args": [
+          "--gs-results-bucket=chromium-result-details",
+          "--recover-devices"
+        ],
+        "merge": {
+          "args": [
+            "--bucket",
+            "chromium-result-details",
+            "--test-name",
+            "weblayer_instrumentation_test_apk"
+          ],
+          "script": "//build/android/pylib/results/presentation/test_results_presentation.py"
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
+              "location": "bin",
+              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "device_os": "MMB29Q",
+              "device_os_type": "userdebug",
+              "device_type": "bullhead",
+              "os": "Android"
+            }
+          ],
+          "output_links": [
+            {
+              "link": [
+                "https://luci-logdog.appspot.com/v/?s",
+                "=android%2Fswarming%2Flogcats%2F",
+                "${TASK_ID}%2F%2B%2Funified_logcats"
+              ],
+              "name": "shard #${SHARD_INDEX} logcats"
+            }
+          ]
+        },
+        "test": "weblayer_instrumentation_test_apk"
+      },
+      {
+        "args": [
           "--enable-features=NetworkService,NetworkServiceInProcess",
           "--test-launcher-filter-file=../../testing/buildbot/filters/mojo.fyi.network_webview_instrumentation_test_apk.filter",
           "--gs-results-bucket=chromium-result-details",
@@ -8582,6 +8671,25 @@
       },
       {
         "args": [
+          "--test-launcher-filter-file=../../testing/buildbot/filters/fuchsia.components_unittests.filter"
+        ],
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_gtest_merge.py"
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "cpu": "arm64",
+              "os": "Ubuntu-16.04"
+            }
+          ]
+        },
+        "test": "components_unittests"
+      },
+      {
+        "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/fuchsia.content_unittests.filter"
         ],
         "merge": {
@@ -9100,6 +9208,25 @@
       },
       {
         "args": [
+          "--test-launcher-filter-file=../../testing/buildbot/filters/fuchsia.components_unittests.filter"
+        ],
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_gtest_merge.py"
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "kvm": "1",
+              "os": "Ubuntu-16.04"
+            }
+          ]
+        },
+        "test": "components_unittests"
+      },
+      {
+        "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/fuchsia.content_unittests.filter"
         ],
         "merge": {
@@ -9618,6 +9745,25 @@
       },
       {
         "args": [
+          "--test-launcher-filter-file=../../testing/buildbot/filters/fuchsia.components_unittests.filter"
+        ],
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_gtest_merge.py"
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "kvm": "1",
+              "os": "Ubuntu-16.04"
+            }
+          ]
+        },
+        "test": "components_unittests"
+      },
+      {
+        "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/fuchsia.content_unittests.filter"
         ],
         "merge": {
@@ -14540,7 +14686,7 @@
       },
       {
         "args": [
-          "--enable-features=VizDisplayCompositor,UseSkiaRenderer",
+          "--enable-features=UseSkiaRenderer",
           "--test-launcher-filter-file=../../testing/buildbot/filters/skia_renderer.content_browsertests.filter"
         ],
         "merge": {
@@ -15705,7 +15851,7 @@
         "args": [
           "--num-retries=3",
           "--additional-driver-flag=--enable-gpu-rasterization",
-          "--additional-driver-flag=--enable-features=VizDisplayCompositor,UseSkiaRenderer",
+          "--additional-driver-flag=--enable-features=UseSkiaRenderer",
           "--additional-driver-flag=--use-gl=swiftshader",
           "--additional-driver-flag=--force-gpu-rasterization",
           "--additional-driver-flag=--enable-oop-rasterization",
@@ -15820,7 +15966,7 @@
         "args": [
           "--num-retries=3",
           "--additional-driver-flag=--enable-gpu-rasterization",
-          "--additional-driver-flag=--enable-features=VizDisplayCompositor,UseSkiaRenderer",
+          "--additional-driver-flag=--enable-features=UseSkiaRenderer",
           "--additional-driver-flag=--force-gpu-rasterization",
           "--additional-driver-flag=--enable-oop-rasterization",
           "--additional-driver-flag=--use-vulkan=swiftshader",
diff --git a/testing/buildbot/chromium.gpu.fyi.json b/testing/buildbot/chromium.gpu.fyi.json
index 7722a5e1..4aa93ad 100644
--- a/testing/buildbot/chromium.gpu.fyi.json
+++ b/testing/buildbot/chromium.gpu.fyi.json
@@ -6802,7 +6802,7 @@
           "--browser=android-chromium",
           "--passthrough",
           "-v",
-          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc --enable-features=VizDisplayCompositor,UseSkiaRenderer"
+          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc --enable-features=UseSkiaRenderer"
         ],
         "isolate_name": "telemetry_gpu_integration_test",
         "merge": {
@@ -6832,7 +6832,7 @@
           "--browser=android-chromium",
           "--passthrough",
           "-v",
-          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc --enable-features=VizDisplayCompositor,UseSkiaRenderer"
+          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc --enable-features=UseSkiaRenderer"
         ],
         "isolate_name": "telemetry_gpu_integration_test",
         "merge": {
@@ -6862,7 +6862,7 @@
           "--browser=android-chromium",
           "--passthrough",
           "-v",
-          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc --enable-features=VizDisplayCompositor,UseSkiaRenderer"
+          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc --enable-features=UseSkiaRenderer"
         ],
         "isolate_name": "telemetry_gpu_integration_test",
         "merge": {
@@ -6892,7 +6892,7 @@
           "--browser=android-chromium",
           "--passthrough",
           "-v",
-          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc --enable-features=VizDisplayCompositor,UseSkiaRenderer"
+          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc --enable-features=UseSkiaRenderer"
         ],
         "isolate_name": "telemetry_gpu_integration_test",
         "merge": {
@@ -6922,7 +6922,7 @@
           "--browser=android-chromium",
           "--passthrough",
           "-v",
-          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc --enable-features=VizDisplayCompositor,UseSkiaRenderer",
+          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc --enable-features=UseSkiaRenderer",
           "--dont-restore-color-profile-after-test",
           "--os-type",
           "android",
@@ -6959,7 +6959,7 @@
           "--browser=android-chromium",
           "--passthrough",
           "-v",
-          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc --enable-features=VizDisplayCompositor,UseSkiaRenderer",
+          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc --enable-features=UseSkiaRenderer",
           "--dont-restore-color-profile-after-test"
         ],
         "isolate_name": "telemetry_gpu_integration_test",
@@ -6990,7 +6990,7 @@
           "--browser=android-chromium",
           "--passthrough",
           "-v",
-          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc --enable-features=VizDisplayCompositor,UseSkiaRenderer",
+          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc --enable-features=UseSkiaRenderer",
           "--dont-restore-color-profile-after-test",
           "--os-type",
           "android",
@@ -7090,7 +7090,7 @@
           "--browser=android-chromium",
           "--passthrough",
           "-v",
-          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc --use-vulkan=native --disable-vulkan-fallback-to-gl-for-testing --enable-features=VizDisplayCompositor,UseSkiaRenderer --disable-software-compositing-fallback",
+          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc --use-vulkan=native --disable-vulkan-fallback-to-gl-for-testing --enable-features=UseSkiaRenderer --disable-software-compositing-fallback",
           "--dont-restore-color-profile-after-test",
           "--os-type",
           "android",
@@ -10409,7 +10409,7 @@
           "--test-launcher-bot-mode",
           "--test-launcher-jobs=1",
           "--test-launcher-filter-file=../../testing/buildbot/filters/vulkan.content_browsertests.filter",
-          "--enable-features=VizDisplayCompositor,UseSkiaRenderer,UiGpuRasterization",
+          "--enable-features=UseSkiaRenderer,UiGpuRasterization",
           "--use-vulkan=native",
           "--enable-oop-rasterization",
           "--enable-gpu-rasterization",
@@ -10529,7 +10529,7 @@
           "--browser=release",
           "--passthrough",
           "-v",
-          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc --enable-features=VizDisplayCompositor,UseSkiaRenderer"
+          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc --enable-features=UseSkiaRenderer"
         ],
         "isolate_name": "telemetry_gpu_integration_test",
         "merge": {
@@ -10558,7 +10558,7 @@
           "--browser=release",
           "--passthrough",
           "-v",
-          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc --enable-features=VizDisplayCompositor,UseSkiaRenderer"
+          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc --enable-features=UseSkiaRenderer"
         ],
         "isolate_name": "telemetry_gpu_integration_test",
         "merge": {
@@ -10587,7 +10587,7 @@
           "--browser=release",
           "--passthrough",
           "-v",
-          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc --enable-features=VizDisplayCompositor,UseSkiaRenderer"
+          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc --enable-features=UseSkiaRenderer"
         ],
         "isolate_name": "telemetry_gpu_integration_test",
         "merge": {
@@ -10616,7 +10616,7 @@
           "--browser=release",
           "--passthrough",
           "-v",
-          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc --enable-features=VizDisplayCompositor,UseSkiaRenderer"
+          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc --enable-features=UseSkiaRenderer"
         ],
         "isolate_name": "telemetry_gpu_integration_test",
         "merge": {
@@ -10645,7 +10645,7 @@
           "--browser=release",
           "--passthrough",
           "-v",
-          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc --enable-features=VizDisplayCompositor,UseSkiaRenderer",
+          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc --enable-features=UseSkiaRenderer",
           "--dont-restore-color-profile-after-test",
           "--os-type",
           "linux",
@@ -10681,7 +10681,7 @@
           "--browser=release",
           "--passthrough",
           "-v",
-          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc --enable-features=VizDisplayCompositor,UseSkiaRenderer",
+          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc --enable-features=UseSkiaRenderer",
           "--dont-restore-color-profile-after-test"
         ],
         "isolate_name": "telemetry_gpu_integration_test",
@@ -10708,7 +10708,7 @@
         "args": [
           "--num-retries=3",
           "--additional-driver-flag=--enable-gpu-rasterization",
-          "--additional-driver-flag=--enable-features=VizDisplayCompositor,UseSkiaRenderer",
+          "--additional-driver-flag=--enable-features=UseSkiaRenderer",
           "--additional-driver-flag=--use-gl=any",
           "--additional-driver-flag=--force-gpu-rasterization",
           "--additional-driver-flag=--enable-oop-rasterization",
@@ -10750,7 +10750,7 @@
           "--browser=release",
           "--passthrough",
           "-v",
-          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc --enable-features=VizDisplayCompositor,UseSkiaRenderer",
+          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc --enable-features=UseSkiaRenderer",
           "--dont-restore-color-profile-after-test",
           "--os-type",
           "linux",
@@ -10793,7 +10793,7 @@
         "args": [
           "--num-retries=3",
           "--additional-driver-flag=--enable-gpu-rasterization",
-          "--additional-driver-flag=--enable-features=VizDisplayCompositor,UseSkiaRenderer",
+          "--additional-driver-flag=--enable-features=UseSkiaRenderer",
           "--additional-driver-flag=--use-gl=any",
           "--additional-driver-flag=--force-gpu-rasterization",
           "--additional-driver-flag=--enable-oop-rasterization",
@@ -10837,7 +10837,7 @@
           "--browser=release",
           "--passthrough",
           "-v",
-          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc --use-vulkan=native --disable-vulkan-fallback-to-gl-for-testing --enable-features=VizDisplayCompositor,UseSkiaRenderer --disable-software-compositing-fallback",
+          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc --use-vulkan=native --disable-vulkan-fallback-to-gl-for-testing --enable-features=UseSkiaRenderer --disable-software-compositing-fallback",
           "--dont-restore-color-profile-after-test",
           "--os-type",
           "linux",
@@ -10955,7 +10955,7 @@
           "--test-launcher-bot-mode",
           "--test-launcher-jobs=1",
           "--test-launcher-filter-file=../../testing/buildbot/filters/vulkan.content_browsertests.filter",
-          "--enable-features=VizDisplayCompositor,UseSkiaRenderer,UiGpuRasterization",
+          "--enable-features=UseSkiaRenderer,UiGpuRasterization",
           "--use-vulkan=native",
           "--enable-oop-rasterization",
           "--enable-gpu-rasterization",
@@ -11075,7 +11075,7 @@
           "--browser=release",
           "--passthrough",
           "-v",
-          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc --enable-features=VizDisplayCompositor,UseSkiaRenderer"
+          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc --enable-features=UseSkiaRenderer"
         ],
         "isolate_name": "telemetry_gpu_integration_test",
         "merge": {
@@ -11104,7 +11104,7 @@
           "--browser=release",
           "--passthrough",
           "-v",
-          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc --enable-features=VizDisplayCompositor,UseSkiaRenderer"
+          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc --enable-features=UseSkiaRenderer"
         ],
         "isolate_name": "telemetry_gpu_integration_test",
         "merge": {
@@ -11133,7 +11133,7 @@
           "--browser=release",
           "--passthrough",
           "-v",
-          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc --enable-features=VizDisplayCompositor,UseSkiaRenderer"
+          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc --enable-features=UseSkiaRenderer"
         ],
         "isolate_name": "telemetry_gpu_integration_test",
         "merge": {
@@ -11162,7 +11162,7 @@
           "--browser=release",
           "--passthrough",
           "-v",
-          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc --enable-features=VizDisplayCompositor,UseSkiaRenderer"
+          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc --enable-features=UseSkiaRenderer"
         ],
         "isolate_name": "telemetry_gpu_integration_test",
         "merge": {
@@ -11191,7 +11191,7 @@
           "--browser=release",
           "--passthrough",
           "-v",
-          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc --enable-features=VizDisplayCompositor,UseSkiaRenderer",
+          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc --enable-features=UseSkiaRenderer",
           "--dont-restore-color-profile-after-test",
           "--os-type",
           "linux",
@@ -11227,7 +11227,7 @@
           "--browser=release",
           "--passthrough",
           "-v",
-          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc --enable-features=VizDisplayCompositor,UseSkiaRenderer",
+          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc --enable-features=UseSkiaRenderer",
           "--dont-restore-color-profile-after-test"
         ],
         "isolate_name": "telemetry_gpu_integration_test",
@@ -11254,7 +11254,7 @@
         "args": [
           "--num-retries=3",
           "--additional-driver-flag=--enable-gpu-rasterization",
-          "--additional-driver-flag=--enable-features=VizDisplayCompositor,UseSkiaRenderer",
+          "--additional-driver-flag=--enable-features=UseSkiaRenderer",
           "--additional-driver-flag=--use-gl=any",
           "--additional-driver-flag=--force-gpu-rasterization",
           "--additional-driver-flag=--enable-oop-rasterization",
@@ -11296,7 +11296,7 @@
           "--browser=release",
           "--passthrough",
           "-v",
-          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc --enable-features=VizDisplayCompositor,UseSkiaRenderer",
+          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc --enable-features=UseSkiaRenderer",
           "--dont-restore-color-profile-after-test",
           "--os-type",
           "linux",
@@ -11339,7 +11339,7 @@
         "args": [
           "--num-retries=3",
           "--additional-driver-flag=--enable-gpu-rasterization",
-          "--additional-driver-flag=--enable-features=VizDisplayCompositor,UseSkiaRenderer",
+          "--additional-driver-flag=--enable-features=UseSkiaRenderer",
           "--additional-driver-flag=--use-gl=any",
           "--additional-driver-flag=--force-gpu-rasterization",
           "--additional-driver-flag=--enable-oop-rasterization",
@@ -11383,7 +11383,7 @@
           "--browser=release",
           "--passthrough",
           "-v",
-          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc --use-vulkan=native --disable-vulkan-fallback-to-gl-for-testing --enable-features=VizDisplayCompositor,UseSkiaRenderer --disable-software-compositing-fallback",
+          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc --use-vulkan=native --disable-vulkan-fallback-to-gl-for-testing --enable-features=UseSkiaRenderer --disable-software-compositing-fallback",
           "--dont-restore-color-profile-after-test",
           "--os-type",
           "linux",
@@ -11748,7 +11748,7 @@
           "dimension_sets": [
             {
               "gpu": "1002:6821",
-              "os": "Mac-10.14.4",
+              "os": "Mac-10.14.6",
               "pool": "Chrome-GPU"
             }
           ],
@@ -11773,7 +11773,7 @@
           "dimension_sets": [
             {
               "gpu": "1002:6821",
-              "os": "Mac-10.14.4",
+              "os": "Mac-10.14.6",
               "pool": "Chrome-GPU"
             }
           ],
@@ -11799,7 +11799,7 @@
           "dimension_sets": [
             {
               "gpu": "1002:6821",
-              "os": "Mac-10.14.4",
+              "os": "Mac-10.14.6",
               "pool": "Chrome-GPU"
             }
           ],
@@ -11822,7 +11822,7 @@
           "dimension_sets": [
             {
               "gpu": "1002:6821",
-              "os": "Mac-10.14.4",
+              "os": "Mac-10.14.6",
               "pool": "Chrome-GPU"
             }
           ],
@@ -11844,7 +11844,7 @@
           "dimension_sets": [
             {
               "gpu": "1002:6821",
-              "os": "Mac-10.14.4",
+              "os": "Mac-10.14.6",
               "pool": "Chrome-GPU"
             }
           ],
@@ -11866,7 +11866,7 @@
           "dimension_sets": [
             {
               "gpu": "1002:6821",
-              "os": "Mac-10.14.4",
+              "os": "Mac-10.14.6",
               "pool": "Chrome-GPU"
             }
           ],
@@ -11885,7 +11885,7 @@
           "dimension_sets": [
             {
               "gpu": "1002:6821",
-              "os": "Mac-10.14.4",
+              "os": "Mac-10.14.6",
               "pool": "Chrome-GPU"
             }
           ],
@@ -11908,7 +11908,7 @@
           "dimension_sets": [
             {
               "gpu": "1002:6821",
-              "os": "Mac-10.14.4",
+              "os": "Mac-10.14.6",
               "pool": "Chrome-GPU"
             }
           ],
@@ -11927,7 +11927,7 @@
           "dimension_sets": [
             {
               "gpu": "1002:6821",
-              "os": "Mac-10.14.4",
+              "os": "Mac-10.14.6",
               "pool": "Chrome-GPU"
             }
           ],
@@ -11959,7 +11959,7 @@
           "dimension_sets": [
             {
               "gpu": "1002:6821",
-              "os": "Mac-10.14.4",
+              "os": "Mac-10.14.6",
               "pool": "Chrome-GPU"
             }
           ],
@@ -11989,7 +11989,7 @@
           "dimension_sets": [
             {
               "gpu": "1002:6821",
-              "os": "Mac-10.14.4",
+              "os": "Mac-10.14.6",
               "pool": "Chrome-GPU"
             }
           ],
@@ -12019,7 +12019,7 @@
           "dimension_sets": [
             {
               "gpu": "1002:6821",
-              "os": "Mac-10.14.4",
+              "os": "Mac-10.14.6",
               "pool": "Chrome-GPU"
             }
           ],
@@ -12049,7 +12049,7 @@
           "dimension_sets": [
             {
               "gpu": "1002:6821",
-              "os": "Mac-10.14.4",
+              "os": "Mac-10.14.6",
               "pool": "Chrome-GPU"
             }
           ],
@@ -12083,7 +12083,7 @@
           "dimension_sets": [
             {
               "gpu": "1002:6821",
-              "os": "Mac-10.14.4",
+              "os": "Mac-10.14.6",
               "pool": "Chrome-GPU"
             }
           ],
@@ -12120,7 +12120,7 @@
           "dimension_sets": [
             {
               "gpu": "1002:6821",
-              "os": "Mac-10.14.4",
+              "os": "Mac-10.14.6",
               "pool": "Chrome-GPU"
             }
           ],
@@ -12165,7 +12165,7 @@
           "dimension_sets": [
             {
               "gpu": "1002:6821",
-              "os": "Mac-10.14.4",
+              "os": "Mac-10.14.6",
               "pool": "Chrome-GPU"
             }
           ],
@@ -12197,7 +12197,7 @@
           "dimension_sets": [
             {
               "gpu": "1002:6821",
-              "os": "Mac-10.14.4",
+              "os": "Mac-10.14.6",
               "pool": "Chrome-GPU"
             }
           ],
@@ -12227,7 +12227,7 @@
           "dimension_sets": [
             {
               "gpu": "1002:6821",
-              "os": "Mac-10.14.4",
+              "os": "Mac-10.14.6",
               "pool": "Chrome-GPU"
             }
           ],
@@ -12259,7 +12259,7 @@
           "dimension_sets": [
             {
               "gpu": "1002:6821",
-              "os": "Mac-10.14.4",
+              "os": "Mac-10.14.6",
               "pool": "Chrome-GPU"
             }
           ],
@@ -12290,7 +12290,7 @@
           "dimension_sets": [
             {
               "gpu": "1002:6821",
-              "os": "Mac-10.14.4",
+              "os": "Mac-10.14.6",
               "pool": "Chrome-GPU"
             }
           ],
@@ -12321,7 +12321,7 @@
           "dimension_sets": [
             {
               "gpu": "1002:6821",
-              "os": "Mac-10.14.4",
+              "os": "Mac-10.14.6",
               "pool": "Chrome-GPU"
             }
           ],
@@ -12350,7 +12350,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:0a2e",
-              "os": "Mac-10.14.4",
+              "os": "Mac-10.14.6",
               "pool": "Chrome-GPU"
             }
           ],
@@ -12375,7 +12375,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:0a2e",
-              "os": "Mac-10.14.4",
+              "os": "Mac-10.14.6",
               "pool": "Chrome-GPU"
             }
           ],
@@ -12401,7 +12401,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:0a2e",
-              "os": "Mac-10.14.4",
+              "os": "Mac-10.14.6",
               "pool": "Chrome-GPU"
             }
           ],
@@ -12424,7 +12424,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:0a2e",
-              "os": "Mac-10.14.4",
+              "os": "Mac-10.14.6",
               "pool": "Chrome-GPU"
             }
           ],
@@ -12446,7 +12446,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:0a2e",
-              "os": "Mac-10.14.4",
+              "os": "Mac-10.14.6",
               "pool": "Chrome-GPU"
             }
           ],
@@ -12468,7 +12468,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:0a2e",
-              "os": "Mac-10.14.4",
+              "os": "Mac-10.14.6",
               "pool": "Chrome-GPU"
             }
           ],
@@ -12487,7 +12487,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:0a2e",
-              "os": "Mac-10.14.4",
+              "os": "Mac-10.14.6",
               "pool": "Chrome-GPU"
             }
           ],
@@ -12510,7 +12510,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:0a2e",
-              "os": "Mac-10.14.4",
+              "os": "Mac-10.14.6",
               "pool": "Chrome-GPU"
             }
           ],
@@ -12529,7 +12529,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:0a2e",
-              "os": "Mac-10.14.4",
+              "os": "Mac-10.14.6",
               "pool": "Chrome-GPU"
             }
           ],
@@ -12561,7 +12561,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:0a2e",
-              "os": "Mac-10.14.4",
+              "os": "Mac-10.14.6",
               "pool": "Chrome-GPU"
             }
           ],
@@ -12591,7 +12591,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:0a2e",
-              "os": "Mac-10.14.4",
+              "os": "Mac-10.14.6",
               "pool": "Chrome-GPU"
             }
           ],
@@ -12621,7 +12621,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:0a2e",
-              "os": "Mac-10.14.4",
+              "os": "Mac-10.14.6",
               "pool": "Chrome-GPU"
             }
           ],
@@ -12651,7 +12651,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:0a2e",
-              "os": "Mac-10.14.4",
+              "os": "Mac-10.14.6",
               "pool": "Chrome-GPU"
             }
           ],
@@ -12685,7 +12685,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:0a2e",
-              "os": "Mac-10.14.4",
+              "os": "Mac-10.14.6",
               "pool": "Chrome-GPU"
             }
           ],
@@ -12722,7 +12722,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:0a2e",
-              "os": "Mac-10.14.4",
+              "os": "Mac-10.14.6",
               "pool": "Chrome-GPU"
             }
           ],
@@ -12767,7 +12767,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:0a2e",
-              "os": "Mac-10.14.4",
+              "os": "Mac-10.14.6",
               "pool": "Chrome-GPU"
             }
           ],
@@ -12799,7 +12799,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:0a2e",
-              "os": "Mac-10.14.4",
+              "os": "Mac-10.14.6",
               "pool": "Chrome-GPU"
             }
           ],
@@ -12829,7 +12829,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:0a2e",
-              "os": "Mac-10.14.4",
+              "os": "Mac-10.14.6",
               "pool": "Chrome-GPU"
             }
           ],
@@ -12861,7 +12861,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:0a2e",
-              "os": "Mac-10.14.4",
+              "os": "Mac-10.14.6",
               "pool": "Chrome-GPU"
             }
           ],
@@ -12892,7 +12892,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:0a2e",
-              "os": "Mac-10.14.4",
+              "os": "Mac-10.14.6",
               "pool": "Chrome-GPU"
             }
           ],
@@ -12923,7 +12923,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:0a2e",
-              "os": "Mac-10.14.4",
+              "os": "Mac-10.14.6",
               "pool": "Chrome-GPU"
             }
           ],
@@ -12952,7 +12952,7 @@
           "dimension_sets": [
             {
               "gpu": "10de:0fe9",
-              "os": "Mac-10.14.4",
+              "os": "Mac-10.14.6",
               "pool": "Chrome-GPU"
             }
           ],
@@ -12977,7 +12977,7 @@
           "dimension_sets": [
             {
               "gpu": "10de:0fe9",
-              "os": "Mac-10.14.4",
+              "os": "Mac-10.14.6",
               "pool": "Chrome-GPU"
             }
           ],
@@ -13003,7 +13003,7 @@
           "dimension_sets": [
             {
               "gpu": "10de:0fe9",
-              "os": "Mac-10.14.4",
+              "os": "Mac-10.14.6",
               "pool": "Chrome-GPU"
             }
           ],
@@ -13026,7 +13026,7 @@
           "dimension_sets": [
             {
               "gpu": "10de:0fe9",
-              "os": "Mac-10.14.4",
+              "os": "Mac-10.14.6",
               "pool": "Chrome-GPU"
             }
           ],
@@ -13048,7 +13048,7 @@
           "dimension_sets": [
             {
               "gpu": "10de:0fe9",
-              "os": "Mac-10.14.4",
+              "os": "Mac-10.14.6",
               "pool": "Chrome-GPU"
             }
           ],
@@ -13070,7 +13070,7 @@
           "dimension_sets": [
             {
               "gpu": "10de:0fe9",
-              "os": "Mac-10.14.4",
+              "os": "Mac-10.14.6",
               "pool": "Chrome-GPU"
             }
           ],
@@ -13089,7 +13089,7 @@
           "dimension_sets": [
             {
               "gpu": "10de:0fe9",
-              "os": "Mac-10.14.4",
+              "os": "Mac-10.14.6",
               "pool": "Chrome-GPU"
             }
           ],
@@ -13112,7 +13112,7 @@
           "dimension_sets": [
             {
               "gpu": "10de:0fe9",
-              "os": "Mac-10.14.4",
+              "os": "Mac-10.14.6",
               "pool": "Chrome-GPU"
             }
           ],
@@ -13131,7 +13131,7 @@
           "dimension_sets": [
             {
               "gpu": "10de:0fe9",
-              "os": "Mac-10.14.4",
+              "os": "Mac-10.14.6",
               "pool": "Chrome-GPU"
             }
           ],
@@ -13163,7 +13163,7 @@
           "dimension_sets": [
             {
               "gpu": "10de:0fe9",
-              "os": "Mac-10.14.4",
+              "os": "Mac-10.14.6",
               "pool": "Chrome-GPU"
             }
           ],
@@ -13193,7 +13193,7 @@
           "dimension_sets": [
             {
               "gpu": "10de:0fe9",
-              "os": "Mac-10.14.4",
+              "os": "Mac-10.14.6",
               "pool": "Chrome-GPU"
             }
           ],
@@ -13223,7 +13223,7 @@
           "dimension_sets": [
             {
               "gpu": "10de:0fe9",
-              "os": "Mac-10.14.4",
+              "os": "Mac-10.14.6",
               "pool": "Chrome-GPU"
             }
           ],
@@ -13253,7 +13253,7 @@
           "dimension_sets": [
             {
               "gpu": "10de:0fe9",
-              "os": "Mac-10.14.4",
+              "os": "Mac-10.14.6",
               "pool": "Chrome-GPU"
             }
           ],
@@ -13287,7 +13287,7 @@
           "dimension_sets": [
             {
               "gpu": "10de:0fe9",
-              "os": "Mac-10.14.4",
+              "os": "Mac-10.14.6",
               "pool": "Chrome-GPU"
             }
           ],
@@ -13324,7 +13324,7 @@
           "dimension_sets": [
             {
               "gpu": "10de:0fe9",
-              "os": "Mac-10.14.4",
+              "os": "Mac-10.14.6",
               "pool": "Chrome-GPU"
             }
           ],
@@ -13369,7 +13369,7 @@
           "dimension_sets": [
             {
               "gpu": "10de:0fe9",
-              "os": "Mac-10.14.4",
+              "os": "Mac-10.14.6",
               "pool": "Chrome-GPU"
             }
           ],
@@ -13401,7 +13401,7 @@
           "dimension_sets": [
             {
               "gpu": "10de:0fe9",
-              "os": "Mac-10.14.4",
+              "os": "Mac-10.14.6",
               "pool": "Chrome-GPU"
             }
           ],
@@ -13431,7 +13431,7 @@
           "dimension_sets": [
             {
               "gpu": "10de:0fe9",
-              "os": "Mac-10.14.4",
+              "os": "Mac-10.14.6",
               "pool": "Chrome-GPU"
             }
           ],
@@ -13463,7 +13463,7 @@
           "dimension_sets": [
             {
               "gpu": "10de:0fe9",
-              "os": "Mac-10.14.4",
+              "os": "Mac-10.14.6",
               "pool": "Chrome-GPU"
             }
           ],
@@ -13494,7 +13494,7 @@
           "dimension_sets": [
             {
               "gpu": "10de:0fe9",
-              "os": "Mac-10.14.4",
+              "os": "Mac-10.14.6",
               "pool": "Chrome-GPU"
             }
           ],
@@ -13525,7 +13525,7 @@
           "dimension_sets": [
             {
               "gpu": "10de:0fe9",
-              "os": "Mac-10.14.4",
+              "os": "Mac-10.14.6",
               "pool": "Chrome-GPU"
             }
           ],
diff --git a/testing/buildbot/chromium.linux.json b/testing/buildbot/chromium.linux.json
index b793bb1..3ce4057 100644
--- a/testing/buildbot/chromium.linux.json
+++ b/testing/buildbot/chromium.linux.json
@@ -2670,7 +2670,7 @@
       },
       {
         "args": [
-          "--enable-features=VizDisplayCompositor,UseSkiaRenderer",
+          "--enable-features=UseSkiaRenderer",
           "--test-launcher-filter-file=../../testing/buildbot/filters/skia_renderer.content_browsertests.filter"
         ],
         "isolate_coverage_data": true,
@@ -3911,7 +3911,7 @@
         "args": [
           "--num-retries=3",
           "--additional-driver-flag=--enable-gpu-rasterization",
-          "--additional-driver-flag=--enable-features=VizDisplayCompositor,UseSkiaRenderer",
+          "--additional-driver-flag=--enable-features=UseSkiaRenderer",
           "--additional-driver-flag=--use-gl=swiftshader",
           "--additional-driver-flag=--force-gpu-rasterization",
           "--additional-driver-flag=--enable-oop-rasterization",
@@ -4031,7 +4031,7 @@
         "args": [
           "--num-retries=3",
           "--additional-driver-flag=--enable-gpu-rasterization",
-          "--additional-driver-flag=--enable-features=VizDisplayCompositor,UseSkiaRenderer",
+          "--additional-driver-flag=--enable-features=UseSkiaRenderer",
           "--additional-driver-flag=--force-gpu-rasterization",
           "--additional-driver-flag=--enable-oop-rasterization",
           "--additional-driver-flag=--use-vulkan=swiftshader",
@@ -4531,7 +4531,7 @@
       },
       {
         "args": [
-          "--enable-features=VizDisplayCompositor,UseSkiaRenderer",
+          "--enable-features=UseSkiaRenderer",
           "--test-launcher-filter-file=../../testing/buildbot/filters/skia_renderer.content_browsertests.filter"
         ],
         "merge": {
@@ -6302,7 +6302,7 @@
       },
       {
         "args": [
-          "--enable-features=VizDisplayCompositor,UseSkiaRenderer",
+          "--enable-features=UseSkiaRenderer",
           "--test-launcher-filter-file=../../testing/buildbot/filters/skia_renderer.content_browsertests.filter"
         ],
         "merge": {
@@ -7467,7 +7467,7 @@
         "args": [
           "--num-retries=3",
           "--additional-driver-flag=--enable-gpu-rasterization",
-          "--additional-driver-flag=--enable-features=VizDisplayCompositor,UseSkiaRenderer",
+          "--additional-driver-flag=--enable-features=UseSkiaRenderer",
           "--additional-driver-flag=--use-gl=swiftshader",
           "--additional-driver-flag=--force-gpu-rasterization",
           "--additional-driver-flag=--enable-oop-rasterization",
@@ -7582,7 +7582,7 @@
         "args": [
           "--num-retries=3",
           "--additional-driver-flag=--enable-gpu-rasterization",
-          "--additional-driver-flag=--enable-features=VizDisplayCompositor,UseSkiaRenderer",
+          "--additional-driver-flag=--enable-features=UseSkiaRenderer",
           "--additional-driver-flag=--force-gpu-rasterization",
           "--additional-driver-flag=--enable-oop-rasterization",
           "--additional-driver-flag=--use-vulkan=swiftshader",
diff --git a/testing/buildbot/chromium.memory.json b/testing/buildbot/chromium.memory.json
index ce82193..280fab6 100644
--- a/testing/buildbot/chromium.memory.json
+++ b/testing/buildbot/chromium.memory.json
@@ -11996,7 +11996,7 @@
           "--test-launcher-bot-mode",
           "--test-launcher-jobs=1",
           "--test-launcher-filter-file=../../testing/buildbot/filters/vulkan.content_browsertests.filter",
-          "--enable-features=VizDisplayCompositor,UseSkiaRenderer,UiGpuRasterization",
+          "--enable-features=UseSkiaRenderer,UiGpuRasterization",
           "--use-vulkan=swiftshader",
           "--enable-oop-rasterization",
           "--enable-gpu-rasterization",
diff --git a/testing/buildbot/filters/fuchsia.components_unittests.filter b/testing/buildbot/filters/fuchsia.components_unittests.filter
new file mode 100644
index 0000000..488d609
--- /dev/null
+++ b/testing/buildbot/filters/fuchsia.components_unittests.filter
@@ -0,0 +1,14 @@
+-PersonalDataManagerTest*
+-RemoteSuggestionsProviderImplTest.*
+-S2LangQuadTreeDataTest.TreeContainsDataRank*
+-SecurityStateContentUtilsTest.*
+-ShortcutsProviderTest.*
+-SimpleJsonStringSchemaValidatingPolicyHandlerTest.*
+-SyncBookmarkDataTypeControllerTest.*
+-SyncedBookmarkTrackerTest.*
+-TranslateManagerTest.*
+-TranslatePrefsTest.*
+-TranslateUIDelegateTest.*
+-URLBlacklistPolicyHandlerTest.CheckPolicySettings_*
+-USS/AutofillWalletSyncBridge.MergeSyncData_*
+-ZeroSuggestProviderTest.*
diff --git a/testing/buildbot/filters/gpu.skiarenderer_vulkan_blink_web_tests.filter b/testing/buildbot/filters/gpu.skiarenderer_vulkan_blink_web_tests.filter
index 0929d01..dae5021 100644
--- a/testing/buildbot/filters/gpu.skiarenderer_vulkan_blink_web_tests.filter
+++ b/testing/buildbot/filters/gpu.skiarenderer_vulkan_blink_web_tests.filter
@@ -346,6 +346,36 @@
 images/rendering-broken-block-flow-images.html
 transforms/transformed-document-element.html
 
+# One portion of the image is offset. crbug.com/1002522
+fast/canvas/canvas-toDataURL-webp.html
+
+# Blurring is not pixelated. crbug.com/1002525
+fast/canvas/pixelated.html
+
+# OffscreenCanvas not rendering. crbug.com/1002538
+fast/canvas/OffscreenCanvas-2d-drawImage-in-worker.html
+fast/canvas/OffscreenCanvas-2d-drawImage.html
+fast/canvas/OffscreenCanvas-2d-gradients-in-worker.html
+fast/canvas/OffscreenCanvas-2d-imageSmoothing-in-worker.html
+fast/canvas/OffscreenCanvas-2d-imageSmoothing.html
+fast/canvas/OffscreenCanvas-2d-pattern-in-worker.html
+fast/canvas/OffscreenCanvas-2d-pattern.html
+fast/canvas/OffscreenCanvas-Bitmaprenderer-TransferToImageBitmapResetsToBlack.html
+fast/canvas/OffscreenCanvas-clearRect-in-worker.html
+fast/canvas/OffscreenCanvas-fillRect-in-worker.html
+fast/canvas/OffscreenCanvas-filter-in-worker.html
+fast/canvas/OffscreenCanvas-paths-in-worker.html
+fast/canvas/OffscreenCanvas-strokeRect-in-worker.html
+fast/canvas/OffscreenCanvas-text-FontFace-in-worker.html
+fast/canvas/OffscreenCanvas-text-rendering-in-worker.html
+fast/canvas/OffscreenCanvas-transform-shadow-in-worker.html
+
+# Failing with empty image. crbug.com/1002547
+fast/canvas/imagebitmap/transferFromImageBitmap-alpha.html
+fast/canvas/imagebitmap/transferFromImageBitmap-no-alpha.html
+fast/canvas/imagebitmap/transferFromImageBitmap.html
+
+
 ##### End of Known Tests #####
 # The following is a set of randomly selected tests from a subset of folders:
 # animations, compositing, css2.1, css3, images, media, transforms; which are
@@ -649,6 +679,81 @@
 css3/viewport-percentage-lengths/css3-viewport-percentage-lengths-vmax-absolute.html
 css3/viewport-percentage-lengths/viewport-percentage-lengths-page-zoom.html
 cssom/elementfrompoint-scrolloffset.html
+fast/canvas/2d.fillText.gradient.html
+fast/canvas/2d.text.draw.fill.maxWidth.gradient.html
+fast/canvas/OffscreenCanvas-2d-drawImage-no-context.html
+fast/canvas/OffscreenCanvas-BitmapRenderer-TransferToWithEmptyBitmap.html
+fast/canvas/OffscreenCanvas-Bitmaprenderer-DrawImage.html
+fast/canvas/OffscreenCanvas-Bitmaprenderer-toBlob-worker.html
+fast/canvas/OffscreenCanvas-Bitmaprenderer-toBlob.html
+fast/canvas/OffscreenCanvas-empty-image-source.html
+fast/canvas/bidi-multi-run.html
+fast/canvas/bug412718.html
+fast/canvas/bug532148.html
+fast/canvas/canvas-after-destroy-iframe.html
+fast/canvas/canvas-arc-circumference-fill.html
+fast/canvas/canvas-arc-circumference.html
+fast/canvas/canvas-blend-solid.html
+fast/canvas/canvas-blending-fill-style.html
+fast/canvas/canvas-blending-gradient-over-color.html
+fast/canvas/canvas-blending-gradient-over-pattern.html
+fast/canvas/canvas-clip-rule.html
+fast/canvas/canvas-clip-stack-persistence.html
+fast/canvas/canvas-composite-video-shadow.html
+fast/canvas/canvas-composite-video.html
+fast/canvas/canvas-composite.html
+fast/canvas/canvas-createImageBitmap-drawImage.html
+fast/canvas/canvas-drawImage-antiAlias.html
+fast/canvas/canvas-drawImage-out-of-bounds-src.html
+fast/canvas/canvas-fill-zeroSizeGradient.html
+fast/canvas/canvas-fillPath-gradient-shadow.html
+fast/canvas/canvas-fillPath-pattern-shadow.html
+fast/canvas/canvas-fillStyle-strokeStyle-stringification.html
+fast/canvas/canvas-filter-fill-liveness.html
+fast/canvas/canvas-filter-frameless-document.html
+fast/canvas/canvas-filter-liveness.html
+fast/canvas/canvas-filter-shadow.html
+fast/canvas/canvas-filter-stroke-paint-pattern.html
+fast/canvas/canvas-filter-units-ex.html
+fast/canvas/canvas-frameless-document-text.html
+fast/canvas/canvas-gradient-without-path.html
+fast/canvas/canvas-hidpi-blurry.html
+fast/canvas/canvas-incremental-repaint-2.html
+fast/canvas/canvas-partial-invalidation-zoomed.html
+fast/canvas/canvas-path-context-clip.html
+fast/canvas/canvas-path-non-invertible-transform.html
+fast/canvas/canvas-pattern-transform.html
+fast/canvas/canvas-pattern-video.html
+fast/canvas/canvas-putImageData.html
+fast/canvas/canvas-resize-reset.html
+fast/canvas/canvas-scale-strokePath-shadow.html
+fast/canvas/canvas-state-stack-simple.html
+fast/canvas/canvas-stroke-empty-fill.html
+fast/canvas/canvas-stroke-zeroSizeGradient.html
+fast/canvas/canvas-strokePath-alpha-shadow.html
+fast/canvas/canvas-strokeRect-zeroSizeGradient.html
+fast/canvas/canvas-toBlob-jpeg-maximum-quality.html
+fast/canvas/canvas-toBlob-oversized.html
+fast/canvas/canvas-toBlob-toDataURL-race-imageEncoder-png.html
+fast/canvas/canvas-toDataURL-bitmaprenderer.html
+fast/canvas/canvas-transform-nan.html
+fast/canvas/canvas-transform-skewed.html
+fast/canvas/canvas-transforms-fillRect-shadow.html
+fast/canvas/canvas-unbalanced-save.html
+fast/canvas/canvas-zero-length-lineCap.html
+fast/canvas/color-space/ImageData-fidelity.html
+fast/canvas/color-space/canvas-colorManaged-convertToBlob-roundtrip.html
+fast/canvas/color-space/canvas-createImageBitmap-p3.html
+fast/canvas/color-space/canvas-getImageData-rec2020.html
+fast/canvas/color-space/transferFromImageBitmap.html
+fast/canvas/drawImage-with-globalAlpha.html
+fast/canvas/feimage-with-foreignobject-taint-canvas.html
+fast/canvas/gradient-add-second-start-end-stop.html
+fast/canvas/image-object-in-canvas.html
+fast/canvas/imagebitmap/transferFromImageBitmap-nullability.html
+fast/canvas/shadow-huge-blur.html
+fast/canvas/toDataURL-alpha.html
+fast/canvas/translate-text.html
 images/12-55.html
 images/color-profile-background-clip-text.html
 images/color-profile-image-svg-resource-url.html
diff --git a/testing/buildbot/generate_buildbot_json.py b/testing/buildbot/generate_buildbot_json.py
index eaae5520..bb6471f 100755
--- a/testing/buildbot/generate_buildbot_json.py
+++ b/testing/buildbot/generate_buildbot_json.py
@@ -1050,6 +1050,7 @@
       # Defined in internal configs.
       'chromeos-amd64-generic-google-rel',
       'chromeos-betty-google-rel',
+      'chromeos-betty-pi-arc-google-rel',
       'chromeos-kevin-google-rel',
       # code coverage, see https://crbug.com/1000367.
       'linux-chromeos-coverage-rel-dummy',
diff --git a/testing/buildbot/gn_isolate_map.pyl b/testing/buildbot/gn_isolate_map.pyl
index ff7e949..3591963 100644
--- a/testing/buildbot/gn_isolate_map.pyl
+++ b/testing/buildbot/gn_isolate_map.pyl
@@ -3008,6 +3008,10 @@
     "label": "//android_webview/tools/automated_ui_tests:webview_ui_test_app_test_apk",
     "type": "console_test_launcher",
   },
+  "weblayer_instrumentation_test_apk": {
+    "label": "//weblayer/shell/android:weblayer_instrumentation_test_apk",
+    "type": "console_test_launcher",
+  },
   "weblayer_shell": {
     "label": "//weblayer/shell/android:run_weblayer_shell",
     "type": "additional_compile_target",
diff --git a/testing/buildbot/mixins.pyl b/testing/buildbot/mixins.pyl
index 62b3e3e5..6864becd 100644
--- a/testing/buildbot/mixins.pyl
+++ b/testing/buildbot/mixins.pyl
@@ -382,10 +382,10 @@
       },
     },
   },
-  'mac_10.14.4': {
+  'mac_10.14.6': {
     'swarming': {
       'dimensions': {
-        'os': 'Mac-10.14.4',
+        'os': 'Mac-10.14.6',
       },
     },
   },
diff --git a/testing/buildbot/test_suite_exceptions.pyl b/testing/buildbot/test_suite_exceptions.pyl
index dc1998f4..e654111 100644
--- a/testing/buildbot/test_suite_exceptions.pyl
+++ b/testing/buildbot/test_suite_exceptions.pyl
@@ -386,6 +386,10 @@
         },
       },
     },
+    'remove_from': [
+      # chromium.linux
+      'Fuchsia x64', # https://crbug.com/961457
+    ]
   },
   'content_browsertests': {
     'remove_from': [
diff --git a/testing/buildbot/test_suites.pyl b/testing/buildbot/test_suites.pyl
index da10d52..a0a36ed 100644
--- a/testing/buildbot/test_suites.pyl
+++ b/testing/buildbot/test_suites.pyl
@@ -2803,6 +2803,11 @@
       'cast_runner_browsertests': {},
       'cast_runner_integration_tests': {},
       'cast_runner_unittests': {},
+      'components_unittests': {
+        'args': [
+          '--test-launcher-filter-file=../../testing/buildbot/filters/fuchsia.components_unittests.filter',
+        ],
+      },
       'content_unittests': {
         'args': [
           '--test-launcher-filter-file=../../testing/buildbot/filters/fuchsia.content_unittests.filter',
@@ -3288,7 +3293,7 @@
         'args': [
           '--num-retries=3',
           '--additional-driver-flag=--enable-gpu-rasterization',
-          '--additional-driver-flag=--enable-features=VizDisplayCompositor,UseSkiaRenderer',
+          '--additional-driver-flag=--enable-features=UseSkiaRenderer',
           '--additional-driver-flag=--use-gl=any',
           '--additional-driver-flag=--force-gpu-rasterization',
           '--additional-driver-flag=--enable-oop-rasterization',
@@ -3321,7 +3326,7 @@
         'args': [
           '--num-retries=3',
           '--additional-driver-flag=--enable-gpu-rasterization',
-          '--additional-driver-flag=--enable-features=VizDisplayCompositor,UseSkiaRenderer',
+          '--additional-driver-flag=--enable-features=UseSkiaRenderer',
           '--additional-driver-flag=--use-gl=any',
           '--additional-driver-flag=--force-gpu-rasterization',
           '--additional-driver-flag=--enable-oop-rasterization',
@@ -3600,7 +3605,7 @@
           '--test-launcher-bot-mode',
           '--test-launcher-jobs=1',
           '--test-launcher-filter-file=../../testing/buildbot/filters/vulkan.content_browsertests.filter',
-          '--enable-features=VizDisplayCompositor,UseSkiaRenderer,UiGpuRasterization',
+          '--enable-features=UseSkiaRenderer,UiGpuRasterization',
           '--use-vulkan=native',
           '--enable-oop-rasterization',
           '--enable-gpu-rasterization',
@@ -3621,7 +3626,7 @@
           '--test-launcher-bot-mode',
           '--test-launcher-jobs=1',
           '--test-launcher-filter-file=../../testing/buildbot/filters/vulkan.content_browsertests.filter',
-          '--enable-features=VizDisplayCompositor,UseSkiaRenderer,UiGpuRasterization',
+          '--enable-features=UseSkiaRenderer,UiGpuRasterization',
           '--use-vulkan=swiftshader',
           '--enable-oop-rasterization',
           '--enable-gpu-rasterization',
@@ -3698,7 +3703,7 @@
           '${got_revision}',
           '--test-machine-name',
           '${buildername}',
-          '--extra-browser-args=--enable-features=VizDisplayCompositor,UseSkiaRenderer',
+          '--extra-browser-args=--enable-features=UseSkiaRenderer',
         ],
         'precommit_args': [
           # Gerrit issue ID
@@ -3719,23 +3724,23 @@
       },
       'context_lost': {
         'args': [
-          '--extra-browser-args=--enable-features=VizDisplayCompositor,UseSkiaRenderer',
+          '--extra-browser-args=--enable-features=UseSkiaRenderer',
         ],
       },
       'depth_capture': {
         'args': [
-          '--extra-browser-args=--enable-features=VizDisplayCompositor,UseSkiaRenderer',
+          '--extra-browser-args=--enable-features=UseSkiaRenderer',
         ],
       },
       'gpu_process': {
         'name': 'gpu_process_launch_tests',
         'args': [
-          '--extra-browser-args=--enable-features=VizDisplayCompositor,UseSkiaRenderer',
+          '--extra-browser-args=--enable-features=UseSkiaRenderer',
         ],
       },
       'hardware_accelerated_feature': {
         'args': [
-          '--extra-browser-args=--enable-features=VizDisplayCompositor,UseSkiaRenderer',
+          '--extra-browser-args=--enable-features=UseSkiaRenderer',
         ],
       },
       'maps': {
@@ -3748,13 +3753,13 @@
           '${got_revision}',
           '--test-machine-name',
           '${buildername}',
-          '--extra-browser-args=--enable-features=VizDisplayCompositor,UseSkiaRenderer',
+          '--extra-browser-args=--enable-features=UseSkiaRenderer',
         ],
       },
       'screenshot_sync': {
         'args': [
           '--dont-restore-color-profile-after-test',
-          '--extra-browser-args=--enable-features=VizDisplayCompositor,UseSkiaRenderer',
+          '--extra-browser-args=--enable-features=UseSkiaRenderer',
         ],
       },
     },
@@ -3793,7 +3798,7 @@
           '${got_revision}',
           '--test-machine-name',
           '${buildername}',
-          '--extra-browser-args=--use-vulkan=native --disable-vulkan-fallback-to-gl-for-testing --enable-features=VizDisplayCompositor,UseSkiaRenderer --disable-software-compositing-fallback',
+          '--extra-browser-args=--use-vulkan=native --disable-vulkan-fallback-to-gl-for-testing --enable-features=UseSkiaRenderer --disable-software-compositing-fallback',
         ],
         'precommit_args': [
           # Gerrit issue ID
@@ -4632,7 +4637,7 @@
     'skia_renderer_fyi_gtests': {
       'skia_renderer_browser_tests': {
         'args': [
-          '--enable-features=VizDisplayCompositor,UseSkiaRenderer',
+          '--enable-features=UseSkiaRenderer',
           '--test-launcher-filter-file=../../testing/buildbot/filters/skia_renderer.browser_tests.filter',
         ],
         'swarming': {
@@ -4642,7 +4647,7 @@
       },
       'skia_renderer_content_browsertests': {
         'args': [
-          '--enable-features=VizDisplayCompositor,UseSkiaRenderer',
+          '--enable-features=UseSkiaRenderer',
         ],
         'swarming': {
           'shards': 2,
@@ -4654,7 +4659,7 @@
     'skia_renderer_gtests': {
       'skia_renderer_content_browsertests': {
         'args': [
-          '--enable-features=VizDisplayCompositor,UseSkiaRenderer',
+          '--enable-features=UseSkiaRenderer',
           '--test-launcher-filter-file=../../testing/buildbot/filters/skia_renderer.content_browsertests.filter',
         ],
         'swarming': {
@@ -4672,7 +4677,7 @@
         'args': [
           '--num-retries=3',
           '--additional-driver-flag=--enable-gpu-rasterization',
-          '--additional-driver-flag=--enable-features=VizDisplayCompositor,UseSkiaRenderer',
+          '--additional-driver-flag=--enable-features=UseSkiaRenderer',
           '--additional-driver-flag=--use-gl=swiftshader',
           '--additional-driver-flag=--force-gpu-rasterization',
           '--additional-driver-flag=--enable-oop-rasterization',
@@ -4699,7 +4704,7 @@
         'args': [
           '--num-retries=3',
           '--additional-driver-flag=--enable-gpu-rasterization',
-          '--additional-driver-flag=--enable-features=VizDisplayCompositor,UseSkiaRenderer',
+          '--additional-driver-flag=--enable-features=UseSkiaRenderer',
           '--additional-driver-flag=--force-gpu-rasterization',
           '--additional-driver-flag=--enable-oop-rasterization',
           '--additional-driver-flag=--use-vulkan=swiftshader',
@@ -4800,6 +4805,11 @@
       'vr_pixeltests': {},
     },
 
+    'weblayer_android_gtests': {
+      'weblayer_instrumentation_test_apk': {
+      },
+    },
+
     # TODO(crbug.com/888429): Port remaining WebRTC tests to swarming.
     'webrtc_chromium_baremetal_gtests': {
       # Run capture unittests as well since our bots have real webcams.
@@ -5761,6 +5771,7 @@
 
     'mojo_android_gtests': [
       'network_service_android_gtests',
+      'weblayer_android_gtests',
     ],
 
     'mojo_chromiumos_fyi_gtests': [
diff --git a/testing/buildbot/waterfalls.pyl b/testing/buildbot/waterfalls.pyl
index 156e8705c..4b52638 100644
--- a/testing/buildbot/waterfalls.pyl
+++ b/testing/buildbot/waterfalls.pyl
@@ -35,6 +35,24 @@
           ],
         },
       },
+      'chromeos-betty-pi-arc-google-rel': {
+        'additional_compile_targets': [
+          'chromiumos_preflight',
+        ],
+        'test_suites': {
+          'gtest_tests': 'chromeos_device_friendly_gtests',
+          'isolated_scripts': 'chromeos_isolated_scripts',
+        },
+        'swarming': {
+          'dimension_sets': [
+            {
+              'kvm': '1',
+              'os': 'Ubuntu-16.04',
+              'pool': 'chrome.tests.cros-vm',
+            },
+          ],
+        },
+      },
       'chromeos-kevin-google-rel': {
         'additional_compile_targets': [
           'chromiumos_preflight',
@@ -2786,7 +2804,7 @@
           'amd_8870m',
           'gpu_pool',
           'limited_capacity_bot',
-          'mac_10.14.4',
+          'mac_10.14.6',
         ],
         'test_suites': {
           'gtest_tests': 'gpu_fyi_mac_release_gtests',
@@ -2800,7 +2818,7 @@
           'gpu_pool',
           'intel_iris_5100',
           'limited_capacity_bot',
-          'mac_10.14.4',
+          'mac_10.14.6',
         ],
         'test_suites': {
           'gtest_tests': 'gpu_fyi_mac_release_gtests',
@@ -2812,7 +2830,7 @@
         'browser_config': 'release',
         'mixins': [
           'gpu_pool',
-          'mac_10.14.4',
+          'mac_10.14.6',
           'limited_capacity_bot',
           'nvidia_750m_mac_edition',
         ],
diff --git a/testing/variations/fieldtrial_testing_config.json b/testing/variations/fieldtrial_testing_config.json
index 15b18b8..1d9af21 100644
--- a/testing/variations/fieldtrial_testing_config.json
+++ b/testing/variations/fieldtrial_testing_config.json
@@ -4309,6 +4309,25 @@
             ]
         }
     ],
+    "PerNavigationMojoInterface": [
+        {
+            "platforms": [
+                "chromeos",
+                "linux",
+                "mac",
+                "windows",
+                "android"
+            ],
+            "experiments": [
+                {
+                    "name": "PerNavigationMojoInterface",
+                    "enable_features": [
+                        "PerNavigationMojoInterface"
+                    ]
+                }
+            ]
+        }
+    ],
     "PerProcessReclaim": [
         {
             "platforms": [
diff --git a/third_party/blink/public/mojom/web_feature/web_feature.mojom b/third_party/blink/public/mojom/web_feature/web_feature.mojom
index beefe48..77863a54 100644
--- a/third_party/blink/public/mojom/web_feature/web_feature.mojom
+++ b/third_party/blink/public/mojom/web_feature/web_feature.mojom
@@ -2413,6 +2413,7 @@
   kDelegateFocus = 3030,
   kDelegateFocusNotFirstInFlatTree = 3031,
   kThirdPartySharedWorker = 3032,
+  kThirdPartyBroadcastChannel = 3033,
 
   // 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/blink/public/web/web_security_policy.h b/third_party/blink/public/web/web_security_policy.h
index 6e1a9e11..fb3b59c 100644
--- a/third_party/blink/public/web/web_security_policy.h
+++ b/third_party/blink/public/web/web_security_policy.h
@@ -34,7 +34,6 @@
 #include "services/network/public/mojom/cors_origin_pattern.mojom-shared.h"
 #include "services/network/public/mojom/referrer_policy.mojom-shared.h"
 #include "third_party/blink/public/platform/web_common.h"
-#include "third_party/blink/public/platform/web_security_origin.h"
 
 namespace blink {
 
@@ -109,7 +108,6 @@
   // referrer header should be omitted.
   BLINK_EXPORT static WebString GenerateReferrerHeader(
       network::mojom::ReferrerPolicy,
-      const WebSecurityOrigin& origin,
       const WebURL&,
       const WebString& referrer);
 
diff --git a/third_party/blink/renderer/core/accessibility/apply_dark_mode.cc b/third_party/blink/renderer/core/accessibility/apply_dark_mode.cc
index e2abd92d..12068983 100644
--- a/third_party/blink/renderer/core/accessibility/apply_dark_mode.cc
+++ b/third_party/blink/renderer/core/accessibility/apply_dark_mode.cc
@@ -39,16 +39,16 @@
          kBrightnessThreshold;
 }
 
-DarkMode GetMode(const Settings& frame_settings) {
+DarkModeInversionAlgorithm GetMode(const Settings& frame_settings) {
   switch (features::kForceDarkInversionMethodParam.Get()) {
     case ForceDarkInversionMethod::kUseBlinkSettings:
-      return frame_settings.GetDarkMode();
+      return frame_settings.GetDarkModeInversionAlgorithm();
     case ForceDarkInversionMethod::kCielabBased:
-      return DarkMode::kInvertLightnessLAB;
+      return DarkModeInversionAlgorithm::kInvertLightnessLAB;
     case ForceDarkInversionMethod::kHslBased:
-      return DarkMode::kInvertLightness;
+      return DarkModeInversionAlgorithm::kInvertLightness;
     case ForceDarkInversionMethod::kRgbBased:
-      return DarkMode::kInvertBrightness;
+      return DarkModeInversionAlgorithm::kInvertBrightness;
   }
 }
 
@@ -118,7 +118,7 @@
 const DarkModeSettings& GetCachedDisabledSettings() {
   static const DarkModeSettings* settings = new DarkModeSettings([]() {
     DarkModeSettings settings;
-    settings.mode = DarkMode::kOff;
+    settings.mode = DarkModeInversionAlgorithm::kOff;
     settings.image_policy = DarkModeImagePolicy::kFilterNone;
     return settings;
   }());
diff --git a/third_party/blink/renderer/core/exported/web_security_policy.cc b/third_party/blink/renderer/core/exported/web_security_policy.cc
index 7af0bca..1e69f21 100644
--- a/third_party/blink/renderer/core/exported/web_security_policy.cc
+++ b/third_party/blink/renderer/core/exported/web_security_policy.cc
@@ -117,11 +117,9 @@
 
 WebString WebSecurityPolicy::GenerateReferrerHeader(
     network::mojom::ReferrerPolicy referrer_policy,
-    const WebSecurityOrigin& origin,
     const WebURL& url,
     const WebString& referrer) {
-  return SecurityPolicy::GenerateReferrer(referrer_policy, origin, url,
-                                          referrer)
+  return SecurityPolicy::GenerateReferrer(referrer_policy, url, referrer)
       .referrer;
 }
 
diff --git a/third_party/blink/renderer/core/frame/local_dom_window.cc b/third_party/blink/renderer/core/frame/local_dom_window.cc
index d3f23b0..ed6afc8 100644
--- a/third_party/blink/renderer/core/frame/local_dom_window.cc
+++ b/third_party/blink/renderer/core/frame/local_dom_window.cc
@@ -1507,12 +1507,9 @@
   // ensure the proper referrer is set now.
   // TODO(domfarolino): Stop setting ResourceRequest's HTTP Referrer and store
   // this is a separate member. See https://crbug.com/850813.
-  const SecurityOrigin* origin =
-      active_document ? active_document->GetSecurityOrigin()
-                      : SecurityOrigin::Create(completed_url).get();
   frame_request.GetResourceRequest().SetHttpReferrer(
       SecurityPolicy::GenerateReferrer(
-          active_document->GetReferrerPolicy(), origin, completed_url,
+          active_document->GetReferrerPolicy(), completed_url,
           window_features.noreferrer ? Referrer::NoReferrer()
                                      : active_document->OutgoingReferrer()));
 
diff --git a/third_party/blink/renderer/core/frame/local_frame_view.cc b/third_party/blink/renderer/core/frame/local_frame_view.cc
index c10dd68..920aff1f 100644
--- a/third_party/blink/renderer/core/frame/local_frame_view.cc
+++ b/third_party/blink/renderer/core/frame/local_frame_view.cc
@@ -242,7 +242,8 @@
       layout_count_for_testing_(0),
       lifecycle_update_count_for_testing_(0),
       nested_layout_count_(0),
-      update_plugins_timer_(frame.GetTaskRunner(TaskType::kInternalDefault),
+      // We want plugin updates to happen in FIFO order with loading tasks.
+      update_plugins_timer_(frame.GetTaskRunner(TaskType::kInternalLoading),
                             this,
                             &LocalFrameView::UpdatePluginsTimerFired),
       first_layout_(true),
diff --git a/third_party/blink/renderer/core/frame/settings.cc b/third_party/blink/renderer/core/frame/settings.cc
index 875f17e..90fa96b 100644
--- a/third_party/blink/renderer/core/frame/settings.cc
+++ b/third_party/blink/renderer/core/frame/settings.cc
@@ -109,10 +109,11 @@
   force_dark_mode_ = enabled;
 
   if (force_dark_mode_) {
-    SetDarkMode(DarkMode::kInvertLightnessLAB);
+    SetDarkModeInversionAlgorithm(
+        DarkModeInversionAlgorithm::kInvertLightnessLAB);
     SetDarkModeImagePolicy(DarkModeImagePolicy::kFilterSmart);
   } else {
-    SetDarkMode(DarkMode::kOff);
+    SetDarkModeInversionAlgorithm(DarkModeInversionAlgorithm::kOff);
   }
   Invalidate(SettingsDelegate::kColorSchemeChange);
 }
diff --git a/third_party/blink/renderer/core/frame/settings.json5 b/third_party/blink/renderer/core/frame/settings.json5
index ffd1b30..3f13f65 100644
--- a/third_party/blink/renderer/core/frame/settings.json5
+++ b/third_party/blink/renderer/core/frame/settings.json5
@@ -883,9 +883,9 @@
     // Dark mode
     //
     {
-      name: "darkMode",
-      initial: "DarkMode::kOff",
-      type: "DarkMode",
+      name: "darkModeInversionAlgorithm",
+      initial: "DarkModeInversionAlgorithm::kOff",
+      type: "DarkModeInversionAlgorithm",
       invalidate: "Paint",
     },
     {
diff --git a/third_party/blink/renderer/core/html/portal/portal_contents.cc b/third_party/blink/renderer/core/html/portal/portal_contents.cc
index 03a4f29..a90b7c8 100644
--- a/third_party/blink/renderer/core/html/portal/portal_contents.cc
+++ b/third_party/blink/renderer/core/html/portal/portal_contents.cc
@@ -97,8 +97,7 @@
   if (referrer_policy_to_use == network::mojom::ReferrerPolicy::kDefault)
     referrer_policy_to_use = GetDocument().GetReferrerPolicy();
   Referrer referrer = SecurityPolicy::GenerateReferrer(
-      referrer_policy_to_use, GetDocument().GetSecurityOrigin(), url,
-      GetDocument().OutgoingReferrer());
+      referrer_policy_to_use, url, GetDocument().OutgoingReferrer());
   auto mojo_referrer = mojom::blink::Referrer::New(
       KURL(NullURL(), referrer.referrer), referrer.referrer_policy);
 
diff --git a/third_party/blink/renderer/core/loader/document_loader.cc b/third_party/blink/renderer/core/loader/document_loader.cc
index b49df08..afc7f2d 100644
--- a/third_party/blink/renderer/core/loader/document_loader.cc
+++ b/third_party/blink/renderer/core/loader/document_loader.cc
@@ -497,12 +497,8 @@
     history_item_ = MakeGarbageCollected<HistoryItem>();
 
   history_item_->SetURL(UrlForHistory());
-  scoped_refptr<const SecurityOrigin> origin =
-      requestor_origin_ ? requestor_origin_
-                        : SecurityOrigin::CreateUniqueOpaque();
   history_item_->SetReferrer(SecurityPolicy::GenerateReferrer(
-      referrer_.referrer_policy, origin, history_item_->Url(),
-      referrer_.referrer));
+      referrer_.referrer_policy, history_item_->Url(), referrer_.referrer));
   if (DeprecatedEqualIgnoringCase(http_method_, "POST")) {
     // FIXME: Eventually we have to make this smart enough to handle the case
     // where we have a stream for the body to handle the "data interspersed with
@@ -982,8 +978,9 @@
 
   // If we have a provisional request for a different document, a fragment
   // scroll should cancel it.
+  // Note: see fragment-change-does-not-cancel-pending-navigation, where
+  // this does not actually happen.
   GetFrameLoader().DetachProvisionalDocumentLoader();
-  GetFrameLoader().CancelClientNavigation();
   GetFrameLoader().DidFinishNavigation(
       FrameLoader::NavigationFinishState::kSuccess);
 
diff --git a/third_party/blink/renderer/core/loader/frame_load_request.cc b/third_party/blink/renderer/core/loader/frame_load_request.cc
index 7c3b3e9..270ec3c 100644
--- a/third_party/blink/renderer/core/loader/frame_load_request.cc
+++ b/third_party/blink/renderer/core/loader/frame_load_request.cc
@@ -34,8 +34,7 @@
     referrer_policy_to_use = origin_document->GetReferrerPolicy();
 
   Referrer referrer = SecurityPolicy::GenerateReferrer(
-      referrer_policy_to_use, request.RequestorOrigin(), request.Url(),
-      referrer_to_use);
+      referrer_policy_to_use, request.Url(), referrer_to_use);
 
   // TODO(domfarolino): Stop storing ResourceRequest's generated referrer as a
   // header and instead use a separate member. See https://crbug.com/850813.
diff --git a/third_party/blink/renderer/core/loader/frame_loader.cc b/third_party/blink/renderer/core/loader/frame_loader.cc
index 78b897b..9b44389 100644
--- a/third_party/blink/renderer/core/loader/frame_loader.cc
+++ b/third_party/blink/renderer/core/loader/frame_loader.cc
@@ -158,7 +158,6 @@
   if (client_redirect_policy == ClientRedirectPolicy::kClientRedirect) {
     request.SetHttpReferrer(SecurityPolicy::GenerateReferrer(
         frame_->GetDocument()->GetReferrerPolicy(),
-        frame_->GetDocument()->GetSecurityOrigin(),
         frame_->GetDocument()->Url(),
         frame_->GetDocument()->OutgoingReferrer()));
   }
diff --git a/third_party/blink/renderer/core/loader/history_item.cc b/third_party/blink/renderer/core/loader/history_item.cc
index 3473069..a9131543 100644
--- a/third_party/blink/renderer/core/loader/history_item.cc
+++ b/third_party/blink/renderer/core/loader/history_item.cc
@@ -75,11 +75,8 @@
 
 void HistoryItem::SetReferrer(const Referrer& referrer) {
   // This should be a CHECK.
-  // TODO(domfarolino): Should this function take an |origin| parameter?
-  referrer_ = SecurityPolicy::GenerateReferrer(
-      referrer.referrer_policy,
-      SecurityOrigin::CreateFromString(referrer.referrer), Url(),
-      referrer.referrer);
+  referrer_ = SecurityPolicy::GenerateReferrer(referrer.referrer_policy, Url(),
+                                               referrer.referrer);
 }
 
 void HistoryItem::SetVisualViewportScrollOffset(const ScrollOffset& offset) {
diff --git a/third_party/blink/renderer/core/loader/private/prerender_handle.cc b/third_party/blink/renderer/core/loader/private/prerender_handle.cc
index 88e0b11..01aaa28 100644
--- a/third_party/blink/renderer/core/loader/private/prerender_handle.cc
+++ b/third_party/blink/renderer/core/loader/private/prerender_handle.cc
@@ -53,8 +53,7 @@
 
   auto* prerender = MakeGarbageCollected<Prerender>(
       client, url, prerender_rel_types,
-      SecurityPolicy::GenerateReferrer(document.GetReferrerPolicy(),
-                                       document.GetSecurityOrigin(), url,
+      SecurityPolicy::GenerateReferrer(document.GetReferrerPolicy(), url,
                                        document.OutgoingReferrer()),
       document.GetSecurityOrigin());
 
diff --git a/third_party/blink/renderer/core/paint/theme_painter_default.cc b/third_party/blink/renderer/core/paint/theme_painter_default.cc
index dffb3b4..1557e5d 100644
--- a/third_party/blink/renderer/core/paint/theme_painter_default.cc
+++ b/third_party/blink/renderer/core/paint/theme_painter_default.cc
@@ -226,7 +226,8 @@
   // incorrectly (e.g. https://crbug.com/937872).
   // TODO(gilmanmh): Implement a more permanent solution that allows use of
   // native dark themes.
-  if (paint_info.context.dark_mode_settings().mode != DarkMode::kOff)
+  if (paint_info.context.dark_mode_settings().mode !=
+      DarkModeInversionAlgorithm::kOff)
     return true;
 
   ControlPart part = style.EffectiveAppearance();
diff --git a/third_party/blink/renderer/core/svg/animation/svg_smil_element.cc b/third_party/blink/renderer/core/svg/animation/svg_smil_element.cc
index 12df1fd..0a1dbd7 100644
--- a/third_party/blink/renderer/core/svg/animation/svg_smil_element.cc
+++ b/third_party/blink/renderer/core/svg/animation/svg_smil_element.cc
@@ -265,8 +265,7 @@
   if (svg_target && !svg_target->isConnected())
     svg_target = nullptr;
 
-  if (svg_target != targetElement())
-    SetTargetElement(svg_target);
+  SetTargetElement(svg_target);
 
   if (svg_target) {
     // Register us with the target in the dependencies map. Any change of
@@ -615,6 +614,8 @@
 }
 
 void SVGSMILElement::SetTargetElement(SVGElement* target) {
+  if (target == target_element_)
+    return;
   WillChangeAnimationTarget();
 
   // Clear values that may depend on the previous target.
diff --git a/third_party/blink/renderer/core/svg/svg_animate_element.cc b/third_party/blink/renderer/core/svg/svg_animate_element.cc
index 96239577..72a2abc9 100644
--- a/third_party/blink/renderer/core/svg/svg_animate_element.cc
+++ b/third_party/blink/renderer/core/svg/svg_animate_element.cc
@@ -566,19 +566,24 @@
 }
 
 void SVGAnimateElement::SetAttributeName(const QualifiedName& attribute_name) {
+  if (attribute_name == attribute_name_)
+    return;
   WillChangeAnimationTarget();
   attribute_name_ = attribute_name;
   DidChangeAnimationTarget();
 }
 
-void SVGAnimateElement::SetAttributeType(const AtomicString& attribute_type) {
+void SVGAnimateElement::SetAttributeType(
+    const AtomicString& attribute_type_string) {
+  AttributeType attribute_type = kAttributeTypeAuto;
+  if (attribute_type_string == "CSS")
+    attribute_type = kAttributeTypeCSS;
+  else if (attribute_type_string == "XML")
+    attribute_type = kAttributeTypeXML;
+  if (attribute_type == attribute_type_)
+    return;
   WillChangeAnimationTarget();
-  if (attribute_type == "CSS")
-    attribute_type_ = kAttributeTypeCSS;
-  else if (attribute_type == "XML")
-    attribute_type_ = kAttributeTypeXML;
-  else
-    attribute_type_ = kAttributeTypeAuto;
+  attribute_type_ = attribute_type;
   DidChangeAnimationTarget();
 }
 
diff --git a/third_party/blink/renderer/core/workers/worker_thread_test.cc b/third_party/blink/renderer/core/workers/worker_thread_test.cc
index 69dc5968..238ba858 100644
--- a/third_party/blink/renderer/core/workers/worker_thread_test.cc
+++ b/third_party/blink/renderer/core/workers/worker_thread_test.cc
@@ -298,7 +298,7 @@
 
 // Disabled due to flakiness: https://crbug.com/1003217.
 #if defined(ADDRESS_SANITIZER) || defined(MEMORY_SANITIZER) || \
-    defined(THREAD_SANITIZER) || defined(OS_WIN)
+    defined(THREAD_SANITIZER) || defined(OS_WIN) || defined(OS_ANDROID)
 #define MAYBE_SyncTerminate_ImmediatelyAfterStart \
   DISABLED_SyncTerminate_ImmediatelyAfterStart
 #else
diff --git a/third_party/blink/renderer/devtools/front_end/network/NetworkDataGridNode.js b/third_party/blink/renderer/devtools/front_end/network/NetworkDataGridNode.js
index caef4c3..37c9cf9 100644
--- a/third_party/blink/renderer/devtools/front_end/network/NetworkDataGridNode.js
+++ b/third_party/blink/renderer/devtools/front_end/network/NetworkDataGridNode.js
@@ -796,14 +796,14 @@
     let iconElement;
     if (this._request.resourceType() === Common.resourceTypes.Image) {
       const previewImage = createElementWithClass('img', 'image-network-icon-preview');
-      UI.ARIAUtils.setAccessibleName(previewImage, this._request.resourceType().title());
+      previewImage.alt = this._request.resourceType().title();
       this._request.populateImageSource(previewImage);
 
       iconElement = createElementWithClass('div', 'icon');
       iconElement.appendChild(previewImage);
     } else {
       iconElement = createElementWithClass('img', 'icon');
-      UI.ARIAUtils.setAccessibleName(iconElement, this._request.resourceType().title());
+      iconElement.alt = this._request.resourceType().title();
     }
     iconElement.classList.add(this._request.resourceType().name());
 
diff --git a/third_party/blink/renderer/devtools/front_end/perf_ui/FilmStripView.js b/third_party/blink/renderer/devtools/front_end/perf_ui/FilmStripView.js
index 182cd3b..f7e63d8 100644
--- a/third_party/blink/renderer/devtools/front_end/perf_ui/FilmStripView.js
+++ b/third_party/blink/renderer/devtools/front_end/perf_ui/FilmStripView.js
@@ -59,6 +59,7 @@
     element.title = Common.UIString('Doubleclick to zoom image. Click to view preceding requests.');
     element.createChild('div', 'time').textContent = Number.millisToString(time - this._zeroTime);
     const imageElement = element.createChild('div', 'thumbnail').createChild('img');
+    imageElement.alt = ls`Screenshot`;
     element.addEventListener(
         'mousedown', this._onMouseEvent.bind(this, PerfUI.FilmStripView.Events.FrameSelected, time), false);
     element.addEventListener(
diff --git a/third_party/blink/renderer/devtools/front_end/sdk/CSSMetadata.js b/third_party/blink/renderer/devtools/front_end/sdk/CSSMetadata.js
index b4d70fc..0fa8fe3 100644
--- a/third_party/blink/renderer/devtools/front_end/sdk/CSSMetadata.js
+++ b/third_party/blink/renderer/devtools/front_end/sdk/CSSMetadata.js
@@ -198,6 +198,8 @@
    * @return {string}
    */
   canonicalPropertyName(name) {
+    if (this.isCustomProperty(name))
+      return name;
     name = name.toLowerCase();
     if (!name || name.length < 9 || name.charAt(0) !== '-')
       return name;
diff --git a/third_party/blink/renderer/modules/broadcastchannel/broadcast_channel.cc b/third_party/blink/renderer/modules/broadcastchannel/broadcast_channel.cc
index e963f70..683099a 100644
--- a/third_party/blink/renderer/modules/broadcastchannel/broadcast_channel.cc
+++ b/third_party/blink/renderer/modules/broadcastchannel/broadcast_channel.cc
@@ -5,9 +5,11 @@
 #include "third_party/blink/renderer/modules/broadcastchannel/broadcast_channel.h"
 
 #include "mojo/public/cpp/bindings/remote.h"
+#include "third_party/blink/public/mojom/web_feature/web_feature.mojom-shared.h"
 #include "third_party/blink/public/platform/interface_provider.h"
 #include "third_party/blink/public/platform/platform.h"
 #include "third_party/blink/renderer/bindings/core/v8/serialization/serialized_script_value.h"
+#include "third_party/blink/renderer/core/dom/document.h"
 #include "third_party/blink/renderer/core/events/message_event.h"
 #include "third_party/blink/renderer/platform/mojo/mojo_helper.h"
 #include "third_party/blink/renderer/platform/wtf/functional.h"
@@ -39,6 +41,15 @@
 BroadcastChannel* BroadcastChannel::Create(ExecutionContext* execution_context,
                                            const String& name,
                                            ExceptionState& exception_state) {
+  // Record BroadcastChannel usage in third party context. Don't record if the
+  // frame is same-origin to the top frame, or if we can't tell whether the
+  // frame was ever cross-origin or not.
+  Document* document = DynamicTo<Document>(execution_context);
+  if (document && document->TopFrameOrigin() &&
+      !document->TopFrameOrigin()->CanAccess(document->GetSecurityOrigin())) {
+    UseCounter::Count(document, WebFeature::kThirdPartyBroadcastChannel);
+  }
+
   if (execution_context->GetSecurityOrigin()->IsOpaque()) {
     // TODO(mek): Decide what to do here depending on
     // https://github.com/whatwg/html/issues/1319
diff --git a/third_party/blink/renderer/modules/xr/xr_session.cc b/third_party/blink/renderer/modules/xr/xr_session.cc
index 7db40cee..e54bc0b 100644
--- a/third_party/blink/renderer/modules/xr/xr_session.cc
+++ b/third_party/blink/renderer/modules/xr/xr_session.cc
@@ -830,6 +830,14 @@
   }
 
   XRVisibilityState state = device_visibility_state_;
+
+  // The WebXR spec requires that if our document is not focused, that we don't
+  // hand out real poses. For immersive sessions, we have to rely on the device
+  // to tell us it's visibility state, as some runtimes (WMR) put focus in the
+  // headset, and thus we cannot rely on Document Focus state. This is fine
+  // because while the runtime reports us as focused the content owned by the
+  // session should be focued, which is owned by the document. For inline, we
+  // can and must rely on frame focus.
   if (!immersive() && !xr_->IsFrameFocused()) {
     state = XRVisibilityState::HIDDEN;
   }
@@ -1020,9 +1028,12 @@
 
   XRFrame* presentation_frame =
       MakeGarbageCollected<XRFrame>(this, world_information_);
-  if (base_pose_matrix_) {
-    DVLOG(2) << __func__
-             << " : base_pose_matrix_ is set, updating presentation frame";
+
+  // TODO(1004201): Determine if world_information_ should be treated similarly
+  // to the base pose matrix.
+  if (base_pose_matrix_ && visibility_state_ != XRVisibilityState::HIDDEN) {
+    DVLOG(2) << __func__ << " : base_pose_matrix_ is set and not hidden,"
+             << " updating presentation frame";
     presentation_frame->SetBasePoseMatrix(*base_pose_matrix_);
   }
   return presentation_frame;
@@ -1075,6 +1086,11 @@
     int16_t frame_id,
     base::span<const device::mojom::blink::XRInputSourceStatePtr> input_states,
     bool from_eventing) {
+  // If we're in any state other than visible, input should not be processed
+  if (visibility_state_ != XRVisibilityState::VISIBLE) {
+    return;
+  }
+
   HeapVector<Member<XRInputSource>> added;
   HeapVector<Member<XRInputSource>> removed;
   last_frame_id_ = frame_id;
diff --git a/third_party/blink/renderer/platform/graphics/dark_mode_color_classifier_test.cc b/third_party/blink/renderer/platform/graphics/dark_mode_color_classifier_test.cc
index 5242caf..c2251c5 100644
--- a/third_party/blink/renderer/platform/graphics/dark_mode_color_classifier_test.cc
+++ b/third_party/blink/renderer/platform/graphics/dark_mode_color_classifier_test.cc
@@ -22,7 +22,7 @@
 
 TEST(DarkModeColorClassifierTest, ApplyFilterToDarkTextOnly) {
   DarkModeSettings settings;
-  settings.mode = DarkMode::kSimpleInvertForTesting;
+  settings.mode = DarkModeInversionAlgorithm::kSimpleInvertForTesting;
   settings.text_brightness_threshold = 200;
   auto classifier = DarkModeColorClassifier::MakeTextColorClassifier(settings);
 
@@ -51,7 +51,7 @@
 
 TEST(DarkModeColorClassifierTest, ApplyFilterToLightBackgroundElementsOnly) {
   DarkModeSettings settings;
-  settings.mode = DarkMode::kSimpleInvertForTesting;
+  settings.mode = DarkModeInversionAlgorithm::kSimpleInvertForTesting;
   settings.background_brightness_threshold = 200;
   auto classifier =
       DarkModeColorClassifier::MakeBackgroundColorClassifier(settings);
diff --git a/third_party/blink/renderer/platform/graphics/dark_mode_color_filter.cc b/third_party/blink/renderer/platform/graphics/dark_mode_color_filter.cc
index 571db46..0fe6ee1 100644
--- a/third_party/blink/renderer/platform/graphics/dark_mode_color_filter.cc
+++ b/third_party/blink/renderer/platform/graphics/dark_mode_color_filter.cc
@@ -94,10 +94,10 @@
 std::unique_ptr<DarkModeColorFilter> DarkModeColorFilter::FromSettings(
     const DarkModeSettings& settings) {
   switch (settings.mode) {
-    case DarkMode::kOff:
+    case DarkModeInversionAlgorithm::kOff:
       return nullptr;
 
-    case DarkMode::kSimpleInvertForTesting:
+    case DarkModeInversionAlgorithm::kSimpleInvertForTesting:
       uint8_t identity[256], invert[256];
       for (int i = 0; i < 256; ++i) {
         identity[i] = i;
@@ -106,15 +106,15 @@
       return std::make_unique<SkColorFilterWrapper>(
           SkTableColorFilter::MakeARGB(identity, invert, invert, invert));
 
-    case DarkMode::kInvertBrightness:
+    case DarkModeInversionAlgorithm::kInvertBrightness:
       return std::make_unique<SkColorFilterWrapper>(SkColorFilterFromSettings(
           SkHighContrastConfig::InvertStyle::kInvertBrightness, settings));
 
-    case DarkMode::kInvertLightness:
+    case DarkModeInversionAlgorithm::kInvertLightness:
       return std::make_unique<SkColorFilterWrapper>(SkColorFilterFromSettings(
           SkHighContrastConfig::InvertStyle::kInvertLightness, settings));
 
-    case DarkMode::kInvertLightnessLAB:
+    case DarkModeInversionAlgorithm::kInvertLightnessLAB:
       return std::make_unique<LabColorFilter>();
   }
   NOTREACHED();
diff --git a/third_party/blink/renderer/platform/graphics/dark_mode_filter.cc b/third_party/blink/renderer/platform/graphics/dark_mode_filter.cc
index 94cd199..9d9a97e4 100644
--- a/third_party/blink/renderer/platform/graphics/dark_mode_filter.cc
+++ b/third_party/blink/renderer/platform/graphics/dark_mode_filter.cc
@@ -31,7 +31,7 @@
 
 void VerifySettingsAreUnchanged(const DarkModeSettings& a,
                                 const DarkModeSettings& b) {
-  if (a.mode == DarkMode::kOff)
+  if (a.mode == DarkModeInversionAlgorithm::kOff)
     return;
 
   DCHECK_EQ(a.image_policy, b.image_policy);
@@ -89,7 +89,7 @@
       color_filter_(nullptr),
       image_filter_(nullptr) {
   DarkModeSettings default_settings;
-  default_settings.mode = DarkMode::kOff;
+  default_settings.mode = DarkModeInversionAlgorithm::kOff;
   UpdateSettings(default_settings);
 }
 
diff --git a/third_party/blink/renderer/platform/graphics/dark_mode_filter_test.cc b/third_party/blink/renderer/platform/graphics/dark_mode_filter_test.cc
index 743c9e01..34e414d 100644
--- a/third_party/blink/renderer/platform/graphics/dark_mode_filter_test.cc
+++ b/third_party/blink/renderer/platform/graphics/dark_mode_filter_test.cc
@@ -19,7 +19,7 @@
   DarkModeFilter filter;
 
   DarkModeSettings settings;
-  settings.mode = DarkMode::kOff;
+  settings.mode = DarkModeInversionAlgorithm::kOff;
   filter.UpdateSettings(settings);
 
   EXPECT_EQ(Color::kWhite,
@@ -38,7 +38,7 @@
   DarkModeFilter filter;
 
   DarkModeSettings settings;
-  settings.mode = DarkMode::kSimpleInvertForTesting;
+  settings.mode = DarkModeInversionAlgorithm::kSimpleInvertForTesting;
   filter.UpdateSettings(settings);
 
   EXPECT_EQ(Color::kBlack,
diff --git a/third_party/blink/renderer/platform/graphics/dark_mode_settings.h b/third_party/blink/renderer/platform/graphics/dark_mode_settings.h
index 4d3cd75..babdfb632 100644
--- a/third_party/blink/renderer/platform/graphics/dark_mode_settings.h
+++ b/third_party/blink/renderer/platform/graphics/dark_mode_settings.h
@@ -7,8 +7,10 @@
 
 namespace blink {
 
-enum class DarkMode {
+enum class DarkModeInversionAlgorithm {
   // Default, drawing is unfiltered.
+  // TODO(https://crbug.com/1002664): This value is deprecated and in the
+  // process of being removed.
   kOff,
   // For testing only, does a simple 8-bit invert of every RGB pixel component.
   kSimpleInvertForTesting,
@@ -42,7 +44,7 @@
 // BuildDarkModeSettings() in
 //   //src/third_party/blink/renderer/core/accessibility/apply_dark_mode.h
 struct DarkModeSettings {
-  DarkMode mode = DarkMode::kOff;
+  DarkModeInversionAlgorithm mode = DarkModeInversionAlgorithm::kOff;
   bool grayscale = false;
   float image_grayscale_percent = 0.0;  // Valid range from 0.0 to 1.0
   float contrast = 0.0;                 // Valid range from -1.0 to 1.0
diff --git a/third_party/blink/renderer/platform/graphics/graphics_context_test.cc b/third_party/blink/renderer/platform/graphics/graphics_context_test.cc
index 5b8d37d..5c36463 100644
--- a/third_party/blink/renderer/platform/graphics/graphics_context_test.cc
+++ b/third_party/blink/renderer/platform/graphics/graphics_context_test.cc
@@ -184,7 +184,7 @@
 
 TEST_F(GraphicsContextDarkModeTest, DarkModeOff) {
   DarkModeSettings settings;
-  settings.mode = DarkMode::kOff;
+  settings.mode = DarkModeInversionAlgorithm::kOff;
   settings.grayscale = false;
   settings.contrast = 0;
   context_->SetDarkMode(settings);
@@ -201,7 +201,7 @@
 // is replaced with |255 - c| for easy testing.
 TEST_F(GraphicsContextDarkModeTest, SimpleInvertForTesting) {
   DarkModeSettings settings;
-  settings.mode = DarkMode::kSimpleInvertForTesting;
+  settings.mode = DarkModeInversionAlgorithm::kSimpleInvertForTesting;
   settings.grayscale = false;
   settings.contrast = 0;
   context_->SetDarkMode(settings);
@@ -217,7 +217,7 @@
 // Invert brightness (with gamma correction).
 TEST_F(GraphicsContextDarkModeTest, InvertBrightness) {
   DarkModeSettings settings;
-  settings.mode = DarkMode::kInvertBrightness;
+  settings.mode = DarkModeInversionAlgorithm::kInvertBrightness;
   settings.grayscale = false;
   settings.contrast = 0;
   context_->SetDarkMode(settings);
@@ -233,7 +233,7 @@
 // Invert lightness (in HSL space).
 TEST_F(GraphicsContextDarkModeTest, InvertLightness) {
   DarkModeSettings settings;
-  settings.mode = DarkMode::kInvertLightness;
+  settings.mode = DarkModeInversionAlgorithm::kInvertLightness;
   settings.grayscale = false;
   settings.contrast = 0;
   context_->SetDarkMode(settings);
@@ -249,7 +249,7 @@
 // Invert lightness plus grayscale.
 TEST_F(GraphicsContextDarkModeTest, InvertLightnessPlusGrayscale) {
   DarkModeSettings settings;
-  settings.mode = DarkMode::kInvertLightness;
+  settings.mode = DarkModeInversionAlgorithm::kInvertLightness;
   settings.grayscale = true;
   settings.contrast = 0;
   context_->SetDarkMode(settings);
@@ -264,7 +264,7 @@
 
 TEST_F(GraphicsContextDarkModeTest, InvertLightnessPlusContrast) {
   DarkModeSettings settings;
-  settings.mode = DarkMode::kInvertLightness;
+  settings.mode = DarkModeInversionAlgorithm::kInvertLightness;
   settings.grayscale = false;
   settings.contrast = 0.2;
   context_->SetDarkMode(settings);
diff --git a/third_party/blink/renderer/platform/graphics/test/mock_paint_canvas.h b/third_party/blink/renderer/platform/graphics/test/mock_paint_canvas.h
index 465e9d3..919b9e31 100644
--- a/third_party/blink/renderer/platform/graphics/test/mock_paint_canvas.h
+++ b/third_party/blink/renderer/platform/graphics/test/mock_paint_canvas.h
@@ -19,6 +19,8 @@
 class MockPaintCanvas : public cc::PaintCanvas {
  public:
   MOCK_CONST_METHOD0(imageInfo, SkImageInfo());
+  MOCK_METHOD3(accessTopLayerPixels,
+               void*(SkImageInfo* info, size_t* rowBytes, SkIPoint* origin));
   MOCK_METHOD0(flush, void());
   MOCK_METHOD0(save, int());
   MOCK_METHOD2(saveLayer, int(const SkRect* bounds, const PaintFlags* flags));
diff --git a/third_party/blink/renderer/platform/heap/heap.cc b/third_party/blink/renderer/platform/heap/heap.cc
index 8017bc73f..cf51d3a 100644
--- a/third_party/blink/renderer/platform/heap/heap.cc
+++ b/third_party/blink/renderer/platform/heap/heap.cc
@@ -284,13 +284,12 @@
                                Worklist* worklist,
                                Callback callback,
                                int task_id) {
-  const size_t kDeadlineCheckInterval = 2500;
+  const size_t kDeadlineCheckInterval = 1250;
 
   size_t processed_callback_count = 0;
   typename Worklist::EntryType item;
   while (worklist->Pop(task_id, &item)) {
     callback(item);
-    processed_callback_count++;
     if (++processed_callback_count == kDeadlineCheckInterval) {
       if (deadline <= base::TimeTicks::Now()) {
         return false;
@@ -348,11 +347,12 @@
   return true;
 }
 
-void ThreadHeap::AdvanceConcurrentMarking(ConcurrentMarkingVisitor* visitor) {
-  // TODO(omerkatz): Use deadline to avoid priority inversion and
-  // periodically flush v8 worklist.
-  DrainWorklistWithDeadline(
-      base::TimeTicks::Max(), marking_worklist_.get(),
+bool ThreadHeap::AdvanceConcurrentMarking(ConcurrentMarkingVisitor* visitor,
+                                          base::TimeTicks deadline) {
+  // Iteratively mark all objects that are reachable from the objects
+  // currently pushed onto the marking worklist.
+  return DrainWorklistWithDeadline(
+      deadline, marking_worklist_.get(),
       [visitor](const MarkingItem& item) {
         DCHECK(
             !HeapObjectHeader::FromPayload(item.object)
diff --git a/third_party/blink/renderer/platform/heap/heap.h b/third_party/blink/renderer/platform/heap/heap.h
index 5ab4155..2bde952 100644
--- a/third_party/blink/renderer/platform/heap/heap.h
+++ b/third_party/blink/renderer/platform/heap/heap.h
@@ -293,7 +293,8 @@
   bool AdvanceMarking(MarkingVisitor*, base::TimeTicks deadline);
   void VerifyMarking();
 
-  void AdvanceConcurrentMarking(ConcurrentMarkingVisitor*);
+  // Returns true if marker is done
+  bool AdvanceConcurrentMarking(ConcurrentMarkingVisitor*, base::TimeTicks);
 
   // Conservatively checks whether an address is a pointer in any of the
   // thread heaps.  If so marks the object pointed to as live.
diff --git a/third_party/blink/renderer/platform/heap/thread_state.cc b/third_party/blink/renderer/platform/heap/thread_state.cc
index c5dc8f5..e64aebb2 100644
--- a/third_party/blink/renderer/platform/heap/thread_state.cc
+++ b/third_party/blink/renderer/platform/heap/thread_state.cc
@@ -103,6 +103,14 @@
 constexpr base::TimeDelta kDefaultIncrementalMarkingStepDuration =
     base::TimeDelta::FromMilliseconds(2);
 
+// Concurrent marking should stop every once in a while to flush private
+// segments to v8 marking worklist. It should also stop to avoid priority
+// inversion.
+//
+// TODO(omerkatz): What is a good value to set here?
+constexpr base::TimeDelta kConcurrentMarkingStepDuration =
+    base::TimeDelta::FromMilliseconds(2);
+
 constexpr size_t kMaxTerminationGCLoops = 20;
 
 // Helper function to convert a byte count to a KB count, capping at
@@ -1647,7 +1655,10 @@
           : std::make_unique<ConcurrentMarkingVisitor>(
                 this, GetMarkingMode(Heap().Compaction()->IsCompacting()),
                 task_id);
-  Heap().AdvanceConcurrentMarking(concurrent_visitor.get());
+
+  const bool finished = Heap().AdvanceConcurrentMarking(
+      concurrent_visitor.get(),
+      base::TimeTicks::Now() + kConcurrentMarkingStepDuration);
 
   concurrent_visitor->FlushWorklists();
   {
@@ -1655,8 +1666,16 @@
     // When marking is done, flush visitor worklists and decrement number of
     // active markers so we know how many markers are left
     concurrently_marked_bytes_ += concurrent_visitor->marked_bytes();
-    --active_markers_;
+    if (finished) {
+      --active_markers_;
+      return;
+    }
   }
+
+  // Reschedule this marker
+  marker_scheduler_->ScheduleTask(WTF::CrossThreadBindOnce(
+      &ThreadState::PerformConcurrentMark, WTF::CrossThreadUnretained(this),
+      concurrent_marker_id));
 }
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/platform/loader/fetch/resource_fetcher.cc b/third_party/blink/renderer/platform/loader/fetch/resource_fetcher.cc
index 77f06fe..29faa38 100644
--- a/third_party/blink/renderer/platform/loader/fetch/resource_fetcher.cc
+++ b/third_party/blink/renderer/platform/loader/fetch/resource_fetcher.cc
@@ -322,15 +322,14 @@
     // TODO(domfarolino): Stop storing ResourceRequest's referrer as a header
     // and store it elsewhere. See https://crbug.com/850813.
     request.SetHttpReferrer(SecurityPolicy::GenerateReferrer(
-        referrer_policy_to_use, request.RequestorOrigin(), request.Url(),
-        referrer_to_use));
+        referrer_policy_to_use, request.Url(), referrer_to_use));
   } else {
     // In the case of stale requests that are being revalidated, these requests
     // will already have their HttpReferrer set, and we will end up here. We
     // won't regenerate the referrer, but instead check that it's still correct.
-    CHECK_EQ(SecurityPolicy::GenerateReferrer(
-                 request.GetReferrerPolicy(), request.RequestorOrigin(),
-                 request.Url(), request.ReferrerString())
+    CHECK_EQ(SecurityPolicy::GenerateReferrer(request.GetReferrerPolicy(),
+                                              request.Url(),
+                                              request.ReferrerString())
                  .referrer,
              request.HttpReferrer());
   }
diff --git a/third_party/blink/renderer/platform/weborigin/security_policy.cc b/third_party/blink/renderer/platform/weborigin/security_policy.cc
index c2e809c..28062e71 100644
--- a/third_party/blink/renderer/platform/weborigin/security_policy.cc
+++ b/third_party/blink/renderer/platform/weborigin/security_policy.cc
@@ -103,11 +103,8 @@
   return !url_is_secure_url;
 }
 
-// When making changes to this method that affect the return Referrer, also
-// update net::URLRequestJob::ComputeReferrerForPolicy accordingly.
 Referrer SecurityPolicy::GenerateReferrer(
     network::mojom::ReferrerPolicy referrer_policy,
-    scoped_refptr<const SecurityOrigin> origin,
     const KURL& url,
     const String& referrer) {
   network::mojom::ReferrerPolicy referrer_policy_no_default =
@@ -130,49 +127,50 @@
     case network::mojom::ReferrerPolicy::kAlways:
       return Referrer(referrer, referrer_policy_no_default);
     case network::mojom::ReferrerPolicy::kOrigin: {
-      String referrer_origin_string =
-          SecurityOrigin::Create(referrer_url)->ToString();
+      String origin = SecurityOrigin::Create(referrer_url)->ToString();
       // A security origin is not a canonical URL as it lacks a path. Add /
       // to turn it into a canonical URL we can use as referrer.
-      return Referrer(referrer_origin_string + "/", referrer_policy_no_default);
+      return Referrer(origin + "/", referrer_policy_no_default);
     }
     case network::mojom::ReferrerPolicy::kOriginWhenCrossOrigin: {
-      String referrer_origin_string =
-          SecurityOrigin::Create(referrer_url)->ToString();
+      scoped_refptr<const SecurityOrigin> referrer_origin =
+          SecurityOrigin::Create(referrer_url);
       scoped_refptr<const SecurityOrigin> url_origin =
           SecurityOrigin::Create(url);
-      if (!url_origin->IsSameSchemeHostPort(origin.get())) {
-        return Referrer(referrer_origin_string + "/",
-                        referrer_policy_no_default);
+      if (!url_origin->IsSameSchemeHostPort(referrer_origin.get())) {
+        String origin = referrer_origin->ToString();
+        return Referrer(origin + "/", referrer_policy_no_default);
       }
       break;
     }
     case network::mojom::ReferrerPolicy::kSameOrigin: {
+      scoped_refptr<const SecurityOrigin> referrer_origin =
+          SecurityOrigin::Create(referrer_url);
       scoped_refptr<const SecurityOrigin> url_origin =
           SecurityOrigin::Create(url);
-      if (!url_origin->IsSameSchemeHostPort(origin.get())) {
+      if (!url_origin->IsSameSchemeHostPort(referrer_origin.get())) {
         return Referrer(Referrer::NoReferrer(), referrer_policy_no_default);
       }
       return Referrer(referrer, referrer_policy_no_default);
     }
     case network::mojom::ReferrerPolicy::kStrictOrigin: {
-      String referrer_origin_string =
-          SecurityOrigin::Create(referrer_url)->ToString();
+      String origin = SecurityOrigin::Create(referrer_url)->ToString();
       return Referrer(ShouldHideReferrer(url, referrer_url)
                           ? Referrer::NoReferrer()
-                          : referrer_origin_string + "/",
+                          : origin + "/",
                       referrer_policy_no_default);
     }
     case network::mojom::ReferrerPolicy::
         kNoReferrerWhenDowngradeOriginWhenCrossOrigin: {
-      String referrer_origin_string =
-          SecurityOrigin::Create(referrer_url)->ToString();
+      scoped_refptr<const SecurityOrigin> referrer_origin =
+          SecurityOrigin::Create(referrer_url);
       scoped_refptr<const SecurityOrigin> url_origin =
           SecurityOrigin::Create(url);
-      if (!url_origin->IsSameSchemeHostPort(origin.get())) {
+      if (!url_origin->IsSameSchemeHostPort(referrer_origin.get())) {
+        String origin = referrer_origin->ToString();
         return Referrer(ShouldHideReferrer(url, referrer_url)
                             ? Referrer::NoReferrer()
-                            : referrer_origin_string + "/",
+                            : origin + "/",
                         referrer_policy_no_default);
       }
       break;
diff --git a/third_party/blink/renderer/platform/weborigin/security_policy.h b/third_party/blink/renderer/platform/weborigin/security_policy.h
index b04f73ad0..cb4e4bd 100644
--- a/third_party/blink/renderer/platform/weborigin/security_policy.h
+++ b/third_party/blink/renderer/platform/weborigin/security_policy.h
@@ -71,7 +71,6 @@
   // navigation to a given URL. If the referrer returned is empty, the
   // referrer header should be omitted.
   static Referrer GenerateReferrer(network::mojom::ReferrerPolicy,
-                                   scoped_refptr<const SecurityOrigin> origin,
                                    const KURL&,
                                    const String& referrer);
 
diff --git a/third_party/blink/renderer/platform/weborigin/security_policy_test.cc b/third_party/blink/renderer/platform/weborigin/security_policy_test.cc
index 5794e396..32414fa 100644
--- a/third_party/blink/renderer/platform/weborigin/security_policy_test.cc
+++ b/third_party/blink/renderer/platform/weborigin/security_policy_test.cc
@@ -40,12 +40,10 @@
 
 TEST(SecurityPolicyTest, EmptyReferrerForUnauthorizedScheme) {
   const KURL example_http_url = KURL("http://example.com/");
-  const String chrome_url = String::FromUTF8("chrome://somepage/");
-  scoped_refptr<const SecurityOrigin> origin =
-      SecurityOrigin::CreateFromString(chrome_url);
   EXPECT_TRUE(String() == SecurityPolicy::GenerateReferrer(
-                              network::mojom::ReferrerPolicy::kAlways, origin,
-                              example_http_url, chrome_url)
+                              network::mojom::ReferrerPolicy::kAlways,
+                              example_http_url,
+                              String::FromUTF8("chrome://somepage/"))
                               .referrer);
 }
 
@@ -53,16 +51,14 @@
   const KURL example_http_url = KURL("http://example.com/");
   const String foobar_url = String::FromUTF8("foobar://somepage/");
   const String foobar_scheme = String::FromUTF8("foobar");
-  scoped_refptr<const SecurityOrigin> origin =
-      SecurityOrigin::CreateFromString(foobar_url);
 
   EXPECT_EQ(String(), SecurityPolicy::GenerateReferrer(
-                          network::mojom::ReferrerPolicy::kAlways, origin,
+                          network::mojom::ReferrerPolicy::kAlways,
                           example_http_url, foobar_url)
                           .referrer);
   SchemeRegistry::RegisterURLSchemeAsAllowedForReferrer(foobar_scheme);
   EXPECT_EQ(foobar_url, SecurityPolicy::GenerateReferrer(
-                            network::mojom::ReferrerPolicy::kAlways, origin,
+                            network::mojom::ReferrerPolicy::kAlways,
                             example_http_url, foobar_url)
                             .referrer);
   SchemeRegistry::RemoveURLSchemeAsAllowedForReferrer(foobar_scheme);
@@ -84,7 +80,6 @@
   struct TestCase {
     network::mojom::ReferrerPolicy policy;
     const char* referrer;
-    scoped_refptr<const SecurityOrigin> origin;
     const char* destination;
     const char* expected;
   };
@@ -92,16 +87,10 @@
   const char kInsecureURLA[] = "http://a.test/path/to/file.html";
   const char kInsecureURLB[] = "http://b.test/path/to/file.html";
   const char kInsecureOriginA[] = "http://a.test/";
-  scoped_refptr<const SecurityOrigin> insecure_origin_a =
-      SecurityOrigin::CreateFromString(kInsecureOriginA);
 
   const char kSecureURLA[] = "https://a.test/path/to/file.html";
   const char kSecureURLB[] = "https://b.test/path/to/file.html";
   const char kSecureOriginA[] = "https://a.test/";
-  scoped_refptr<const SecurityOrigin> secure_origin_a =
-      SecurityOrigin::CreateFromString(kSecureOriginA);
-  scoped_refptr<const SecurityOrigin> cross_origin =
-      SecurityOrigin::CreateUniqueOpaque();
 
   const char kBlobURL[] =
       "blob:http://a.test/b3aae9c8-7f90-440d-8d7c-43aa20d72fde";
@@ -109,159 +98,146 @@
 
   TestCase inputs[] = {
       // HTTP -> HTTP: Same Origin
-      {network::mojom::ReferrerPolicy::kAlways, kInsecureURLA,
-       insecure_origin_a, kInsecureURLA, kInsecureURLA},
-      {network::mojom::ReferrerPolicy::kDefault, kInsecureURLA,
-       insecure_origin_a, kInsecureURLA, kInsecureURLA},
+      {network::mojom::ReferrerPolicy::kAlways, kInsecureURLA, kInsecureURLA,
+       kInsecureURLA},
+      {network::mojom::ReferrerPolicy::kDefault, kInsecureURLA, kInsecureURLA,
+       kInsecureURLA},
       {network::mojom::ReferrerPolicy::kNoReferrerWhenDowngrade, kInsecureURLA,
-       insecure_origin_a, kInsecureURLA, kInsecureURLA},
-      {network::mojom::ReferrerPolicy::kNever, kInsecureURLA, insecure_origin_a,
-       kInsecureURLA, nullptr},
-      {network::mojom::ReferrerPolicy::kOrigin, kInsecureURLA,
-       insecure_origin_a, kInsecureURLA, kInsecureOriginA},
+       kInsecureURLA, kInsecureURLA},
+      {network::mojom::ReferrerPolicy::kNever, kInsecureURLA, kInsecureURLA,
+       nullptr},
+      {network::mojom::ReferrerPolicy::kOrigin, kInsecureURLA, kInsecureURLA,
+       kInsecureOriginA},
       {network::mojom::ReferrerPolicy::kOriginWhenCrossOrigin, kInsecureURLA,
-       insecure_origin_a, kInsecureURLA, kInsecureURLA},
+       kInsecureURLA, kInsecureURLA},
       {network::mojom::ReferrerPolicy::kSameOrigin, kInsecureURLA,
-       insecure_origin_a, kInsecureURLA, kInsecureURLA},
+       kInsecureURLA, kInsecureURLA},
       {network::mojom::ReferrerPolicy::kStrictOrigin, kInsecureURLA,
-       insecure_origin_a, kInsecureURLA, kInsecureOriginA},
+       kInsecureURLA, kInsecureOriginA},
       {network::mojom::ReferrerPolicy::
            kNoReferrerWhenDowngradeOriginWhenCrossOrigin,
-       kInsecureURLA, insecure_origin_a, kInsecureURLA, kInsecureURLA},
+       kInsecureURLA, kInsecureURLA, kInsecureURLA},
 
       // HTTP -> HTTP: Cross Origin
-      {network::mojom::ReferrerPolicy::kAlways, kInsecureURLA,
-       insecure_origin_a, kInsecureURLB, kInsecureURLA},
-      {network::mojom::ReferrerPolicy::kDefault, kInsecureURLA,
-       insecure_origin_a, kInsecureURLB, kInsecureURLA},
+      {network::mojom::ReferrerPolicy::kAlways, kInsecureURLA, kInsecureURLB,
+       kInsecureURLA},
+      {network::mojom::ReferrerPolicy::kDefault, kInsecureURLA, kInsecureURLB,
+       kInsecureURLA},
       {network::mojom::ReferrerPolicy::kNoReferrerWhenDowngrade, kInsecureURLA,
-       insecure_origin_a, kInsecureURLB, kInsecureURLA},
-      {network::mojom::ReferrerPolicy::kNever, kInsecureURLA, insecure_origin_a,
-       kInsecureURLB, nullptr},
-      {network::mojom::ReferrerPolicy::kOrigin, kInsecureURLA,
-       insecure_origin_a, kInsecureURLB, kInsecureOriginA},
+       kInsecureURLB, kInsecureURLA},
+      {network::mojom::ReferrerPolicy::kNever, kInsecureURLA, kInsecureURLB,
+       nullptr},
+      {network::mojom::ReferrerPolicy::kOrigin, kInsecureURLA, kInsecureURLB,
+       kInsecureOriginA},
       {network::mojom::ReferrerPolicy::kOriginWhenCrossOrigin, kInsecureURLA,
-       insecure_origin_a, kInsecureURLB, kInsecureOriginA},
+       kInsecureURLB, kInsecureOriginA},
       {network::mojom::ReferrerPolicy::kSameOrigin, kInsecureURLA,
-       insecure_origin_a, kInsecureURLB, nullptr},
+       kInsecureURLB, nullptr},
       {network::mojom::ReferrerPolicy::kStrictOrigin, kInsecureURLA,
-       insecure_origin_a, kInsecureURLB, kInsecureOriginA},
+       kInsecureURLB, kInsecureOriginA},
       {network::mojom::ReferrerPolicy::
            kNoReferrerWhenDowngradeOriginWhenCrossOrigin,
-       kInsecureURLA, insecure_origin_a, kInsecureURLB, kInsecureOriginA},
+       kInsecureURLA, kInsecureURLB, kInsecureOriginA},
 
       // HTTPS -> HTTPS: Same Origin
-      {network::mojom::ReferrerPolicy::kAlways, kSecureURLA, secure_origin_a,
-       kSecureURLA, kSecureURLA},
-      {network::mojom::ReferrerPolicy::kDefault, kSecureURLA, secure_origin_a,
-       kSecureURLA, kSecureURLA},
+      {network::mojom::ReferrerPolicy::kAlways, kSecureURLA, kSecureURLA,
+       kSecureURLA},
+      {network::mojom::ReferrerPolicy::kDefault, kSecureURLA, kSecureURLA,
+       kSecureURLA},
       {network::mojom::ReferrerPolicy::kNoReferrerWhenDowngrade, kSecureURLA,
-       secure_origin_a, kSecureURLA, kSecureURLA},
-      {network::mojom::ReferrerPolicy::kNever, kSecureURLA, secure_origin_a,
-       kSecureURLA, nullptr},
-      {network::mojom::ReferrerPolicy::kOrigin, kSecureURLA, secure_origin_a,
-       kSecureURLA, kSecureOriginA},
+       kSecureURLA, kSecureURLA},
+      {network::mojom::ReferrerPolicy::kNever, kSecureURLA, kSecureURLA,
+       nullptr},
+      {network::mojom::ReferrerPolicy::kOrigin, kSecureURLA, kSecureURLA,
+       kSecureOriginA},
       {network::mojom::ReferrerPolicy::kOriginWhenCrossOrigin, kSecureURLA,
-       secure_origin_a, kSecureURLA, kSecureURLA},
-      {network::mojom::ReferrerPolicy::kSameOrigin, kSecureURLA,
-       secure_origin_a, kSecureURLA, kSecureURLA},
-      {network::mojom::ReferrerPolicy::kStrictOrigin, kSecureURLA,
-       secure_origin_a, kSecureURLA, kSecureOriginA},
+       kSecureURLA, kSecureURLA},
+      {network::mojom::ReferrerPolicy::kSameOrigin, kSecureURLA, kSecureURLA,
+       kSecureURLA},
+      {network::mojom::ReferrerPolicy::kStrictOrigin, kSecureURLA, kSecureURLA,
+       kSecureOriginA},
       {network::mojom::ReferrerPolicy::
            kNoReferrerWhenDowngradeOriginWhenCrossOrigin,
-       kSecureURLA, secure_origin_a, kSecureURLA, kSecureURLA},
+       kSecureURLA, kSecureURLA, kSecureURLA},
 
       // HTTPS -> HTTPS: Cross Origin
-      {network::mojom::ReferrerPolicy::kAlways, kSecureURLA, secure_origin_a,
-       kSecureURLB, kSecureURLA},
-      {network::mojom::ReferrerPolicy::kDefault, kSecureURLA, secure_origin_a,
-       kSecureURLB, kSecureURLA},
+      {network::mojom::ReferrerPolicy::kAlways, kSecureURLA, kSecureURLB,
+       kSecureURLA},
+      {network::mojom::ReferrerPolicy::kDefault, kSecureURLA, kSecureURLB,
+       kSecureURLA},
       {network::mojom::ReferrerPolicy::kNoReferrerWhenDowngrade, kSecureURLA,
-       secure_origin_a, kSecureURLB, kSecureURLA},
-      {network::mojom::ReferrerPolicy::kNever, kSecureURLA, secure_origin_a,
-       kSecureURLB, nullptr},
-      {network::mojom::ReferrerPolicy::kOrigin, kSecureURLA, secure_origin_a,
-       kSecureURLB, kSecureOriginA},
+       kSecureURLB, kSecureURLA},
+      {network::mojom::ReferrerPolicy::kNever, kSecureURLA, kSecureURLB,
+       nullptr},
+      {network::mojom::ReferrerPolicy::kOrigin, kSecureURLA, kSecureURLB,
+       kSecureOriginA},
       {network::mojom::ReferrerPolicy::kOriginWhenCrossOrigin, kSecureURLA,
-       secure_origin_a, kSecureURLB, kSecureOriginA},
-      {network::mojom::ReferrerPolicy::kSameOrigin, kSecureURLA,
-       secure_origin_a, kSecureURLB, nullptr},
-      {network::mojom::ReferrerPolicy::kStrictOrigin, kSecureURLA,
-       secure_origin_a, kSecureURLB, kSecureOriginA},
+       kSecureURLB, kSecureOriginA},
+      {network::mojom::ReferrerPolicy::kSameOrigin, kSecureURLA, kSecureURLB,
+       nullptr},
+      {network::mojom::ReferrerPolicy::kStrictOrigin, kSecureURLA, kSecureURLB,
+       kSecureOriginA},
       {network::mojom::ReferrerPolicy::
            kNoReferrerWhenDowngradeOriginWhenCrossOrigin,
-       kSecureURLA, secure_origin_a, kSecureURLB, kSecureOriginA},
+       kSecureURLA, kSecureURLB, kSecureOriginA},
 
       // HTTP -> HTTPS
-      {network::mojom::ReferrerPolicy::kAlways, kInsecureURLA,
-       insecure_origin_a, kSecureURLB, kInsecureURLA},
-      {network::mojom::ReferrerPolicy::kDefault, kInsecureURLA,
-       insecure_origin_a, kSecureURLB, kInsecureURLA},
+      {network::mojom::ReferrerPolicy::kAlways, kInsecureURLA, kSecureURLB,
+       kInsecureURLA},
+      {network::mojom::ReferrerPolicy::kDefault, kInsecureURLA, kSecureURLB,
+       kInsecureURLA},
       {network::mojom::ReferrerPolicy::kNoReferrerWhenDowngrade, kInsecureURLA,
-       insecure_origin_a, kSecureURLB, kInsecureURLA},
-      {network::mojom::ReferrerPolicy::kNever, kInsecureURLA, insecure_origin_a,
-       kSecureURLB, nullptr},
-      {network::mojom::ReferrerPolicy::kOrigin, kInsecureURLA,
-       insecure_origin_a, kSecureURLB, kInsecureOriginA},
+       kSecureURLB, kInsecureURLA},
+      {network::mojom::ReferrerPolicy::kNever, kInsecureURLA, kSecureURLB,
+       nullptr},
+      {network::mojom::ReferrerPolicy::kOrigin, kInsecureURLA, kSecureURLB,
+       kInsecureOriginA},
       {network::mojom::ReferrerPolicy::kOriginWhenCrossOrigin, kInsecureURLA,
-       insecure_origin_a, kSecureURLB, kInsecureOriginA},
-      {network::mojom::ReferrerPolicy::kSameOrigin, kInsecureURLA,
-       insecure_origin_a, kSecureURLB, nullptr},
+       kSecureURLB, kInsecureOriginA},
+      {network::mojom::ReferrerPolicy::kSameOrigin, kInsecureURLA, kSecureURLB,
+       nullptr},
       {network::mojom::ReferrerPolicy::kStrictOrigin, kInsecureURLA,
-       insecure_origin_a, kSecureURLB, kInsecureOriginA},
+       kSecureURLB, kInsecureOriginA},
       {network::mojom::ReferrerPolicy::
            kNoReferrerWhenDowngradeOriginWhenCrossOrigin,
-       kInsecureURLA, insecure_origin_a, kSecureURLB, kInsecureOriginA},
+       kInsecureURLA, kSecureURLB, kInsecureOriginA},
 
       // HTTPS -> HTTP
-      {network::mojom::ReferrerPolicy::kAlways, kSecureURLA, secure_origin_a,
-       kInsecureURLB, kSecureURLA},
-      {network::mojom::ReferrerPolicy::kDefault, kSecureURLA, secure_origin_a,
-       kInsecureURLB, nullptr},
+      {network::mojom::ReferrerPolicy::kAlways, kSecureURLA, kInsecureURLB,
+       kSecureURLA},
+      {network::mojom::ReferrerPolicy::kDefault, kSecureURLA, kInsecureURLB,
+       nullptr},
       {network::mojom::ReferrerPolicy::kNoReferrerWhenDowngrade, kSecureURLA,
-       secure_origin_a, kInsecureURLB, nullptr},
-      {network::mojom::ReferrerPolicy::kNever, kSecureURLA, secure_origin_a,
        kInsecureURLB, nullptr},
-      {network::mojom::ReferrerPolicy::kOrigin, kSecureURLA, secure_origin_a,
-       kInsecureURLB, kSecureOriginA},
+      {network::mojom::ReferrerPolicy::kNever, kSecureURLA, kInsecureURLB,
+       nullptr},
+      {network::mojom::ReferrerPolicy::kOrigin, kSecureURLA, kInsecureURLB,
+       kSecureOriginA},
       {network::mojom::ReferrerPolicy::kOriginWhenCrossOrigin, kSecureURLA,
-       secure_origin_a, kSecureURLB, kSecureOriginA},
-      {network::mojom::ReferrerPolicy::kSameOrigin, kSecureURLA,
-       secure_origin_a, kInsecureURLB, nullptr},
+       kSecureURLB, kSecureOriginA},
+      {network::mojom::ReferrerPolicy::kSameOrigin, kSecureURLA, kInsecureURLB,
+       nullptr},
       {network::mojom::ReferrerPolicy::kStrictOrigin, kSecureURLA,
-       secure_origin_a, kInsecureURLB, nullptr},
+       kInsecureURLB, nullptr},
       {network::mojom::ReferrerPolicy::
            kNoReferrerWhenDowngradeOriginWhenCrossOrigin,
-       kSecureURLA, secure_origin_a, kInsecureURLB, nullptr},
+       kSecureURLA, kInsecureURLB, nullptr},
 
       // blob and filesystem URL handling
-      {network::mojom::ReferrerPolicy::kAlways, kInsecureURLA,
-       insecure_origin_a, kBlobURL, nullptr},
-      {network::mojom::ReferrerPolicy::kAlways, kBlobURL,
-       SecurityOrigin::CreateFromString(kBlobURL), kInsecureURLA, nullptr},
-      {network::mojom::ReferrerPolicy::kAlways, kInsecureURLA,
-       insecure_origin_a, kFilesystemURL, nullptr},
-      {network::mojom::ReferrerPolicy::kAlways, kFilesystemURL,
-       SecurityOrigin::CreateFromString(kFilesystemURL), kInsecureURLA,
+      {network::mojom::ReferrerPolicy::kAlways, kInsecureURLA, kBlobURL,
        nullptr},
-
-      // Request's origin is cross-origin with referrer URL.
-      {network::mojom::ReferrerPolicy::kOriginWhenCrossOrigin, kSecureURLA,
-       cross_origin, kSecureURLA, kSecureOriginA},
-      {network::mojom::ReferrerPolicy::kOriginWhenCrossOrigin, kSecureURLA,
-       cross_origin, kSecureURLB, kSecureOriginA},
-      {network::mojom::ReferrerPolicy::kSameOrigin, kSecureURLA, cross_origin,
-       kSecureURLA, nullptr},
-      {network::mojom::ReferrerPolicy::kSameOrigin, kSecureURLA, cross_origin,
-       kSecureURLB, nullptr},
+      {network::mojom::ReferrerPolicy::kAlways, kBlobURL, kInsecureURLA,
+       nullptr},
+      {network::mojom::ReferrerPolicy::kAlways, kInsecureURLA, kFilesystemURL,
+       nullptr},
+      {network::mojom::ReferrerPolicy::kAlways, kFilesystemURL, kInsecureURLA,
+       nullptr},
   };
 
   for (TestCase test : inputs) {
     KURL destination(test.destination);
-    String referrer_string = String::FromUTF8(test.referrer);
-    scoped_refptr<const SecurityOrigin> origin = test.origin;
     Referrer result = SecurityPolicy::GenerateReferrer(
-        test.policy, origin, destination, referrer_string);
+        test.policy, destination, String::FromUTF8(test.referrer));
     if (test.expected) {
       EXPECT_EQ(String::FromUTF8(test.expected), result.referrer)
           << "'" << test.referrer << "' to '" << test.destination
diff --git a/third_party/blink/web_tests/FlagExpectations/enable-blink-features=HeapIncrementalMarkingStress b/third_party/blink/web_tests/FlagExpectations/enable-blink-features=HeapIncrementalMarkingStress
index b57fc18..bafc3da 100644
--- a/third_party/blink/web_tests/FlagExpectations/enable-blink-features=HeapIncrementalMarkingStress
+++ b/third_party/blink/web_tests/FlagExpectations/enable-blink-features=HeapIncrementalMarkingStress
@@ -1,2 +1 @@
 crbug.com/831541 inspector-protocol/css/css-collect-class-names.js [ Pass Failure ]
-crbug.com/865348 http/tests/navigation/navigation-interrupted-by-fragment.html [ Pass Timeout ]
diff --git a/third_party/blink/web_tests/FlagExpectations/enable-features=UseSkiaRenderer b/third_party/blink/web_tests/FlagExpectations/enable-features=UseSkiaRenderer
index 05e620c..d560397 100644
--- a/third_party/blink/web_tests/FlagExpectations/enable-features=UseSkiaRenderer
+++ b/third_party/blink/web_tests/FlagExpectations/enable-features=UseSkiaRenderer
@@ -1 +1,5 @@
-# TODO(jonross): Remove once Finch completes.
+# One portion of the image is offset.
+crbug.com/1002522 fast/canvas/canvas-toDataURL-webp.html [ Skip ]
+
+# Blurring is not pixelated.
+crbug.com/1002525 fast/canvas/pixelated.html [ Skip ]
diff --git a/third_party/blink/web_tests/FlagExpectations/use-vulkan=native b/third_party/blink/web_tests/FlagExpectations/use-vulkan=native
index f59a24e..ab7813b 100644
--- a/third_party/blink/web_tests/FlagExpectations/use-vulkan=native
+++ b/third_party/blink/web_tests/FlagExpectations/use-vulkan=native
@@ -66,3 +66,34 @@
 
 # Not rendering the rightmost frame.
 crbug.com/1001616 media/alpha-video-playback.html [ Skip ]
+
+# OffscreenCanvas not rendering.
+crbug.com/1002538 fast/canvas/OffscreenCanvas-2d-drawImage-in-worker.html [ Skip ]
+crbug.com/1002538 fast/canvas/OffscreenCanvas-2d-drawImage.html [ Skip ]
+crbug.com/1002538 fast/canvas/OffscreenCanvas-2d-gradients-in-worker.html [ Skip ]
+crbug.com/1002538 fast/canvas/OffscreenCanvas-2d-imageSmoothing-in-worker.html [ Skip ]
+crbug.com/1002538 fast/canvas/OffscreenCanvas-2d-imageSmoothing.html [ Skip ]
+crbug.com/1002538 fast/canvas/OffscreenCanvas-2d-pattern-in-worker.html [ Skip ]
+crbug.com/1002538 fast/canvas/OffscreenCanvas-2d-pattern.html [ Skip ]
+crbug.com/1002538 fast/canvas/OffscreenCanvas-Bitmaprenderer-TransferToImageBitmapResetsToBlack.html [ Skip ]
+crbug.com/1002538 fast/canvas/OffscreenCanvas-clearRect-in-worker.html [ Skip ]
+crbug.com/1002538 fast/canvas/OffscreenCanvas-fillRect-in-worker.html [ Skip ]
+crbug.com/1002538 fast/canvas/OffscreenCanvas-filter-in-worker.html [ Skip ]
+crbug.com/1002538 fast/canvas/OffscreenCanvas-paths-in-worker.html [ Skip ]
+crbug.com/1002538 fast/canvas/OffscreenCanvas-strokeRect-in-worker.html [ Skip ]
+crbug.com/1002538 fast/canvas/OffscreenCanvas-text-FontFace-in-worker.html [ Skip ]
+crbug.com/1002538 fast/canvas/OffscreenCanvas-text-rendering-in-worker.html [ Skip ]
+crbug.com/1002538 fast/canvas/OffscreenCanvas-transform-shadow-in-worker.html [ Skip ]
+
+# Expected Image Region Rendering Nothing.
+crbug.com/1002547 fast/canvas/imagebitmap/transferFromImageBitmap-alpha.html [ Skip ]
+crbug.com/1002547 fast/canvas/imagebitmap/transferFromImageBitmap-no-alpha.html [ Skip ]
+crbug.com/1002547 fast/canvas/imagebitmap/transferFromImageBitmap.html [ Skip ]
+
+# Canvas not painting correctly.
+crbug.com/1003794 fast/canvas/canvas-composite-video-shadow.html [ Skip ]
+crbug.com/1003794 fast/canvas/canvas-composite-video.html [ Skip ]
+crbug.com/1003794 fast/canvas/canvas-pattern-video.html [ Skip ]
+
+# createImageBitmap fails for HTMLVideoElement
+crbug.com/1003799 fast/canvas/color-space/canvas-createImageBitmap-p3.html [ Skip ]
diff --git a/third_party/blink/web_tests/FlagExpectations/use-vulkan=swiftshader b/third_party/blink/web_tests/FlagExpectations/use-vulkan=swiftshader
index 3cda21f..cd3775b 100644
--- a/third_party/blink/web_tests/FlagExpectations/use-vulkan=swiftshader
+++ b/third_party/blink/web_tests/FlagExpectations/use-vulkan=swiftshader
@@ -19,3 +19,34 @@
 
 # Not rendering the rightmost frame.
 crbug.com/1001616 media/alpha-video-playback.html [ Skip ]
+
+# OffscreenCanvas not rendering.
+crbug.com/1002538 fast/canvas/OffscreenCanvas-2d-drawImage-in-worker.html [ Skip ]
+crbug.com/1002538 fast/canvas/OffscreenCanvas-2d-drawImage.html [ Skip ]
+crbug.com/1002538 fast/canvas/OffscreenCanvas-2d-gradients-in-worker.html [ Skip ]
+crbug.com/1002538 fast/canvas/OffscreenCanvas-2d-imageSmoothing-in-worker.html [ Skip ]
+crbug.com/1002538 fast/canvas/OffscreenCanvas-2d-imageSmoothing.html [ Skip ]
+crbug.com/1002538 fast/canvas/OffscreenCanvas-2d-pattern-in-worker.html [ Skip ]
+crbug.com/1002538 fast/canvas/OffscreenCanvas-2d-pattern.html [ Skip ]
+crbug.com/1002538 fast/canvas/OffscreenCanvas-Bitmaprenderer-TransferToImageBitmapResetsToBlack.html [ Skip ]
+crbug.com/1002538 fast/canvas/OffscreenCanvas-clearRect-in-worker.html [ Skip ]
+crbug.com/1002538 fast/canvas/OffscreenCanvas-fillRect-in-worker.html [ Skip ]
+crbug.com/1002538 fast/canvas/OffscreenCanvas-filter-in-worker.html [ Skip ]
+crbug.com/1002538 fast/canvas/OffscreenCanvas-paths-in-worker.html [ Skip ]
+crbug.com/1002538 fast/canvas/OffscreenCanvas-strokeRect-in-worker.html [ Skip ]
+crbug.com/1002538 fast/canvas/OffscreenCanvas-text-FontFace-in-worker.html [ Skip ]
+crbug.com/1002538 fast/canvas/OffscreenCanvas-text-rendering-in-worker.html [ Skip ]
+crbug.com/1002538 fast/canvas/OffscreenCanvas-transform-shadow-in-worker.html [ Skip ]
+
+# Expected Image Region Rendering Nothing.
+crbug.com/1002547 fast/canvas/imagebitmap/transferFromImageBitmap-alpha.html [ Skip ]
+crbug.com/1002547 fast/canvas/imagebitmap/transferFromImageBitmap-no-alpha.html [ Skip ]
+crbug.com/1002547 fast/canvas/imagebitmap/transferFromImageBitmap.html [ Skip ]
+
+# Canvas not painting correctly.
+crbug.com/1003794 fast/canvas/canvas-composite-video-shadow.html [ Skip ]
+crbug.com/1003794 fast/canvas/canvas-composite-video.html [ Skip ]
+crbug.com/1003794 fast/canvas/canvas-pattern-video.html [ Skip ]
+
+# createImageBitmap fails for HTMLVideoElement
+crbug.com/1003799 fast/canvas/color-space/canvas-createImageBitmap-p3.html [ Skip ]
diff --git a/third_party/blink/web_tests/LeakExpectations b/third_party/blink/web_tests/LeakExpectations
index 1d97ec5..4555e10 100644
--- a/third_party/blink/web_tests/LeakExpectations
+++ b/third_party/blink/web_tests/LeakExpectations
@@ -36,11 +36,6 @@
 crbug.com/860117 [ Linux ] editing/pasteboard/drag-drop-iframe-refresh-crash.html [ Pass Leak ]
 crbug.com/976438 [ Linux ] external/wpt/css/selectors/focus-visible-007.html [ Pass Leak ]
 
-# -----------------------------------------------------------------
-# Not revert suspected CL as jam@ request, expected to be fixed soon.
-# -----------------------------------------------------------------
-crbug.com/765721 [ Linux ] http/tests/navigation/navigation-interrupted-by-fragment.html [ Pass Leak ]
-crbug.com/765721 [ Linux ] virtual/stable/http/tests/navigation/navigation-interrupted-by-fragment.html [ Pass Leak ]
 
 crbug.com/809609 [ Linux ] editing/pasteboard/drop-file-svg.html [ Pass Leak ]
 crbug.com/809609 [ Linux ] editing/inserting/insert_div_with_style.html [ Pass Leak ]
diff --git a/third_party/blink/web_tests/SlowTests b/third_party/blink/web_tests/SlowTests
index e68e06db..eb14621 100644
--- a/third_party/blink/web_tests/SlowTests
+++ b/third_party/blink/web_tests/SlowTests
@@ -570,7 +570,6 @@
 crbug.com/874695 virtual/mouseevent_fractional/fast/events/touch/gesture/gesture-click.html [ Slow ]
 crbug.com/874695 virtual/mouseevent_fractional/fast/events/touch/touch-slider-no-js-touch-listener.html [ Slow ]
 crbug.com/874695 virtual/scroll_customization/fast/scroll-behavior/overscroll-behavior.html [ Slow ]
-crbug.com/874695 virtual/stable/http/tests/navigation/navigation-interrupted-by-fragment.html [ Slow ]
 crbug.com/874695 virtual/stable/http/tests/navigation/new-window-redirect-history.html [ Slow ]
 crbug.com/874695 virtual/stable/http/tests/navigation/slowmetaredirect-basic.html [ Slow ]
 crbug.com/874695 virtual/stable/http/tests/navigation/slowtimerredirect-basic.html [ Slow ]
diff --git a/third_party/blink/web_tests/TestExpectations b/third_party/blink/web_tests/TestExpectations
index a71ecd2..d796a83 100644
--- a/third_party/blink/web_tests/TestExpectations
+++ b/third_party/blink/web_tests/TestExpectations
@@ -255,10 +255,6 @@
 # MSAN failure
 crbug.com/996625 inspector-protocol/accessibility/accessibility-getFullAXTree-display-locked.js [ Skip ]
 
-# Sheriff 2018/05/25
-crbug.com/846747 http/tests/navigation/navigation-interrupted-by-fragment.html  [ Pass Timeout ]
-crbug.com/846747 virtual/stable/http/tests/navigation/navigation-interrupted-by-fragment.html  [ Pass Timeout ]
-
 crbug.com/849459 fragmentation/repeating-thead-under-repeating-thead.html [ Failure ]
 
 # These tests are no longer applicable in BlinkGenPropertyTree mode.
diff --git a/third_party/blink/web_tests/VirtualTestSuites b/third_party/blink/web_tests/VirtualTestSuites
index 6542ae73..31a376e 100644
--- a/third_party/blink/web_tests/VirtualTestSuites
+++ b/third_party/blink/web_tests/VirtualTestSuites
@@ -439,47 +439,47 @@
   {
     "prefix": "dark-mode",
     "base": "paint/dark-mode/grayscale-images",
-    "args": ["--blink-settings=darkMode=3,darkModeImagePolicy=0,darkModeImageStyle=1,darkModeTextBrightnessThreshold=256,darkModeBackgroundBrightnessThreshold=0"]
+    "args": ["--blink-settings=darkModeInversionAlgorithm=3,darkModeImagePolicy=0,darkModeImageStyle=1,darkModeTextBrightnessThreshold=256,darkModeBackgroundBrightnessThreshold=0"]
   },
   {
     "prefix": "dark-mode",
     "base": "paint/dark-mode/image-filter-all",
-    "args": ["--blink-settings=darkMode=3,darkModeImagePolicy=0,darkModeTextBrightnessThreshold=256,darkModeBackgroundBrightnessThreshold=0"]
+    "args": ["--blink-settings=darkModeInversionAlgorithm=3,darkModeImagePolicy=0,darkModeTextBrightnessThreshold=256,darkModeBackgroundBrightnessThreshold=0"]
   },
   {
     "prefix": "dark-mode",
     "base": "paint/dark-mode/image-filter-none",
-    "args": ["--blink-settings=darkMode=3,darkModeImagePolicy=1,darkModeTextBrightnessThreshold=256,darkModeBackgroundBrightnessThreshold=0"]
+    "args": ["--blink-settings=darkModeInversionAlgorithm=3,darkModeImagePolicy=1,darkModeTextBrightnessThreshold=256,darkModeBackgroundBrightnessThreshold=0"]
   },
   {
     "prefix": "dark-mode",
     "base": "paint/dark-mode/image-filter-smart",
-    "args": ["--blink-settings=darkMode=3,darkModeImagePolicy=2,darkModeTextBrightnessThreshold=256,darkModeBackgroundBrightnessThreshold=0"]
+    "args": ["--blink-settings=darkModeInversionAlgorithm=3,darkModeImagePolicy=2,darkModeTextBrightnessThreshold=256,darkModeBackgroundBrightnessThreshold=0"]
   },
   {
     "prefix": "dark-mode",
     "base": "paint/dark-mode/native-theme-off",
-    "args": ["--blink-settings=darkMode=3,darkModeTextBrightnessThreshold=256,darkModeBackgroundBrightnessThreshold=0"]
+    "args": ["--blink-settings=darkModeInversionAlgorithm=3,darkModeTextBrightnessThreshold=256,darkModeBackgroundBrightnessThreshold=0"]
   },
   {
     "prefix": "dark-mode",
     "base": "paint/dark-mode/native-theme-on",
-    "args": ["--blink-settings=darkMode=3,darkModeTextBrightnessThreshold=256,darkModeBackgroundBrightnessThreshold=0"]
+    "args": ["--blink-settings=darkModeInversionAlgorithm=3,darkModeTextBrightnessThreshold=256,darkModeBackgroundBrightnessThreshold=0"]
   },
   {
     "prefix": "dark-mode",
     "base": "paint/dark-mode/page-policy-all",
-    "args": ["--blink-settings=darkMode=3,darkModePagePolicy=0,darkModeTextBrightnessThreshold=256,darkModeBackgroundBrightnessThreshold=0"]
+    "args": ["--blink-settings=darkModeInversionAlgorithm=3,darkModePagePolicy=0,darkModeTextBrightnessThreshold=256,darkModeBackgroundBrightnessThreshold=0"]
   },
   {
     "prefix": "dark-mode",
     "base": "paint/dark-mode/page-policy-background",
-    "args": ["--blink-settings=darkMode=3,darkModePagePolicy=1,darkModeTextBrightnessThreshold=256,darkModeBackgroundBrightnessThreshold=0"]
+    "args": ["--blink-settings=darkModeInversionAlgorithm=3,darkModePagePolicy=1,darkModeTextBrightnessThreshold=256,darkModeBackgroundBrightnessThreshold=0"]
   },
   {
     "prefix": "dark-mode",
     "base": "paint/dark-mode/svg-invert-all",
-    "args": ["--blink-settings=darkMode=3,darkModeImagePolicy=0,darkModeTextBrightnessThreshold=256,darkModeBackgroundBrightnessThreshold=0"]
+    "args": ["--blink-settings=darkModeInversionAlgorithm=3,darkModeImagePolicy=0,darkModeTextBrightnessThreshold=256,darkModeBackgroundBrightnessThreshold=0"]
   },
   {
     "prefix": "presentation",
diff --git a/third_party/blink/web_tests/compositing/overflow/do-not-crash-use-after-free-update-widget-positions.html b/third_party/blink/web_tests/compositing/overflow/do-not-crash-use-after-free-update-widget-positions.html
index 8f4d71c..5fa8b72 100644
--- a/third_party/blink/web_tests/compositing/overflow/do-not-crash-use-after-free-update-widget-positions.html
+++ b/third_party/blink/web_tests/compositing/overflow/do-not-crash-use-after-free-update-widget-positions.html
@@ -36,6 +36,8 @@
   }
 
   function iframeOnLoad() {
+    w3Iframe.onload = undefined;
+
     bodyElement.appendChild(acronymElement);
     acronymElement.offsetWidth;
 
diff --git a/third_party/blink/web_tests/external/wpt/html/semantics/scripting-1/the-script-element/module/referrer-no-referrer.sub.html b/third_party/blink/web_tests/external/wpt/html/semantics/scripting-1/the-script-element/module/referrer-no-referrer.sub.html
index e640fe4..e50c7b52 100644
--- a/third_party/blink/web_tests/external/wpt/html/semantics/scripting-1/the-script-element/module/referrer-no-referrer.sub.html
+++ b/third_party/blink/web_tests/external/wpt/html/semantics/scripting-1/the-script-element/module/referrer-no-referrer.sub.html
@@ -21,8 +21,6 @@
 
 import { referrer as referrerRemoteRemote } from "http://{{domains[www1]}}:{{ports[http][0]}}/html/semantics/scripting-1/the-script-element/module/resources/import-referrer-checker.sub.js?name=remote_remote";
 
-import { referrer as referrerRemoteSame } from "http://{{domains[www1]}}:{{ports[http][0]}}/html/semantics/scripting-1/the-script-element/module/resources/import-same-origin-referrer-checker-from-remote-origin.sub.js?name=remote_same";
-
 test(t => {
   assert_equals(
       referrerSame, "",
@@ -51,9 +49,9 @@
 
 test(t => {
   assert_equals(
-      referrerRemoteSame, "",
-      "Referrer should not be sent for the same-origin descendant script.");
-}, "Importing a same-origin descendant script from a remote-origin " +
+      referrerRemoteRemote, "",
+      "Referrer should not be sent for the remote-origin descendant script.");
+}, "Importing a remote-origin descendant script from a remote-origin " +
    "top-level script with the no-referrer policy.");
 
 </script>
diff --git a/third_party/blink/web_tests/external/wpt/html/semantics/scripting-1/the-script-element/module/referrer-origin-when-cross-origin.sub-expected.txt b/third_party/blink/web_tests/external/wpt/html/semantics/scripting-1/the-script-element/module/referrer-origin-when-cross-origin.sub-expected.txt
new file mode 100644
index 0000000..cd990f90
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/html/semantics/scripting-1/the-script-element/module/referrer-origin-when-cross-origin.sub-expected.txt
@@ -0,0 +1,8 @@
+This is a testharness.js-based test.
+PASS Importing a same-origin top-level script with the origin-when-cross-origin policy.
+PASS Importing a remote-origin top-level script with the origin-when-cross-origin policy.
+PASS Importing a same-origin descendant script from a same-origin top-level script with the origin-when-cross-origin policy.
+PASS Importing a remote-origin descendant script from a same-origin top-level script with the origin-when-cross-origin policy.
+FAIL Importing a remote-origin descendant script from a remote-origin top-level script with the origin-when-cross-origin policy. assert_equals: Referrer should be sent for the remote-origin descendant script. expected "http://www1.web-platform.test:8001/" but got "http://www1.web-platform.test:8001/html/semantics/scripting-1/the-script-element/module/resources/import-referrer-checker.sub.js?name=remote_remote"
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/external/wpt/html/semantics/scripting-1/the-script-element/module/referrer-origin-when-cross-origin.sub.html b/third_party/blink/web_tests/external/wpt/html/semantics/scripting-1/the-script-element/module/referrer-origin-when-cross-origin.sub.html
index 1ca6b1df..3623ac2 100644
--- a/third_party/blink/web_tests/external/wpt/html/semantics/scripting-1/the-script-element/module/referrer-origin-when-cross-origin.sub.html
+++ b/third_party/blink/web_tests/external/wpt/html/semantics/scripting-1/the-script-element/module/referrer-origin-when-cross-origin.sub.html
@@ -21,8 +21,6 @@
 
 import { referrer as referrerRemoteRemote } from "http://{{domains[www1]}}:{{ports[http][0]}}/html/semantics/scripting-1/the-script-element/module/resources/import-referrer-checker.sub.js?name=remote_remote";
 
-import { referrer as referrerRemoteSame } from "http://{{domains[www1]}}:{{ports[http][0]}}/html/semantics/scripting-1/the-script-element/module/resources/import-same-origin-referrer-checker-from-remote-origin.sub.js?name=remote_same";
-
 const origin = (new URL(location.href)).origin + "/";
 const remoteOrigin = "http://{{domains[www1]}}:{{ports[http][0]}}/";
 
@@ -39,6 +37,7 @@
       "Referrer should be sent for the remote-origin top-level script.");
 }, "Importing a remote-origin top-level script with the " +
    "origin-when-cross-origin policy.");
+
 test(t => {
   const scriptURL =
       new URL("resources/import-referrer-checker.sub.js", location.href)
@@ -47,6 +46,7 @@
       "Referrer should be sent for the same-origin descendant script.");
 }, "Importing a same-origin descendant script from a same-origin top-level " +
    "script with the origin-when-cross-origin policy.");
+
 test(t => {
   assert_equals(
       referrerSameRemote, origin,
@@ -61,16 +61,6 @@
 }, "Importing a remote-origin descendant script from a remote-origin " +
    "top-level script with the origin-when-cross-origin policy.");
 
-test(t => {
-  const scriptURL = new URL(
-    "html/semantics/scripting-1/the-script-element/module/resources/" +
-    "import-same-origin-referrer-checker-from-remote-origin.sub.js",
-    remoteOrigin);
-  assert_equals(referrerRemoteSame, scriptURL + "?name=remote_same",
-      "Referrer should be sent for the same-origin descendant script.");
-}, "Importing a same-origin descendant script from a remote-origin " +
-   "top-level script with the origin-when-cross-origin policy.");
-
 </script>
 </body>
 </html>
diff --git a/third_party/blink/web_tests/external/wpt/html/semantics/scripting-1/the-script-element/module/referrer-origin.sub.html b/third_party/blink/web_tests/external/wpt/html/semantics/scripting-1/the-script-element/module/referrer-origin.sub.html
index a554fb4..f512982a 100644
--- a/third_party/blink/web_tests/external/wpt/html/semantics/scripting-1/the-script-element/module/referrer-origin.sub.html
+++ b/third_party/blink/web_tests/external/wpt/html/semantics/scripting-1/the-script-element/module/referrer-origin.sub.html
@@ -21,8 +21,6 @@
 
 import { referrer as referrerRemoteRemote } from "http://{{domains[www1]}}:{{ports[http][0]}}/html/semantics/scripting-1/the-script-element/module/resources/import-referrer-checker.sub.js?name=remote_remote";
 
-import { referrer as referrerRemoteSame } from "http://{{domains[www1]}}:{{ports[http][0]}}/html/semantics/scripting-1/the-script-element/module/resources/import-same-origin-referrer-checker-from-remote-origin.sub.js?name=remote_same";
-
 const origin = (new URL(location.href)).origin + "/";
 const remoteOrigin = "http://{{domains[www1]}}:{{ports[http][0]}}/";
 
@@ -59,13 +57,6 @@
 }, "Importing a remote-origin descendant script from a remote-origin " +
    "top-level script with the origin policy.");
 
-test(t => {
-  assert_equals(
-      referrerRemoteSame, remoteOrigin,
-      "Referrer should be sent for the same-origin descendant script.");
-}, "Importing a same-origin descendant script from a remote-origin " +
-   "top-level script with the origin policy.");
-
 </script>
 </body>
 </html>
diff --git a/third_party/blink/web_tests/external/wpt/html/semantics/scripting-1/the-script-element/module/referrer-same-origin.sub-expected.txt b/third_party/blink/web_tests/external/wpt/html/semantics/scripting-1/the-script-element/module/referrer-same-origin.sub-expected.txt
new file mode 100644
index 0000000..6720439b
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/html/semantics/scripting-1/the-script-element/module/referrer-same-origin.sub-expected.txt
@@ -0,0 +1,8 @@
+This is a testharness.js-based test.
+PASS Importing a same-origin top-level script with the same-origin policy.
+PASS Importing a remote-origin top-level script with the same-origin policy.
+PASS Importing a same-origin descendant script from a same-origin top-level script with the same-origin policy.
+PASS Importing a remote-origin descendant script from a same-origin top-level script with the same-origin policy.
+FAIL Importing a remote-origin descendant script from a remote-origin top-level script with the same-origin policy. assert_equals: Referrer should not be sent for the remote-origin descendant script even if it is imported from the script in the same remote-origin. expected "" but got "http://www1.web-platform.test:8001/html/semantics/scripting-1/the-script-element/module/resources/import-referrer-checker.sub.js?name=remote_remote"
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/external/wpt/html/semantics/scripting-1/the-script-element/module/referrer-same-origin.sub.html b/third_party/blink/web_tests/external/wpt/html/semantics/scripting-1/the-script-element/module/referrer-same-origin.sub.html
index 1d470e6..67b055c 100644
--- a/third_party/blink/web_tests/external/wpt/html/semantics/scripting-1/the-script-element/module/referrer-same-origin.sub.html
+++ b/third_party/blink/web_tests/external/wpt/html/semantics/scripting-1/the-script-element/module/referrer-same-origin.sub.html
@@ -21,10 +21,6 @@
 
 import { referrer as referrerRemoteRemote } from "http://{{domains[www1]}}:{{ports[http][0]}}/html/semantics/scripting-1/the-script-element/module/resources/import-referrer-checker.sub.js?name=remote_remote";
 
-import { referrer as referrerRemoteSame } from "http://{{domains[www1]}}:{{ports[http][0]}}/html/semantics/scripting-1/the-script-element/module/resources/import-same-origin-referrer-checker-from-remote-origin.sub.js?name=remote_same";
-
-const remoteOrigin = "http://{{domains[www1]}}:{{ports[http][0]}}/";
-
 test(t => {
   assert_equals(
       referrerSame, location.href,
@@ -61,18 +57,6 @@
 }, "Importing a remote-origin descendant script from a remote-origin " +
    "top-level script with the same-origin policy.");
 
-test(t => {
-  const scriptURL = new URL(
-    "html/semantics/scripting-1/the-script-element/module/resources/" +
-    "import-same-origin-referrer-checker-from-remote-origin.sub.js",
-    remoteOrigin);
-  assert_equals(
-      referrerRemoteSame, scriptURL + "?name=remote_same",
-      "Referrer should be sent for the same-origin descendant script " +
-      "even if it is imported from the script in the remote-origin.");
-}, "Importing a same-origin descendant script from a remote-origin " +
-   "top-level script with the same-origin policy.");
-
 </script>
 </body>
 </html>
diff --git a/third_party/blink/web_tests/external/wpt/html/semantics/scripting-1/the-script-element/module/referrer-unsafe-url.sub.html b/third_party/blink/web_tests/external/wpt/html/semantics/scripting-1/the-script-element/module/referrer-unsafe-url.sub.html
index 443731c..11f60c0 100644
--- a/third_party/blink/web_tests/external/wpt/html/semantics/scripting-1/the-script-element/module/referrer-unsafe-url.sub.html
+++ b/third_party/blink/web_tests/external/wpt/html/semantics/scripting-1/the-script-element/module/referrer-unsafe-url.sub.html
@@ -21,8 +21,6 @@
 
 import { referrer as referrerRemoteRemote } from "http://{{domains[www1]}}:{{ports[http][0]}}/html/semantics/scripting-1/the-script-element/module/resources/import-referrer-checker.sub.js?name=remote_remote";
 
-import { referrer as referrerRemoteSame } from "http://{{domains[www1]}}:{{ports[http][0]}}/html/semantics/scripting-1/the-script-element/module/resources/import-same-origin-referrer-checker-from-remote-origin.sub.js?name=remote_same";
-
 test(t => {
   assert_equals(
       referrerSame, location.href,
@@ -65,17 +63,6 @@
 }, "Importing a remote-origin descendant script from a remote-origin " +
    "top-level script with the unsafe-url policy.");
 
-test(t => {
-  const scriptURL =
-      "http://{{domains[www1]}}:{{ports[http][0]}}/html/semantics/" +
-      "scripting-1/the-script-element/module/resources/" +
-      "import-same-origin-referrer-checker-from-remote-origin.sub.js";
-  assert_equals(
-      referrerRemoteSame, scriptURL + "?name=remote_same",
-      "Referrer should be sent for the same-origin descendant script.");
-}, "Importing a same-origin descendant script from a remote-origin " +
-   "top-level script with the unsafe-url policy.");
-
 </script>
 </body>
 </html>
diff --git a/third_party/blink/web_tests/external/wpt/html/semantics/scripting-1/the-script-element/module/resources/import-same-origin-referrer-checker-from-remote-origin.sub.js b/third_party/blink/web_tests/external/wpt/html/semantics/scripting-1/the-script-element/module/resources/import-same-origin-referrer-checker-from-remote-origin.sub.js
deleted file mode 100644
index 5a53bcd..0000000
--- a/third_party/blink/web_tests/external/wpt/html/semantics/scripting-1/the-script-element/module/resources/import-same-origin-referrer-checker-from-remote-origin.sub.js
+++ /dev/null
@@ -1,2 +0,0 @@
-import { referrer as referrerImport } from 'http://{{host}}:{{ports[http][0]}}/html/semantics/scripting-1/the-script-element/module/resources/referrer-checker.py?name={{GET[name]}}';
-export const referrer = referrerImport;
diff --git a/third_party/blink/web_tests/external/wpt/html/semantics/scripting-1/the-script-element/module/resources/import-same-origin-referrer-checker-from-remote-origin.sub.js.headers b/third_party/blink/web_tests/external/wpt/html/semantics/scripting-1/the-script-element/module/resources/import-same-origin-referrer-checker-from-remote-origin.sub.js.headers
deleted file mode 100644
index cb762eff..0000000
--- a/third_party/blink/web_tests/external/wpt/html/semantics/scripting-1/the-script-element/module/resources/import-same-origin-referrer-checker-from-remote-origin.sub.js.headers
+++ /dev/null
@@ -1 +0,0 @@
-Access-Control-Allow-Origin: *
diff --git a/third_party/blink/web_tests/external/wpt/worklets/animation-worklet-referrer.https-expected.txt b/third_party/blink/web_tests/external/wpt/worklets/animation-worklet-referrer.https-expected.txt
new file mode 100644
index 0000000..d605c756
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/worklets/animation-worklet-referrer.https-expected.txt
@@ -0,0 +1,18 @@
+This is a testharness.js-based test.
+PASS Importing a same-origin script from a page that has "no-referrer" referrer policy should not send referrer.
+PASS Importing a remote-origin script from a page that has "no-referrer" referrer policy should not send referrer.
+PASS Importing a same-origin script from a page that has "origin" referrer policy should send only an origin as referrer.
+PASS Importing a remote-origin script from a page that has "origin" referrer policy should send only an origin as referrer.
+PASS Importing a same-origin script from a page that has "same-origin" referrer policy should send referrer.
+PASS Importing a remote-origin script from a page that has "same-origin" referrer policy should not send referrer.
+PASS Importing a same-origin script from a same-origin worklet script that has "no-referrer" referrer policy should not send referrer.
+PASS Importing a remote-origin script from a same-origin worklet script that has "no-referrer" referrer policy should not send referrer.
+PASS Importing a remote-origin script from a remote-origin worklet script that has "no-referrer" referrer policy should not send referrer.
+PASS Importing a same-origin script from a same-origin worklet script that has "origin" referrer policy should send referrer.
+PASS Importing a remote-origin script from a same-origin worklet script that has "origin" referrer policy should send referrer.
+PASS Importing a remote-origin script from a remote-origin worklet script that has "origin" referrer policy should send referrer.
+PASS Importing a same-origin script from a same-origin worklet script that has "same-origin" referrer policy should send referrer.
+PASS Importing a remote-origin script from a same-origin worklet script that has "same-origin" referrer policy should not send referrer.
+FAIL Importing a remote-origin script from a remote-origin worklet script that has "same-origin" referrer policy should not send referrer. assert_equals: expected "RESOLVED" but got "The user aborted a request."
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/external/wpt/worklets/audio-worklet-referrer.https-expected.txt b/third_party/blink/web_tests/external/wpt/worklets/audio-worklet-referrer.https-expected.txt
new file mode 100644
index 0000000..d605c756
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/worklets/audio-worklet-referrer.https-expected.txt
@@ -0,0 +1,18 @@
+This is a testharness.js-based test.
+PASS Importing a same-origin script from a page that has "no-referrer" referrer policy should not send referrer.
+PASS Importing a remote-origin script from a page that has "no-referrer" referrer policy should not send referrer.
+PASS Importing a same-origin script from a page that has "origin" referrer policy should send only an origin as referrer.
+PASS Importing a remote-origin script from a page that has "origin" referrer policy should send only an origin as referrer.
+PASS Importing a same-origin script from a page that has "same-origin" referrer policy should send referrer.
+PASS Importing a remote-origin script from a page that has "same-origin" referrer policy should not send referrer.
+PASS Importing a same-origin script from a same-origin worklet script that has "no-referrer" referrer policy should not send referrer.
+PASS Importing a remote-origin script from a same-origin worklet script that has "no-referrer" referrer policy should not send referrer.
+PASS Importing a remote-origin script from a remote-origin worklet script that has "no-referrer" referrer policy should not send referrer.
+PASS Importing a same-origin script from a same-origin worklet script that has "origin" referrer policy should send referrer.
+PASS Importing a remote-origin script from a same-origin worklet script that has "origin" referrer policy should send referrer.
+PASS Importing a remote-origin script from a remote-origin worklet script that has "origin" referrer policy should send referrer.
+PASS Importing a same-origin script from a same-origin worklet script that has "same-origin" referrer policy should send referrer.
+PASS Importing a remote-origin script from a same-origin worklet script that has "same-origin" referrer policy should not send referrer.
+FAIL Importing a remote-origin script from a remote-origin worklet script that has "same-origin" referrer policy should not send referrer. assert_equals: expected "RESOLVED" but got "The user aborted a request."
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/external/wpt/worklets/layout-worklet-referrer.https-expected.txt b/third_party/blink/web_tests/external/wpt/worklets/layout-worklet-referrer.https-expected.txt
new file mode 100644
index 0000000..d605c756
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/worklets/layout-worklet-referrer.https-expected.txt
@@ -0,0 +1,18 @@
+This is a testharness.js-based test.
+PASS Importing a same-origin script from a page that has "no-referrer" referrer policy should not send referrer.
+PASS Importing a remote-origin script from a page that has "no-referrer" referrer policy should not send referrer.
+PASS Importing a same-origin script from a page that has "origin" referrer policy should send only an origin as referrer.
+PASS Importing a remote-origin script from a page that has "origin" referrer policy should send only an origin as referrer.
+PASS Importing a same-origin script from a page that has "same-origin" referrer policy should send referrer.
+PASS Importing a remote-origin script from a page that has "same-origin" referrer policy should not send referrer.
+PASS Importing a same-origin script from a same-origin worklet script that has "no-referrer" referrer policy should not send referrer.
+PASS Importing a remote-origin script from a same-origin worklet script that has "no-referrer" referrer policy should not send referrer.
+PASS Importing a remote-origin script from a remote-origin worklet script that has "no-referrer" referrer policy should not send referrer.
+PASS Importing a same-origin script from a same-origin worklet script that has "origin" referrer policy should send referrer.
+PASS Importing a remote-origin script from a same-origin worklet script that has "origin" referrer policy should send referrer.
+PASS Importing a remote-origin script from a remote-origin worklet script that has "origin" referrer policy should send referrer.
+PASS Importing a same-origin script from a same-origin worklet script that has "same-origin" referrer policy should send referrer.
+PASS Importing a remote-origin script from a same-origin worklet script that has "same-origin" referrer policy should not send referrer.
+FAIL Importing a remote-origin script from a remote-origin worklet script that has "same-origin" referrer policy should not send referrer. assert_equals: expected "RESOLVED" but got "The user aborted a request."
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/external/wpt/worklets/paint-worklet-referrer.https-expected.txt b/third_party/blink/web_tests/external/wpt/worklets/paint-worklet-referrer.https-expected.txt
new file mode 100644
index 0000000..d605c756
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/worklets/paint-worklet-referrer.https-expected.txt
@@ -0,0 +1,18 @@
+This is a testharness.js-based test.
+PASS Importing a same-origin script from a page that has "no-referrer" referrer policy should not send referrer.
+PASS Importing a remote-origin script from a page that has "no-referrer" referrer policy should not send referrer.
+PASS Importing a same-origin script from a page that has "origin" referrer policy should send only an origin as referrer.
+PASS Importing a remote-origin script from a page that has "origin" referrer policy should send only an origin as referrer.
+PASS Importing a same-origin script from a page that has "same-origin" referrer policy should send referrer.
+PASS Importing a remote-origin script from a page that has "same-origin" referrer policy should not send referrer.
+PASS Importing a same-origin script from a same-origin worklet script that has "no-referrer" referrer policy should not send referrer.
+PASS Importing a remote-origin script from a same-origin worklet script that has "no-referrer" referrer policy should not send referrer.
+PASS Importing a remote-origin script from a remote-origin worklet script that has "no-referrer" referrer policy should not send referrer.
+PASS Importing a same-origin script from a same-origin worklet script that has "origin" referrer policy should send referrer.
+PASS Importing a remote-origin script from a same-origin worklet script that has "origin" referrer policy should send referrer.
+PASS Importing a remote-origin script from a remote-origin worklet script that has "origin" referrer policy should send referrer.
+PASS Importing a same-origin script from a same-origin worklet script that has "same-origin" referrer policy should send referrer.
+PASS Importing a remote-origin script from a same-origin worklet script that has "same-origin" referrer policy should not send referrer.
+FAIL Importing a remote-origin script from a remote-origin worklet script that has "same-origin" referrer policy should not send referrer. assert_equals: expected "RESOLVED" but got "The user aborted a request."
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/http/tests/broadcastchannel/resources/create-broadcastchannel-verify-third-party-use-counter.html b/third_party/blink/web_tests/http/tests/broadcastchannel/resources/create-broadcastchannel-verify-third-party-use-counter.html
new file mode 100644
index 0000000..762708b2
--- /dev/null
+++ b/third_party/blink/web_tests/http/tests/broadcastchannel/resources/create-broadcastchannel-verify-third-party-use-counter.html
@@ -0,0 +1,18 @@
+<body></body>
+<script>
+// |kThirdPartyBroadcastChannel| from web_feature.mojom.
+const kFeature = 3033;
+
+async function verifyUseCounter() {
+  await window.internals.observeUseCounter(document, kFeature);
+}
+
+window.onload = function() {
+  var bc = new BroadcastChannel('test_channel');
+  verifyUseCounter();
+  if (window.internals.isUseCounted(document, kFeature)) {
+    window.parent.postMessage('verified_has_use_counter', '*');
+  }
+};
+
+</script>
\ No newline at end of file
diff --git a/third_party/blink/web_tests/http/tests/broadcastchannel/use-counter-third-party-broadcastchannel.html b/third_party/blink/web_tests/http/tests/broadcastchannel/use-counter-third-party-broadcastchannel.html
new file mode 100644
index 0000000..44e4bd9
--- /dev/null
+++ b/third_party/blink/web_tests/http/tests/broadcastchannel/use-counter-third-party-broadcastchannel.html
@@ -0,0 +1,39 @@
+<!DOCTYPE html>
+<!-- Tests UseCounter for 'new BroadcastChannel()' in third party context. This
+  cannot be upstreamed to WPT because it tests Chrome's UseCounter mechanism.
+-->
+<meta charset="utf-8">
+<title>Test UseCounter for 'new BroadcastChannel()' in third party context.</title>
+<body></body>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/resources/get-host-info.js"></script>
+<script>
+
+function with_iframe(url) {
+  return new Promise(function(resolve) {
+      var frame = document.createElement('iframe');
+      frame.src = url;
+      frame.onload = function() { resolve(frame); };
+      document.body.appendChild(frame);
+    });
+}
+
+function child_frame_has_verified_use_counter() {
+  return new Promise(function(resolve, reject) {
+      window.onmessage = (msg) => {
+        if (msg.data == 'verified_has_use_counter')
+          resolve();
+        else
+          reject(msg.data);
+      };
+    });
+}
+
+promise_test(async t => {
+  const remote_origin_url = get_host_info().HTTPS_REMOTE_ORIGIN +
+        '/broadcastchannel/resources/create-broadcastchannel-verify-third-party-use-counter.html';
+  const frame1 = await with_iframe(remote_origin_url);
+  await child_frame_has_verified_use_counter();
+}, "Test UseCounter for 'new BroadcastChannel()' in third party context.");
+</script>
\ No newline at end of file
diff --git a/third_party/blink/web_tests/http/tests/devtools/elements/css-variables/defined-css-variables-expected.txt b/third_party/blink/web_tests/http/tests/devtools/elements/css-variables/defined-css-variables-expected.txt
index 2981203..39af2be 100644
--- a/third_party/blink/web_tests/http/tests/devtools/elements/css-variables/defined-css-variables-expected.txt
+++ b/third_party/blink/web_tests/http/tests/devtools/elements/css-variables/defined-css-variables-expected.txt
@@ -5,11 +5,13 @@
   --another-div-variable
   --div-variable
   --span-variable
+  --camelCased
 span
   --body-variable
   --another-div-variable
   --div-variable
   --span-variable
+  --camelCased
 .myelement
   --body-variable
   --another-div-variable
diff --git a/third_party/blink/web_tests/http/tests/devtools/elements/css-variables/defined-css-variables.js b/third_party/blink/web_tests/http/tests/devtools/elements/css-variables/defined-css-variables.js
index c0acd2f..84255703 100644
--- a/third_party/blink/web_tests/http/tests/devtools/elements/css-variables/defined-css-variables.js
+++ b/third_party/blink/web_tests/http/tests/devtools/elements/css-variables/defined-css-variables.js
@@ -22,6 +22,7 @@
 
       span {
         --span-variable: green;
+        --camelCased: blue;
       }
     </style>
     <body>
diff --git a/third_party/blink/web_tests/http/tests/navigation/fragment-change-does-not-cancel-pending-navigation-expected.txt b/third_party/blink/web_tests/http/tests/navigation/fragment-change-does-not-cancel-pending-navigation-expected.txt
new file mode 100644
index 0000000..7c38a23
--- /dev/null
+++ b/third_party/blink/web_tests/http/tests/navigation/fragment-change-does-not-cancel-pending-navigation-expected.txt
@@ -0,0 +1 @@
+PASS - navigated to ...?done
diff --git a/third_party/blink/web_tests/http/tests/navigation/fragment-change-does-not-cancel-pending-navigation.html b/third_party/blink/web_tests/http/tests/navigation/fragment-change-does-not-cancel-pending-navigation.html
new file mode 100644
index 0000000..9b187425
--- /dev/null
+++ b/third_party/blink/web_tests/http/tests/navigation/fragment-change-does-not-cancel-pending-navigation.html
@@ -0,0 +1,28 @@
+<a href="#" id="anchor"></a>
+<span id="result">FAIL - did not navigate to ...?done</span>
+
+<script>
+if (window.location.href.indexOf('?') !== -1) {
+  document.getElementById('result').textContent = 'PASS - navigated to ...?done';
+  if (window.testRunner)
+    testRunner.notifyDone();
+} else {
+  if (window.testRunner) {
+    testRunner.dumpAsText();
+    testRunner.waitUntilDone();
+  }
+
+  document.getElementById('anchor').addEventListener('click', () => {
+    // Next line should schedule a navigation.
+    location.assign(location.href + '?done');
+    // Default handler should perform fragment scroll
+    // and not cancel scheduled navigation.
+  });
+
+  window.onload = () => {
+    setTimeout(() => {
+      document.getElementById('anchor').click();
+    }, 0);
+  };
+}
+</script>
diff --git a/third_party/blink/web_tests/http/tests/navigation/navigation-interrupted-by-fragment-expected.txt b/third_party/blink/web_tests/http/tests/navigation/navigation-interrupted-by-fragment-expected.txt
deleted file mode 100644
index 4b8d2fe..0000000
--- a/third_party/blink/web_tests/http/tests/navigation/navigation-interrupted-by-fragment-expected.txt
+++ /dev/null
@@ -1,8 +0,0 @@
-CONSOLE MESSAGE: line 23: First visit.
-CONSOLE MESSAGE: line 17: Visited fragment and waited.
-This test checks that interrupting a slow navigation with a fragment navigation will cancel the first navigation.
-
-============== Back Forward List ==============
-        http://127.0.0.1:8000/navigation/navigation-interrupted-by-fragment.html
-curr->  http://127.0.0.1:8000/navigation/navigation-interrupted-by-fragment.html#abc
-===============================================
diff --git a/third_party/blink/web_tests/http/tests/navigation/navigation-interrupted-by-fragment.html b/third_party/blink/web_tests/http/tests/navigation/navigation-interrupted-by-fragment.html
deleted file mode 100644
index 4ef2b4d0..0000000
--- a/third_party/blink/web_tests/http/tests/navigation/navigation-interrupted-by-fragment.html
+++ /dev/null
@@ -1,26 +0,0 @@
-<script>
-if (window.testRunner) {
-    testRunner.dumpBackForwardList();
-    testRunner.dumpAsText();
-    testRunner.waitUntilDone();
-}
-onload = function() {
-    window.location = 'resources/slow-resource.pl?delay=100';
-    setTimeout(function() {window.location = 'navigation-interrupted-by-fragment.html#abc'}, 10);
-}
-
-onhashchange = function() {
-    setTimeout(done, 100);
-}
-
-function done() {
-    console.log('Visited fragment and waited.');
-    if (window.testRunner) {
-        testRunner.notifyDone();
-    }
-}
-
-console.log('First visit.');
-
-</script>
-<p>This test checks that interrupting a slow navigation with a fragment navigation will cancel the first navigation.
diff --git a/third_party/dav1d/README.chromium b/third_party/dav1d/README.chromium
index 90b75a5..b2fb84e 100644
--- a/third_party/dav1d/README.chromium
+++ b/third_party/dav1d/README.chromium
@@ -1,7 +1,7 @@
 Name: dav1d is an AV1 decoder :)
 Short Name: dav1d
 URL: https://code.videolan.org/videolan/dav1d
-Version: acad1a99eaaeefacadbd1756c80365665bc7570a
+Version: 556890be42d8affef280188c1a5d22cf299b2197
 License: 2-Clause BSD
 License File: LICENSE
 Security Critical: yes
diff --git a/third_party/dav1d/dav1d_generated.gni b/third_party/dav1d/dav1d_generated.gni
index 9281f4e5..5fafdd7 100644
--- a/third_party/dav1d/dav1d_generated.gni
+++ b/third_party/dav1d/dav1d_generated.gni
@@ -8,6 +8,7 @@
   "libdav1d/src/x86/cdef.asm",
   "libdav1d/src/x86/cdef_sse.asm",
   "libdav1d/src/x86/cpuid.asm",
+  "libdav1d/src/x86/film_grain.asm",
   "libdav1d/src/x86/ipred.asm",
   "libdav1d/src/x86/ipred_ssse3.asm",
   "libdav1d/src/x86/itx.asm",
@@ -22,6 +23,7 @@
 
 x86_template_sources = [
   "libdav1d/src/x86/cdef_init_tmpl.c",
+  "libdav1d/src/x86/film_grain_init_tmpl.c",
   "libdav1d/src/x86/ipred_init_tmpl.c",
   "libdav1d/src/x86/itx_init_tmpl.c",
   "libdav1d/src/x86/loopfilter_init_tmpl.c",
@@ -56,6 +58,7 @@
 template_sources = [
   "libdav1d/src/cdef_apply_tmpl.c",
   "libdav1d/src/cdef_tmpl.c",
+  "libdav1d/src/fg_apply_tmpl.c",
   "libdav1d/src/film_grain_tmpl.c",
   "libdav1d/src/ipred_prepare_tmpl.c",
   "libdav1d/src/ipred_tmpl.c",
@@ -83,6 +86,7 @@
   "libdav1d/src/dequant_tables.c",
   "libdav1d/src/dequant_tables.h",
   "libdav1d/src/env.h",
+  "libdav1d/src/fg_apply.h",
   "libdav1d/src/film_grain.h",
   "libdav1d/src/getbits.c",
   "libdav1d/src/getbits.h",
diff --git a/third_party/lottie/README.md b/third_party/lottie/README.md
index b92e3ad..dbb28272 100644
--- a/third_party/lottie/README.md
+++ b/third_party/lottie/README.md
@@ -39,6 +39,15 @@
 })
 ```
 
+### 3. Pausing the animation
+```js
+worker.postMessage({
+  control: {
+    play: false
+  }
+})
+```
+
 ## Message field description
 ```python
 data: {
@@ -51,6 +60,9 @@
   params: {
     loop: 'Set "true" for a looping animation',
     autoplay: 'Set "true" for the animation to autoplay on load',
+  },
+  control: {
+    play: 'Set "true" to play a paused animation or "false" to pause a playing animation',
   }
 },
 ```
@@ -71,7 +83,13 @@
     name: 'playing'
 }
 ```
-3. **'resized'**
+3. **'paused'**
+```javascript
+{
+    name: 'paused'
+}
+```
+4. **'resized'**
 ```javascript
 {
     name: 'resized',
diff --git a/third_party/lottie/lottie_worker.js b/third_party/lottie/lottie_worker.js
index 208426d..dcc9d10 100644
--- a/third_party/lottie/lottie_worker.js
+++ b/third_party/lottie/lottie_worker.js
@@ -12163,7 +12163,8 @@
   INITIALIZED: 'initialized',  // Send when the animation was successfully
                                // initialized.
   RESIZED: 'resized',  // Sent when the animation has been resized.
-  PLAYING: 'playing'   // Send when the animation started playing.
+  PLAYING: 'playing',  // Send when the animation started playing.
+  PAUSED: 'paused'  // Sent when the animation has paused.
 };
 
 /**
@@ -12191,12 +12192,17 @@
 };
 
 /**
- * Informs the parent thread that the animation has started playing.
+ * Informs the parent thread that the animation is playing.
  */
 sendPlayEvent = function() {
-  postMessage({
-    name: events.PLAYING
-  });
+  postMessage({name: events.PLAYING});
+}
+
+/**
+ * Informs the parent thread that the animation is paused.
+ */
+sendPauseEvent = function() {
+  postMessage({name: events.PAUSED});
 }
 
 /**
@@ -12272,6 +12278,25 @@
   }
 }
 
+/**
+ * Updates the animation state to play or pause. Informs the parent thread if
+ * the state has changed.
+ * @param {Object<string, bool>} control Has information about playing or
+ *     pausing the animation.
+ */
+updateAnimationState = function(control) {
+  if (!control) {
+    return;
+  }
+  if (control.play && currentAnimation.isPaused) {
+    currentAnimation.play();
+    sendPlayEvent();
+  } else if (!control.play && !currentAnimation.isPaused) {
+    currentAnimation.pause();
+    sendPauseEvent();
+  }
+}
+
 onmessage = function(evt) {
   if (!evt || !evt.data) return;
 
@@ -12286,4 +12311,5 @@
 
   updateCanvasSize(canvas, evt.data.drawSize);
   initAnimation(evt.data.animationData, evt.data.params, canvas);
+  updateAnimationState(evt.data.control);
 };
diff --git a/third_party/lottie/lottie_worker.min.js b/third_party/lottie/lottie_worker.min.js
index 786a2f3..0a72bccf 100644
--- a/third_party/lottie/lottie_worker.min.js
+++ b/third_party/lottie/lottie_worker.min.js
@@ -1 +1 @@
-var lottiejs=function(window){"use strict";var svgNS="http://www.w3.org/2000/svg",locationHref="",initialDefaultFrame=-999999,subframeEnabled=!0,expressionsPlugin,isSafari=/^((?!chrome|android).)*safari/i.test(navigator.userAgent),cachedColors={},bm_rounder=Math.round,bm_rnd,bm_pow=Math.pow,bm_sqrt=Math.sqrt,bm_abs=Math.abs,bm_floor=Math.floor,bm_max=Math.max,bm_min=Math.min,blitter=10,BMMath={};function ProjectInterface(){return{}}!function(){var t,e=["abs","acos","acosh","asin","asinh","atan","atanh","atan2","ceil","cbrt","expm1","clz32","cos","cosh","exp","floor","fround","hypot","imul","log","log1p","log2","log10","max","min","pow","random","round","sign","sin","sinh","sqrt","tan","tanh","trunc","E","LN10","LN2","LOG10E","LOG2E","PI","SQRT1_2","SQRT2"],r=e.length;for(t=0;t<r;t+=1)BMMath[e[t]]=Math[e[t]]}(),BMMath.random=Math.random,BMMath.abs=function(t){if("object"==typeof t&&t.length){var e,r=createSizedArray(t.length),i=t.length;for(e=0;e<i;e+=1)r[e]=Math.abs(t[e]);return r}return Math.abs(t)};var defaultCurveSegments=150,degToRads=Math.PI/180,roundCorner=.5519;function roundValues(t){bm_rnd=t?Math.round:function(t){return t}}function styleDiv(t){t.style.position="absolute",t.style.top=0,t.style.left=0,t.style.display="block",t.style.transformOrigin=t.style.webkitTransformOrigin="0 0",t.style.backfaceVisibility=t.style.webkitBackfaceVisibility="visible",t.style.transformStyle=t.style.webkitTransformStyle=t.style.mozTransformStyle="preserve-3d"}function BMEnterFrameEvent(t,e,r,i){this.type=t,this.currentTime=e,this.totalTime=r,this.direction=i<0?-1:1}function BMCompleteEvent(t,e){this.type=t,this.direction=e<0?-1:1}function BMCompleteLoopEvent(t,e,r,i){this.type=t,this.currentLoop=r,this.totalLoops=e,this.direction=i<0?-1:1}function BMSegmentStartEvent(t,e,r){this.type=t,this.firstFrame=e,this.totalFrames=r}function BMDestroyEvent(t,e){this.type=t,this.target=e}roundValues(!1);var createElementID=(B=0,function(){return"__lottie_element_"+ ++B}),B;function HSVtoRGB(t,e,r){var i,s,a,n,o,h,p,l;switch(h=r*(1-e),p=r*(1-(o=6*t-(n=Math.floor(6*t)))*e),l=r*(1-(1-o)*e),n%6){case 0:i=r,s=l,a=h;break;case 1:i=p,s=r,a=h;break;case 2:i=h,s=r,a=l;break;case 3:i=h,s=p,a=r;break;case 4:i=l,s=h,a=r;break;case 5:i=r,s=h,a=p}return[i,s,a]}function RGBtoHSV(t,e,r){var i,s=Math.max(t,e,r),a=Math.min(t,e,r),n=s-a,o=0===s?0:n/s,h=s/255;switch(s){case a:i=0;break;case t:i=e-r+n*(e<r?6:0),i/=6*n;break;case e:i=r-t+2*n,i/=6*n;break;case r:i=t-e+4*n,i/=6*n}return[i,o,h]}function addSaturationToRGB(t,e){var r=RGBtoHSV(255*t[0],255*t[1],255*t[2]);return r[1]+=e,1<r[1]?r[1]=1:r[1]<=0&&(r[1]=0),HSVtoRGB(r[0],r[1],r[2])}function addBrightnessToRGB(t,e){var r=RGBtoHSV(255*t[0],255*t[1],255*t[2]);return r[2]+=e,1<r[2]?r[2]=1:r[2]<0&&(r[2]=0),HSVtoRGB(r[0],r[1],r[2])}function addHueToRGB(t,e){var r=RGBtoHSV(255*t[0],255*t[1],255*t[2]);return r[0]+=e/360,1<r[0]?r[0]-=1:r[0]<0&&(r[0]+=1),HSVtoRGB(r[0],r[1],r[2])}var rgbToHex=function(){var t,e,i=[];for(t=0;t<256;t+=1)e=t.toString(16),i[t]=1==e.length?"0"+e:e;return function(t,e,r){return t<0&&(t=0),e<0&&(e=0),r<0&&(r=0),"#"+i[t]+i[e]+i[r]}}();function BaseEvent(){}BaseEvent.prototype={triggerEvent:function(t,e){if(this._cbs[t])for(var r=this._cbs[t].length,i=0;i<r;i++)this._cbs[t][i](e)},addEventListener:function(t,e){return this._cbs[t]||(this._cbs[t]=[]),this._cbs[t].push(e),function(){this.removeEventListener(t,e)}.bind(this)},removeEventListener:function(t,e){if(e){if(this._cbs[t]){for(var r=0,i=this._cbs[t].length;r<i;)this._cbs[t][r]===e&&(this._cbs[t].splice(r,1),r-=1,i-=1),r+=1;this._cbs[t].length||(this._cbs[t]=null)}}else this._cbs[t]=null}};var createTypedArray="function"==typeof Uint8ClampedArray&&"function"==typeof Float32Array?function(t,e){return"float32"===t?new Float32Array(e):"int16"===t?new Int16Array(e):"uint8c"===t?new Uint8ClampedArray(e):void 0}:function(t,e){var r,i=0,s=[];switch(t){case"int16":case"uint8c":r=1;break;default:r=1.1}for(i=0;i<e;i+=1)s.push(r);return s};function createSizedArray(t){return Array.apply(null,{length:t})}function createTag(t){return document.createElement(t)}function DynamicPropertyContainer(){}DynamicPropertyContainer.prototype={addDynamicProperty:function(t){-1===this.dynamicProperties.indexOf(t)&&(this.dynamicProperties.push(t),this.container.addDynamicProperty(this),this._isAnimated=!0)},iterateDynamicProperties:function(){this._mdf=!1;var t,e=this.dynamicProperties.length;for(t=0;t<e;t+=1)this.dynamicProperties[t].getValue(),this.dynamicProperties[t]._mdf&&(this._mdf=!0)},initDynamicPropertyContainer:function(t){this.container=t,this.dynamicProperties=[],this._mdf=!1,this._isAnimated=!1}};var getBlendMode=(Ja={0:"source-over",1:"multiply",2:"screen",3:"overlay",4:"darken",5:"lighten",6:"color-dodge",7:"color-burn",8:"hard-light",9:"soft-light",10:"difference",11:"exclusion",12:"hue",13:"saturation",14:"color",15:"luminosity"},function(t){return Ja[t]||""}),Ja,Matrix=(La=Math.cos,Ma=Math.sin,Na=Math.tan,Oa=Math.round,function(){this.reset=Pa,this.rotate=Qa,this.rotateX=Ra,this.rotateY=Sa,this.rotateZ=Ta,this.skew=Va,this.skewFromAxis=Wa,this.shear=Ua,this.scale=Xa,this.setTransform=Ya,this.translate=Za,this.transform=$a,this.applyToPoint=db,this.applyToX=eb,this.applyToY=fb,this.applyToZ=gb,this.applyToPointArray=kb,this.applyToTriplePoints=jb,this.applyToPointStringified=lb,this.toCSS=mb,this.to2dCSS=pb,this.clone=bb,this.cloneFromProps=cb,this.equals=ab,this.inversePoints=ib,this.inversePoint=hb,this._t=this.transform,this.isIdentity=_a,this._identity=!0,this._identityCalculated=!1,this.props=createTypedArray("float32",16),this.reset()}),La,Ma,Na,Oa;function Pa(){return this.props[0]=1,this.props[1]=0,this.props[2]=0,this.props[3]=0,this.props[4]=0,this.props[5]=1,this.props[6]=0,this.props[7]=0,this.props[8]=0,this.props[9]=0,this.props[10]=1,this.props[11]=0,this.props[12]=0,this.props[13]=0,this.props[14]=0,this.props[15]=1,this}function Qa(t){if(0===t)return this;var e=La(t),r=Ma(t);return this._t(e,-r,0,0,r,e,0,0,0,0,1,0,0,0,0,1)}function Ra(t){if(0===t)return this;var e=La(t),r=Ma(t);return this._t(1,0,0,0,0,e,-r,0,0,r,e,0,0,0,0,1)}function Sa(t){if(0===t)return this;var e=La(t),r=Ma(t);return this._t(e,0,r,0,0,1,0,0,-r,0,e,0,0,0,0,1)}function Ta(t){if(0===t)return this;var e=La(t),r=Ma(t);return this._t(e,-r,0,0,r,e,0,0,0,0,1,0,0,0,0,1)}function Ua(t,e){return this._t(1,e,t,1,0,0)}function Va(t,e){return this.shear(Na(t),Na(e))}function Wa(t,e){var r=La(e),i=Ma(e);return this._t(r,i,0,0,-i,r,0,0,0,0,1,0,0,0,0,1)._t(1,0,0,0,Na(t),1,0,0,0,0,1,0,0,0,0,1)._t(r,-i,0,0,i,r,0,0,0,0,1,0,0,0,0,1)}function Xa(t,e,r){return r||0===r||(r=1),1===t&&1===e&&1===r?this:this._t(t,0,0,0,0,e,0,0,0,0,r,0,0,0,0,1)}function Ya(t,e,r,i,s,a,n,o,h,p,l,m,f,c,d,u){return this.props[0]=t,this.props[1]=e,this.props[2]=r,this.props[3]=i,this.props[4]=s,this.props[5]=a,this.props[6]=n,this.props[7]=o,this.props[8]=h,this.props[9]=p,this.props[10]=l,this.props[11]=m,this.props[12]=f,this.props[13]=c,this.props[14]=d,this.props[15]=u,this}function Za(t,e,r){return r=r||0,0!==t||0!==e||0!==r?this._t(1,0,0,0,0,1,0,0,0,0,1,0,t,e,r,1):this}function $a(t,e,r,i,s,a,n,o,h,p,l,m,f,c,d,u){var y=this.props;if(1===t&&0===e&&0===r&&0===i&&0===s&&1===a&&0===n&&0===o&&0===h&&0===p&&1===l&&0===m)return y[12]=y[12]*t+y[15]*f,y[13]=y[13]*a+y[15]*c,y[14]=y[14]*l+y[15]*d,y[15]=y[15]*u,this._identityCalculated=!1,this;var g=y[0],v=y[1],P=y[2],b=y[3],x=y[4],_=y[5],S=y[6],T=y[7],A=y[8],C=y[9],E=y[10],k=y[11],D=y[12],I=y[13],M=y[14],w=y[15];return y[0]=g*t+v*s+P*h+b*f,y[1]=g*e+v*a+P*p+b*c,y[2]=g*r+v*n+P*l+b*d,y[3]=g*i+v*o+P*m+b*u,y[4]=x*t+_*s+S*h+T*f,y[5]=x*e+_*a+S*p+T*c,y[6]=x*r+_*n+S*l+T*d,y[7]=x*i+_*o+S*m+T*u,y[8]=A*t+C*s+E*h+k*f,y[9]=A*e+C*a+E*p+k*c,y[10]=A*r+C*n+E*l+k*d,y[11]=A*i+C*o+E*m+k*u,y[12]=D*t+I*s+M*h+w*f,y[13]=D*e+I*a+M*p+w*c,y[14]=D*r+I*n+M*l+w*d,y[15]=D*i+I*o+M*m+w*u,this._identityCalculated=!1,this}function _a(){return this._identityCalculated||(this._identity=!(1!==this.props[0]||0!==this.props[1]||0!==this.props[2]||0!==this.props[3]||0!==this.props[4]||1!==this.props[5]||0!==this.props[6]||0!==this.props[7]||0!==this.props[8]||0!==this.props[9]||1!==this.props[10]||0!==this.props[11]||0!==this.props[12]||0!==this.props[13]||0!==this.props[14]||1!==this.props[15]),this._identityCalculated=!0),this._identity}function ab(t){for(var e=0;e<16;){if(t.props[e]!==this.props[e])return!1;e+=1}return!0}function bb(t){var e;for(e=0;e<16;e+=1)t.props[e]=this.props[e]}function cb(t){var e;for(e=0;e<16;e+=1)this.props[e]=t[e]}function db(t,e,r){return{x:t*this.props[0]+e*this.props[4]+r*this.props[8]+this.props[12],y:t*this.props[1]+e*this.props[5]+r*this.props[9]+this.props[13],z:t*this.props[2]+e*this.props[6]+r*this.props[10]+this.props[14]}}function eb(t,e,r){return t*this.props[0]+e*this.props[4]+r*this.props[8]+this.props[12]}function fb(t,e,r){return t*this.props[1]+e*this.props[5]+r*this.props[9]+this.props[13]}function gb(t,e,r){return t*this.props[2]+e*this.props[6]+r*this.props[10]+this.props[14]}function hb(t){var e=this.props[0]*this.props[5]-this.props[1]*this.props[4],r=this.props[5]/e,i=-this.props[1]/e,s=-this.props[4]/e,a=this.props[0]/e,n=(this.props[4]*this.props[13]-this.props[5]*this.props[12])/e,o=-(this.props[0]*this.props[13]-this.props[1]*this.props[12])/e;return[t[0]*r+t[1]*s+n,t[0]*i+t[1]*a+o,0]}function ib(t){var e,r=t.length,i=[];for(e=0;e<r;e+=1)i[e]=hb(t[e]);return i}function jb(t,e,r){var i=createTypedArray("float32",6);if(this.isIdentity())i[0]=t[0],i[1]=t[1],i[2]=e[0],i[3]=e[1],i[4]=r[0],i[5]=r[1];else{var s=this.props[0],a=this.props[1],n=this.props[4],o=this.props[5],h=this.props[12],p=this.props[13];i[0]=t[0]*s+t[1]*n+h,i[1]=t[0]*a+t[1]*o+p,i[2]=e[0]*s+e[1]*n+h,i[3]=e[0]*a+e[1]*o+p,i[4]=r[0]*s+r[1]*n+h,i[5]=r[0]*a+r[1]*o+p}return i}function kb(t,e,r){return this.isIdentity()?[t,e,r]:[t*this.props[0]+e*this.props[4]+r*this.props[8]+this.props[12],t*this.props[1]+e*this.props[5]+r*this.props[9]+this.props[13],t*this.props[2]+e*this.props[6]+r*this.props[10]+this.props[14]]}function lb(t,e){if(this.isIdentity())return t+","+e;var r=this.props;return Math.round(100*(t*r[0]+e*r[4]+r[12]))/100+","+Math.round(100*(t*r[1]+e*r[5]+r[13]))/100}function mb(){for(var t=0,e=this.props,r="matrix3d(";t<16;)r+=Oa(1e4*e[t])/1e4,r+=15===t?")":",",t+=1;return r}function nb(t){return t<1e-6&&0<t||-1e-6<t&&t<0?Oa(1e4*t)/1e4:t}function pb(){var t=this.props;return"matrix("+nb(t[0])+","+nb(t[1])+","+nb(t[4])+","+nb(t[5])+","+nb(t[12])+","+nb(t[13])+")"}!function(o,h){var p,l=this,m=256,f=6,c="random",d=h.pow(m,f),u=h.pow(2,52),y=2*u,g=m-1;function v(t){var e,r=t.length,n=this,i=0,s=n.i=n.j=0,a=n.S=[];for(r||(t=[r++]);i<m;)a[i]=i++;for(i=0;i<m;i++)a[i]=a[s=g&s+t[i%r]+(e=a[i])],a[s]=e;n.g=function(t){for(var e,r=0,i=n.i,s=n.j,a=n.S;t--;)e=a[i=g&i+1],r=r*m+a[g&(a[i]=a[s=g&s+e])+(a[s]=e)];return n.i=i,n.j=s,r}}function P(t,e){return e.i=t.i,e.j=t.j,e.S=t.S.slice(),e}function b(t,e){for(var r,i=t+"",s=0;s<i.length;)e[g&s]=g&(r^=19*e[g&s])+i.charCodeAt(s++);return x(e)}function x(t){return String.fromCharCode.apply(0,t)}h["seed"+c]=function(t,e,r){function i(){for(var t=n.g(f),e=d,r=0;t<u;)t=(t+r)*m,e*=m,r=n.g(1);for(;y<=t;)t/=2,e/=2,r>>>=1;return(t+r)/e}var s=[],a=b(function t(e,r){var i,s=[],a=typeof e;if(r&&"object"==a)for(i in e)try{s.push(t(e[i],r-1))}catch(t){}return s.length?s:"string"==a?e:e+"\0"}((e=!0===e?{entropy:!0}:e||{}).entropy?[t,x(o)]:null===t?function(){try{if(p)return x(p.randomBytes(m));var t=new Uint8Array(m);return(l.crypto||l.msCrypto).getRandomValues(t),x(t)}catch(t){var e=l.navigator,r=e&&e.plugins;return[+new Date,l,r,l.screen,x(o)]}}():t,3),s),n=new v(s);return i.int32=function(){return 0|n.g(4)},i.quick=function(){return n.g(4)/4294967296},i.double=i,b(x(n.S),o),(e.pass||r||function(t,e,r,i){return i&&(i.S&&P(i,n),t.state=function(){return P(n,{})}),r?(h[c]=t,e):t})(i,a,"global"in e?e.global:this==h,e.state)},b(h.random(),o)}([],BMMath);var BezierFactory=(_e={getBezierEasing:function(t,e,r,i,s){var a=s||("bez_"+t+"_"+e+"_"+r+"_"+i).replace(/\./g,"p");if(af[a])return af[a];var n=new rf([t,e,r,i]);return af[a]=n}},af={},gf=11,hf=1/(gf-1),jf="function"==typeof Float32Array,rf.prototype={get:function(t){var e=this._p[0],r=this._p[1],i=this._p[2],s=this._p[3];return this._precomputed||this._precompute(),e===r&&i===s?t:0===t?0:1===t?1:nf(this._getTForX(t),r,s)},_precompute:function(){var t=this._p[0],e=this._p[1],r=this._p[2],i=this._p[3];this._precomputed=!0,t===e&&r===i||this._calcSampleValues()},_calcSampleValues:function(){for(var t=this._p[0],e=this._p[2],r=0;r<gf;++r)this._mSampleValues[r]=nf(r*hf,t,e)},_getTForX:function(t){for(var e=this._p[0],r=this._p[2],i=this._mSampleValues,s=0,a=1,n=gf-1;a!==n&&i[a]<=t;++a)s+=hf;var o=s+(t-i[--a])/(i[a+1]-i[a])*hf,h=of(o,e,r);return.001<=h?function(t,e,r,i){for(var s=0;s<4;++s){var a=of(e,r,i);if(0===a)return e;e-=(nf(e,r,i)-t)/a}return e}(t,o,e,r):0===h?o:function(t,e,r,i,s){for(var a,n,o=0;0<(a=nf(n=e+(r-e)/2,i,s)-t)?r=n:e=n,1e-7<Math.abs(a)&&++o<10;);return n}(t,s,s+hf,e,r)}},_e),_e,af,gf,hf,jf;function kf(t,e){return 1-3*e+3*t}function lf(t,e){return 3*e-6*t}function mf(t){return 3*t}function nf(t,e,r){return((kf(e,r)*t+lf(e,r))*t+mf(e))*t}function of(t,e,r){return 3*kf(e,r)*t*t+2*lf(e,r)*t+mf(e)}function rf(t){this._p=t,this._mSampleValues=jf?new Float32Array(gf):new Array(gf),this._precomputed=!1,this.get=this.get.bind(this)}function extendPrototype(t,e){var r,i,s=t.length;for(r=0;r<s;r+=1)for(var a in i=t[r].prototype)i.hasOwnProperty(a)&&(e.prototype[a]=i[a])}function getDescriptor(t,e){return Object.getOwnPropertyDescriptor(t,e)}function createProxyFunction(t){function e(){}return e.prototype=t,e}function bezFunction(){Math;function y(t,e,r,i,s,a){var n=t*i+e*s+r*a-s*i-a*t-r*e;return-.001<n&&n<.001}var l=function(t,e,r,i){var s,a,n,o,h,p,l=defaultCurveSegments,m=0,f=[],c=[],d=bezier_length_pool.newElement();for(n=r.length,s=0;s<l;s+=1){for(h=s/(l-1),a=p=0;a<n;a+=1)o=bm_pow(1-h,3)*t[a]+3*bm_pow(1-h,2)*h*r[a]+3*(1-h)*bm_pow(h,2)*i[a]+bm_pow(h,3)*e[a],f[a]=o,null!==c[a]&&(p+=bm_pow(f[a]-c[a],2)),c[a]=f[a];p&&(m+=p=bm_sqrt(p)),d.percents[s]=h,d.lengths[s]=m}return d.addedLength=m,d};function g(t){this.segmentLength=0,this.points=new Array(t)}function v(t,e){this.partialLength=t,this.point=e}var P,t=(P={},function(t,e,r,i){var s=(t[0]+"_"+t[1]+"_"+e[0]+"_"+e[1]+"_"+r[0]+"_"+r[1]+"_"+i[0]+"_"+i[1]).replace(/\./g,"p");if(!P[s]){var a,n,o,h,p,l,m,f=defaultCurveSegments,c=0,d=null;2===t.length&&(t[0]!=e[0]||t[1]!=e[1])&&y(t[0],t[1],e[0],e[1],t[0]+r[0],t[1]+r[1])&&y(t[0],t[1],e[0],e[1],e[0]+i[0],e[1]+i[1])&&(f=2);var u=new g(f);for(o=r.length,a=0;a<f;a+=1){for(m=createSizedArray(o),p=a/(f-1),n=l=0;n<o;n+=1)h=bm_pow(1-p,3)*t[n]+3*bm_pow(1-p,2)*p*(t[n]+r[n])+3*(1-p)*bm_pow(p,2)*(e[n]+i[n])+bm_pow(p,3)*e[n],m[n]=h,null!==d&&(l+=bm_pow(m[n]-d[n],2));c+=l=bm_sqrt(l),u.points[a]=new v(l,m),d=m}u.segmentLength=c,P[s]=u}return P[s]});function D(t,e){var r=e.percents,i=e.lengths,s=r.length,a=bm_floor((s-1)*t),n=t*e.addedLength,o=0;if(a===s-1||0===a||n===i[a])return r[a];for(var h=i[a]>n?-1:1,p=!0;p;)if(i[a]<=n&&i[a+1]>n?(o=(n-i[a])/(i[a+1]-i[a]),p=!1):a+=h,a<0||s-1<=a){if(a===s-1)return r[a];p=!1}return r[a]+(r[a+1]-r[a])*o}var I=createTypedArray("float32",8);return{getSegmentsLength:function(t){var e,r=segments_length_pool.newElement(),i=t.c,s=t.v,a=t.o,n=t.i,o=t._length,h=r.lengths,p=0;for(e=0;e<o-1;e+=1)h[e]=l(s[e],s[e+1],a[e],n[e+1]),p+=h[e].addedLength;return i&&o&&(h[e]=l(s[e],s[0],a[e],n[0]),p+=h[e].addedLength),r.totalLength=p,r},getNewSegment:function(t,e,r,i,s,a,n){var o,h=D(s=s<0?0:1<s?1:s,n),p=D(a=1<a?1:a,n),l=t.length,m=1-h,f=1-p,c=m*m*m,d=h*m*m*3,u=h*h*m*3,y=h*h*h,g=m*m*f,v=h*m*f+m*h*f+m*m*p,P=h*h*f+m*h*p+h*m*p,b=h*h*p,x=m*f*f,_=h*f*f+m*p*f+m*f*p,S=h*p*f+m*p*p+h*f*p,T=h*p*p,A=f*f*f,C=p*f*f+f*p*f+f*f*p,E=p*p*f+f*p*p+p*f*p,k=p*p*p;for(o=0;o<l;o+=1)I[4*o]=Math.round(1e3*(c*t[o]+d*r[o]+u*i[o]+y*e[o]))/1e3,I[4*o+1]=Math.round(1e3*(g*t[o]+v*r[o]+P*i[o]+b*e[o]))/1e3,I[4*o+2]=Math.round(1e3*(x*t[o]+_*r[o]+S*i[o]+T*e[o]))/1e3,I[4*o+3]=Math.round(1e3*(A*t[o]+C*r[o]+E*i[o]+k*e[o]))/1e3;return I},getPointInSegment:function(t,e,r,i,s,a){var n=D(s,a),o=1-n;return[Math.round(1e3*(o*o*o*t[0]+(n*o*o+o*n*o+o*o*n)*r[0]+(n*n*o+o*n*n+n*o*n)*i[0]+n*n*n*e[0]))/1e3,Math.round(1e3*(o*o*o*t[1]+(n*o*o+o*n*o+o*o*n)*r[1]+(n*n*o+o*n*n+n*o*n)*i[1]+n*n*n*e[1]))/1e3]},buildBezierData:t,pointOnLine2D:y,pointOnLine3D:function(t,e,r,i,s,a,n,o,h){if(0===r&&0===a&&0===h)return y(t,e,i,s,n,o);var p,l=Math.sqrt(Math.pow(i-t,2)+Math.pow(s-e,2)+Math.pow(a-r,2)),m=Math.sqrt(Math.pow(n-t,2)+Math.pow(o-e,2)+Math.pow(h-r,2)),f=Math.sqrt(Math.pow(n-i,2)+Math.pow(o-s,2)+Math.pow(h-a,2));return-1e-4<(p=m<l?f<l?l-m-f:f-m-l:m<f?f-m-l:m-l-f)&&p<1e-4}}}!function(){for(var a=0,t=["ms","moz","webkit","o"],e=0;e<t.length&&!window.requestAnimationFrame;++e)window.requestAnimationFrame=window[t[e]+"RequestAnimationFrame"],window.cancelAnimationFrame=window[t[e]+"CancelAnimationFrame"]||window[t[e]+"CancelRequestAnimationFrame"];window.requestAnimationFrame||(window.requestAnimationFrame=function(t,e){var r=(new Date).getTime(),i=Math.max(0,16-(r-a)),s=setTimeout(function(){t(r+i)},i);return a=r+i,s}),window.cancelAnimationFrame||(window.cancelAnimationFrame=function(t){clearTimeout(t)})}();var bez=bezFunction();function dataFunctionManager(){function m(t,e,r){var i,s,a,n,o,h,p=t.length;for(s=0;s<p;s+=1)if("ks"in(i=t[s])&&!i.completed){if(i.completed=!0,i.tt&&(t[s-1].td=i.tt),[],-1,i.hasMask){var l=i.masksProperties;for(n=l.length,a=0;a<n;a+=1)if(l[a].pt.k.i)d(l[a].pt.k);else for(h=l[a].pt.k.length,o=0;o<h;o+=1)l[a].pt.k[o].s&&d(l[a].pt.k[o].s[0]),l[a].pt.k[o].e&&d(l[a].pt.k[o].e[0])}0===i.ty?(i.layers=f(i.refId,e),m(i.layers,e,r)):4===i.ty?c(i.shapes):5==i.ty&&b(i,r)}}function f(t,e){for(var r=0,i=e.length;r<i;){if(e[r].id===t)return e[r].layers.__used?JSON.parse(JSON.stringify(e[r].layers)):(e[r].layers.__used=!0,e[r].layers);r+=1}}function c(t){var e,r,i;for(e=t.length-1;0<=e;e-=1)if("sh"==t[e].ty){if(t[e].ks.k.i)d(t[e].ks.k);else for(i=t[e].ks.k.length,r=0;r<i;r+=1)t[e].ks.k[r].s&&d(t[e].ks.k[r].s[0]),t[e].ks.k[r].e&&d(t[e].ks.k[r].e[0]);!0}else"gr"==t[e].ty&&c(t[e].it)}function d(t){var e,r=t.i.length;for(e=0;e<r;e+=1)t.i[e][0]+=t.v[e][0],t.i[e][1]+=t.v[e][1],t.o[e][0]+=t.v[e][0],t.o[e][1]+=t.v[e][1]}function o(t,e){var r=e?e.split("."):[100,100,100];return t[0]>r[0]||!(r[0]>t[0])&&(t[1]>r[1]||!(r[1]>t[1])&&(t[2]>r[2]||!(r[2]>t[2])&&void 0))}var i,r=(i=[4,4,14],function(t){if(o(i,t.v)&&(s(t.layers),t.assets)){var e,r=t.assets.length;for(e=0;e<r;e+=1)t.assets[e].layers&&s(t.assets[e].layers)}});function s(t){var e,r,i,s=t.length;for(e=0;e<s;e+=1)5===t[e].ty&&(r=t[e],void 0,i=r.t.d,r.t.d={k:[{s:i,t:0}]})}var h,a,n=(h=[4,7,99],function(t){if(t.chars&&!o(h,t.v)){var e,r,i,s,a,n=t.chars.length;for(e=0;e<n;e+=1)if(t.chars[e].data&&t.chars[e].data.shapes)for(i=(a=t.chars[e].data.shapes[0].it).length,r=0;r<i;r+=1)(s=a[r].ks.k).__converted||(d(a[r].ks.k),s.__converted=!0)}}),p=(a=[4,1,9],function(t){if(o(a,t.v)&&(u(t.layers),t.assets)){var e,r=t.assets.length;for(e=0;e<r;e+=1)t.assets[e].layers&&u(t.assets[e].layers)}});function l(t){var e,r,i,s=t.length;for(e=0;e<s;e+=1)if("gr"===t[e].ty)l(t[e].it);else if("fl"===t[e].ty||"st"===t[e].ty)if(t[e].c.k&&t[e].c.k[0].i)for(i=t[e].c.k.length,r=0;r<i;r+=1)t[e].c.k[r].s&&(t[e].c.k[r].s[0]/=255,t[e].c.k[r].s[1]/=255,t[e].c.k[r].s[2]/=255,t[e].c.k[r].s[3]/=255),t[e].c.k[r].e&&(t[e].c.k[r].e[0]/=255,t[e].c.k[r].e[1]/=255,t[e].c.k[r].e[2]/=255,t[e].c.k[r].e[3]/=255);else t[e].c.k[0]/=255,t[e].c.k[1]/=255,t[e].c.k[2]/=255,t[e].c.k[3]/=255}function u(t){var e,r=t.length;for(e=0;e<r;e+=1)4===t[e].ty&&l(t[e].shapes)}var y,g=(y=[4,4,18],function(t){if(o(y,t.v)&&(P(t.layers),t.assets)){var e,r=t.assets.length;for(e=0;e<r;e+=1)t.assets[e].layers&&P(t.assets[e].layers)}});function v(t){var e,r,i;for(e=t.length-1;0<=e;e-=1)if("sh"==t[e].ty){if(t[e].ks.k.i)t[e].ks.k.c=t[e].closed;else for(i=t[e].ks.k.length,r=0;r<i;r+=1)t[e].ks.k[r].s&&(t[e].ks.k[r].s[0].c=t[e].closed),t[e].ks.k[r].e&&(t[e].ks.k[r].e[0].c=t[e].closed);!0}else"gr"==t[e].ty&&v(t[e].it)}function P(t){var e,r,i,s,a,n,o=t.length;for(r=0;r<o;r+=1){if((e=t[r]).hasMask){var h=e.masksProperties;for(s=h.length,i=0;i<s;i+=1)if(h[i].pt.k.i)h[i].pt.k.c=h[i].cl;else for(n=h[i].pt.k.length,a=0;a<n;a+=1)h[i].pt.k[a].s&&(h[i].pt.k[a].s[0].c=h[i].cl),h[i].pt.k[a].e&&(h[i].pt.k[a].e[0].c=h[i].cl)}4===e.ty&&v(e.shapes)}}function b(t,e){0!==t.t.a.length||"m"in t.t.p||(t.singleShape=!0)}var t={completeData:function(t,e){t.__complete||(p(t),r(t),n(t),g(t),m(t.layers,t.assets,e),t.__complete=!0)}};return t.checkColors=p,t.checkChars=n,t.checkShapes=g,t.completeLayers=m,t}var dataManager=dataFunctionManager();dataManager.completeData=function(t,e){t.__complete||(this.checkColors(t),this.checkChars(t),this.checkShapes(t),this.completeLayers(t.layers,t.assets,e),t.__complete=!0)};var FontManager=function(){var a={w:0,size:0,shapes:[]},t=[];function u(t,e){var r=createTag("span");r.style.fontFamily=e;var i=createTag("span");i.innerHTML="giItT1WQy@!-/#",r.style.position="absolute",r.style.left="-10000px",r.style.top="-10000px",r.style.fontSize="300px",r.style.fontVariant="normal",r.style.fontStyle="normal",r.style.fontWeight="normal",r.style.letterSpacing="0",r.appendChild(i),document.body.appendChild(r);var s=i.offsetWidth;return i.style.fontFamily=t+", "+e,{node:i,w:s,parent:r}}t=t.concat([2304,2305,2306,2307,2362,2363,2364,2364,2366,2367,2368,2369,2370,2371,2372,2373,2374,2375,2376,2377,2378,2379,2380,2381,2382,2383,2387,2388,2389,2390,2391,2402,2403]);function e(){this.fonts=[],this.chars=null,this.typekitLoaded=0,this.isLoaded=!1,this.initTime=Date.now()}return e.getCombinedCharacterCodes=function(){return t},e.prototype.addChars=function(t){if(t){this.chars||(this.chars=[]);var e,r,i,s=t.length,a=this.chars.length;for(e=0;e<s;e+=1){for(r=0,i=!1;r<a;)this.chars[r].style===t[e].style&&this.chars[r].fFamily===t[e].fFamily&&this.chars[r].ch===t[e].ch&&(i=!0),r+=1;i||(this.chars.push(t[e]),a+=1)}}},e.prototype.addFonts=function(t,e){if(t){if(this.chars)return this.isLoaded=!0,void(this.fonts=t.list);var r,i,s,a,n=t.list,o=n.length,h=o;for(r=0;r<o;r+=1){var p,l,m=!0;if(n[r].loaded=!1,n[r].monoCase=u(n[r].fFamily,"monospace"),n[r].sansCase=u(n[r].fFamily,"sans-serif"),n[r].fPath){if("p"===n[r].fOrigin||3===n[r].origin){if(0<(p=document.querySelectorAll('style[f-forigin="p"][f-family="'+n[r].fFamily+'"], style[f-origin="3"][f-family="'+n[r].fFamily+'"]')).length&&(m=!1),m){var f=createTag("style");f.setAttribute("f-forigin",n[r].fOrigin),f.setAttribute("f-origin",n[r].origin),f.setAttribute("f-family",n[r].fFamily),f.type="text/css",f.innerHTML="@font-face {font-family: "+n[r].fFamily+"; font-style: normal; src: url('"+n[r].fPath+"');}",e.appendChild(f)}}else if("g"===n[r].fOrigin||1===n[r].origin){for(p=document.querySelectorAll('link[f-forigin="g"], link[f-origin="1"]'),l=0;l<p.length;l++)-1!==p[l].href.indexOf(n[r].fPath)&&(m=!1);if(m){var c=createTag("link");c.setAttribute("f-forigin",n[r].fOrigin),c.setAttribute("f-origin",n[r].origin),c.type="text/css",c.rel="stylesheet",c.href=n[r].fPath,document.body.appendChild(c)}}else if("t"===n[r].fOrigin||2===n[r].origin){for(p=document.querySelectorAll('script[f-forigin="t"], script[f-origin="2"]'),l=0;l<p.length;l++)n[r].fPath===p[l].src&&(m=!1);if(m){var d=createTag("link");d.setAttribute("f-forigin",n[r].fOrigin),d.setAttribute("f-origin",n[r].origin),d.setAttribute("rel","stylesheet"),d.setAttribute("href",n[r].fPath),e.appendChild(d)}}}else n[r].loaded=!0,h-=1;n[r].helper=(i=e,s=n[r],a=void 0,(a=createNS("text")).style.fontSize="100px",a.setAttribute("font-family",s.fFamily),a.setAttribute("font-style",s.fStyle),a.setAttribute("font-weight",s.fWeight),a.textContent="1",s.fClass?(a.style.fontFamily="inherit",a.setAttribute("class",s.fClass)):a.style.fontFamily=s.fFamily,i.appendChild(a),createTag("canvas").getContext("2d").font=s.fWeight+" "+s.fStyle+" 100px "+s.fFamily,a),n[r].cache={},this.fonts.push(n[r])}0===h?this.isLoaded=!0:setTimeout(this.checkLoadedFonts.bind(this),100)}else this.isLoaded=!0},e.prototype.getCharData=function(t,e,r){for(var i=0,s=this.chars.length;i<s;){if(this.chars[i].ch===t&&this.chars[i].style===e&&this.chars[i].fFamily===r)return this.chars[i];i+=1}return console&&console.warn&&console.warn("Missing character from exported characters list: ",t,e,r),a},e.prototype.getFontByName=function(t){for(var e=0,r=this.fonts.length;e<r;){if(this.fonts[e].fName===t)return this.fonts[e];e+=1}return this.fonts[0]},e.prototype.measureText=function(t,e,r){var i=this.getFontByName(e),s=t.charCodeAt(0);if(!i.cache[s+1]){var a=i.helper;if(" "===t){a.textContent="|"+t+"|";var n=a.getComputedTextLength();a.textContent="||";var o=a.getComputedTextLength();i.cache[s+1]=(n-o)/100}else a.textContent=t,i.cache[s+1]=a.getComputedTextLength()/100}return i.cache[s+1]*r},e.prototype.checkLoadedFonts=function(){var t,e,r,i=this.fonts.length,s=i;for(t=0;t<i;t+=1)this.fonts[t].loaded?s-=1:"n"===this.fonts[t].fOrigin||0===this.fonts[t].origin?this.fonts[t].loaded=!0:(e=this.fonts[t].monoCase.node,r=this.fonts[t].monoCase.w,e.offsetWidth!==r?(s-=1,this.fonts[t].loaded=!0):(e=this.fonts[t].sansCase.node,r=this.fonts[t].sansCase.w,e.offsetWidth!==r&&(s-=1,this.fonts[t].loaded=!0)),this.fonts[t].loaded&&(this.fonts[t].sansCase.parent.parentNode.removeChild(this.fonts[t].sansCase.parent),this.fonts[t].monoCase.parent.parentNode.removeChild(this.fonts[t].monoCase.parent)));0!==s&&Date.now()-this.initTime<5e3?setTimeout(this.checkLoadedFonts.bind(this),20):setTimeout(function(){this.isLoaded=!0}.bind(this),0)},e.prototype.loaded=function(){return this.isLoaded},e}();FontManager=function(){this.fonts=[],this.chars=null,this.typekitLoaded=0,this.isLoaded=!1,this.initTime=Date.now()};var PropertyFactory=(km=initialDefaultFrame,lm=Math.abs,{getProp:function(t,e,r,i,s){var a;if(e.k.length)if("number"==typeof e.k[0])a=new vm(t,e,i,s);else switch(r){case 0:a=new wm(t,e,i,s);break;case 1:a=new xm(t,e,i,s)}else a=new um(t,e,i,s);return a.effectsSequence.length&&s.addDynamicProperty(a),a}}),km,lm;function mm(t,e){var r,i=this.offsetTime;"multidimensional"===this.propType&&(r=createTypedArray("float32",this.pv.length));for(var s,a,n,o,h,p,l,m,f=e.lastIndex,c=f,d=this.keyframes.length-1,u=!0;u;){if(s=this.keyframes[c],a=this.keyframes[c+1],c===d-1&&t>=a.t-i){s.h&&(s=a),f=0;break}if(a.t-i>t){f=c;break}c<d-1?c+=1:(f=0,u=!1)}var y,g=a.t-i,v=s.t-i;if(s.to){s.bezierData||(s.bezierData=bez.buildBezierData(s.s,a.s||s.e,s.to,s.ti));var P=s.bezierData;if(g<=t||t<v){var b=g<=t?P.points.length-1:0;for(o=P.points[b].point.length,n=0;n<o;n+=1)r[n]=P.points[b].point[n]}else{s.__fnct?m=s.__fnct:(m=BezierFactory.getBezierEasing(s.o.x,s.o.y,s.i.x,s.i.y,s.n).get,s.__fnct=m),h=m((t-v)/(g-v));var x,_=P.segmentLength*h,S=e.lastFrame<t&&e._lastKeyframeIndex===c?e._lastAddedLength:0;for(l=e.lastFrame<t&&e._lastKeyframeIndex===c?e._lastPoint:0,u=!0,p=P.points.length;u;){if(S+=P.points[l].partialLength,0==_||0===h||l===P.points.length-1){for(o=P.points[l].point.length,n=0;n<o;n+=1)r[n]=P.points[l].point[n];break}if(S<=_&&_<S+P.points[l+1].partialLength){for(x=(_-S)/P.points[l+1].partialLength,o=P.points[l].point.length,n=0;n<o;n+=1)r[n]=P.points[l].point[n]+(P.points[l+1].point[n]-P.points[l].point[n])*x;break}l<p-1?l+=1:u=!1}e._lastPoint=l,e._lastAddedLength=S-P.points[l].partialLength,e._lastKeyframeIndex=c}}else{var T,A,C,E,k;if(d=s.s.length,y=a.s||s.e,this.sh&&1!==s.h)if(g<=t)r[0]=y[0],r[1]=y[1],r[2]=y[2];else if(t<=v)r[0]=s.s[0],r[1]=s.s[1],r[2]=s.s[2];else{!function(t,e){var r=e[0],i=e[1],s=e[2],a=e[3],n=Math.atan2(2*i*a-2*r*s,1-2*i*i-2*s*s),o=Math.asin(2*r*i+2*s*a),h=Math.atan2(2*r*a-2*i*s,1-2*r*r-2*s*s);t[0]=n/degToRads,t[1]=o/degToRads,t[2]=h/degToRads}(r,function(t,e,r){var i,s,a,n,o,h=[],p=t[0],l=t[1],m=t[2],f=t[3],c=e[0],d=e[1],u=e[2],y=e[3];(s=p*c+l*d+m*u+f*y)<0&&(s=-s,c=-c,d=-d,u=-u,y=-y);o=1e-6<1-s?(i=Math.acos(s),a=Math.sin(i),n=Math.sin((1-r)*i)/a,Math.sin(r*i)/a):(n=1-r,r);return h[0]=n*p+o*c,h[1]=n*l+o*d,h[2]=n*m+o*u,h[3]=n*f+o*y,h}(pm(s.s),pm(y),(t-v)/(g-v)))}else for(c=0;c<d;c+=1)1!==s.h&&(h=g<=t?1:t<v?0:(s.o.x.constructor===Array?(s.__fnct||(s.__fnct=[]),s.__fnct[c]?m=s.__fnct[c]:(T=void 0===s.o.x[c]?s.o.x[0]:s.o.x[c],A=void 0===s.o.y[c]?s.o.y[0]:s.o.y[c],C=void 0===s.i.x[c]?s.i.x[0]:s.i.x[c],E=void 0===s.i.y[c]?s.i.y[0]:s.i.y[c],m=BezierFactory.getBezierEasing(T,A,C,E).get,s.__fnct[c]=m)):s.__fnct?m=s.__fnct:(T=s.o.x,A=s.o.y,C=s.i.x,E=s.i.y,m=BezierFactory.getBezierEasing(T,A,C,E).get,s.__fnct=m),m((t-v)/(g-v)))),y=a.s||s.e,k=1===s.h?s.s[c]:s.s[c]+(y[c]-s.s[c])*h,1===d?r=k:r[c]=k}return e.lastIndex=f,r}function pm(t){var e=t[0]*degToRads,r=t[1]*degToRads,i=t[2]*degToRads,s=Math.cos(e/2),a=Math.cos(r/2),n=Math.cos(i/2),o=Math.sin(e/2),h=Math.sin(r/2),p=Math.sin(i/2);return[o*h*n+s*a*p,o*a*n+s*h*p,s*h*n-o*a*p,s*a*n-o*h*p]}function qm(){var t=this.comp.renderedFrame-this.offsetTime,e=this.keyframes[0].t-this.offsetTime,r=this.keyframes[this.keyframes.length-1].t-this.offsetTime;if(!(t===this._caching.lastFrame||this._caching.lastFrame!==km&&(this._caching.lastFrame>=r&&r<=t||this._caching.lastFrame<e&&t<e))){this._caching.lastFrame>=t&&(this._caching._lastKeyframeIndex=-1,this._caching.lastIndex=0);var i=this.interpolateValue(t,this._caching);this.pv=i}return this._caching.lastFrame=t,this.pv}function rm(t){var e;if("unidimensional"===this.propType)e=t*this.mult,1e-5<lm(this.v-e)&&(this.v=e,this._mdf=!0);else for(var r=0,i=this.v.length;r<i;)e=t[r]*this.mult,1e-5<lm(this.v[r]-e)&&(this.v[r]=e,this._mdf=!0),r+=1}function sm(){if(this.elem.globalData.frameId!==this.frameId&&this.effectsSequence.length)if(this.lock)this.setVValue(this.pv);else{this.lock=!0,this._mdf=this._isFirstFrame;var t,e=this.effectsSequence.length,r=this.kf?this.pv:this.data.k;for(t=0;t<e;t+=1)r=this.effectsSequence[t](r);this.setVValue(r),this._isFirstFrame=!1,this.lock=!1,this.frameId=this.elem.globalData.frameId}}function tm(t){this.effectsSequence.push(t),this.container.addDynamicProperty(this)}function um(t,e,r,i){this.propType="unidimensional",this.mult=r||1,this.data=e,this.v=r?e.k*r:e.k,this.pv=e.k,this._mdf=!1,this.elem=t,this.container=i,this.comp=t.comp,this.k=!1,this.kf=!1,this.vel=0,this.effectsSequence=[],this._isFirstFrame=!0,this.getValue=sm,this.setVValue=rm,this.addEffect=tm}function vm(t,e,r,i){this.propType="multidimensional",this.mult=r||1,this.data=e,this._mdf=!1,this.elem=t,this.container=i,this.comp=t.comp,this.k=!1,this.kf=!1,this.frameId=-1;var s,a=e.k.length;this.v=createTypedArray("float32",a),this.pv=createTypedArray("float32",a);createTypedArray("float32",a);for(this.vel=createTypedArray("float32",a),s=0;s<a;s+=1)this.v[s]=e.k[s]*this.mult,this.pv[s]=e.k[s];this._isFirstFrame=!0,this.effectsSequence=[],this.getValue=sm,this.setVValue=rm,this.addEffect=tm}function wm(t,e,r,i){this.propType="unidimensional",this.keyframes=e.k,this.offsetTime=t.data.st,this.frameId=-1,this._caching={lastFrame:km,lastIndex:0,value:0,_lastKeyframeIndex:-1},this.k=!0,this.kf=!0,this.data=e,this.mult=r||1,this.elem=t,this.container=i,this.comp=t.comp,this.v=km,this.pv=km,this._isFirstFrame=!0,this.getValue=sm,this.setVValue=rm,this.interpolateValue=mm,this.effectsSequence=[qm.bind(this)],this.addEffect=tm}function xm(t,e,r,i){this.propType="multidimensional";var s,a,n,o,h,p=e.k.length;for(s=0;s<p-1;s+=1)e.k[s].to&&e.k[s].s&&e.k[s].e&&(a=e.k[s].s,n=e.k[s].e,o=e.k[s].to,h=e.k[s].ti,(2===a.length&&(a[0]!==n[0]||a[1]!==n[1])&&bez.pointOnLine2D(a[0],a[1],n[0],n[1],a[0]+o[0],a[1]+o[1])&&bez.pointOnLine2D(a[0],a[1],n[0],n[1],n[0]+h[0],n[1]+h[1])||3===a.length&&(a[0]!==n[0]||a[1]!==n[1]||a[2]!==n[2])&&bez.pointOnLine3D(a[0],a[1],a[2],n[0],n[1],n[2],a[0]+o[0],a[1]+o[1],a[2]+o[2])&&bez.pointOnLine3D(a[0],a[1],a[2],n[0],n[1],n[2],n[0]+h[0],n[1]+h[1],n[2]+h[2]))&&(e.k[s].to=null,e.k[s].ti=null),a[0]===n[0]&&a[1]===n[1]&&0===o[0]&&0===o[1]&&0===h[0]&&0===h[1]&&(2===a.length||a[2]===n[2]&&0===o[2]&&0===h[2])&&(e.k[s].to=null,e.k[s].ti=null));this.effectsSequence=[qm.bind(this)],this.keyframes=e.k,this.offsetTime=t.data.st,this.k=!0,this.kf=!0,this._isFirstFrame=!0,this.mult=r||1,this.elem=t,this.container=i,this.comp=t.comp,this.getValue=sm,this.setVValue=rm,this.interpolateValue=mm,this.frameId=-1;var l=e.k[0].s.length;for(this.v=createTypedArray("float32",l),this.pv=createTypedArray("float32",l),s=0;s<l;s+=1)this.v[s]=km,this.pv[s]=km;this._caching={lastFrame:km,lastIndex:0,value:createTypedArray("float32",l)},this.addEffect=tm}var TransformPropertyFactory=(Qo.prototype={applyToMatrix:function(t){var e=this._mdf;this.iterateDynamicProperties(),this._mdf=this._mdf||e,this.a&&t.translate(-this.a.v[0],-this.a.v[1],this.a.v[2]),this.s&&t.scale(this.s.v[0],this.s.v[1],this.s.v[2]),this.sk&&t.skewFromAxis(-this.sk.v,this.sa.v),this.r?t.rotate(-this.r.v):t.rotateZ(-this.rz.v).rotateY(this.ry.v).rotateX(this.rx.v).rotateZ(-this.or.v[2]).rotateY(this.or.v[1]).rotateX(this.or.v[0]),this.data.p.s?this.data.p.z?t.translate(this.px.v,this.py.v,-this.pz.v):t.translate(this.px.v,this.py.v,0):t.translate(this.p.v[0],this.p.v[1],-this.p.v[2])},getValue:function(t){if(this.elem.globalData.frameId!==this.frameId){if(this._isDirty&&(this.precalculateMatrix(),this._isDirty=!1),this.iterateDynamicProperties(),this._mdf||t){if(this.v.cloneFromProps(this.pre.props),this.appliedTransformations<1&&this.v.translate(-this.a.v[0],-this.a.v[1],this.a.v[2]),this.appliedTransformations<2&&this.v.scale(this.s.v[0],this.s.v[1],this.s.v[2]),this.sk&&this.appliedTransformations<3&&this.v.skewFromAxis(-this.sk.v,this.sa.v),this.r&&this.appliedTransformations<4?this.v.rotate(-this.r.v):!this.r&&this.appliedTransformations<4&&this.v.rotateZ(-this.rz.v).rotateY(this.ry.v).rotateX(this.rx.v).rotateZ(-this.or.v[2]).rotateY(this.or.v[1]).rotateX(this.or.v[0]),this.autoOriented){var e,r,i=this.elem.globalData.frameRate;if(this.p&&this.p.keyframes&&this.p.getValueAtTime)r=this.p._caching.lastFrame+this.p.offsetTime<=this.p.keyframes[0].t?(e=this.p.getValueAtTime((this.p.keyframes[0].t+.01)/i,0),this.p.getValueAtTime(this.p.keyframes[0].t/i,0)):this.p._caching.lastFrame+this.p.offsetTime>=this.p.keyframes[this.p.keyframes.length-1].t?(e=this.p.getValueAtTime(this.p.keyframes[this.p.keyframes.length-1].t/i,0),this.p.getValueAtTime((this.p.keyframes[this.p.keyframes.length-1].t-.01)/i,0)):(e=this.p.pv,this.p.getValueAtTime((this.p._caching.lastFrame+this.p.offsetTime-.01)/i,this.p.offsetTime));else if(this.px&&this.px.keyframes&&this.py.keyframes&&this.px.getValueAtTime&&this.py.getValueAtTime){e=[],r=[];var s=this.px,a=this.py;s._caching.lastFrame+s.offsetTime<=s.keyframes[0].t?(e[0]=s.getValueAtTime((s.keyframes[0].t+.01)/i,0),e[1]=a.getValueAtTime((a.keyframes[0].t+.01)/i,0),r[0]=s.getValueAtTime(s.keyframes[0].t/i,0),r[1]=a.getValueAtTime(a.keyframes[0].t/i,0)):s._caching.lastFrame+s.offsetTime>=s.keyframes[s.keyframes.length-1].t?(e[0]=s.getValueAtTime(s.keyframes[s.keyframes.length-1].t/i,0),e[1]=a.getValueAtTime(a.keyframes[a.keyframes.length-1].t/i,0),r[0]=s.getValueAtTime((s.keyframes[s.keyframes.length-1].t-.01)/i,0),r[1]=a.getValueAtTime((a.keyframes[a.keyframes.length-1].t-.01)/i,0)):(e=[s.pv,a.pv],r[0]=s.getValueAtTime((s._caching.lastFrame+s.offsetTime-.01)/i,s.offsetTime),r[1]=a.getValueAtTime((a._caching.lastFrame+a.offsetTime-.01)/i,a.offsetTime))}this.v.rotate(-Math.atan2(e[1]-r[1],e[0]-r[0]))}this.data.p&&this.data.p.s?this.data.p.z?this.v.translate(this.px.v,this.py.v,-this.pz.v):this.v.translate(this.px.v,this.py.v,0):this.v.translate(this.p.v[0],this.p.v[1],-this.p.v[2])}this.frameId=this.elem.globalData.frameId}},precalculateMatrix:function(){if(!this.a.k&&(this.pre.translate(-this.a.v[0],-this.a.v[1],this.a.v[2]),this.appliedTransformations=1,!this.s.effectsSequence.length)){if(this.pre.scale(this.s.v[0],this.s.v[1],this.s.v[2]),this.appliedTransformations=2,this.sk){if(this.sk.effectsSequence.length||this.sa.effectsSequence.length)return;this.pre.skewFromAxis(-this.sk.v,this.sa.v),this.appliedTransformations=3}if(this.r){if(this.r.effectsSequence.length)return;this.pre.rotate(-this.r.v),this.appliedTransformations=4}else this.rz.effectsSequence.length||this.ry.effectsSequence.length||this.rx.effectsSequence.length||this.or.effectsSequence.length||(this.pre.rotateZ(-this.rz.v).rotateY(this.ry.v).rotateX(this.rx.v).rotateZ(-this.or.v[2]).rotateY(this.or.v[1]).rotateX(this.or.v[0]),this.appliedTransformations=4)}},autoOrient:function(){}},extendPrototype([DynamicPropertyContainer],Qo),Qo.prototype.addDynamicProperty=function(t){this._addDynamicProperty(t),this.elem.addDynamicProperty(t),this._isDirty=!0},Qo.prototype._addDynamicProperty=DynamicPropertyContainer.prototype.addDynamicProperty,{getTransformProperty:function(t,e,r){return new Qo(t,e,r)}});function Qo(t,e,r){if(this.elem=t,this.frameId=-1,this.propType="transform",this.data=e,this.v=new Matrix,this.pre=new Matrix,this.appliedTransformations=0,this.initDynamicPropertyContainer(r||t),e.p&&e.p.s?(this.px=PropertyFactory.getProp(t,e.p.x,0,0,this),this.py=PropertyFactory.getProp(t,e.p.y,0,0,this),e.p.z&&(this.pz=PropertyFactory.getProp(t,e.p.z,0,0,this))):this.p=PropertyFactory.getProp(t,e.p||{k:[0,0,0]},1,0,this),e.rx){if(this.rx=PropertyFactory.getProp(t,e.rx,0,degToRads,this),this.ry=PropertyFactory.getProp(t,e.ry,0,degToRads,this),this.rz=PropertyFactory.getProp(t,e.rz,0,degToRads,this),e.or.k[0].ti){var i,s=e.or.k.length;for(i=0;i<s;i+=1)e.or.k[i].to=e.or.k[i].ti=null}this.or=PropertyFactory.getProp(t,e.or,1,degToRads,this),this.or.sh=!0}else this.r=PropertyFactory.getProp(t,e.r||{k:0},0,degToRads,this);e.sk&&(this.sk=PropertyFactory.getProp(t,e.sk,0,degToRads,this),this.sa=PropertyFactory.getProp(t,e.sa,0,degToRads,this)),this.a=PropertyFactory.getProp(t,e.a||{k:[0,0,0]},1,0,this),this.s=PropertyFactory.getProp(t,e.s||{k:[100,100,100]},1,.01,this),e.o?this.o=PropertyFactory.getProp(t,e.o,0,.01,t):this.o={_mdf:!1,v:1},this._isDirty=!0,this.dynamicProperties.length||this.getValue(!0)}function ShapePath(){this.c=!1,this._length=0,this._maxLength=8,this.v=createSizedArray(this._maxLength),this.o=createSizedArray(this._maxLength),this.i=createSizedArray(this._maxLength)}ShapePath.prototype.setPathData=function(t,e){this.c=t,this.setLength(e);for(var r=0;r<e;)this.v[r]=point_pool.newElement(),this.o[r]=point_pool.newElement(),this.i[r]=point_pool.newElement(),r+=1},ShapePath.prototype.setLength=function(t){for(;this._maxLength<t;)this.doubleArrayLength();this._length=t},ShapePath.prototype.doubleArrayLength=function(){this.v=this.v.concat(createSizedArray(this._maxLength)),this.i=this.i.concat(createSizedArray(this._maxLength)),this.o=this.o.concat(createSizedArray(this._maxLength)),this._maxLength*=2},ShapePath.prototype.setXYAt=function(t,e,r,i,s){var a;switch(this._length=Math.max(this._length,i+1),this._length>=this._maxLength&&this.doubleArrayLength(),r){case"v":a=this.v;break;case"i":a=this.i;break;case"o":a=this.o}a[i]&&(!a[i]||s)||(a[i]=point_pool.newElement()),a[i][0]=t,a[i][1]=e},ShapePath.prototype.setTripleAt=function(t,e,r,i,s,a,n,o){this.setXYAt(t,e,"v",n,o),this.setXYAt(r,i,"o",n,o),this.setXYAt(s,a,"i",n,o)},ShapePath.prototype.reverse=function(){var t=new ShapePath;t.setPathData(this.c,this._length);var e=this.v,r=this.o,i=this.i,s=0;this.c&&(t.setTripleAt(e[0][0],e[0][1],i[0][0],i[0][1],r[0][0],r[0][1],0,!1),s=1);var a,n=this._length-1,o=this._length;for(a=s;a<o;a+=1)t.setTripleAt(e[n][0],e[n][1],i[n][0],i[n][1],r[n][0],r[n][1],a,!1),n-=1;return t};var ShapePropertyFactory=function(){var s=-999999;function t(t,e,r){var i,s,a,n,o,h,p,l,m,f=r.lastIndex,c=this.keyframes;if(t<c[0].t-this.offsetTime)i=c[0].s[0],a=!0,f=0;else if(t>=c[c.length-1].t-this.offsetTime)i=c[c.length-1].s?c[c.length-1].s[0]:c[c.length-2].e[0],a=!0;else{for(var d,u,y=f,g=c.length-1,v=!0;v&&(d=c[y],!((u=c[y+1]).t-this.offsetTime>t));)y<g-1?y+=1:v=!1;if(f=y,!(a=1===d.h)){if(t>=u.t-this.offsetTime)l=1;else if(t<d.t-this.offsetTime)l=0;else{var P;d.__fnct?P=d.__fnct:(P=BezierFactory.getBezierEasing(d.o.x,d.o.y,d.i.x,d.i.y).get,d.__fnct=P),l=P((t-(d.t-this.offsetTime))/(u.t-this.offsetTime-(d.t-this.offsetTime)))}s=u.s?u.s[0]:d.e[0]}i=d.s[0]}for(h=e._length,p=i.i[0].length,r.lastIndex=f,n=0;n<h;n+=1)for(o=0;o<p;o+=1)m=a?i.i[n][o]:i.i[n][o]+(s.i[n][o]-i.i[n][o])*l,e.i[n][o]=m,m=a?i.o[n][o]:i.o[n][o]+(s.o[n][o]-i.o[n][o])*l,e.o[n][o]=m,m=a?i.v[n][o]:i.v[n][o]+(s.v[n][o]-i.v[n][o])*l,e.v[n][o]=m}function a(){this.paths=this.localShapeCollection}function e(t){!function(t,e){if(t._length!==e._length||t.c!==e.c)return!1;var r,i=t._length;for(r=0;r<i;r+=1)if(t.v[r][0]!==e.v[r][0]||t.v[r][1]!==e.v[r][1]||t.o[r][0]!==e.o[r][0]||t.o[r][1]!==e.o[r][1]||t.i[r][0]!==e.i[r][0]||t.i[r][1]!==e.i[r][1])return!1;return!0}(this.v,t)&&(this.v=shape_pool.clone(t),this.localShapeCollection.releaseShapes(),this.localShapeCollection.addShape(this.v),this._mdf=!0,this.paths=this.localShapeCollection)}function r(){if(this.elem.globalData.frameId!==this.frameId&&this.effectsSequence.length)if(this.lock)this.setVValue(this.pv);else{this.lock=!0,this._mdf=!1;var t,e=this.kf?this.pv:this.data.ks?this.data.ks.k:this.data.pt.k,r=this.effectsSequence.length;for(t=0;t<r;t+=1)e=this.effectsSequence[t](e);this.setVValue(e),this.lock=!1,this.frameId=this.elem.globalData.frameId}}function n(t,e,r){this.propType="shape",this.comp=t.comp,this.container=t,this.elem=t,this.data=e,this.k=!1,this.kf=!1,this._mdf=!1;var i=3===r?e.pt.k:e.ks.k;this.v=shape_pool.clone(i),this.pv=shape_pool.clone(this.v),this.localShapeCollection=shapeCollection_pool.newShapeCollection(),this.paths=this.localShapeCollection,this.paths.addShape(this.v),this.reset=a,this.effectsSequence=[]}function i(t){this.effectsSequence.push(t),this.container.addDynamicProperty(this)}function o(t,e,r){this.propType="shape",this.comp=t.comp,this.elem=t,this.container=t,this.offsetTime=t.data.st,this.keyframes=3===r?e.pt.k:e.ks.k,this.k=!0,this.kf=!0;var i=this.keyframes[0].s[0].i.length;this.keyframes[0].s[0].i[0].length;this.v=shape_pool.newElement(),this.v.setPathData(this.keyframes[0].s[0].c,i),this.pv=shape_pool.clone(this.v),this.localShapeCollection=shapeCollection_pool.newShapeCollection(),this.paths=this.localShapeCollection,this.paths.addShape(this.v),this.lastFrame=s,this.reset=a,this._caching={lastFrame:s,lastIndex:0},this.effectsSequence=[function(){var t=this.comp.renderedFrame-this.offsetTime,e=this.keyframes[0].t-this.offsetTime,r=this.keyframes[this.keyframes.length-1].t-this.offsetTime,i=this._caching.lastFrame;return i!==s&&(i<e&&t<e||r<i&&r<t)||(this._caching.lastIndex=i<t?this._caching.lastIndex:0,this.interpolateShape(t,this.pv,this._caching)),this._caching.lastFrame=t,this.pv}.bind(this)]}n.prototype.interpolateShape=t,n.prototype.getValue=r,n.prototype.setVValue=e,n.prototype.addEffect=i,o.prototype.getValue=r,o.prototype.interpolateShape=t,o.prototype.setVValue=e,o.prototype.addEffect=i;var h,p=(h=roundCorner,l.prototype={reset:a,getValue:function(){this.elem.globalData.frameId!==this.frameId&&(this.frameId=this.elem.globalData.frameId,this.iterateDynamicProperties(),this._mdf&&this.convertEllToPath())},convertEllToPath:function(){var t=this.p.v[0],e=this.p.v[1],r=this.s.v[0]/2,i=this.s.v[1]/2,s=3!==this.d,a=this.v;a.v[0][0]=t,a.v[0][1]=e-i,a.v[1][0]=s?t+r:t-r,a.v[1][1]=e,a.v[2][0]=t,a.v[2][1]=e+i,a.v[3][0]=s?t-r:t+r,a.v[3][1]=e,a.i[0][0]=s?t-r*h:t+r*h,a.i[0][1]=e-i,a.i[1][0]=s?t+r:t-r,a.i[1][1]=e-i*h,a.i[2][0]=s?t+r*h:t-r*h,a.i[2][1]=e+i,a.i[3][0]=s?t-r:t+r,a.i[3][1]=e+i*h,a.o[0][0]=s?t+r*h:t-r*h,a.o[0][1]=e-i,a.o[1][0]=s?t+r:t-r,a.o[1][1]=e+i*h,a.o[2][0]=s?t-r*h:t+r*h,a.o[2][1]=e+i,a.o[3][0]=s?t-r:t+r,a.o[3][1]=e-i*h}},extendPrototype([DynamicPropertyContainer],l),l);function l(t,e){this.v=shape_pool.newElement(),this.v.setPathData(!0,4),this.localShapeCollection=shapeCollection_pool.newShapeCollection(),this.paths=this.localShapeCollection,this.localShapeCollection.addShape(this.v),this.d=e.d,this.elem=t,this.comp=t.comp,this.frameId=-1,this.initDynamicPropertyContainer(t),this.p=PropertyFactory.getProp(t,e.p,1,0,this),this.s=PropertyFactory.getProp(t,e.s,1,0,this),this.dynamicProperties.length?this.k=!0:(this.k=!1,this.convertEllToPath())}var m=(f.prototype={reset:a,getValue:function(){this.elem.globalData.frameId!==this.frameId&&(this.frameId=this.elem.globalData.frameId,this.iterateDynamicProperties(),this._mdf&&this.convertToPath())},convertStarToPath:function(){var t,e,r,i,s=2*Math.floor(this.pt.v),a=2*Math.PI/s,n=!0,o=this.or.v,h=this.ir.v,p=this.os.v,l=this.is.v,m=2*Math.PI*o/(2*s),f=2*Math.PI*h/(2*s),c=-Math.PI/2;c+=this.r.v;var d=3===this.data.d?-1:1;for(t=this.v._length=0;t<s;t+=1){r=n?p:l,i=n?m:f;var u=(e=n?o:h)*Math.cos(c),y=e*Math.sin(c),g=0===u&&0===y?0:y/Math.sqrt(u*u+y*y),v=0===u&&0===y?0:-u/Math.sqrt(u*u+y*y);u+=+this.p.v[0],y+=+this.p.v[1],this.v.setTripleAt(u,y,u-g*i*r*d,y-v*i*r*d,u+g*i*r*d,y+v*i*r*d,t,!0),n=!n,c+=a*d}},convertPolygonToPath:function(){var t,e=Math.floor(this.pt.v),r=2*Math.PI/e,i=this.or.v,s=this.os.v,a=2*Math.PI*i/(4*e),n=-Math.PI/2,o=3===this.data.d?-1:1;for(n+=this.r.v,t=this.v._length=0;t<e;t+=1){var h=i*Math.cos(n),p=i*Math.sin(n),l=0===h&&0===p?0:p/Math.sqrt(h*h+p*p),m=0===h&&0===p?0:-h/Math.sqrt(h*h+p*p);h+=+this.p.v[0],p+=+this.p.v[1],this.v.setTripleAt(h,p,h-l*a*s*o,p-m*a*s*o,h+l*a*s*o,p+m*a*s*o,t,!0),n+=r*o}this.paths.length=0,this.paths[0]=this.v}},extendPrototype([DynamicPropertyContainer],f),f);function f(t,e){this.v=shape_pool.newElement(),this.v.setPathData(!0,0),this.elem=t,this.comp=t.comp,this.data=e,this.frameId=-1,this.d=e.d,this.initDynamicPropertyContainer(t),1===e.sy?(this.ir=PropertyFactory.getProp(t,e.ir,0,0,this),this.is=PropertyFactory.getProp(t,e.is,0,.01,this),this.convertToPath=this.convertStarToPath):this.convertToPath=this.convertPolygonToPath,this.pt=PropertyFactory.getProp(t,e.pt,0,0,this),this.p=PropertyFactory.getProp(t,e.p,1,0,this),this.r=PropertyFactory.getProp(t,e.r,0,degToRads,this),this.or=PropertyFactory.getProp(t,e.or,0,0,this),this.os=PropertyFactory.getProp(t,e.os,0,.01,this),this.localShapeCollection=shapeCollection_pool.newShapeCollection(),this.localShapeCollection.addShape(this.v),this.paths=this.localShapeCollection,this.dynamicProperties.length?this.k=!0:(this.k=!1,this.convertToPath())}var c=(d.prototype={convertRectToPath:function(){var t=this.p.v[0],e=this.p.v[1],r=this.s.v[0]/2,i=this.s.v[1]/2,s=bm_min(r,i,this.r.v),a=s*(1-roundCorner);this.v._length=0,2===this.d||1===this.d?(this.v.setTripleAt(t+r,e-i+s,t+r,e-i+s,t+r,e-i+a,0,!0),this.v.setTripleAt(t+r,e+i-s,t+r,e+i-a,t+r,e+i-s,1,!0),0!==s?(this.v.setTripleAt(t+r-s,e+i,t+r-s,e+i,t+r-a,e+i,2,!0),this.v.setTripleAt(t-r+s,e+i,t-r+a,e+i,t-r+s,e+i,3,!0),this.v.setTripleAt(t-r,e+i-s,t-r,e+i-s,t-r,e+i-a,4,!0),this.v.setTripleAt(t-r,e-i+s,t-r,e-i+a,t-r,e-i+s,5,!0),this.v.setTripleAt(t-r+s,e-i,t-r+s,e-i,t-r+a,e-i,6,!0),this.v.setTripleAt(t+r-s,e-i,t+r-a,e-i,t+r-s,e-i,7,!0)):(this.v.setTripleAt(t-r,e+i,t-r+a,e+i,t-r,e+i,2),this.v.setTripleAt(t-r,e-i,t-r,e-i+a,t-r,e-i,3))):(this.v.setTripleAt(t+r,e-i+s,t+r,e-i+a,t+r,e-i+s,0,!0),0!==s?(this.v.setTripleAt(t+r-s,e-i,t+r-s,e-i,t+r-a,e-i,1,!0),this.v.setTripleAt(t-r+s,e-i,t-r+a,e-i,t-r+s,e-i,2,!0),this.v.setTripleAt(t-r,e-i+s,t-r,e-i+s,t-r,e-i+a,3,!0),this.v.setTripleAt(t-r,e+i-s,t-r,e+i-a,t-r,e+i-s,4,!0),this.v.setTripleAt(t-r+s,e+i,t-r+s,e+i,t-r+a,e+i,5,!0),this.v.setTripleAt(t+r-s,e+i,t+r-a,e+i,t+r-s,e+i,6,!0),this.v.setTripleAt(t+r,e+i-s,t+r,e+i-s,t+r,e+i-a,7,!0)):(this.v.setTripleAt(t-r,e-i,t-r+a,e-i,t-r,e-i,1,!0),this.v.setTripleAt(t-r,e+i,t-r,e+i-a,t-r,e+i,2,!0),this.v.setTripleAt(t+r,e+i,t+r-a,e+i,t+r,e+i,3,!0)))},getValue:function(t){this.elem.globalData.frameId!==this.frameId&&(this.frameId=this.elem.globalData.frameId,this.iterateDynamicProperties(),this._mdf&&this.convertRectToPath())},reset:a},extendPrototype([DynamicPropertyContainer],d),d);function d(t,e){this.v=shape_pool.newElement(),this.v.c=!0,this.localShapeCollection=shapeCollection_pool.newShapeCollection(),this.localShapeCollection.addShape(this.v),this.paths=this.localShapeCollection,this.elem=t,this.comp=t.comp,this.frameId=-1,this.d=e.d,this.initDynamicPropertyContainer(t),this.p=PropertyFactory.getProp(t,e.p,1,0,this),this.s=PropertyFactory.getProp(t,e.s,1,0,this),this.r=PropertyFactory.getProp(t,e.r,0,0,this),this.dynamicProperties.length?this.k=!0:(this.k=!1,this.convertRectToPath())}var u={getShapeProp:function(t,e,r){var i;return 3===r||4===r?i=(3===r?e.pt:e.ks).k.length?new o(t,e,r):new n(t,e,r):5===r?i=new c(t,e):6===r?i=new p(t,e):7===r&&(i=new m(t,e)),i.k&&t.addDynamicProperty(i),i},getConstructorFunction:function(){return n},getKeyframedConstructorFunction:function(){return o}};return u}(),ShapeModifiers=(Tr={},Ur={},Tr.registerModifier=function(t,e){Ur[t]||(Ur[t]=e)},Tr.getModifier=function(t,e,r){return new Ur[t](e,r)},Tr),Tr,Ur;function ShapeModifier(){}function TrimModifier(){}function RoundCornersModifier(){}function RepeaterModifier(){}function ShapeCollection(){this._length=0,this._maxLength=4,this.shapes=createSizedArray(this._maxLength)}function DashProperty(t,e,r,i){this.elem=t,this.frameId=-1,this.dataProps=createSizedArray(e.length),this.renderer=r,this.k=!1,this.dashStr="",this.dashArray=createTypedArray("float32",e.length?e.length-1:0),this.dashoffset=createTypedArray("float32",1),this.initDynamicPropertyContainer(i);var s,a,n=e.length||0;for(s=0;s<n;s+=1)a=PropertyFactory.getProp(t,e[s].v,0,0,this),this.k=a.k||this.k,this.dataProps[s]={n:e[s].n,p:a};this.k||this.getValue(!0),this._isAnimated=this.k}function GradientProperty(t,e,r){this.data=e,this.c=createTypedArray("uint8c",4*e.p);var i=e.k.k[0].s?e.k.k[0].s.length-4*e.p:e.k.k.length-4*e.p;this.o=createTypedArray("float32",i),this._cmdf=!1,this._omdf=!1,this._collapsable=this.checkCollapsable(),this._hasOpacity=i,this.initDynamicPropertyContainer(r),this.prop=PropertyFactory.getProp(t,e.k,1,null,this),this.k=this.prop.k,this.getValue(!0)}ShapeModifier.prototype.initModifierProperties=function(){},ShapeModifier.prototype.addShapeToModifier=function(){},ShapeModifier.prototype.addShape=function(t){if(!this.closed){var e={shape:t.sh,data:t,localShapeCollection:shapeCollection_pool.newShapeCollection()};this.shapes.push(e),this.addShapeToModifier(e),this._isAnimated&&t.setAsAnimated()}},ShapeModifier.prototype.init=function(t,e){this.shapes=[],this.elem=t,this.initDynamicPropertyContainer(t),this.initModifierProperties(t,e),this.frameId=initialDefaultFrame,this.closed=!1,this.k=!1,this.dynamicProperties.length?this.k=!0:this.getValue(!0)},ShapeModifier.prototype.processKeys=function(){this.elem.globalData.frameId!==this.frameId&&(this.frameId=this.elem.globalData.frameId,this.iterateDynamicProperties())},extendPrototype([DynamicPropertyContainer],ShapeModifier),extendPrototype([ShapeModifier],TrimModifier),TrimModifier.prototype.initModifierProperties=function(t,e){this.s=PropertyFactory.getProp(t,e.s,0,.01,this),this.e=PropertyFactory.getProp(t,e.e,0,.01,this),this.o=PropertyFactory.getProp(t,e.o,0,0,this),this.sValue=0,this.eValue=0,this.getValue=this.processKeys,this.m=e.m,this._isAnimated=!!this.s.effectsSequence.length||!!this.e.effectsSequence.length||!!this.o.effectsSequence.length},TrimModifier.prototype.addShapeToModifier=function(t){t.pathsData=[]},TrimModifier.prototype.calculateShapeEdges=function(t,e,r,i,s){var a=[];e<=1?a.push({s:t,e:e}):1<=t?a.push({s:t-1,e:e-1}):(a.push({s:t,e:1}),a.push({s:0,e:e-1}));var n,o,h=[],p=a.length;for(n=0;n<p;n+=1){var l,m;if((o=a[n]).e*s<i||o.s*s>i+r);else l=o.s*s<=i?0:(o.s*s-i)/r,m=o.e*s>=i+r?1:(o.e*s-i)/r,h.push([l,m])}return h.length||h.push([0,0]),h},TrimModifier.prototype.releasePathsData=function(t){var e,r=t.length;for(e=0;e<r;e+=1)segments_length_pool.release(t[e]);return t.length=0,t},TrimModifier.prototype.processShapes=function(t){var e,r,i;if(this._mdf||t){var s=this.o.v%360/360;if(s<0&&(s+=1),e=(1<this.s.v?1:this.s.v<0?0:this.s.v)+s,(r=(1<this.e.v?1:this.e.v<0?0:this.e.v)+s)<e){var a=e;e=r,r=a}e=1e-4*Math.round(1e4*e),r=1e-4*Math.round(1e4*r),this.sValue=e,this.eValue=r}else e=this.sValue,r=this.eValue;var n,o,h,p,l,m,f=this.shapes.length,c=0;if(r===e)for(n=0;n<f;n+=1)this.shapes[n].localShapeCollection.releaseShapes(),this.shapes[n].shape._mdf=!0,this.shapes[n].shape.paths=this.shapes[n].localShapeCollection;else if(1===r&&0===e||0===r&&1===e){if(this._mdf)for(n=0;n<f;n+=1)this.shapes[n].pathsData.length=0,this.shapes[n].shape._mdf=!0}else{var d,u,y=[];for(n=0;n<f;n+=1)if((d=this.shapes[n]).shape._mdf||this._mdf||t||2===this.m){if(h=(i=d.shape.paths)._length,m=0,!d.shape._mdf&&d.pathsData.length)m=d.totalShapeLength;else{for(p=this.releasePathsData(d.pathsData),o=0;o<h;o+=1)l=bez.getSegmentsLength(i.shapes[o]),p.push(l),m+=l.totalLength;d.totalShapeLength=m,d.pathsData=p}c+=m,d.shape._mdf=!0}else d.shape.paths=d.localShapeCollection;var g,v=e,P=r,b=0;for(n=f-1;0<=n;n-=1)if((d=this.shapes[n]).shape._mdf){for((u=d.localShapeCollection).releaseShapes(),2===this.m&&1<f?(g=this.calculateShapeEdges(e,r,d.totalShapeLength,b,c),b+=d.totalShapeLength):g=[[v,P]],h=g.length,o=0;o<h;o+=1){v=g[o][0],P=g[o][1],y.length=0,P<=1?y.push({s:d.totalShapeLength*v,e:d.totalShapeLength*P}):1<=v?y.push({s:d.totalShapeLength*(v-1),e:d.totalShapeLength*(P-1)}):(y.push({s:d.totalShapeLength*v,e:d.totalShapeLength}),y.push({s:0,e:d.totalShapeLength*(P-1)}));var x=this.addShapes(d,y[0]);if(y[0].s!==y[0].e){if(1<y.length)if(d.shape.paths.shapes[d.shape.paths._length-1].c){var _=x.pop();this.addPaths(x,u),x=this.addShapes(d,y[1],_)}else this.addPaths(x,u),x=this.addShapes(d,y[1]);this.addPaths(x,u)}}d.shape.paths=u}}},TrimModifier.prototype.addPaths=function(t,e){var r,i=t.length;for(r=0;r<i;r+=1)e.addShape(t[r])},TrimModifier.prototype.addSegment=function(t,e,r,i,s,a,n){s.setXYAt(e[0],e[1],"o",a),s.setXYAt(r[0],r[1],"i",a+1),n&&s.setXYAt(t[0],t[1],"v",a),s.setXYAt(i[0],i[1],"v",a+1)},TrimModifier.prototype.addSegmentFromArray=function(t,e,r,i){e.setXYAt(t[1],t[5],"o",r),e.setXYAt(t[2],t[6],"i",r+1),i&&e.setXYAt(t[0],t[4],"v",r),e.setXYAt(t[3],t[7],"v",r+1)},TrimModifier.prototype.addShapes=function(t,e,r){var i,s,a,n,o,h,p,l,m=t.pathsData,f=t.shape.paths.shapes,c=t.shape.paths._length,d=0,u=[],y=!0;for(l=r?(o=r._length,r._length):(r=shape_pool.newElement(),o=0),u.push(r),i=0;i<c;i+=1){for(h=m[i].lengths,r.c=f[i].c,a=f[i].c?h.length:h.length+1,s=1;s<a;s+=1)if(d+(n=h[s-1]).addedLength<e.s)d+=n.addedLength,r.c=!1;else{if(d>e.e){r.c=!1;break}e.s<=d&&e.e>=d+n.addedLength?(this.addSegment(f[i].v[s-1],f[i].o[s-1],f[i].i[s],f[i].v[s],r,o,y),y=!1):(p=bez.getNewSegment(f[i].v[s-1],f[i].v[s],f[i].o[s-1],f[i].i[s],(e.s-d)/n.addedLength,(e.e-d)/n.addedLength,h[s-1]),this.addSegmentFromArray(p,r,o,y),y=!1,r.c=!1),d+=n.addedLength,o+=1}if(f[i].c&&h.length){if(n=h[s-1],d<=e.e){var g=h[s-1].addedLength;e.s<=d&&e.e>=d+g?(this.addSegment(f[i].v[s-1],f[i].o[s-1],f[i].i[0],f[i].v[0],r,o,y),y=!1):(p=bez.getNewSegment(f[i].v[s-1],f[i].v[0],f[i].o[s-1],f[i].i[0],(e.s-d)/g,(e.e-d)/g,h[s-1]),this.addSegmentFromArray(p,r,o,y),y=!1,r.c=!1)}else r.c=!1;d+=n.addedLength,o+=1}if(r._length&&(r.setXYAt(r.v[l][0],r.v[l][1],"i",l),r.setXYAt(r.v[r._length-1][0],r.v[r._length-1][1],"o",r._length-1)),d>e.e)break;i<c-1&&(r=shape_pool.newElement(),y=!0,u.push(r),o=0)}return u},ShapeModifiers.registerModifier("tm",TrimModifier),extendPrototype([ShapeModifier],RoundCornersModifier),RoundCornersModifier.prototype.initModifierProperties=function(t,e){this.getValue=this.processKeys,this.rd=PropertyFactory.getProp(t,e.r,0,null,this),this._isAnimated=!!this.rd.effectsSequence.length},RoundCornersModifier.prototype.processPath=function(t,e){var r=shape_pool.newElement();r.c=t.c;var i,s,a,n,o,h,p,l,m,f,c,d,u,y=t._length,g=0;for(i=0;i<y;i+=1)s=t.v[i],n=t.o[i],a=t.i[i],s[0]===n[0]&&s[1]===n[1]&&s[0]===a[0]&&s[1]===a[1]?0!==i&&i!==y-1||t.c?(o=0===i?t.v[y-1]:t.v[i-1],p=(h=Math.sqrt(Math.pow(s[0]-o[0],2)+Math.pow(s[1]-o[1],2)))?Math.min(h/2,e)/h:0,l=d=s[0]+(o[0]-s[0])*p,m=u=s[1]-(s[1]-o[1])*p,f=l-(l-s[0])*roundCorner,c=m-(m-s[1])*roundCorner,r.setTripleAt(l,m,f,c,d,u,g),g+=1,o=i===y-1?t.v[0]:t.v[i+1],p=(h=Math.sqrt(Math.pow(s[0]-o[0],2)+Math.pow(s[1]-o[1],2)))?Math.min(h/2,e)/h:0,l=f=s[0]+(o[0]-s[0])*p,m=c=s[1]+(o[1]-s[1])*p,d=l-(l-s[0])*roundCorner,u=m-(m-s[1])*roundCorner,r.setTripleAt(l,m,f,c,d,u,g)):r.setTripleAt(s[0],s[1],n[0],n[1],a[0],a[1],g):r.setTripleAt(t.v[i][0],t.v[i][1],t.o[i][0],t.o[i][1],t.i[i][0],t.i[i][1],g),g+=1;return r},RoundCornersModifier.prototype.processShapes=function(t){var e,r,i,s,a,n,o=this.shapes.length,h=this.rd.v;if(0!==h)for(r=0;r<o;r+=1){if((a=this.shapes[r]).shape.paths,n=a.localShapeCollection,a.shape._mdf||this._mdf||t)for(n.releaseShapes(),a.shape._mdf=!0,e=a.shape.paths.shapes,s=a.shape.paths._length,i=0;i<s;i+=1)n.addShape(this.processPath(e[i],h));a.shape.paths=a.localShapeCollection}this.dynamicProperties.length||(this._mdf=!1)},ShapeModifiers.registerModifier("rd",RoundCornersModifier),extendPrototype([ShapeModifier],RepeaterModifier),RepeaterModifier.prototype.initModifierProperties=function(t,e){this.getValue=this.processKeys,this.c=PropertyFactory.getProp(t,e.c,0,null,this),this.o=PropertyFactory.getProp(t,e.o,0,null,this),this.tr=TransformPropertyFactory.getTransformProperty(t,e.tr,this),this.so=PropertyFactory.getProp(t,e.tr.so,0,.01,this),this.eo=PropertyFactory.getProp(t,e.tr.eo,0,.01,this),this.data=e,this.dynamicProperties.length||this.getValue(!0),this._isAnimated=!!this.dynamicProperties.length,this.pMatrix=new Matrix,this.rMatrix=new Matrix,this.sMatrix=new Matrix,this.tMatrix=new Matrix,this.matrix=new Matrix},RepeaterModifier.prototype.applyTransforms=function(t,e,r,i,s,a){var n=a?-1:1,o=i.s.v[0]+(1-i.s.v[0])*(1-s),h=i.s.v[1]+(1-i.s.v[1])*(1-s);t.translate(i.p.v[0]*n*s,i.p.v[1]*n*s,i.p.v[2]),e.translate(-i.a.v[0],-i.a.v[1],i.a.v[2]),e.rotate(-i.r.v*n*s),e.translate(i.a.v[0],i.a.v[1],i.a.v[2]),r.translate(-i.a.v[0],-i.a.v[1],i.a.v[2]),r.scale(a?1/o:o,a?1/h:h),r.translate(i.a.v[0],i.a.v[1],i.a.v[2])},RepeaterModifier.prototype.init=function(t,e,r,i){this.elem=t,this.arr=e,this.pos=r,this.elemsData=i,this._currentCopies=0,this._elements=[],this._groups=[],this.frameId=-1,this.initDynamicPropertyContainer(t),this.initModifierProperties(t,e[r]);for(;0<r;)r-=1,this._elements.unshift(e[r]),1;this.dynamicProperties.length?this.k=!0:this.getValue(!0)},RepeaterModifier.prototype.resetElements=function(t){var e,r=t.length;for(e=0;e<r;e+=1)t[e]._processed=!1,"gr"===t[e].ty&&this.resetElements(t[e].it)},RepeaterModifier.prototype.cloneElements=function(t){t.length;var e=JSON.parse(JSON.stringify(t));return this.resetElements(e),e},RepeaterModifier.prototype.changeGroupRender=function(t,e){var r,i=t.length;for(r=0;r<i;r+=1)t[r]._render=e,"gr"===t[r].ty&&this.changeGroupRender(t[r].it,e)},RepeaterModifier.prototype.processShapes=function(t){var e,r,i,s,a;if(this._mdf||t){var n,o=Math.ceil(this.c.v);if(this._groups.length<o){for(;this._groups.length<o;){var h={it:this.cloneElements(this._elements),ty:"gr"};h.it.push({a:{a:0,ix:1,k:[0,0]},nm:"Transform",o:{a:0,ix:7,k:100},p:{a:0,ix:2,k:[0,0]},r:{a:1,ix:6,k:[{s:0,e:0,t:0},{s:0,e:0,t:1}]},s:{a:0,ix:3,k:[100,100]},sa:{a:0,ix:5,k:0},sk:{a:0,ix:4,k:0},ty:"tr"}),this.arr.splice(0,0,h),this._groups.splice(0,0,h),this._currentCopies+=1}this.elem.reloadShapes()}for(i=a=0;i<=this._groups.length-1;i+=1)n=a<o,this._groups[i]._render=n,this.changeGroupRender(this._groups[i].it,n),a+=1;this._currentCopies=o;var p=this.o.v,l=p%1,m=0<p?Math.floor(p):Math.ceil(p),f=(this.tr.v.props,this.pMatrix.props),c=this.rMatrix.props,d=this.sMatrix.props;this.pMatrix.reset(),this.rMatrix.reset(),this.sMatrix.reset(),this.tMatrix.reset(),this.matrix.reset();var u,y,g=0;if(0<p){for(;g<m;)this.applyTransforms(this.pMatrix,this.rMatrix,this.sMatrix,this.tr,1,!1),g+=1;l&&(this.applyTransforms(this.pMatrix,this.rMatrix,this.sMatrix,this.tr,l,!1),g+=l)}else if(p<0){for(;m<g;)this.applyTransforms(this.pMatrix,this.rMatrix,this.sMatrix,this.tr,1,!0),g-=1;l&&(this.applyTransforms(this.pMatrix,this.rMatrix,this.sMatrix,this.tr,-l,!0),g-=l)}for(i=1===this.data.m?0:this._currentCopies-1,s=1===this.data.m?1:-1,a=this._currentCopies;a;){if(y=(r=(e=this.elemsData[i].it)[e.length-1].transform.mProps.v.props).length,e[e.length-1].transform.mProps._mdf=!0,e[e.length-1].transform.op._mdf=!0,e[e.length-1].transform.op.v=this.so.v+(this.eo.v-this.so.v)*(i/(this._currentCopies-1)),0!==g){for((0!==i&&1===s||i!==this._currentCopies-1&&-1===s)&&this.applyTransforms(this.pMatrix,this.rMatrix,this.sMatrix,this.tr,1,!1),this.matrix.transform(c[0],c[1],c[2],c[3],c[4],c[5],c[6],c[7],c[8],c[9],c[10],c[11],c[12],c[13],c[14],c[15]),this.matrix.transform(d[0],d[1],d[2],d[3],d[4],d[5],d[6],d[7],d[8],d[9],d[10],d[11],d[12],d[13],d[14],d[15]),this.matrix.transform(f[0],f[1],f[2],f[3],f[4],f[5],f[6],f[7],f[8],f[9],f[10],f[11],f[12],f[13],f[14],f[15]),u=0;u<y;u+=1)r[u]=this.matrix.props[u];this.matrix.reset()}else for(this.matrix.reset(),u=0;u<y;u+=1)r[u]=this.matrix.props[u];g+=1,a-=1,i+=s}}else for(a=this._currentCopies,i=0,s=1;a;)r=(e=this.elemsData[i].it)[e.length-1].transform.mProps.v.props,e[e.length-1].transform.mProps._mdf=!1,e[e.length-1].transform.op._mdf=!1,a-=1,i+=s},RepeaterModifier.prototype.addShape=function(){},ShapeModifiers.registerModifier("rp",RepeaterModifier),ShapeCollection.prototype.addShape=function(t){this._length===this._maxLength&&(this.shapes=this.shapes.concat(createSizedArray(this._maxLength)),this._maxLength*=2),this.shapes[this._length]=t,this._length+=1},ShapeCollection.prototype.releaseShapes=function(){var t;for(t=0;t<this._length;t+=1)shape_pool.release(this.shapes[t]);this._length=0},DashProperty.prototype.getValue=function(t){if((this.elem.globalData.frameId!==this.frameId||t)&&(this.frameId=this.elem.globalData.frameId,this.iterateDynamicProperties(),this._mdf=this._mdf||t,this._mdf)){var e=0,r=this.dataProps.length;for("svg"===this.renderer&&(this.dashStr=""),e=0;e<r;e+=1)"o"!=this.dataProps[e].n?"svg"===this.renderer?this.dashStr+=" "+this.dataProps[e].p.v:this.dashArray[e]=this.dataProps[e].p.v:this.dashoffset[0]=this.dataProps[e].p.v}},extendPrototype([DynamicPropertyContainer],DashProperty),GradientProperty.prototype.comparePoints=function(t,e){for(var r=0,i=this.o.length/2;r<i;){if(.01<Math.abs(t[4*r]-t[4*e+2*r]))return!1;r+=1}return!0},GradientProperty.prototype.checkCollapsable=function(){if(this.o.length/2!=this.c.length/4)return!1;if(this.data.k.k[0].s)for(var t=0,e=this.data.k.k.length;t<e;){if(!this.comparePoints(this.data.k.k[t].s,this.data.p))return!1;t+=1}else if(!this.comparePoints(this.data.k.k,this.data.p))return!1;return!0},GradientProperty.prototype.getValue=function(t){if(this.prop.getValue(),this._mdf=!1,this._cmdf=!1,this._omdf=!1,this.prop._mdf||t){var e,r,i,s=4*this.data.p;for(e=0;e<s;e+=1)r=e%4==0?100:255,i=Math.round(this.prop.v[e]*r),this.c[e]!==i&&(this.c[e]=i,this._cmdf=!t);if(this.o.length)for(s=this.prop.v.length,e=4*this.data.p;e<s;e+=1)r=e%2==0?100:1,i=e%2==0?Math.round(100*this.prop.v[e]):this.prop.v[e],this.o[e-4*this.data.p]!==i&&(this.o[e-4*this.data.p]=i,this._omdf=!t);this._mdf=!t}},extendPrototype([DynamicPropertyContainer],GradientProperty);var buildShapeString=function(t,e,r,i){if(0===e)return"";var s,a=t.o,n=t.i,o=t.v,h=" M"+i.applyToPointStringified(o[0][0],o[0][1]);for(s=1;s<e;s+=1)h+=" C"+i.applyToPointStringified(a[s-1][0],a[s-1][1])+" "+i.applyToPointStringified(n[s][0],n[s][1])+" "+i.applyToPointStringified(o[s][0],o[s][1]);return r&&e&&(h+=" C"+i.applyToPointStringified(a[s-1][0],a[s-1][1])+" "+i.applyToPointStringified(n[0][0],n[0][1])+" "+i.applyToPointStringified(o[0][0],o[0][1]),h+="z"),h},ImagePreloader=function(){},featureSupport=(Iv={maskType:!0},(/MSIE 10/i.test(navigator.userAgent)||/MSIE 9/i.test(navigator.userAgent)||/rv:11.0/i.test(navigator.userAgent)||/Edge\/\d./i.test(navigator.userAgent))&&(Iv.maskType=!1),Iv),Iv,filtersFactory=(Jv={},Jv.createFilter=function(t){var e=createNS("filter");return e.setAttribute("id",t),e.setAttribute("filterUnits","objectBoundingBox"),e.setAttribute("x","0%"),e.setAttribute("y","0%"),e.setAttribute("width","100%"),e.setAttribute("height","100%"),e},Jv.createAlphaToLuminanceFilter=function(){var t=createNS("feColorMatrix");return t.setAttribute("type","matrix"),t.setAttribute("color-interpolation-filters","sRGB"),t.setAttribute("values","0 0 0 1 0  0 0 0 1 0  0 0 0 1 0  0 0 0 1 1"),t},Jv),Jv,assetLoader={load:function(t,e,r){var i,s=new XMLHttpRequest;s.open("GET",t,!0);try{s.responseType="json"}catch(t){}s.send(),s.onreadystatechange=function(){if(4==s.readyState)if(200==s.status)i=Pv(s),e(i);else try{i=Pv(s),e(i)}catch(t){r&&r(t)}}}};function Pv(t){return t.response&&"object"==typeof t.response?t.response:t.response&&"string"==typeof t.response?JSON.parse(t.response):t.responseText?JSON.parse(t.responseText):void 0}var assetLoader=null;function TextAnimatorProperty(t,e,r){this._isFirstFrame=!0,this._hasMaskedPath=!1,this._frameId=-1,this._textData=t,this._renderType=e,this._elem=r,this._animatorsData=createSizedArray(this._textData.a.length),this._pathData={},this._moreOptions={alignment:{}},this.renderedLetters=[],this.lettersChangedFlag=!1,this.initDynamicPropertyContainer(r)}function TextAnimatorDataProperty(t,e,r){var i={propType:!1},s=PropertyFactory.getProp,a=e.a;this.a={r:a.r?s(t,a.r,0,degToRads,r):i,rx:a.rx?s(t,a.rx,0,degToRads,r):i,ry:a.ry?s(t,a.ry,0,degToRads,r):i,sk:a.sk?s(t,a.sk,0,degToRads,r):i,sa:a.sa?s(t,a.sa,0,degToRads,r):i,s:a.s?s(t,a.s,1,.01,r):i,a:a.a?s(t,a.a,1,0,r):i,o:a.o?s(t,a.o,0,.01,r):i,p:a.p?s(t,a.p,1,0,r):i,sw:a.sw?s(t,a.sw,0,0,r):i,sc:a.sc?s(t,a.sc,1,0,r):i,fc:a.fc?s(t,a.fc,1,0,r):i,fh:a.fh?s(t,a.fh,0,0,r):i,fs:a.fs?s(t,a.fs,0,.01,r):i,fb:a.fb?s(t,a.fb,0,.01,r):i,t:a.t?s(t,a.t,0,0,r):i},this.s=TextSelectorProp.getTextSelectorProp(t,e.s,r),this.s.t=e.s.t}function LetterProps(t,e,r,i,s,a){this.o=t,this.sw=e,this.sc=r,this.fc=i,this.m=s,this.p=a,this._mdf={o:!0,sw:!!e,sc:!!r,fc:!!i,m:!0,p:!0}}function TextProperty(t,e){this._frameId=initialDefaultFrame,this.pv="",this.v="",this.kf=!1,this._isFirstFrame=!0,this._mdf=!1,this.data=e,this.elem=t,this.comp=this.elem.comp,this.keysIndex=0,this.canResize=!1,this.minimumFontSize=1,this.effectsSequence=[],this.currentData={ascent:0,boxWidth:this.defaultBoxWidth,f:"",fStyle:"",fWeight:"",fc:"",j:"",justifyOffset:"",l:[],lh:0,lineWidths:[],ls:"",of:"",s:"",sc:"",sw:0,t:0,tr:0,sz:0,ps:null,fillColorAnim:!1,strokeColorAnim:!1,strokeWidthAnim:!1,yOffset:0,finalSize:0,finalText:[],finalLineHeight:0,__complete:!1},this.copyData(this.currentData,this.data.d.k[0].s),this.searchProperty()||this.completeTextData(this.currentData)}TextAnimatorProperty.prototype.searchProperties=function(){var t,e,r=this._textData.a.length,i=PropertyFactory.getProp;for(t=0;t<r;t+=1)e=this._textData.a[t],this._animatorsData[t]=new TextAnimatorDataProperty(this._elem,e,this);this._textData.p&&"m"in this._textData.p?(this._pathData={f:i(this._elem,this._textData.p.f,0,0,this),l:i(this._elem,this._textData.p.l,0,0,this),r:this._textData.p.r,m:this._elem.maskManager.getMaskProperty(this._textData.p.m)},this._hasMaskedPath=!0):this._hasMaskedPath=!1,this._moreOptions.alignment=i(this._elem,this._textData.m.a,1,0,this)},TextAnimatorProperty.prototype.getMeasures=function(t,e){if(this.lettersChangedFlag=e,this._mdf||this._isFirstFrame||e||this._hasMaskedPath&&this._pathData.m._mdf){this._isFirstFrame=!1;var r,i,s,a,n,o,h,p,l,m,f,c,d,u,y,g,v,P,b,x=this._moreOptions.alignment.v,_=this._animatorsData,S=this._textData,T=this.mHelper,A=this._renderType,C=this.renderedLetters.length,E=(this.data,t.l);if(this._hasMaskedPath){if(b=this._pathData.m,!this._pathData.n||this._pathData._mdf){var k,D=b.v;for(this._pathData.r&&(D=D.reverse()),n={tLength:0,segments:[]},a=D._length-1,s=g=0;s<a;s+=1)k=bez.buildBezierData(D.v[s],D.v[s+1],[D.o[s][0]-D.v[s][0],D.o[s][1]-D.v[s][1]],[D.i[s+1][0]-D.v[s+1][0],D.i[s+1][1]-D.v[s+1][1]]),n.tLength+=k.segmentLength,n.segments.push(k),g+=k.segmentLength;s=a,b.v.c&&(k=bez.buildBezierData(D.v[s],D.v[0],[D.o[s][0]-D.v[s][0],D.o[s][1]-D.v[s][1]],[D.i[0][0]-D.v[0][0],D.i[0][1]-D.v[0][1]]),n.tLength+=k.segmentLength,n.segments.push(k),g+=k.segmentLength),this._pathData.pi=n}if(n=this._pathData.pi,o=this._pathData.f.v,m=1,l=!(p=f=0),u=n.segments,o<0&&b.v.c)for(n.tLength<Math.abs(o)&&(o=-Math.abs(o)%n.tLength),m=(d=u[f=u.length-1].points).length-1;o<0;)o+=d[m].partialLength,(m-=1)<0&&(m=(d=u[f-=1].points).length-1);c=(d=u[f].points)[m-1],y=(h=d[m]).partialLength}a=E.length,i=r=0;var I,M,w,F,V=1.2*t.finalSize*.714,R=!0;w=_.length;var L,z,O,B,N,G,j,J,K,q,H,W,Y,X=-1,Q=o,$=f,U=m,Z=-1,tt="",et=this.defaultPropsArray;if(2===t.j||1===t.j){var rt=0,it=0,st=2===t.j?-.5:-1,at=0,nt=!0;for(s=0;s<a;s+=1)if(E[s].n){for(rt&&(rt+=it);at<s;)E[at].animatorJustifyOffset=rt,at+=1;nt=!(rt=0)}else{for(M=0;M<w;M+=1)(I=_[M].a).t.propType&&(nt&&2===t.j&&(it+=I.t.v*st),(L=_[M].s.getMult(E[s].anIndexes[M],S.a[M].s.totalChars)).length?rt+=I.t.v*L[0]*st:rt+=I.t.v*L*st);nt=!1}for(rt&&(rt+=it);at<s;)E[at].animatorJustifyOffset=rt,at+=1}for(s=0;s<a;s+=1){if(T.reset(),N=1,E[s].n)r=0,i+=t.yOffset,i+=R?1:0,o=Q,R=!1,0,this._hasMaskedPath&&(m=U,c=(d=u[f=$].points)[m-1],y=(h=d[m]).partialLength,p=0),Y=q=W=tt="",et=this.defaultPropsArray;else{if(this._hasMaskedPath){if(Z!==E[s].line){switch(t.j){case 1:o+=g-t.lineWidths[E[s].line];break;case 2:o+=(g-t.lineWidths[E[s].line])/2}Z=E[s].line}X!==E[s].ind&&(E[X]&&(o+=E[X].extra),o+=E[s].an/2,X=E[s].ind),o+=x[0]*E[s].an/200;var ot=0;for(M=0;M<w;M+=1)(I=_[M].a).p.propType&&((L=_[M].s.getMult(E[s].anIndexes[M],S.a[M].s.totalChars)).length?ot+=I.p.v[0]*L[0]:ot+=I.p.v[0]*L),I.a.propType&&((L=_[M].s.getMult(E[s].anIndexes[M],S.a[M].s.totalChars)).length?ot+=I.a.v[0]*L[0]:ot+=I.a.v[0]*L);for(l=!0;l;)o+ot<=p+y||!d?(v=(o+ot-p)/h.partialLength,O=c.point[0]+(h.point[0]-c.point[0])*v,B=c.point[1]+(h.point[1]-c.point[1])*v,T.translate(-x[0]*E[s].an/200,-x[1]*V/100),l=!1):d&&(p+=h.partialLength,(m+=1)>=d.length&&(m=0,d=u[f+=1]?u[f].points:b.v.c?u[f=m=0].points:(p-=h.partialLength,null)),d&&(c=h,y=(h=d[m]).partialLength));z=E[s].an/2-E[s].add,T.translate(-z,0,0)}else z=E[s].an/2-E[s].add,T.translate(-z,0,0),T.translate(-x[0]*E[s].an/200,-x[1]*V/100,0);for(E[s].l/2,M=0;M<w;M+=1)(I=_[M].a).t.propType&&(L=_[M].s.getMult(E[s].anIndexes[M],S.a[M].s.totalChars),0===r&&0===t.j||(this._hasMaskedPath?L.length?o+=I.t.v*L[0]:o+=I.t.v*L:L.length?r+=I.t.v*L[0]:r+=I.t.v*L));for(E[s].l/2,t.strokeWidthAnim&&(j=t.sw||0),t.strokeColorAnim&&(G=t.sc?[t.sc[0],t.sc[1],t.sc[2]]:[0,0,0]),t.fillColorAnim&&t.fc&&(J=[t.fc[0],t.fc[1],t.fc[2]]),M=0;M<w;M+=1)(I=_[M].a).a.propType&&((L=_[M].s.getMult(E[s].anIndexes[M],S.a[M].s.totalChars)).length?T.translate(-I.a.v[0]*L[0],-I.a.v[1]*L[1],I.a.v[2]*L[2]):T.translate(-I.a.v[0]*L,-I.a.v[1]*L,I.a.v[2]*L));for(M=0;M<w;M+=1)(I=_[M].a).s.propType&&((L=_[M].s.getMult(E[s].anIndexes[M],S.a[M].s.totalChars)).length?T.scale(1+(I.s.v[0]-1)*L[0],1+(I.s.v[1]-1)*L[1],1):T.scale(1+(I.s.v[0]-1)*L,1+(I.s.v[1]-1)*L,1));for(M=0;M<w;M+=1){if(I=_[M].a,L=_[M].s.getMult(E[s].anIndexes[M],S.a[M].s.totalChars),I.sk.propType&&(L.length?T.skewFromAxis(-I.sk.v*L[0],I.sa.v*L[1]):T.skewFromAxis(-I.sk.v*L,I.sa.v*L)),I.r.propType&&(L.length?T.rotateZ(-I.r.v*L[2]):T.rotateZ(-I.r.v*L)),I.ry.propType&&(L.length?T.rotateY(I.ry.v*L[1]):T.rotateY(I.ry.v*L)),I.rx.propType&&(L.length?T.rotateX(I.rx.v*L[0]):T.rotateX(I.rx.v*L)),I.o.propType&&(L.length?N+=(I.o.v*L[0]-N)*L[0]:N+=(I.o.v*L-N)*L),t.strokeWidthAnim&&I.sw.propType&&(L.length?j+=I.sw.v*L[0]:j+=I.sw.v*L),t.strokeColorAnim&&I.sc.propType)for(K=0;K<3;K+=1)L.length?G[K]=G[K]+(I.sc.v[K]-G[K])*L[0]:G[K]=G[K]+(I.sc.v[K]-G[K])*L;if(t.fillColorAnim&&t.fc){if(I.fc.propType)for(K=0;K<3;K+=1)L.length?J[K]=J[K]+(I.fc.v[K]-J[K])*L[0]:J[K]=J[K]+(I.fc.v[K]-J[K])*L;I.fh.propType&&(J=L.length?addHueToRGB(J,I.fh.v*L[0]):addHueToRGB(J,I.fh.v*L)),I.fs.propType&&(J=L.length?addSaturationToRGB(J,I.fs.v*L[0]):addSaturationToRGB(J,I.fs.v*L)),I.fb.propType&&(J=L.length?addBrightnessToRGB(J,I.fb.v*L[0]):addBrightnessToRGB(J,I.fb.v*L))}}for(M=0;M<w;M+=1)(I=_[M].a).p.propType&&(L=_[M].s.getMult(E[s].anIndexes[M],S.a[M].s.totalChars),this._hasMaskedPath?L.length?T.translate(0,I.p.v[1]*L[0],-I.p.v[2]*L[1]):T.translate(0,I.p.v[1]*L,-I.p.v[2]*L):L.length?T.translate(I.p.v[0]*L[0],I.p.v[1]*L[1],-I.p.v[2]*L[2]):T.translate(I.p.v[0]*L,I.p.v[1]*L,-I.p.v[2]*L));if(t.strokeWidthAnim&&(q=j<0?0:j),t.strokeColorAnim&&(H="rgb("+Math.round(255*G[0])+","+Math.round(255*G[1])+","+Math.round(255*G[2])+")"),t.fillColorAnim&&t.fc&&(W="rgb("+Math.round(255*J[0])+","+Math.round(255*J[1])+","+Math.round(255*J[2])+")"),this._hasMaskedPath){if(T.translate(0,-t.ls),T.translate(0,x[1]*V/100+i,0),S.p.p){P=(h.point[1]-c.point[1])/(h.point[0]-c.point[0]);var ht=180*Math.atan(P)/Math.PI;h.point[0]<c.point[0]&&(ht+=180),T.rotate(-ht*Math.PI/180)}T.translate(O,B,0),o-=x[0]*E[s].an/200,E[s+1]&&X!==E[s+1].ind&&(o+=E[s].an/2,o+=t.tr/1e3*t.finalSize)}else{switch(T.translate(r,i,0),t.ps&&T.translate(t.ps[0],t.ps[1]+t.ascent,0),t.j){case 1:T.translate(E[s].animatorJustifyOffset+t.justifyOffset+(t.boxWidth-t.lineWidths[E[s].line]),0,0);break;case 2:T.translate(E[s].animatorJustifyOffset+t.justifyOffset+(t.boxWidth-t.lineWidths[E[s].line])/2,0,0)}T.translate(0,-t.ls),T.translate(z,0,0),T.translate(x[0]*E[s].an/200,x[1]*V/100,0),r+=E[s].l+t.tr/1e3*t.finalSize}"html"===A?tt=T.toCSS():"svg"===A?tt=T.to2dCSS():et=[T.props[0],T.props[1],T.props[2],T.props[3],T.props[4],T.props[5],T.props[6],T.props[7],T.props[8],T.props[9],T.props[10],T.props[11],T.props[12],T.props[13],T.props[14],T.props[15]],Y=N}C<=s?(F=new LetterProps(Y,q,H,W,tt,et),this.renderedLetters.push(F),C+=1,this.lettersChangedFlag=!0):(F=this.renderedLetters[s],this.lettersChangedFlag=F.update(Y,q,H,W,tt,et)||this.lettersChangedFlag)}}},TextAnimatorProperty.prototype.getValue=function(){this._elem.globalData.frameId!==this._frameId&&(this._frameId=this._elem.globalData.frameId,this.iterateDynamicProperties())},TextAnimatorProperty.prototype.mHelper=new Matrix,TextAnimatorProperty.prototype.defaultPropsArray=[],extendPrototype([DynamicPropertyContainer],TextAnimatorProperty),LetterProps.prototype.update=function(t,e,r,i,s,a){this._mdf.o=!1,this._mdf.sw=!1,this._mdf.sc=!1,this._mdf.fc=!1,this._mdf.m=!1;var n=this._mdf.p=!1;return this.o!==t&&(this.o=t,n=this._mdf.o=!0),this.sw!==e&&(this.sw=e,n=this._mdf.sw=!0),this.sc!==r&&(this.sc=r,n=this._mdf.sc=!0),this.fc!==i&&(this.fc=i,n=this._mdf.fc=!0),this.m!==s&&(this.m=s,n=this._mdf.m=!0),!a.length||this.p[0]===a[0]&&this.p[1]===a[1]&&this.p[4]===a[4]&&this.p[5]===a[5]&&this.p[12]===a[12]&&this.p[13]===a[13]||(this.p=a,n=this._mdf.p=!0),n},TextProperty.prototype.defaultBoxWidth=[0,0],TextProperty.prototype.copyData=function(t,e){for(var r in e)e.hasOwnProperty(r)&&(t[r]=e[r]);return t},TextProperty.prototype.setCurrentData=function(t){t.__complete||this.completeTextData(t),this.currentData=t,this.currentData.boxWidth=this.currentData.boxWidth||this.defaultBoxWidth,this._mdf=!0},TextProperty.prototype.searchProperty=function(){return this.searchKeyframes()},TextProperty.prototype.searchKeyframes=function(){return this.kf=1<this.data.d.k.length,this.kf&&this.addEffect(this.getKeyframeValue.bind(this)),this.kf},TextProperty.prototype.addEffect=function(t){this.effectsSequence.push(t),this.elem.addDynamicProperty(this)},TextProperty.prototype.getValue=function(t){if(this.elem.globalData.frameId!==this.frameId&&this.effectsSequence.length||t){this.currentData.t=this.data.d.k[this.keysIndex].s.t;var e=this.currentData,r=this.keysIndex;if(this.lock)this.setCurrentData(this.currentData);else{this.lock=!0,this._mdf=!1;var i,s=this.effectsSequence.length,a=t||this.data.d.k[this.keysIndex].s;for(i=0;i<s;i+=1)a=r!==this.keysIndex?this.effectsSequence[i](a,a.t):this.effectsSequence[i](this.currentData,a.t);e!==a&&this.setCurrentData(a),this.pv=this.v=this.currentData,this.lock=!1,this.frameId=this.elem.globalData.frameId}}},TextProperty.prototype.getKeyframeValue=function(){for(var t=this.data.d.k,e=this.elem.comp.renderedFrame,r=0,i=t.length;r<=i-1&&(t[r].s,!(r===i-1||t[r+1].t>e));)r+=1;return this.keysIndex!==r&&(this.keysIndex=r),this.data.d.k[this.keysIndex].s},TextProperty.prototype.buildFinalText=function(t){for(var e=FontManager.getCombinedCharacterCodes(),r=[],i=0,s=t.length;i<s;)-1!==e.indexOf(t.charCodeAt(i))?r[r.length-1]+=t.charAt(i):r.push(t.charAt(i)),i+=1;return r},TextProperty.prototype.completeTextData=function(t){t.__complete=!0;var e,r,i,s,a,n,o,h=this.elem.globalData.fontManager,p=this.data,l=[],m=0,f=p.m.g,c=0,d=0,u=0,y=[],g=0,v=0,P=h.getFontByName(t.f),b=0,x=P.fStyle?P.fStyle.split(" "):[],_="normal",S="normal";for(r=x.length,e=0;e<r;e+=1)switch(x[e].toLowerCase()){case"italic":S="italic";break;case"bold":_="700";break;case"black":_="900";break;case"medium":_="500";break;case"regular":case"normal":_="400";break;case"light":case"thin":_="200"}t.fWeight=P.fWeight||_,t.fStyle=S,r=t.t.length,t.finalSize=t.s,t.finalText=this.buildFinalText(t.t),t.finalLineHeight=t.lh;var T,A=t.tr/1e3*t.finalSize;if(t.sz)for(var C,E,k=!0,D=t.sz[0],I=t.sz[1];k;){g=C=0,r=(E=this.buildFinalText(t.t)).length,A=t.tr/1e3*t.finalSize;var M=-1;for(e=0;e<r;e+=1)T=E[e].charCodeAt(0),i=!1," "===E[e]?M=e:13!==T&&3!==T||(i=!(g=0),C+=t.finalLineHeight||1.2*t.finalSize),D<g+(b=h.chars?(o=h.getCharData(E[e],P.fStyle,P.fFamily),i?0:o.w*t.finalSize/100):h.measureText(E[e],t.f,t.finalSize))&&" "!==E[e]?(-1===M?r+=1:e=M,C+=t.finalLineHeight||1.2*t.finalSize,E.splice(e,M===e?1:0,"\r"),M=-1,g=0):(g+=b,g+=A);C+=P.ascent*t.finalSize/100,this.canResize&&t.finalSize>this.minimumFontSize&&I<C?(t.finalSize-=1,t.finalLineHeight=t.finalSize*t.lh/t.s):(t.finalText=E,r=t.finalText.length,k=!1)}g=-A;var w,F=b=0;for(e=0;e<r;e+=1)if(i=!1,T=(w=t.finalText[e]).charCodeAt(0)," "===w?s="\xa0":13===T||3===T?(F=0,y.push(g),v=v<g?g:v,g=-2*A,i=!(s=""),u+=1):s=t.finalText[e],b=h.chars?(o=h.getCharData(w,P.fStyle,h.getFontByName(t.f).fFamily),i?0:o.w*t.finalSize/100):h.measureText(s,t.f,t.finalSize)," "===w?F+=b+A:(g+=b+A+F,F=0),l.push({l:b,an:b,add:c,n:i,anIndexes:[],val:s,line:u,animatorJustifyOffset:0}),2==f){if(c+=b,""===s||"\xa0"===s||e===r-1){for(""!==s&&"\xa0"!==s||(c-=b);d<=e;)l[d].an=c,l[d].ind=m,l[d].extra=b,d+=1;m+=1,c=0}}else if(3==f){if(c+=b,""===s||e===r-1){for(""===s&&(c-=b);d<=e;)l[d].an=c,l[d].ind=m,l[d].extra=b,d+=1;c=0,m+=1}}else l[m].ind=m,l[m].extra=0,m+=1;if(t.l=l,v=v<g?g:v,y.push(g),t.sz)t.boxWidth=t.sz[0],t.justifyOffset=0;else switch(t.boxWidth=v,t.j){case 1:t.justifyOffset=-t.boxWidth;break;case 2:t.justifyOffset=-t.boxWidth/2;break;default:t.justifyOffset=0}t.lineWidths=y;var V,R,L=p.a;n=L.length;var z,O,B=[];for(a=0;a<n;a+=1){for((V=L[a]).a.sc&&(t.strokeColorAnim=!0),V.a.sw&&(t.strokeWidthAnim=!0),(V.a.fc||V.a.fh||V.a.fs||V.a.fb)&&(t.fillColorAnim=!0),O=0,z=V.s.b,e=0;e<r;e+=1)(R=l[e]).anIndexes[a]=O,(1==z&&""!==R.val||2==z&&""!==R.val&&"\xa0"!==R.val||3==z&&(R.n||"\xa0"==R.val||e==r-1)||4==z&&(R.n||e==r-1))&&(1===V.s.rn&&B.push(O),O+=1);p.a[a].s.totalChars=O;var N,G=-1;if(1===V.s.rn)for(e=0;e<r;e+=1)G!=(R=l[e]).anIndexes[a]&&(G=R.anIndexes[a],N=B.splice(Math.floor(Math.random()*B.length),1)[0]),R.anIndexes[a]=N}t.yOffset=t.finalLineHeight||1.2*t.finalSize,t.ls=t.ls||0,t.ascent=P.ascent*t.finalSize/100},TextProperty.prototype.updateDocumentData=function(t,e){e=void 0===e?this.keysIndex:e;var r=this.copyData({},this.data.d.k[e].s);r=this.copyData(r,t),this.data.d.k[e].s=r,this.recalculate(e),this.elem.addDynamicProperty(this)},TextProperty.prototype.recalculate=function(t){var e=this.data.d.k[t].s;e.__complete=!1,this.keysIndex=0,this._isFirstFrame=!0,this.getValue(e)},TextProperty.prototype.canResizeFont=function(t){this.canResize=t,this.recalculate(this.keysIndex),this.elem.addDynamicProperty(this)},TextProperty.prototype.setMinimumFontSize=function(t){this.minimumFontSize=Math.floor(t)||1,this.recalculate(this.keysIndex),this.elem.addDynamicProperty(this)};var TextSelectorProp=(cz=Math.max,dz=Math.min,ez=Math.floor,fz.prototype={getMult:function(t){this._currentTextLength!==this.elem.textProperty.currentData.l.length&&this.getValue();var e=BezierFactory.getBezierEasing(this.ne.v/100,0,1-this.xe.v/100,1).get,r=0,i=this.finalS,s=this.finalE,a=this.data.sh;if(2==a)r=e(r=s===i?s<=t?1:0:cz(0,dz(.5/(s-i)+(t-i)/(s-i),1)));else if(3==a)r=e(r=s===i?s<=t?0:1:1-cz(0,dz(.5/(s-i)+(t-i)/(s-i),1)));else if(4==a)s===i?r=0:(r=cz(0,dz(.5/(s-i)+(t-i)/(s-i),1)))<.5?r*=2:r=1-2*(r-.5),r=e(r);else if(5==a){if(s===i)r=0;else{var n=s-i,o=-n/2+(t=dz(cz(0,t+.5-i),s-i)),h=n/2;r=Math.sqrt(1-o*o/(h*h))}r=e(r)}else r=6==a?e(r=s===i?0:(t=dz(cz(0,t+.5-i),s-i),(1+Math.cos(Math.PI+2*Math.PI*t/(s-i)))/2)):(t>=ez(i)&&(r=t-i<0?1-(i-t):cz(0,dz(s-t,1))),e(r));return r*this.a.v},getValue:function(t){this.iterateDynamicProperties(),this._mdf=t||this._mdf,this._currentTextLength=this.elem.textProperty.currentData.l.length||0,t&&2===this.data.r&&(this.e.v=this._currentTextLength);var e=2===this.data.r?1:100/this.data.totalChars,r=this.o.v/e,i=this.s.v/e+r,s=this.e.v/e+r;if(s<i){var a=i;i=s,s=a}this.finalS=i,this.finalE=s}},extendPrototype([DynamicPropertyContainer],fz),{getTextSelectorProp:function(t,e,r){return new fz(t,e,r)}}),cz,dz,ez;function fz(t,e){this._currentTextLength=-1,this.k=!1,this.data=e,this.elem=t,this.comp=t.comp,this.finalS=0,this.finalE=0,this.initDynamicPropertyContainer(t),this.s=PropertyFactory.getProp(t,e.s||{k:0},0,0,this),this.e="e"in e?PropertyFactory.getProp(t,e.e,0,0,this):{v:100},this.o=PropertyFactory.getProp(t,e.o||{k:0},0,0,this),this.xe=PropertyFactory.getProp(t,e.xe||{k:0},0,0,this),this.ne=PropertyFactory.getProp(t,e.ne||{k:0},0,0,this),this.a=PropertyFactory.getProp(t,e.a,0,.01,this),this.dynamicProperties.length||this.getValue()}var pool_factory=function(t,e,r,i){var s=0,a=t,n=createSizedArray(a);function o(){return s?n[s-=1]:e()}return{newElement:o,release:function(t){s===a&&(n=pooling.double(n),a*=2),r&&r(t),n[s]=t,s+=1}}},pooling={double:function(t){return t.concat(createSizedArray(t.length))}},point_pool=pool_factory(8,function(){return createTypedArray("float32",2)}),shape_pool=(Vz=pool_factory(4,function(){return new ShapePath},function(t){var e,r=t._length;for(e=0;e<r;e+=1)point_pool.release(t.v[e]),point_pool.release(t.i[e]),point_pool.release(t.o[e]),t.v[e]=null,t.i[e]=null,t.o[e]=null;t._length=0,t.c=!1}),Vz.clone=function(t){var e,r=Vz.newElement(),i=void 0===t._length?t.v.length:t._length;for(r.setLength(i),r.c=t.c,e=0;e<i;e+=1)r.setTripleAt(t.v[e][0],t.v[e][1],t.o[e][0],t.o[e][1],t.i[e][0],t.i[e][1],e);return r},Vz),Vz,shapeCollection_pool=(cA={newShapeCollection:function(){var t;t=dA?fA[dA-=1]:new ShapeCollection;return t},release:function(t){var e,r=t._length;for(e=0;e<r;e+=1)shape_pool.release(t.shapes[e]);t._length=0,dA===eA&&(fA=pooling.double(fA),eA*=2);fA[dA]=t,dA+=1}},dA=0,eA=4,fA=createSizedArray(eA),cA),cA,dA,eA,fA,segments_length_pool=pool_factory(8,function(){return{lengths:[],totalLength:0}},function(t){var e,r=t.lengths.length;for(e=0;e<r;e+=1)bezier_length_pool.release(t.lengths[e]);t.lengths.length=0}),bezier_length_pool=pool_factory(8,function(){return{addedLength:0,percents:createTypedArray("float32",defaultCurveSegments),lengths:createTypedArray("float32",defaultCurveSegments)}});function BaseRenderer(){}function SVGRenderer(t,e){this.animationItem=t,this.layers=null,this.renderedFrame=-1,this.svgElement=createNS("svg");var r="";if(e&&e.title){var i=createNS("title"),s=createElementID();i.setAttribute("id",s),i.textContent=e.title,this.svgElement.appendChild(i),r+=s}if(e&&e.description){var a=createNS("desc"),n=createElementID();a.setAttribute("id",n),a.textContent=e.description,this.svgElement.appendChild(a),r+=" "+n}r&&this.svgElement.setAttribute("aria-labelledby",r);var o=createNS("defs");this.svgElement.appendChild(o);var h=createNS("g");this.svgElement.appendChild(h),this.layerElement=h,this.renderConfig={preserveAspectRatio:e&&e.preserveAspectRatio||"xMidYMid meet",imagePreserveAspectRatio:e&&e.imagePreserveAspectRatio||"xMidYMid slice",progressiveLoad:e&&e.progressiveLoad||!1,hideOnTransparent:!e||!1!==e.hideOnTransparent,viewBoxOnly:e&&e.viewBoxOnly||!1,viewBoxSize:e&&e.viewBoxSize||!1,className:e&&e.className||""},this.globalData={_mdf:!1,frameNum:-1,defs:o,renderConfig:this.renderConfig},this.elements=[],this.pendingElements=[],this.destroyed=!1,this.rendererType="svg"}function CanvasRenderer(t,e){this.animationItem=t,this.renderConfig={clearCanvas:!e||void 0===e.clearCanvas||e.clearCanvas,context:e&&e.context||null,progressiveLoad:e&&e.progressiveLoad||!1,preserveAspectRatio:e&&e.preserveAspectRatio||"xMidYMid meet",imagePreserveAspectRatio:e&&e.imagePreserveAspectRatio||"xMidYMid slice",className:e&&e.className||""},this.renderConfig.dpr=e&&e.dpr||1,this.animationItem.wrapper&&(this.renderConfig.dpr=e&&e.dpr||window.devicePixelRatio||1),this.renderedFrame=-1,this.globalData={frameNum:-1,_mdf:!1,renderConfig:this.renderConfig,currentGlobalAlpha:-1},this.contextData=new CVContextData,this.elements=[],this.pendingElements=[],this.transformMat=new Matrix,this.completeLayers=!1,this.rendererType="canvas"}function MaskElement(t,e,r){this.data=t,this.element=e,this.globalData=r,this.storedData=[],this.masksProperties=this.data.masksProperties||[],this.maskElement=null;var i,s=this.globalData.defs,a=this.masksProperties?this.masksProperties.length:0;this.viewData=createSizedArray(a),this.solidPath="";var n,o,h,p,l,m,f,c=this.masksProperties,d=0,u=[],y=createElementID(),g="clipPath",v="clip-path";for(i=0;i<a;i++)if(("a"!==c[i].mode&&"n"!==c[i].mode||c[i].inv||100!==c[i].o.k)&&(v=g="mask"),"s"!=c[i].mode&&"i"!=c[i].mode||0!==d?p=null:((p=createNS("rect")).setAttribute("fill","#ffffff"),p.setAttribute("width",this.element.comp.data.w||0),p.setAttribute("height",this.element.comp.data.h||0),u.push(p)),n=createNS("path"),"n"!=c[i].mode){var P;if(d+=1,n.setAttribute("fill","s"===c[i].mode?"#000000":"#ffffff"),n.setAttribute("clip-rule","nonzero"),0!==c[i].x.k?(v=g="mask",f=PropertyFactory.getProp(this.element,c[i].x,0,null,this.element),P=createElementID(),(l=createNS("filter")).setAttribute("id",P),(m=createNS("feMorphology")).setAttribute("operator","erode"),m.setAttribute("in","SourceGraphic"),m.setAttribute("radius","0"),l.appendChild(m),s.appendChild(l),n.setAttribute("stroke","s"===c[i].mode?"#000000":"#ffffff")):f=m=null,this.storedData[i]={elem:n,x:f,expan:m,lastPath:"",lastOperator:"",filterId:P,lastRadius:0},"i"==c[i].mode){h=u.length;var b=createNS("g");for(o=0;o<h;o+=1)b.appendChild(u[o]);var x=createNS("mask");x.setAttribute("mask-type","alpha"),x.setAttribute("id",y+"_"+d),x.appendChild(n),s.appendChild(x),b.setAttribute("mask","url("+locationHref+"#"+y+"_"+d+")"),u.length=0,u.push(b)}else u.push(n);c[i].inv&&!this.solidPath&&(this.solidPath=this.createLayerSolidPath()),this.viewData[i]={elem:n,lastPath:"",op:PropertyFactory.getProp(this.element,c[i].o,0,.01,this.element),prop:ShapePropertyFactory.getShapeProp(this.element,c[i],3),invRect:p},this.viewData[i].prop.k||this.drawPath(c[i],this.viewData[i].prop.v,this.viewData[i])}else this.viewData[i]={op:PropertyFactory.getProp(this.element,c[i].o,0,.01,this.element),prop:ShapePropertyFactory.getShapeProp(this.element,c[i],3),elem:n,lastPath:""},s.appendChild(n);for(this.maskElement=createNS(g),a=u.length,i=0;i<a;i+=1)this.maskElement.appendChild(u[i]);0<d&&(this.maskElement.setAttribute("id",y),this.element.maskedElement.setAttribute(v,"url("+locationHref+"#"+y+")"),s.appendChild(this.maskElement)),this.viewData.length&&this.element.addRenderableComponent(this)}function HierarchyElement(){}function FrameElement(){}function TransformElement(){}function RenderableElement(){}function RenderableDOMElement(){}function ProcessedElement(t,e){this.elem=t,this.pos=e}function SVGShapeData(t,e,r){this.caches=[],this.styles=[],this.transformers=t,this.lStr="",this.sh=r,this.lvl=e,this._isAnimated=!!r.k;for(var i=0,s=t.length;i<s;){if(t[i].mProps.dynamicProperties.length){this._isAnimated=!0;break}i+=1}}function ShapeGroupData(){this.it=[],this.prevViewData=[],this.gr=createNS("g")}function ShapeTransformManager(){this.sequences={},this.sequenceList=[],this.transform_key_count=0}function CVShapeData(t,e,r,i){this.styledShapes=[],this.tr=[0,0,0,0,0,0];var s=4;"rc"==e.ty?s=5:"el"==e.ty?s=6:"sr"==e.ty&&(s=7),this.sh=ShapePropertyFactory.getShapeProp(t,e,s,t);var a,n,o=r.length;for(a=0;a<o;a+=1)r[a].closed||(n={transforms:i.addTransformSequence(r[a].transforms),trNodes:[]},this.styledShapes.push(n),r[a].elements.push(n))}function BaseElement(){}function NullElement(t,e,r){this.initFrame(),this.initBaseData(t,e,r),this.initFrame(),this.initTransform(t,e,r),this.initHierarchy()}function SVGBaseElement(){}function IShapeElement(){}function ITextElement(){}function ICompElement(){}function IImageElement(t,e,r){this.assetData=e.getAssetData(t.refId),this.initElement(t,e,r),this.sourceRect={top:0,left:0,width:this.assetData.w,height:this.assetData.h}}function ISolidElement(t,e,r){this.initElement(t,e,r)}function SVGShapeElement(t,e,r){this.shapes=[],this.shapesData=t.shapes,this.stylesList=[],this.shapeModifiers=[],this.itemsData=[],this.processedElements=[],this.animatedContents=[],this.initElement(t,e,r),this.prevViewData=[]}function CVContextData(){this.saved=[],this.cArrPos=0,this.cTr=new Matrix,this.cO=1;var t;for(this.savedOp=createTypedArray("float32",15),t=0;t<15;t+=1)this.saved[t]=createTypedArray("float32",16);this._length=15}function CVBaseElement(){}function CVCompElement(t,e,r){this.completeLayers=!1,this.layers=t.layers,this.pendingElements=[],this.elements=createSizedArray(this.layers.length),this.initElement(t,e,r),this.tm=t.tm?PropertyFactory.getProp(this,t.tm,0,e.frameRate,this):{_placeholder:!0}}function CVMaskElement(t,e){this.data=t,this.element=e,this.masksProperties=this.data.masksProperties||[],this.viewData=createSizedArray(this.masksProperties.length);var r,i=this.masksProperties.length,s=!1;for(r=0;r<i;r++)"n"!==this.masksProperties[r].mode&&(s=!0),this.viewData[r]=ShapePropertyFactory.getShapeProp(this.element,this.masksProperties[r],3);(this.hasMasks=s)&&this.element.addRenderableComponent(this)}function CVShapeElement(t,e,r){this.shapes=[],this.shapesData=t.shapes,this.stylesList=[],this.itemsData=[],this.prevViewData=[],this.shapeModifiers=[],this.processedElements=[],this.transformsManager=new ShapeTransformManager,this.initElement(t,e,r)}function CVSolidElement(t,e,r){this.initElement(t,e,r)}function CVEffects(){}BaseRenderer.prototype.checkLayers=function(t){var e,r,i=this.layers.length;for(this.completeLayers=!0,e=i-1;0<=e;e--)this.elements[e]||(r=this.layers[e]).ip-r.st<=t-this.layers[e].st&&r.op-r.st>t-this.layers[e].st&&this.buildItem(e),this.completeLayers=!!this.elements[e]&&this.completeLayers;this.checkPendingElements()},BaseRenderer.prototype.createItem=function(t){switch(t.ty){case 2:return this.createImage(t);case 0:return this.createComp(t);case 1:return this.createSolid(t);case 3:return this.createNull(t);case 4:return this.createShape(t);case 5:return this.createText(t);case 13:return this.createCamera(t)}return this.createNull(t)},BaseRenderer.prototype.createCamera=function(){throw new Error("You're using a 3d camera. Try the html renderer.")},BaseRenderer.prototype.buildAllItems=function(){var t,e=this.layers.length;for(t=0;t<e;t+=1)this.buildItem(t);this.checkPendingElements()},BaseRenderer.prototype.includeLayers=function(t){this.completeLayers=!1;var e,r,i=t.length,s=this.layers.length;for(e=0;e<i;e+=1)for(r=0;r<s;){if(this.layers[r].id==t[e].id){this.layers[r]=t[e];break}r+=1}},BaseRenderer.prototype.setProjectInterface=function(t){this.globalData.projectInterface=t},BaseRenderer.prototype.initItems=function(){this.globalData.progressiveLoad||this.buildAllItems()},BaseRenderer.prototype.buildElementParenting=function(t,e,r){for(var i=this.elements,s=this.layers,a=0,n=s.length;a<n;)s[a].ind==e&&(i[a]&&!0!==i[a]?(r.push(i[a]),i[a].setAsParent(),void 0!==s[a].parent?this.buildElementParenting(t,s[a].parent,r):t.setHierarchy(r)):(this.buildItem(a),this.addPendingElement(t))),a+=1},BaseRenderer.prototype.addPendingElement=function(t){this.pendingElements.push(t)},BaseRenderer.prototype.searchExtraCompositions=function(t){var e,r=t.length;for(e=0;e<r;e+=1)if(t[e].xt){var i=this.createComp(t[e]);i.initExpressions(),this.globalData.projectInterface.registerComposition(i)}},BaseRenderer.prototype.setupGlobalData=function(t,e){this.globalData.fontManager=new FontManager,this.globalData.fontManager.addChars(t.chars),this.globalData.fontManager.addFonts(t.fonts,e),this.globalData.getAssetData=this.animationItem.getAssetData.bind(this.animationItem),this.globalData.getAssetsPath=this.animationItem.getAssetsPath.bind(this.animationItem),this.globalData.imageLoader=this.animationItem.imagePreloader,this.globalData.frameId=0,this.globalData.frameRate=t.fr,this.globalData.nm=t.nm,this.globalData.compSize={w:t.w,h:t.h}},extendPrototype([BaseRenderer],SVGRenderer),SVGRenderer.prototype.createNull=function(t){return new NullElement(t,this.globalData,this)},SVGRenderer.prototype.createShape=function(t){return new SVGShapeElement(t,this.globalData,this)},SVGRenderer.prototype.createText=function(t){return new SVGTextElement(t,this.globalData,this)},SVGRenderer.prototype.createImage=function(t){return new IImageElement(t,this.globalData,this)},SVGRenderer.prototype.createComp=function(t){return new SVGCompElement(t,this.globalData,this)},SVGRenderer.prototype.createSolid=function(t){return new ISolidElement(t,this.globalData,this)},SVGRenderer.prototype.configAnimation=function(t){this.svgElement.setAttribute("xmlns","http://www.w3.org/2000/svg"),this.renderConfig.viewBoxSize?this.svgElement.setAttribute("viewBox",this.renderConfig.viewBoxSize):this.svgElement.setAttribute("viewBox","0 0 "+t.w+" "+t.h),this.renderConfig.viewBoxOnly||(this.svgElement.setAttribute("width",t.w),this.svgElement.setAttribute("height",t.h),this.svgElement.style.width="100%",this.svgElement.style.height="100%",this.svgElement.style.transform="translate3d(0,0,0)"),this.renderConfig.className&&this.svgElement.setAttribute("class",this.renderConfig.className),this.svgElement.setAttribute("preserveAspectRatio",this.renderConfig.preserveAspectRatio),this.animationItem.wrapper.appendChild(this.svgElement);var e=this.globalData.defs;this.setupGlobalData(t,e),this.globalData.progressiveLoad=this.renderConfig.progressiveLoad,this.data=t;var r=createNS("clipPath"),i=createNS("rect");i.setAttribute("width",t.w),i.setAttribute("height",t.h),i.setAttribute("x",0),i.setAttribute("y",0);var s=createElementID();r.setAttribute("id",s),r.appendChild(i),this.layerElement.setAttribute("clip-path","url("+locationHref+"#"+s+")"),e.appendChild(r),this.layers=t.layers,this.elements=createSizedArray(t.layers.length)},SVGRenderer.prototype.destroy=function(){this.animationItem.wrapper.innerHTML="",this.layerElement=null,this.globalData.defs=null;var t,e=this.layers?this.layers.length:0;for(t=0;t<e;t++)this.elements[t]&&this.elements[t].destroy();this.elements.length=0,this.destroyed=!0,this.animationItem=null},SVGRenderer.prototype.updateContainerSize=function(){},SVGRenderer.prototype.buildItem=function(t){var e=this.elements;if(!e[t]&&99!=this.layers[t].ty){e[t]=!0;var r=this.createItem(this.layers[t]);e[t]=r,expressionsPlugin&&(0===this.layers[t].ty&&this.globalData.projectInterface.registerComposition(r),r.initExpressions()),this.appendElementInPos(r,t),this.layers[t].tt&&(this.elements[t-1]&&!0!==this.elements[t-1]?r.setMatte(e[t-1].layerId):(this.buildItem(t-1),this.addPendingElement(r)))}},SVGRenderer.prototype.checkPendingElements=function(){for(;this.pendingElements.length;){var t=this.pendingElements.pop();if(t.checkParenting(),t.data.tt)for(var e=0,r=this.elements.length;e<r;){if(this.elements[e]===t){t.setMatte(this.elements[e-1].layerId);break}e+=1}}},SVGRenderer.prototype.renderFrame=function(t){if(this.renderedFrame!==t&&!this.destroyed){null===t?t=this.renderedFrame:this.renderedFrame=t,this.globalData.frameNum=t,this.globalData.frameId+=1,this.globalData.projectInterface.currentFrame=t,this.globalData._mdf=!1;var e,r=this.layers.length;for(this.completeLayers||this.checkLayers(t),e=r-1;0<=e;e--)(this.completeLayers||this.elements[e])&&this.elements[e].prepareFrame(t-this.layers[e].st);if(this.globalData._mdf)for(e=0;e<r;e+=1)(this.completeLayers||this.elements[e])&&this.elements[e].renderFrame()}},SVGRenderer.prototype.appendElementInPos=function(t,e){var r=t.getBaseElement();if(r){for(var i,s=0;s<e;)this.elements[s]&&!0!==this.elements[s]&&this.elements[s].getBaseElement()&&(i=this.elements[s].getBaseElement()),s+=1;i?this.layerElement.insertBefore(r,i):this.layerElement.appendChild(r)}},SVGRenderer.prototype.hide=function(){this.layerElement.style.display="none"},SVGRenderer.prototype.show=function(){this.layerElement.style.display="block"},extendPrototype([BaseRenderer],CanvasRenderer),CanvasRenderer.prototype.createShape=function(t){return new CVShapeElement(t,this.globalData,this)},CanvasRenderer.prototype.createText=function(t){return new CVTextElement(t,this.globalData,this)},CanvasRenderer.prototype.createImage=function(t){return new CVImageElement(t,this.globalData,this)},CanvasRenderer.prototype.createComp=function(t){return new CVCompElement(t,this.globalData,this)},CanvasRenderer.prototype.createSolid=function(t){return new CVSolidElement(t,this.globalData,this)},CanvasRenderer.prototype.createNull=SVGRenderer.prototype.createNull,CanvasRenderer.prototype.ctxTransform=function(t){if(1!==t[0]||0!==t[1]||0!==t[4]||1!==t[5]||0!==t[12]||0!==t[13])if(this.renderConfig.clearCanvas){this.transformMat.cloneFromProps(t);var e=this.contextData.cTr.props;this.transformMat.transform(e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8],e[9],e[10],e[11],e[12],e[13],e[14],e[15]),this.contextData.cTr.cloneFromProps(this.transformMat.props);var r=this.contextData.cTr.props;this.canvasContext.setTransform(r[0],r[1],r[4],r[5],r[12],r[13])}else this.canvasContext.transform(t[0],t[1],t[4],t[5],t[12],t[13])},CanvasRenderer.prototype.ctxOpacity=function(t){if(!this.renderConfig.clearCanvas)return this.canvasContext.globalAlpha*=t<0?0:t,void(this.globalData.currentGlobalAlpha=this.contextData.cO);this.contextData.cO*=t<0?0:t,this.globalData.currentGlobalAlpha!==this.contextData.cO&&(this.canvasContext.globalAlpha=this.contextData.cO,this.globalData.currentGlobalAlpha=this.contextData.cO)},CanvasRenderer.prototype.reset=function(){this.renderConfig.clearCanvas?this.contextData.reset():this.canvasContext.restore()},CanvasRenderer.prototype.save=function(t){if(this.renderConfig.clearCanvas){t&&this.canvasContext.save();var e=this.contextData.cTr.props;this.contextData._length<=this.contextData.cArrPos&&this.contextData.duplicate();var r,i=this.contextData.saved[this.contextData.cArrPos];for(r=0;r<16;r+=1)i[r]=e[r];this.contextData.savedOp[this.contextData.cArrPos]=this.contextData.cO,this.contextData.cArrPos+=1}else this.canvasContext.save()},CanvasRenderer.prototype.restore=function(t){if(this.renderConfig.clearCanvas){t&&(this.canvasContext.restore(),this.globalData.blendMode="source-over"),this.contextData.cArrPos-=1;var e,r=this.contextData.saved[this.contextData.cArrPos],i=this.contextData.cTr.props;for(e=0;e<16;e+=1)i[e]=r[e];this.canvasContext.setTransform(r[0],r[1],r[4],r[5],r[12],r[13]),r=this.contextData.savedOp[this.contextData.cArrPos],this.contextData.cO=r,this.globalData.currentGlobalAlpha!==r&&(this.canvasContext.globalAlpha=r,this.globalData.currentGlobalAlpha=r)}else this.canvasContext.restore()},CanvasRenderer.prototype.configAnimation=function(t){this.animationItem.wrapper?(this.animationItem.container=createTag("canvas"),this.animationItem.container.style.width="100%",this.animationItem.container.style.height="100%",this.animationItem.container.style.transformOrigin=this.animationItem.container.style.mozTransformOrigin=this.animationItem.container.style.webkitTransformOrigin=this.animationItem.container.style["-webkit-transform"]="0px 0px 0px",this.animationItem.wrapper.appendChild(this.animationItem.container),this.canvasContext=this.animationItem.container.getContext("2d"),this.renderConfig.className&&this.animationItem.container.setAttribute("class",this.renderConfig.className)):this.canvasContext=this.renderConfig.context,this.data=t,this.layers=t.layers,this.transformCanvas={w:t.w,h:t.h,sx:0,sy:0,tx:0,ty:0},this.setupGlobalData(t,document.body),this.globalData.canvasContext=this.canvasContext,(this.globalData.renderer=this).globalData.isDashed=!1,this.globalData.progressiveLoad=this.renderConfig.progressiveLoad,this.globalData.transformCanvas=this.transformCanvas,this.elements=createSizedArray(t.layers.length),this.updateContainerSize()},CanvasRenderer.prototype.updateContainerSize=function(){var t,e,r,i;if(this.reset(),this.animationItem.wrapper&&this.animationItem.container?(t=this.animationItem.wrapper.offsetWidth,e=this.animationItem.wrapper.offsetHeight,this.animationItem.container.setAttribute("width",t*this.renderConfig.dpr),this.animationItem.container.setAttribute("height",e*this.renderConfig.dpr)):(t=this.canvasContext.canvas.width*this.renderConfig.dpr,e=this.canvasContext.canvas.height*this.renderConfig.dpr),-1!==this.renderConfig.preserveAspectRatio.indexOf("meet")||-1!==this.renderConfig.preserveAspectRatio.indexOf("slice")){var s=this.renderConfig.preserveAspectRatio.split(" "),a=s[1]||"meet",n=s[0]||"xMidYMid",o=n.substr(0,4),h=n.substr(4);(r=t/e)<(i=this.transformCanvas.w/this.transformCanvas.h)&&"meet"===a||i<r&&"slice"===a?(this.transformCanvas.sx=t/(this.transformCanvas.w/this.renderConfig.dpr),this.transformCanvas.sy=t/(this.transformCanvas.w/this.renderConfig.dpr)):(this.transformCanvas.sx=e/(this.transformCanvas.h/this.renderConfig.dpr),this.transformCanvas.sy=e/(this.transformCanvas.h/this.renderConfig.dpr)),this.transformCanvas.tx="xMid"===o&&(i<r&&"meet"===a||r<i&&"slice"===a)?(t-this.transformCanvas.w*(e/this.transformCanvas.h))/2*this.renderConfig.dpr:"xMax"===o&&(i<r&&"meet"===a||r<i&&"slice"===a)?(t-this.transformCanvas.w*(e/this.transformCanvas.h))*this.renderConfig.dpr:0,this.transformCanvas.ty="YMid"===h&&(r<i&&"meet"===a||i<r&&"slice"===a)?(e-this.transformCanvas.h*(t/this.transformCanvas.w))/2*this.renderConfig.dpr:"YMax"===h&&(r<i&&"meet"===a||i<r&&"slice"===a)?(e-this.transformCanvas.h*(t/this.transformCanvas.w))*this.renderConfig.dpr:0}else"none"==this.renderConfig.preserveAspectRatio?(this.transformCanvas.sx=t/(this.transformCanvas.w/this.renderConfig.dpr),this.transformCanvas.sy=e/(this.transformCanvas.h/this.renderConfig.dpr)):(this.transformCanvas.sx=this.renderConfig.dpr,this.transformCanvas.sy=this.renderConfig.dpr),this.transformCanvas.tx=0,this.transformCanvas.ty=0;this.transformCanvas.props=[this.transformCanvas.sx,0,0,0,0,this.transformCanvas.sy,0,0,0,0,1,0,this.transformCanvas.tx,this.transformCanvas.ty,0,1],this.ctxTransform(this.transformCanvas.props),this.canvasContext.beginPath(),this.canvasContext.rect(0,0,this.transformCanvas.w,this.transformCanvas.h),this.canvasContext.closePath(),this.canvasContext.clip(),this.renderFrame(this.renderedFrame,!0)},CanvasRenderer.prototype.destroy=function(){var t;for(this.renderConfig.clearCanvas&&(this.animationItem.wrapper.innerHTML=""),t=(this.layers?this.layers.length:0)-1;0<=t;t-=1)this.elements[t]&&this.elements[t].destroy();this.elements.length=0,this.globalData.canvasContext=null,this.animationItem.container=null,this.destroyed=!0},CanvasRenderer.prototype.renderFrame=function(t,e){if((this.renderedFrame!==t||!0!==this.renderConfig.clearCanvas||e)&&!this.destroyed&&-1!==t){this.renderedFrame=t,this.globalData.frameNum=t-this.animationItem._isFirstFrame,this.globalData.frameId+=1,this.globalData._mdf=!this.renderConfig.clearCanvas||e,this.globalData.projectInterface.currentFrame=t;var r,i=this.layers.length;for(this.completeLayers||this.checkLayers(t),r=0;r<i;r++)(this.completeLayers||this.elements[r])&&this.elements[r].prepareFrame(t-this.layers[r].st);if(this.globalData._mdf){for(!0===this.renderConfig.clearCanvas?this.canvasContext.clearRect(0,0,this.transformCanvas.w,this.transformCanvas.h):this.save(),r=i-1;0<=r;r-=1)(this.completeLayers||this.elements[r])&&this.elements[r].renderFrame();!0!==this.renderConfig.clearCanvas&&this.restore()}}},CanvasRenderer.prototype.buildItem=function(t){var e=this.elements;if(!e[t]&&99!=this.layers[t].ty){var r=this.createItem(this.layers[t],this,this.globalData);(e[t]=r).initExpressions()}},CanvasRenderer.prototype.checkPendingElements=function(){for(;this.pendingElements.length;){this.pendingElements.pop().checkParenting()}},CanvasRenderer.prototype.hide=function(){this.animationItem.container.style.display="none"},CanvasRenderer.prototype.show=function(){this.animationItem.container.style.display="block"},CanvasRenderer.prototype.configAnimation=function(t){this.animationItem.wrapper?(this.animationItem.container=createTag("canvas"),this.animationItem.container.style.width="100%",this.animationItem.container.style.height="100%",this.animationItem.container.style.transformOrigin=this.animationItem.container.style.mozTransformOrigin=this.animationItem.container.style.webkitTransformOrigin=this.animationItem.container.style["-webkit-transform"]="0px 0px 0px",this.animationItem.wrapper.appendChild(this.animationItem.container),this.canvasContext=this.animationItem.container.getContext("2d"),this.renderConfig.className&&this.animationItem.container.setAttribute("class",this.renderConfig.className)):this.canvasContext=this.renderConfig.context,this.data=t,this.layers=t.layers,this.transformCanvas={w:t.w,h:t.h,sx:0,sy:0,tx:0,ty:0},this.globalData.frameId=0,this.globalData.frameRate=t.fr,this.globalData.nm=t.nm,this.globalData.compSize={w:t.w,h:t.h},this.globalData.canvasContext=this.canvasContext,(this.globalData.renderer=this).globalData.isDashed=!1,this.globalData.progressiveLoad=this.renderConfig.progressiveLoad,this.globalData.transformCanvas=this.transformCanvas,this.elements=createSizedArray(t.layers.length),this.updateContainerSize()},MaskElement.prototype.getMaskProperty=function(t){return this.viewData[t].prop},MaskElement.prototype.renderFrame=function(t){var e,r=this.element.finalTransform.mat,i=this.masksProperties.length;for(e=0;e<i;e++)if((this.viewData[e].prop._mdf||t)&&this.drawPath(this.masksProperties[e],this.viewData[e].prop.v,this.viewData[e]),(this.viewData[e].op._mdf||t)&&this.viewData[e].elem.setAttribute("fill-opacity",this.viewData[e].op.v),"n"!==this.masksProperties[e].mode&&(this.viewData[e].invRect&&(this.element.finalTransform.mProp._mdf||t)&&(this.viewData[e].invRect.setAttribute("x",-r.props[12]),this.viewData[e].invRect.setAttribute("y",-r.props[13])),this.storedData[e].x&&(this.storedData[e].x._mdf||t))){var s=this.storedData[e].expan;this.storedData[e].x.v<0?("erode"!==this.storedData[e].lastOperator&&(this.storedData[e].lastOperator="erode",this.storedData[e].elem.setAttribute("filter","url("+locationHref+"#"+this.storedData[e].filterId+")")),s.setAttribute("radius",-this.storedData[e].x.v)):("dilate"!==this.storedData[e].lastOperator&&(this.storedData[e].lastOperator="dilate",this.storedData[e].elem.setAttribute("filter",null)),this.storedData[e].elem.setAttribute("stroke-width",2*this.storedData[e].x.v))}},MaskElement.prototype.getMaskelement=function(){return this.maskElement},MaskElement.prototype.createLayerSolidPath=function(){var t="M0,0 ";return t+=" h"+this.globalData.compSize.w,t+=" v"+this.globalData.compSize.h,t+=" h-"+this.globalData.compSize.w,t+=" v-"+this.globalData.compSize.h+" "},MaskElement.prototype.drawPath=function(t,e,r){var i,s,a=" M"+e.v[0][0]+","+e.v[0][1];for(s=e._length,i=1;i<s;i+=1)a+=" C"+e.o[i-1][0]+","+e.o[i-1][1]+" "+e.i[i][0]+","+e.i[i][1]+" "+e.v[i][0]+","+e.v[i][1];if(e.c&&1<s&&(a+=" C"+e.o[i-1][0]+","+e.o[i-1][1]+" "+e.i[0][0]+","+e.i[0][1]+" "+e.v[0][0]+","+e.v[0][1]),r.lastPath!==a){var n="";r.elem&&(e.c&&(n=t.inv?this.solidPath+a:a),r.elem.setAttribute("d",n)),r.lastPath=a}},MaskElement.prototype.destroy=function(){this.element=null,this.globalData=null,this.maskElement=null,this.data=null,this.masksProperties=null},HierarchyElement.prototype={initHierarchy:function(){this.hierarchy=[],this._isParent=!1,this.checkParenting()},setHierarchy:function(t){this.hierarchy=t},setAsParent:function(){this._isParent=!0},checkParenting:function(){void 0!==this.data.parent&&this.comp.buildElementParenting(this,this.data.parent,[])}},FrameElement.prototype={initFrame:function(){this._isFirstFrame=!1,this.dynamicProperties=[],this._mdf=!1},prepareProperties:function(t,e){var r,i=this.dynamicProperties.length;for(r=0;r<i;r+=1)(e||this._isParent&&"transform"===this.dynamicProperties[r].propType)&&(this.dynamicProperties[r].getValue(),this.dynamicProperties[r]._mdf&&(this.globalData._mdf=!0,this._mdf=!0))},addDynamicProperty:function(t){-1===this.dynamicProperties.indexOf(t)&&this.dynamicProperties.push(t)}},TransformElement.prototype={initTransform:function(){this.finalTransform={mProp:this.data.ks?TransformPropertyFactory.getTransformProperty(this,this.data.ks,this):{o:0},_matMdf:!1,_opMdf:!1,mat:new Matrix},this.data.ao&&(this.finalTransform.mProp.autoOriented=!0),this.data.ty},renderTransform:function(){if(this.finalTransform._opMdf=this.finalTransform.mProp.o._mdf||this._isFirstFrame,this.finalTransform._matMdf=this.finalTransform.mProp._mdf||this._isFirstFrame,this.hierarchy){var t,e=this.finalTransform.mat,r=0,i=this.hierarchy.length;if(!this.finalTransform._matMdf)for(;r<i;){if(this.hierarchy[r].finalTransform.mProp._mdf){this.finalTransform._matMdf=!0;break}r+=1}if(this.finalTransform._matMdf)for(t=this.finalTransform.mProp.v.props,e.cloneFromProps(t),r=0;r<i;r+=1)t=this.hierarchy[r].finalTransform.mProp.v.props,e.transform(t[0],t[1],t[2],t[3],t[4],t[5],t[6],t[7],t[8],t[9],t[10],t[11],t[12],t[13],t[14],t[15])}},globalToLocal:function(t){var e=[];e.push(this.finalTransform);for(var r=!0,i=this.comp;r;)i.finalTransform?(i.data.hasMask&&e.splice(0,0,i.finalTransform),i=i.comp):r=!1;var s,a,n=e.length;for(s=0;s<n;s+=1)a=e[s].mat.applyToPointArray(0,0,0),t=[t[0]-a[0],t[1]-a[1],0];return t},mHelper:new Matrix},RenderableElement.prototype={initRenderable:function(){this.isInRange=!1,this.hidden=!1,this.isTransparent=!1,this.renderableComponents=[]},addRenderableComponent:function(t){-1===this.renderableComponents.indexOf(t)&&this.renderableComponents.push(t)},removeRenderableComponent:function(t){-1!==this.renderableComponents.indexOf(t)&&this.renderableComponents.splice(this.renderableComponents.indexOf(t),1)},prepareRenderableFrame:function(t){this.checkLayerLimits(t)},checkTransparency:function(){this.finalTransform.mProp.o.v<=0?!this.isTransparent&&this.globalData.renderConfig.hideOnTransparent&&(this.isTransparent=!0,this.hide()):this.isTransparent&&(this.isTransparent=!1,this.show())},checkLayerLimits:function(t){this.data.ip-this.data.st<=t&&this.data.op-this.data.st>t?!0!==this.isInRange&&(this.globalData._mdf=!0,this._mdf=!0,this.isInRange=!0,this.show()):!1!==this.isInRange&&(this.globalData._mdf=!0,this.isInRange=!1,this.hide())},renderRenderable:function(){var t,e=this.renderableComponents.length;for(t=0;t<e;t+=1)this.renderableComponents[t].renderFrame(this._isFirstFrame)},sourceRectAtTime:function(){return{top:0,left:0,width:100,height:100}},getLayerSize:function(){return 5===this.data.ty?{w:this.data.textData.width,h:this.data.textData.height}:{w:this.data.width,h:this.data.height}}},extendPrototype([RenderableElement,createProxyFunction({initElement:function(t,e,r){this.initFrame(),this.initBaseData(t,e,r),this.initTransform(t,e,r),this.initHierarchy(),this.initRenderable(),this.initRendererElement(),this.createContainerElements(),this.createRenderableComponents(),this.createContent(),this.hide()},hide:function(){this.hidden||this.isInRange&&!this.isTransparent||((this.baseElement||this.layerElement).style.display="none",this.hidden=!0)},show:function(){this.isInRange&&!this.isTransparent&&(this.data.hd||((this.baseElement||this.layerElement).style.display="block"),this.hidden=!1,this._isFirstFrame=!0)},renderFrame:function(){this.data.hd||this.hidden||(this.renderTransform(),this.renderRenderable(),this.renderElement(),this.renderInnerContent(),this._isFirstFrame&&(this._isFirstFrame=!1))},renderInnerContent:function(){},prepareFrame:function(t){this._mdf=!1,this.prepareRenderableFrame(t),this.prepareProperties(t,this.isInRange),this.checkTransparency()},destroy:function(){this.innerElem=null,this.destroyBaseElement()}})],RenderableDOMElement),SVGShapeData.prototype.setAsAnimated=function(){this._isAnimated=!0},ShapeTransformManager.prototype={addTransformSequence:function(t){var e,r=t.length,i="_";for(e=0;e<r;e+=1)i+=t[e].transform.key+"_";var s=this.sequences[i];return s||(s={transforms:[].concat(t),finalTransform:new Matrix,_mdf:!1},this.sequences[i]=s,this.sequenceList.push(s)),s},processSequence:function(t,e){for(var r,i=0,s=t.transforms.length,a=e;i<s&&!e;){if(t.transforms[i].transform.mProps._mdf){a=!0;break}i+=1}if(a)for(t.finalTransform.reset(),i=s-1;0<=i;i-=1)r=t.transforms[i].transform.mProps.v.props,t.finalTransform.transform(r[0],r[1],r[2],r[3],r[4],r[5],r[6],r[7],r[8],r[9],r[10],r[11],r[12],r[13],r[14],r[15]);t._mdf=a},processSequences:function(t){var e,r=this.sequenceList.length;for(e=0;e<r;e+=1)this.processSequence(this.sequenceList[e],t)},getNewKey:function(){return"_"+this.transform_key_count++}},CVShapeData.prototype.setAsAnimated=SVGShapeData.prototype.setAsAnimated,BaseElement.prototype={checkMasks:function(){if(!this.data.hasMask)return!1;for(var t=0,e=this.data.masksProperties.length;t<e;){if("n"!==this.data.masksProperties[t].mode&&!1!==this.data.masksProperties[t].cl)return!0;t+=1}return!1},initExpressions:function(){this.layerInterface=LayerExpressionInterface(this),this.data.hasMask&&this.maskManager&&this.layerInterface.registerMaskInterface(this.maskManager);var t=EffectsExpressionInterface.createEffectsInterface(this,this.layerInterface);this.layerInterface.registerEffectsInterface(t),0===this.data.ty||this.data.xt?this.compInterface=CompExpressionInterface(this):4===this.data.ty?(this.layerInterface.shapeInterface=ShapeExpressionInterface(this.shapesData,this.itemsData,this.layerInterface),this.layerInterface.content=this.layerInterface.shapeInterface):5===this.data.ty&&(this.layerInterface.textInterface=TextExpressionInterface(this),this.layerInterface.text=this.layerInterface.textInterface)},setBlendMode:function(){var t=getBlendMode(this.data.bm);(this.baseElement||this.layerElement).style["mix-blend-mode"]=t},initBaseData:function(t,e,r){this.globalData=e,this.comp=r,this.data=t,this.layerId=createElementID(),this.data.sr||(this.data.sr=1),this.effectsManager=new EffectsManager(this.data,this,this.dynamicProperties)},getType:function(){return this.type},sourceRectAtTime:function(){}},NullElement.prototype.prepareFrame=function(t){this.prepareProperties(t,!0)},NullElement.prototype.renderFrame=function(){},NullElement.prototype.getBaseElement=function(){return null},NullElement.prototype.destroy=function(){},NullElement.prototype.sourceRectAtTime=function(){},NullElement.prototype.hide=function(){},extendPrototype([BaseElement,TransformElement,HierarchyElement,FrameElement],NullElement),SVGBaseElement.prototype={initRendererElement:function(){this.layerElement=createNS("g")},createContainerElements:function(){this.matteElement=createNS("g"),this.transformedElement=this.layerElement,this.maskedElement=this.layerElement,this._sizeChanged=!1;var t,e,r,i=null;if(this.data.td){if(3==this.data.td||1==this.data.td){var s=createNS("mask");s.setAttribute("id",this.layerId),s.setAttribute("mask-type",3==this.data.td?"luminance":"alpha"),s.appendChild(this.layerElement),i=s,this.globalData.defs.appendChild(s),featureSupport.maskType||1!=this.data.td||(s.setAttribute("mask-type","luminance"),t=createElementID(),e=filtersFactory.createFilter(t),this.globalData.defs.appendChild(e),e.appendChild(filtersFactory.createAlphaToLuminanceFilter()),(r=createNS("g")).appendChild(this.layerElement),i=r,s.appendChild(r),r.setAttribute("filter","url("+locationHref+"#"+t+")"))}else if(2==this.data.td){var a=createNS("mask");a.setAttribute("id",this.layerId),a.setAttribute("mask-type","alpha");var n=createNS("g");a.appendChild(n),t=createElementID(),e=filtersFactory.createFilter(t);var o=createNS("feComponentTransfer");o.setAttribute("in","SourceGraphic"),e.appendChild(o);var h=createNS("feFuncA");h.setAttribute("type","table"),h.setAttribute("tableValues","1.0 0.0"),o.appendChild(h),this.globalData.defs.appendChild(e);var p=createNS("rect");p.setAttribute("width",this.comp.data.w),p.setAttribute("height",this.comp.data.h),p.setAttribute("x","0"),p.setAttribute("y","0"),p.setAttribute("fill","#ffffff"),p.setAttribute("opacity","0"),n.setAttribute("filter","url("+locationHref+"#"+t+")"),n.appendChild(p),n.appendChild(this.layerElement),i=n,featureSupport.maskType||(a.setAttribute("mask-type","luminance"),e.appendChild(filtersFactory.createAlphaToLuminanceFilter()),r=createNS("g"),n.appendChild(p),r.appendChild(this.layerElement),i=r,n.appendChild(r)),this.globalData.defs.appendChild(a)}}else this.data.tt?(this.matteElement.appendChild(this.layerElement),i=this.matteElement,this.baseElement=this.matteElement):this.baseElement=this.layerElement;if(this.data.ln&&this.layerElement.setAttribute("id",this.data.ln),this.data.cl&&this.layerElement.setAttribute("class",this.data.cl),0===this.data.ty&&!this.data.hd){var l=createNS("clipPath"),m=createNS("path");m.setAttribute("d","M0,0 L"+this.data.w+",0 L"+this.data.w+","+this.data.h+" L0,"+this.data.h+"z");var f=createElementID();if(l.setAttribute("id",f),l.appendChild(m),this.globalData.defs.appendChild(l),this.checkMasks()){var c=createNS("g");c.setAttribute("clip-path","url("+locationHref+"#"+f+")"),c.appendChild(this.layerElement),this.transformedElement=c,i?i.appendChild(this.transformedElement):this.baseElement=this.transformedElement}else this.layerElement.setAttribute("clip-path","url("+locationHref+"#"+f+")")}0!==this.data.bm&&this.setBlendMode()},renderElement:function(){this.finalTransform._matMdf&&this.transformedElement.setAttribute("transform",this.finalTransform.mat.to2dCSS()),this.finalTransform._opMdf&&this.transformedElement.setAttribute("opacity",this.finalTransform.mProp.o.v)},destroyBaseElement:function(){this.layerElement=null,this.matteElement=null,this.maskManager.destroy()},getBaseElement:function(){return this.data.hd?null:this.baseElement},createRenderableComponents:function(){this.maskManager=new MaskElement(this.data,this,this.globalData),this.renderableEffectsManager=new SVGEffects(this)},setMatte:function(t){this.matteElement&&this.matteElement.setAttribute("mask","url("+locationHref+"#"+t+")")}},IShapeElement.prototype={addShapeToModifiers:function(t){var e,r=this.shapeModifiers.length;for(e=0;e<r;e+=1)this.shapeModifiers[e].addShape(t)},isShapeInAnimatedModifiers:function(t){for(var e=this.shapeModifiers.length;0<e;)if(this.shapeModifiers[0].isAnimatedWithShape(t))return!0;return!1},renderModifiers:function(){if(this.shapeModifiers.length){var t,e=this.shapes.length;for(t=0;t<e;t+=1)this.shapes[t].sh.reset();for(t=(e=this.shapeModifiers.length)-1;0<=t;t-=1)this.shapeModifiers[t].processShapes(this._isFirstFrame)}},lcEnum:{1:"butt",2:"round",3:"square"},ljEnum:{1:"miter",2:"round",3:"bevel"},searchProcessedElement:function(t){for(var e=this.processedElements,r=0,i=e.length;r<i;){if(e[r].elem===t)return e[r].pos;r+=1}return 0},addProcessedElement:function(t,e){for(var r=this.processedElements,i=r.length;i;)if(r[i-=1].elem===t)return void(r[i].pos=e);r.push(new ProcessedElement(t,e))},prepareFrame:function(t){this.prepareRenderableFrame(t),this.prepareProperties(t,this.isInRange)}},ITextElement.prototype.initElement=function(t,e,r){this.lettersChangedFlag=!0,this.initFrame(),this.initBaseData(t,e,r),this.textProperty=new TextProperty(this,t.t,this.dynamicProperties),this.textAnimator=new TextAnimatorProperty(t.t,this.renderType,this),this.initTransform(t,e,r),this.initHierarchy(),this.initRenderable(),this.initRendererElement(),this.createContainerElements(),this.createRenderableComponents(),this.createContent(),this.hide(),this.textAnimator.searchProperties(this.dynamicProperties)},ITextElement.prototype.prepareFrame=function(t){this._mdf=!1,this.prepareRenderableFrame(t),this.prepareProperties(t,this.isInRange),(this.textProperty._mdf||this.textProperty._isFirstFrame)&&(this.buildNewText(),this.textProperty._isFirstFrame=!1,this.textProperty._mdf=!1)},ITextElement.prototype.createPathShape=function(t,e){var r,i,s=e.length,a="";for(r=0;r<s;r+=1)i=e[r].ks.k,a+=buildShapeString(i,i.i.length,!0,t);return a},ITextElement.prototype.updateDocumentData=function(t,e){this.textProperty.updateDocumentData(t,e)},ITextElement.prototype.canResizeFont=function(t){this.textProperty.canResizeFont(t)},ITextElement.prototype.setMinimumFontSize=function(t){this.textProperty.setMinimumFontSize(t)},ITextElement.prototype.applyTextPropertiesToMatrix=function(t,e,r,i,s){switch(t.ps&&e.translate(t.ps[0],t.ps[1]+t.ascent,0),e.translate(0,-t.ls,0),t.j){case 1:e.translate(t.justifyOffset+(t.boxWidth-t.lineWidths[r]),0,0);break;case 2:e.translate(t.justifyOffset+(t.boxWidth-t.lineWidths[r])/2,0,0)}e.translate(i,s,0)},ITextElement.prototype.buildColor=function(t){return"rgb("+Math.round(255*t[0])+","+Math.round(255*t[1])+","+Math.round(255*t[2])+")"},ITextElement.prototype.emptyProp=new LetterProps,ITextElement.prototype.destroy=function(){},extendPrototype([BaseElement,TransformElement,HierarchyElement,FrameElement,RenderableDOMElement],ICompElement),ICompElement.prototype.initElement=function(t,e,r){this.initFrame(),this.initBaseData(t,e,r),this.initTransform(t,e,r),this.initRenderable(),this.initHierarchy(),this.initRendererElement(),this.createContainerElements(),this.createRenderableComponents(),!this.data.xt&&e.progressiveLoad||this.buildAllItems(),this.hide()},ICompElement.prototype.prepareFrame=function(t){if(this._mdf=!1,this.prepareRenderableFrame(t),this.prepareProperties(t,this.isInRange),this.isInRange||this.data.xt){if(this.tm._placeholder)this.renderedFrame=t/this.data.sr;else{var e=this.tm.v;e===this.data.op&&(e=this.data.op-1),this.renderedFrame=e}var r,i=this.elements.length;for(this.completeLayers||this.checkLayers(this.renderedFrame),r=i-1;0<=r;r-=1)(this.completeLayers||this.elements[r])&&(this.elements[r].prepareFrame(this.renderedFrame-this.layers[r].st),this.elements[r]._mdf&&(this._mdf=!0))}},ICompElement.prototype.renderInnerContent=function(){var t,e=this.layers.length;for(t=0;t<e;t+=1)(this.completeLayers||this.elements[t])&&this.elements[t].renderFrame()},ICompElement.prototype.setElements=function(t){this.elements=t},ICompElement.prototype.getElements=function(){return this.elements},ICompElement.prototype.destroyElements=function(){var t,e=this.layers.length;for(t=0;t<e;t+=1)this.elements[t]&&this.elements[t].destroy()},ICompElement.prototype.destroy=function(){this.destroyElements(),this.destroyBaseElement()},extendPrototype([BaseElement,TransformElement,SVGBaseElement,HierarchyElement,FrameElement,RenderableDOMElement],IImageElement),IImageElement.prototype.createContent=function(){var t=this.globalData.getAssetsPath(this.assetData);this.innerElem=createNS("image"),this.innerElem.setAttribute("width",this.assetData.w+"px"),this.innerElem.setAttribute("height",this.assetData.h+"px"),this.innerElem.setAttribute("preserveAspectRatio",this.assetData.pr||this.globalData.renderConfig.imagePreserveAspectRatio),this.innerElem.setAttributeNS("http://www.w3.org/1999/xlink","href",t),this.layerElement.appendChild(this.innerElem)},IImageElement.prototype.sourceRectAtTime=function(){return this.sourceRect},extendPrototype([IImageElement],ISolidElement),ISolidElement.prototype.createContent=function(){var t=createNS("rect");t.setAttribute("width",this.data.sw),t.setAttribute("height",this.data.sh),t.setAttribute("fill",this.data.sc),this.layerElement.appendChild(t)},extendPrototype([BaseElement,TransformElement,SVGBaseElement,IShapeElement,HierarchyElement,FrameElement,RenderableDOMElement],SVGShapeElement),SVGShapeElement.prototype.initSecondaryElement=function(){},SVGShapeElement.prototype.identityMatrix=new Matrix,SVGShapeElement.prototype.buildExpressionInterface=function(){},SVGShapeElement.prototype.createContent=function(){this.searchShapes(this.shapesData,this.itemsData,this.prevViewData,this.layerElement,0,[],!0),this.filterUniqueShapes()},SVGShapeElement.prototype.filterUniqueShapes=function(){var t,e,r,i,s=this.shapes.length,a=this.stylesList.length,n=[],o=!1;for(r=0;r<a;r+=1){for(i=this.stylesList[r],o=!1,t=n.length=0;t<s;t+=1)-1!==(e=this.shapes[t]).styles.indexOf(i)&&(n.push(e),o=e._isAnimated||o);1<n.length&&o&&this.setShapesAsAnimated(n)}},SVGShapeElement.prototype.setShapesAsAnimated=function(t){var e,r=t.length;for(e=0;e<r;e+=1)t[e].setAsAnimated()},SVGShapeElement.prototype.createStyleElement=function(t,e){var r,i=new SVGStyleData(t,e),s=i.pElem;if("st"===t.ty)r=new SVGStrokeStyleData(this,t,i);else if("fl"===t.ty)r=new SVGFillStyleData(this,t,i);else if("gf"===t.ty||"gs"===t.ty){r=new("gf"===t.ty?SVGGradientFillStyleData:SVGGradientStrokeStyleData)(this,t,i),this.globalData.defs.appendChild(r.gf),r.maskId&&(this.globalData.defs.appendChild(r.ms),this.globalData.defs.appendChild(r.of),s.setAttribute("mask","url("+locationHref+"#"+r.maskId+")"))}return"st"!==t.ty&&"gs"!==t.ty||(s.setAttribute("stroke-linecap",this.lcEnum[t.lc]||"round"),s.setAttribute("stroke-linejoin",this.ljEnum[t.lj]||"round"),s.setAttribute("fill-opacity","0"),1===t.lj&&s.setAttribute("stroke-miterlimit",t.ml)),2===t.r&&s.setAttribute("fill-rule","evenodd"),t.ln&&s.setAttribute("id",t.ln),t.cl&&s.setAttribute("class",t.cl),t.bm&&(s.style["mix-blend-mode"]=getBlendMode(t.bm)),this.stylesList.push(i),this.addToAnimatedContents(t,r),r},SVGShapeElement.prototype.createGroupElement=function(t){var e=new ShapeGroupData;return t.ln&&e.gr.setAttribute("id",t.ln),t.cl&&e.gr.setAttribute("class",t.cl),t.bm&&(e.gr.style["mix-blend-mode"]=getBlendMode(t.bm)),e},SVGShapeElement.prototype.createTransformElement=function(t,e){var r=TransformPropertyFactory.getTransformProperty(this,t,this),i=new SVGTransformData(r,r.o,e);return this.addToAnimatedContents(t,i),i},SVGShapeElement.prototype.createShapeElement=function(t,e,r){var i=4;"rc"===t.ty?i=5:"el"===t.ty?i=6:"sr"===t.ty&&(i=7);var s=new SVGShapeData(e,r,ShapePropertyFactory.getShapeProp(this,t,i,this));return this.shapes.push(s),this.addShapeToModifiers(s),this.addToAnimatedContents(t,s),s},SVGShapeElement.prototype.addToAnimatedContents=function(t,e){for(var r=0,i=this.animatedContents.length;r<i;){if(this.animatedContents[r].element===e)return;r+=1}this.animatedContents.push({fn:SVGElementsRenderer.createRenderFunction(t),element:e,data:t})},SVGShapeElement.prototype.setElementStyles=function(t){var e,r=t.styles,i=this.stylesList.length;for(e=0;e<i;e+=1)this.stylesList[e].closed||r.push(this.stylesList[e])},SVGShapeElement.prototype.reloadShapes=function(){this._isFirstFrame=!0;var t,e=this.itemsData.length;for(t=0;t<e;t+=1)this.prevViewData[t]=this.itemsData[t];for(this.searchShapes(this.shapesData,this.itemsData,this.prevViewData,this.layerElement,0,[],!0),this.filterUniqueShapes(),e=this.dynamicProperties.length,t=0;t<e;t+=1)this.dynamicProperties[t].getValue();this.renderModifiers()},SVGShapeElement.prototype.searchShapes=function(t,e,r,i,s,a,n){var o,h,p,l,m,f,c=[].concat(a),d=t.length-1,u=[],y=[];for(o=d;0<=o;o-=1){if((f=this.searchProcessedElement(t[o]))?e[o]=r[f-1]:t[o]._render=n,"fl"==t[o].ty||"st"==t[o].ty||"gf"==t[o].ty||"gs"==t[o].ty)f?e[o].style.closed=!1:e[o]=this.createStyleElement(t[o],s),t[o]._render&&i.appendChild(e[o].style.pElem),u.push(e[o].style);else if("gr"==t[o].ty){if(f)for(p=e[o].it.length,h=0;h<p;h+=1)e[o].prevViewData[h]=e[o].it[h];else e[o]=this.createGroupElement(t[o]);this.searchShapes(t[o].it,e[o].it,e[o].prevViewData,e[o].gr,s+1,c,n),t[o]._render&&i.appendChild(e[o].gr)}else"tr"==t[o].ty?(f||(e[o]=this.createTransformElement(t[o],i)),l=e[o].transform,c.push(l)):"sh"==t[o].ty||"rc"==t[o].ty||"el"==t[o].ty||"sr"==t[o].ty?(f||(e[o]=this.createShapeElement(t[o],c,s)),this.setElementStyles(e[o])):"tm"==t[o].ty||"rd"==t[o].ty||"ms"==t[o].ty?(f?(m=e[o]).closed=!1:((m=ShapeModifiers.getModifier(t[o].ty)).init(this,t[o]),e[o]=m,this.shapeModifiers.push(m)),y.push(m)):"rp"==t[o].ty&&(f?(m=e[o]).closed=!0:(m=ShapeModifiers.getModifier(t[o].ty),(e[o]=m).init(this,t,o,e),this.shapeModifiers.push(m),n=!1),y.push(m));this.addProcessedElement(t[o],o+1)}for(d=u.length,o=0;o<d;o+=1)u[o].closed=!0;for(d=y.length,o=0;o<d;o+=1)y[o].closed=!0},SVGShapeElement.prototype.renderInnerContent=function(){this.renderModifiers();var t,e=this.stylesList.length;for(t=0;t<e;t+=1)this.stylesList[t].reset();for(this.renderShape(),t=0;t<e;t+=1)(this.stylesList[t]._mdf||this._isFirstFrame)&&(this.stylesList[t].msElem&&(this.stylesList[t].msElem.setAttribute("d",this.stylesList[t].d),this.stylesList[t].d="M0 0"+this.stylesList[t].d),this.stylesList[t].pElem.setAttribute("d",this.stylesList[t].d||"M0 0"))},SVGShapeElement.prototype.renderShape=function(){var t,e,r=this.animatedContents.length;for(t=0;t<r;t+=1)e=this.animatedContents[t],(this._isFirstFrame||e.element._isAnimated)&&!0!==e.data&&e.fn(e.data,e.element,this._isFirstFrame)},SVGShapeElement.prototype.destroy=function(){this.destroyBaseElement(),this.shapesData=null,this.itemsData=null},CVContextData.prototype.duplicate=function(){var t=2*this._length,e=this.savedOp;this.savedOp=createTypedArray("float32",t),this.savedOp.set(e);var r=0;for(r=this._length;r<t;r+=1)this.saved[r]=createTypedArray("float32",16);this._length=t},CVContextData.prototype.reset=function(){this.cArrPos=0,this.cTr.reset(),this.cO=1},CVBaseElement.prototype={createElements:function(){},initRendererElement:function(){},createContainerElements:function(){this.canvasContext=this.globalData.canvasContext,this.renderableEffectsManager=new CVEffects(this)},createContent:function(){},setBlendMode:function(){var t=this.globalData;if(t.blendMode!==this.data.bm){t.blendMode=this.data.bm;var e=getBlendMode(this.data.bm);t.canvasContext.globalCompositeOperation=e}},createRenderableComponents:function(){this.maskManager=new CVMaskElement(this.data,this)},hideElement:function(){this.hidden||this.isInRange&&!this.isTransparent||(this.hidden=!0)},showElement:function(){this.isInRange&&!this.isTransparent&&(this.hidden=!1,this._isFirstFrame=!0,this.maskManager._isFirstFrame=!0)},renderFrame:function(){this.hidden||this.data.hd||(this.renderTransform(),this.renderRenderable(),this.setBlendMode(),this.globalData.renderer.save(),this.globalData.renderer.ctxTransform(this.finalTransform.mat.props),this.globalData.renderer.ctxOpacity(this.finalTransform.mProp.o.v),this.renderInnerContent(),this.globalData.renderer.restore(),this.maskManager.hasMasks&&this.globalData.renderer.restore(!0),this._isFirstFrame&&(this._isFirstFrame=!1))},destroy:function(){this.canvasContext=null,this.data=null,this.globalData=null,this.maskManager.destroy()},mHelper:new Matrix},CVBaseElement.prototype.hide=CVBaseElement.prototype.hideElement,CVBaseElement.prototype.show=CVBaseElement.prototype.showElement,extendPrototype([CanvasRenderer,ICompElement,CVBaseElement],CVCompElement),CVCompElement.prototype.renderInnerContent=function(){var t;for(t=this.layers.length-1;0<=t;t-=1)(this.completeLayers||this.elements[t])&&this.elements[t].renderFrame()},CVCompElement.prototype.destroy=function(){var t;for(t=this.layers.length-1;0<=t;t-=1)this.elements[t]&&this.elements[t].destroy();this.layers=null,this.elements=null},CVMaskElement.prototype.renderFrame=function(){if(this.hasMasks){var t,e,r,i,s=this.element.finalTransform.mat,a=this.element.canvasContext,n=this.masksProperties.length;for(a.beginPath(),t=0;t<n;t++)if("n"!==this.masksProperties[t].mode){this.masksProperties[t].inv&&(a.moveTo(0,0),a.lineTo(this.element.globalData.compSize.w,0),a.lineTo(this.element.globalData.compSize.w,this.element.globalData.compSize.h),a.lineTo(0,this.element.globalData.compSize.h),a.lineTo(0,0)),i=this.viewData[t].v,e=s.applyToPointArray(i.v[0][0],i.v[0][1],0),a.moveTo(e[0],e[1]);var o,h=i._length;for(o=1;o<h;o++)r=s.applyToTriplePoints(i.o[o-1],i.i[o],i.v[o]),a.bezierCurveTo(r[0],r[1],r[2],r[3],r[4],r[5]);r=s.applyToTriplePoints(i.o[o-1],i.i[0],i.v[0]),a.bezierCurveTo(r[0],r[1],r[2],r[3],r[4],r[5])}this.element.globalData.renderer.save(!0),a.clip()}},CVMaskElement.prototype.getMaskProperty=MaskElement.prototype.getMaskProperty,CVMaskElement.prototype.destroy=function(){this.element=null},extendPrototype([BaseElement,TransformElement,CVBaseElement,IShapeElement,HierarchyElement,FrameElement,RenderableElement],CVShapeElement),CVShapeElement.prototype.initElement=RenderableDOMElement.prototype.initElement,CVShapeElement.prototype.transformHelper={opacity:1,_opMdf:!1},CVShapeElement.prototype.dashResetter=[],CVShapeElement.prototype.createContent=function(){this.searchShapes(this.shapesData,this.itemsData,this.prevViewData,!0,[])},CVShapeElement.prototype.createStyleElement=function(t,e){var r={data:t,type:t.ty,preTransforms:this.transformsManager.addTransformSequence(e),transforms:[],elements:[],closed:!0===t.hd},i={};if("fl"==t.ty||"st"==t.ty?(i.c=PropertyFactory.getProp(this,t.c,1,255,this),i.c.k||(r.co="rgb("+bm_floor(i.c.v[0])+","+bm_floor(i.c.v[1])+","+bm_floor(i.c.v[2])+")")):"gf"!==t.ty&&"gs"!==t.ty||(i.s=PropertyFactory.getProp(this,t.s,1,null,this),i.e=PropertyFactory.getProp(this,t.e,1,null,this),i.h=PropertyFactory.getProp(this,t.h||{k:0},0,.01,this),i.a=PropertyFactory.getProp(this,t.a||{k:0},0,degToRads,this),i.g=new GradientProperty(this,t.g,this)),i.o=PropertyFactory.getProp(this,t.o,0,.01,this),"st"==t.ty||"gs"==t.ty){if(r.lc=this.lcEnum[t.lc]||"round",r.lj=this.ljEnum[t.lj]||"round",1==t.lj&&(r.ml=t.ml),i.w=PropertyFactory.getProp(this,t.w,0,null,this),i.w.k||(r.wi=i.w.v),t.d){var s=new DashProperty(this,t.d,"canvas",this);i.d=s,i.d.k||(r.da=i.d.dashArray,r.do=i.d.dashoffset[0])}}else r.r=2===t.r?"evenodd":"nonzero";return this.stylesList.push(r),i.style=r,i},CVShapeElement.prototype.createGroupElement=function(t){return{it:[],prevViewData:[]}},CVShapeElement.prototype.createTransformElement=function(t){return{transform:{opacity:1,_opMdf:!1,key:this.transformsManager.getNewKey(),op:PropertyFactory.getProp(this,t.o,0,.01,this),mProps:TransformPropertyFactory.getTransformProperty(this,t,this)}}},CVShapeElement.prototype.createShapeElement=function(t){var e=new CVShapeData(this,t,this.stylesList,this.transformsManager);return this.shapes.push(e),this.addShapeToModifiers(e),e},CVShapeElement.prototype.reloadShapes=function(){this._isFirstFrame=!0;var t,e=this.itemsData.length;for(t=0;t<e;t+=1)this.prevViewData[t]=this.itemsData[t];for(this.searchShapes(this.shapesData,this.itemsData,this.prevViewData,!0,[]),e=this.dynamicProperties.length,t=0;t<e;t+=1)this.dynamicProperties[t].getValue();this.renderModifiers(),this.transformsManager.processSequences(this._isFirstFrame)},CVShapeElement.prototype.addTransformToStyleList=function(t){var e,r=this.stylesList.length;for(e=0;e<r;e+=1)this.stylesList[e].closed||this.stylesList[e].transforms.push(t)},CVShapeElement.prototype.removeTransformFromStyleList=function(){var t,e=this.stylesList.length;for(t=0;t<e;t+=1)this.stylesList[t].closed||this.stylesList[t].transforms.pop()},CVShapeElement.prototype.closeStyles=function(t){var e,r=t.length;for(e=0;e<r;e+=1)t[e].closed=!0},CVShapeElement.prototype.searchShapes=function(t,e,r,i,s){var a,n,o,h,p,l,m=t.length-1,f=[],c=[],d=[].concat(s);for(a=m;0<=a;a-=1){if((h=this.searchProcessedElement(t[a]))?e[a]=r[h-1]:t[a]._shouldRender=i,"fl"==t[a].ty||"st"==t[a].ty||"gf"==t[a].ty||"gs"==t[a].ty)h?e[a].style.closed=!1:e[a]=this.createStyleElement(t[a],d),f.push(e[a].style);else if("gr"==t[a].ty){if(h)for(o=e[a].it.length,n=0;n<o;n+=1)e[a].prevViewData[n]=e[a].it[n];else e[a]=this.createGroupElement(t[a]);this.searchShapes(t[a].it,e[a].it,e[a].prevViewData,i,d)}else"tr"==t[a].ty?(h||(l=this.createTransformElement(t[a]),e[a]=l),d.push(e[a]),this.addTransformToStyleList(e[a])):"sh"==t[a].ty||"rc"==t[a].ty||"el"==t[a].ty||"sr"==t[a].ty?h||(e[a]=this.createShapeElement(t[a])):"tm"==t[a].ty||"rd"==t[a].ty?(h?(p=e[a]).closed=!1:((p=ShapeModifiers.getModifier(t[a].ty)).init(this,t[a]),e[a]=p,this.shapeModifiers.push(p)),c.push(p)):"rp"==t[a].ty&&(h?(p=e[a]).closed=!0:(p=ShapeModifiers.getModifier(t[a].ty),(e[a]=p).init(this,t,a,e),this.shapeModifiers.push(p),i=!1),c.push(p));this.addProcessedElement(t[a],a+1)}for(this.removeTransformFromStyleList(),this.closeStyles(f),m=c.length,a=0;a<m;a+=1)c[a].closed=!0},CVShapeElement.prototype.renderInnerContent=function(){this.transformHelper.opacity=1,this.transformHelper._opMdf=!1,this.renderModifiers(),this.transformsManager.processSequences(this._isFirstFrame),this.renderShape(this.transformHelper,this.shapesData,this.itemsData,!0)},CVShapeElement.prototype.renderShapeTransform=function(t,e){(t._opMdf||e.op._mdf||this._isFirstFrame)&&(e.opacity=t.opacity,e.opacity*=e.op.v,e._opMdf=!0)},CVShapeElement.prototype.drawLayer=function(){var t,e,r,i,s,a,n,o,h,p=this.stylesList.length,l=this.globalData.renderer,m=this.globalData.canvasContext;for(t=0;t<p;t+=1)if(("st"!==(o=(h=this.stylesList[t]).type)&&"gs"!==o||0!==h.wi)&&h.data._shouldRender&&0!==h.coOp&&0!==this.globalData.currentGlobalAlpha){for(l.save(),a=h.elements,"st"===o||"gs"===o?(m.strokeStyle="st"===o?h.co:h.grd,m.lineWidth=h.wi,m.lineCap=h.lc,m.lineJoin=h.lj,m.miterLimit=h.ml||0):m.fillStyle="fl"===o?h.co:h.grd,l.ctxOpacity(h.coOp),"st"!==o&&"gs"!==o&&m.beginPath(),l.ctxTransform(h.preTransforms.finalTransform.props),r=a.length,e=0;e<r;e+=1){for("st"!==o&&"gs"!==o||(m.beginPath(),h.da&&(m.setLineDash(h.da),m.lineDashOffset=h.do)),s=(n=a[e].trNodes).length,i=0;i<s;i+=1)"m"==n[i].t?m.moveTo(n[i].p[0],n[i].p[1]):"c"==n[i].t?m.bezierCurveTo(n[i].pts[0],n[i].pts[1],n[i].pts[2],n[i].pts[3],n[i].pts[4],n[i].pts[5]):m.closePath();"st"!==o&&"gs"!==o||(m.stroke(),h.da&&m.setLineDash(this.dashResetter))}"st"!==o&&"gs"!==o&&m.fill(h.r),l.restore()}},CVShapeElement.prototype.renderShape=function(t,e,r,i){var s,a;for(a=t,s=e.length-1;0<=s;s-=1)"tr"==e[s].ty?(a=r[s].transform,this.renderShapeTransform(t,a)):"sh"==e[s].ty||"el"==e[s].ty||"rc"==e[s].ty||"sr"==e[s].ty?this.renderPath(e[s],r[s]):"fl"==e[s].ty?this.renderFill(e[s],r[s],a):"st"==e[s].ty?this.renderStroke(e[s],r[s],a):"gf"==e[s].ty||"gs"==e[s].ty?this.renderGradientFill(e[s],r[s],a):"gr"==e[s].ty?this.renderShape(a,e[s].it,r[s].it):e[s].ty;i&&this.drawLayer()},CVShapeElement.prototype.renderStyledShape=function(t,e){if(this._isFirstFrame||e._mdf||t.transforms._mdf){var r,i,s,a=t.trNodes,n=e.paths,o=n._length;a.length=0;var h=t.transforms.finalTransform;for(s=0;s<o;s+=1){var p=n.shapes[s];if(p&&p.v){for(i=p._length,r=1;r<i;r+=1)1===r&&a.push({t:"m",p:h.applyToPointArray(p.v[0][0],p.v[0][1],0)}),a.push({t:"c",pts:h.applyToTriplePoints(p.o[r-1],p.i[r],p.v[r])});1===i&&a.push({t:"m",p:h.applyToPointArray(p.v[0][0],p.v[0][1],0)}),p.c&&i&&(a.push({t:"c",pts:h.applyToTriplePoints(p.o[r-1],p.i[0],p.v[0])}),a.push({t:"z"}))}}t.trNodes=a}},CVShapeElement.prototype.renderPath=function(t,e){if(!0!==t.hd&&t._shouldRender){var r,i=e.styledShapes.length;for(r=0;r<i;r+=1)this.renderStyledShape(e.styledShapes[r],e.sh)}},CVShapeElement.prototype.renderFill=function(t,e,r){var i=e.style;(e.c._mdf||this._isFirstFrame)&&(i.co="rgb("+bm_floor(e.c.v[0])+","+bm_floor(e.c.v[1])+","+bm_floor(e.c.v[2])+")"),(e.o._mdf||r._opMdf||this._isFirstFrame)&&(i.coOp=e.o.v*r.opacity)},CVShapeElement.prototype.renderGradientFill=function(t,e,r){var i=e.style;if(!i.grd||e.g._mdf||e.s._mdf||e.e._mdf||1!==t.t&&(e.h._mdf||e.a._mdf)){var s=this.globalData.canvasContext,a=e.s.v,n=e.e.v;if(1===t.t)f=s.createLinearGradient(a[0],a[1],n[0],n[1]);else var o=Math.sqrt(Math.pow(a[0]-n[0],2)+Math.pow(a[1]-n[1],2)),h=Math.atan2(n[1]-a[1],n[0]-a[0]),p=o*(1<=e.h.v?.99:e.h.v<=-1?-.99:e.h.v),l=Math.cos(h+e.a.v)*p+a[0],m=Math.sin(h+e.a.v)*p+a[1],f=s.createRadialGradient(l,m,0,a[0],a[1],o);var c,d=t.g.p,u=e.g.c,y=1;for(c=0;c<d;c+=1)e.g._hasOpacity&&e.g._collapsable&&(y=e.g.o[2*c+1]),f.addColorStop(u[4*c]/100,"rgba("+u[4*c+1]+","+u[4*c+2]+","+u[4*c+3]+","+y+")");i.grd=f}i.coOp=e.o.v*r.opacity},CVShapeElement.prototype.renderStroke=function(t,e,r){var i=e.style,s=e.d;s&&(s._mdf||this._isFirstFrame)&&(i.da=s.dashArray,i.do=s.dashoffset[0]),(e.c._mdf||this._isFirstFrame)&&(i.co="rgb("+bm_floor(e.c.v[0])+","+bm_floor(e.c.v[1])+","+bm_floor(e.c.v[2])+")"),(e.o._mdf||r._opMdf||this._isFirstFrame)&&(i.coOp=e.o.v*r.opacity),(e.w._mdf||this._isFirstFrame)&&(i.wi=e.w.v)},CVShapeElement.prototype.destroy=function(){this.shapesData=null,this.globalData=null,this.canvasContext=null,this.stylesList.length=0,this.itemsData.length=0},extendPrototype([BaseElement,TransformElement,CVBaseElement,HierarchyElement,FrameElement,RenderableElement],CVSolidElement),CVSolidElement.prototype.initElement=SVGShapeElement.prototype.initElement,CVSolidElement.prototype.prepareFrame=IImageElement.prototype.prepareFrame,CVSolidElement.prototype.renderInnerContent=function(){var t=this.canvasContext;t.fillStyle=this.data.sc,t.fillRect(0,0,this.data.sw,this.data.sh)},CVEffects.prototype.renderFrame=function(){};var animationManager=(tJ={},uJ=[],vJ=0,wJ=0,xJ=0,yJ=!0,zJ=!1,tJ.registerAnimation=BJ,tJ.loadAnimation=function(t){var e=new AnimationItem;return FJ(e,null),e.setParams(t),e},tJ.setSpeed=function(t,e){var r;for(r=0;r<wJ;r+=1)uJ[r].animation.setSpeed(t,e)},tJ.setDirection=function(t,e){var r;for(r=0;r<wJ;r+=1)uJ[r].animation.setDirection(t,e)},tJ.play=function(t){var e;for(e=0;e<wJ;e+=1)uJ[e].animation.play(t)},tJ.pause=function(t){var e;for(e=0;e<wJ;e+=1)uJ[e].animation.pause(t)},tJ.stop=function(t){var e;for(e=0;e<wJ;e+=1)uJ[e].animation.stop(t)},tJ.togglePause=function(t){var e;for(e=0;e<wJ;e+=1)uJ[e].animation.togglePause(t)},tJ.searchAnimations=function(t,e,r){var i,s=[].concat([].slice.call(document.getElementsByClassName("lottie")),[].slice.call(document.getElementsByClassName("bodymovin"))),a=s.length;for(i=0;i<a;i+=1)r&&s[i].setAttribute("data-bm-type",r),BJ(s[i],t);if(e&&0===a){r||(r="svg");var n=document.getElementsByTagName("body")[0];n.innerHTML="";var o=createTag("div");o.style.width="100%",o.style.height="100%",o.setAttribute("data-bm-type",r),n.appendChild(o),BJ(o,t)}},tJ.resize=function(){var t;for(t=0;t<wJ;t+=1)uJ[t].animation.resize()},tJ.goToAndStop=function(t,e,r){var i;for(i=0;i<wJ;i+=1)uJ[i].animation.goToAndStop(t,e,r)},tJ.destroy=function(t){var e;for(e=wJ-1;0<=e;e-=1)uJ[e].animation.destroy(t)},tJ.freeze=function(){zJ=!0},tJ.unfreeze=function(){zJ=!1,TJ()},tJ.getRegisteredAnimations=function(){var t,e=uJ.length,r=[];for(t=0;t<e;t+=1)r.push(uJ[t].animation);return r},tJ),tJ,uJ,vJ,wJ,xJ,yJ,zJ,PK,QK,RK,SK,TK,UK,VK;function AJ(t){for(var e=0,r=t.target;e<wJ;)uJ[e].animation===r&&(uJ.splice(e,1),e-=1,wJ-=1,r.isPaused||EJ()),e+=1}function BJ(t,e){if(!t)return null;for(var r=0;r<wJ;){if(uJ[r].elem==t&&null!==uJ[r].elem)return uJ[r].animation;r+=1}var i=new AnimationItem;return FJ(i,t),i.setData(t,e),i}function DJ(){xJ+=1,TJ()}function EJ(){xJ-=1}function FJ(t,e){t.addEventListener("destroy",AJ),t.addEventListener("_active",DJ),t.addEventListener("_idle",EJ),uJ.push({elem:e,animation:t}),wJ+=1}function KJ(t){var e,r=t-vJ;for(e=0;e<wJ;e+=1)uJ[e].animation.advanceTime(r);vJ=t,xJ&&!zJ?window.requestAnimationFrame(KJ):yJ=!0}function LJ(t){vJ=t,window.requestAnimationFrame(KJ)}function TJ(){!zJ&&xJ&&yJ&&(window.requestAnimationFrame(LJ),yJ=!1)}function WK(t){for(var e=0,r=t.target;e<SK;)QK[e].animation===r&&(QK.splice(e,1),e-=1,SK-=1,r.isPaused||$K()),e+=1}function ZK(){TK+=1,nL()}function $K(){TK-=1}function _K(t,e){t.addEventListener("destroy",WK),t.addEventListener("_active",ZK),t.addEventListener("_idle",$K),QK.push({elem:e,animation:t}),SK+=1}function eL(t){var e,r=t-RK;for(e=0;e<SK;e+=1)QK[e].animation.advanceTime(r);RK=t,TK&&!VK?requestAnimationFrame(eL):UK=!0}function fL(t){RK=t,requestAnimationFrame(eL)}function nL(){!VK&&TK&&UK&&(requestAnimationFrame(fL),UK=!1)}PK={},QK=[],RK=0,SK=0,TK=0,UK=!0,VK=!1,PK.registerAnimation=function(t,e){if(!t)return null;for(var r=0;r<SK;){if(QK[r].elem==t&&null!==QK[r].elem)return QK[r].animation;r+=1}var i=new AnimationItem;return _K(i,t),i.setData(t,e),i},PK.loadAnimation=function(t){var e=new AnimationItem;return _K(e,null),e.setParams(t),e},PK.setSpeed=function(t,e){var r;for(r=0;r<SK;r+=1)QK[r].animation.setSpeed(t,e)},PK.setDirection=function(t,e){var r;for(r=0;r<SK;r+=1)QK[r].animation.setDirection(t,e)},PK.play=function(t){var e;for(e=0;e<SK;e+=1)QK[e].animation.play(t)},PK.pause=function(t){var e;for(e=0;e<SK;e+=1)QK[e].animation.pause(t)},PK.stop=function(t){var e;for(e=0;e<SK;e+=1)QK[e].animation.stop(t)},PK.togglePause=function(t){var e;for(e=0;e<SK;e+=1)QK[e].animation.togglePause(t)},PK.searchAnimations=function(t,e,r){throw new Error("Cannot access DOM from worker thread")},PK.resize=function(){var t;for(t=0;t<SK;t+=1)QK[t].animation.resize()},PK.goToAndStop=function(t,e,r){var i;for(i=0;i<SK;i+=1)QK[i].animation.goToAndStop(t,e,r)},PK.destroy=function(t){var e;for(e=SK-1;0<=e;e-=1)QK[e].animation.destroy(t)},PK.freeze=function(){VK=!0},PK.unfreeze=function(){VK=!1,nL()},PK.getRegisteredAnimations=function(){var t,e=QK.length,r=[];for(t=0;t<e;t+=1)r.push(QK[t].animation);return r},animationManager=PK;var AnimationItem=function(){this._cbs=[],this.name="",this.path="",this.isLoaded=!1,this.currentFrame=0,this.currentRawFrame=0,this.totalFrames=0,this.frameRate=0,this.frameMult=0,this.playSpeed=1,this.playDirection=1,this.playCount=0,this.animationData={},this.assets=[],this.isPaused=!0,this.autoplay=!1,this.loop=!0,this.renderer=null,this.animationID=createElementID(),this.assetsPath="",this.timeCompleted=0,this.segmentPos=0,this.subframeEnabled=subframeEnabled,this.segments=[],this._idle=!0,this._completedLoop=!1,this.projectInterface=ProjectInterface(),this.imagePreloader=new ImagePreloader};extendPrototype([BaseEvent],AnimationItem),AnimationItem.prototype.setParams=function(t){t.context&&(this.context=t.context),(t.wrapper||t.container)&&(this.wrapper=t.wrapper||t.container);var e=t.animType?t.animType:t.renderer?t.renderer:"svg";switch(e){case"canvas":this.renderer=new CanvasRenderer(this,t.rendererSettings);break;case"svg":this.renderer=new SVGRenderer(this,t.rendererSettings);break;default:this.renderer=new HybridRenderer(this,t.rendererSettings)}this.renderer.setProjectInterface(this.projectInterface),this.animType=e,""===t.loop||null===t.loop||(!1===t.loop?this.loop=!1:!0===t.loop?this.loop=!0:this.loop=parseInt(t.loop)),this.autoplay=!("autoplay"in t)||t.autoplay,this.name=t.name?t.name:"",this.autoloadSegments=!t.hasOwnProperty("autoloadSegments")||t.autoloadSegments,this.assetsPath=t.assetsPath,t.animationData?this.configAnimation(t.animationData):t.path&&("json"!=t.path.substr(-4)&&("/"!=t.path.substr(-1,1)&&(t.path+="/"),t.path+="data.json"),-1!=t.path.lastIndexOf("\\")?this.path=t.path.substr(0,t.path.lastIndexOf("\\")+1):this.path=t.path.substr(0,t.path.lastIndexOf("/")+1),this.fileName=t.path.substr(t.path.lastIndexOf("/")+1),this.fileName=this.fileName.substr(0,this.fileName.lastIndexOf(".json")),assetLoader.load(t.path,this.configAnimation.bind(this),function(){this.trigger("data_failed")}.bind(this)))},AnimationItem.prototype.setData=function(t,e){var r={wrapper:t,animationData:e?"object"==typeof e?e:JSON.parse(e):null},i=t.attributes;r.path=i.getNamedItem("data-animation-path")?i.getNamedItem("data-animation-path").value:i.getNamedItem("data-bm-path")?i.getNamedItem("data-bm-path").value:i.getNamedItem("bm-path")?i.getNamedItem("bm-path").value:"",r.animType=i.getNamedItem("data-anim-type")?i.getNamedItem("data-anim-type").value:i.getNamedItem("data-bm-type")?i.getNamedItem("data-bm-type").value:i.getNamedItem("bm-type")?i.getNamedItem("bm-type").value:i.getNamedItem("data-bm-renderer")?i.getNamedItem("data-bm-renderer").value:i.getNamedItem("bm-renderer")?i.getNamedItem("bm-renderer").value:"canvas";var s=i.getNamedItem("data-anim-loop")?i.getNamedItem("data-anim-loop").value:i.getNamedItem("data-bm-loop")?i.getNamedItem("data-bm-loop").value:i.getNamedItem("bm-loop")?i.getNamedItem("bm-loop").value:"";""===s||(r.loop="false"!==s&&("true"===s||parseInt(s)));var a=i.getNamedItem("data-anim-autoplay")?i.getNamedItem("data-anim-autoplay").value:i.getNamedItem("data-bm-autoplay")?i.getNamedItem("data-bm-autoplay").value:!i.getNamedItem("bm-autoplay")||i.getNamedItem("bm-autoplay").value;r.autoplay="false"!==a,r.name=i.getNamedItem("data-name")?i.getNamedItem("data-name").value:i.getNamedItem("data-bm-name")?i.getNamedItem("data-bm-name").value:i.getNamedItem("bm-name")?i.getNamedItem("bm-name").value:"","false"===(i.getNamedItem("data-anim-prerender")?i.getNamedItem("data-anim-prerender").value:i.getNamedItem("data-bm-prerender")?i.getNamedItem("data-bm-prerender").value:i.getNamedItem("bm-prerender")?i.getNamedItem("bm-prerender").value:"")&&(r.prerender=!1),this.setParams(r)},AnimationItem.prototype.includeLayers=function(t){t.op>this.animationData.op&&(this.animationData.op=t.op,this.totalFrames=Math.floor(t.op-this.animationData.ip));var e,r,i=this.animationData.layers,s=i.length,a=t.layers,n=a.length;for(r=0;r<n;r+=1)for(e=0;e<s;){if(i[e].id==a[r].id){i[e]=a[r];break}e+=1}if((t.chars||t.fonts)&&(this.renderer.globalData.fontManager.addChars(t.chars),this.renderer.globalData.fontManager.addFonts(t.fonts,this.renderer.globalData.defs)),t.assets)for(s=t.assets.length,e=0;e<s;e+=1)this.animationData.assets.push(t.assets[e]);this.animationData.__complete=!1,dataManager.completeData(this.animationData,this.renderer.globalData.fontManager),this.renderer.includeLayers(t.layers),expressionsPlugin&&expressionsPlugin.initExpressions(this),this.loadNextSegment()},AnimationItem.prototype.loadNextSegment=function(){var t=this.animationData.segments;if(!t||0===t.length||!this.autoloadSegments)return this.trigger("data_ready"),void(this.timeCompleted=this.totalFrames);var e=t.shift();this.timeCompleted=e.time*this.frameRate;var r=this.path+this.fileName+"_"+this.segmentPos+".json";this.segmentPos+=1,assetLoader.load(r,this.includeLayers.bind(this),function(){this.trigger("data_failed")}.bind(this))},AnimationItem.prototype.loadSegments=function(){this.animationData.segments||(this.timeCompleted=this.totalFrames),this.loadNextSegment()},AnimationItem.prototype.imagesLoaded=function(){this.trigger("loaded_images"),this.checkLoaded()},AnimationItem.prototype.preloadImages=function(){this.imagePreloader.setAssetsPath(this.assetsPath),this.imagePreloader.setPath(this.path),this.imagePreloader.loadAssets(this.animationData.assets,this.imagesLoaded.bind(this))},AnimationItem.prototype.configAnimation=function(t){this.renderer&&(this.animationData=t,this.totalFrames=Math.floor(this.animationData.op-this.animationData.ip),this.renderer.configAnimation(t),t.assets||(t.assets=[]),this.renderer.searchExtraCompositions(t.assets),this.assets=this.animationData.assets,this.frameRate=this.animationData.fr,this.firstFrame=Math.round(this.animationData.ip),this.frameMult=this.animationData.fr/1e3,this.trigger("config_ready"),this.preloadImages(),this.loadSegments(),this.updaFrameModifier(),this.waitForFontsLoaded())},AnimationItem.prototype.waitForFontsLoaded=function(){this.renderer&&(this.renderer.globalData.fontManager.loaded()?this.checkLoaded():setTimeout(this.waitForFontsLoaded.bind(this),20))},AnimationItem.prototype.checkLoaded=function(){this.isLoaded||!this.renderer.globalData.fontManager.loaded()||!this.imagePreloader.loaded()&&"canvas"===this.renderer.rendererType||(this.isLoaded=!0,dataManager.completeData(this.animationData,this.renderer.globalData.fontManager),expressionsPlugin&&expressionsPlugin.initExpressions(this),this.renderer.initItems(),setTimeout(function(){this.trigger("DOMLoaded")}.bind(this),0),this.gotoFrame(),this.autoplay&&this.play())},AnimationItem.prototype.resize=function(){this.renderer.updateContainerSize()},AnimationItem.prototype.setSubframe=function(t){this.subframeEnabled=!!t},AnimationItem.prototype.gotoFrame=function(){this.currentFrame=this.subframeEnabled?this.currentRawFrame:~~this.currentRawFrame,this.timeCompleted!==this.totalFrames&&this.currentFrame>this.timeCompleted&&(this.currentFrame=this.timeCompleted),this.trigger("enterFrame"),this.renderFrame()},AnimationItem.prototype.renderFrame=function(){!1!==this.isLoaded&&this.renderer.renderFrame(this.currentFrame+this.firstFrame)},AnimationItem.prototype.play=function(t){t&&this.name!=t||!0===this.isPaused&&(this.isPaused=!1,this._idle&&(this._idle=!1,this.trigger("_active")))},AnimationItem.prototype.pause=function(t){t&&this.name!=t||!1===this.isPaused&&(this.isPaused=!0,this._idle=!0,this.trigger("_idle"))},AnimationItem.prototype.togglePause=function(t){t&&this.name!=t||(!0===this.isPaused?this.play():this.pause())},AnimationItem.prototype.stop=function(t){t&&this.name!=t||(this.pause(),this.playCount=0,this._completedLoop=!1,this.setCurrentRawFrameValue(0))},AnimationItem.prototype.goToAndStop=function(t,e,r){r&&this.name!=r||(e?this.setCurrentRawFrameValue(t):this.setCurrentRawFrameValue(t*this.frameModifier),this.pause())},AnimationItem.prototype.goToAndPlay=function(t,e,r){this.goToAndStop(t,e,r),this.play()},AnimationItem.prototype.advanceTime=function(t){if(!0!==this.isPaused&&!1!==this.isLoaded){var e=this.currentRawFrame+t*this.frameModifier,r=!1;e>=this.totalFrames-1&&0<this.frameModifier?this.loop&&this.playCount!==this.loop?e>=this.totalFrames?(this.playCount+=1,this.checkSegments(e%this.totalFrames)||(this.setCurrentRawFrameValue(e%this.totalFrames),this._completedLoop=!0,this.trigger("loopComplete"))):this.setCurrentRawFrameValue(e):this.checkSegments(e>this.totalFrames?e%this.totalFrames:0)||(r=!0,e=this.totalFrames-1):e<0?this.checkSegments(e%this.totalFrames)||(!this.loop||this.playCount--<=0&&!0!==this.loop?(r=!0,e=0):(this.setCurrentRawFrameValue(this.totalFrames+e%this.totalFrames),this._completedLoop?this.trigger("loopComplete"):this._completedLoop=!0)):this.setCurrentRawFrameValue(e),r&&(this.setCurrentRawFrameValue(e),this.pause(),this.trigger("complete"))}},AnimationItem.prototype.adjustSegment=function(t,e){this.playCount=0,t[1]<t[0]?(0<this.frameModifier&&(this.playSpeed<0?this.setSpeed(-this.playSpeed):this.setDirection(-1)),this.timeCompleted=this.totalFrames=t[0]-t[1],this.firstFrame=t[1],this.setCurrentRawFrameValue(this.totalFrames-.001-e)):t[1]>t[0]&&(this.frameModifier<0&&(this.playSpeed<0?this.setSpeed(-this.playSpeed):this.setDirection(1)),this.timeCompleted=this.totalFrames=t[1]-t[0],this.firstFrame=t[0],this.setCurrentRawFrameValue(.001+e)),this.trigger("segmentStart")},AnimationItem.prototype.setSegment=function(t,e){var r=-1;this.isPaused&&(this.currentRawFrame+this.firstFrame<t?r=t:this.currentRawFrame+this.firstFrame>e&&(r=e-t)),this.firstFrame=t,this.timeCompleted=this.totalFrames=e-t,-1!==r&&this.goToAndStop(r,!0)},AnimationItem.prototype.playSegments=function(t,e){if(e&&(this.segments.length=0),"object"==typeof t[0]){var r,i=t.length;for(r=0;r<i;r+=1)this.segments.push(t[r])}else this.segments.push(t);this.segments.length&&e&&this.adjustSegment(this.segments.shift(),0),this.isPaused&&this.play()},AnimationItem.prototype.resetSegments=function(t){this.segments.length=0,this.segments.push([this.animationData.ip,this.animationData.op]),t&&this.checkSegments(0)},AnimationItem.prototype.checkSegments=function(t){return!!this.segments.length&&(this.adjustSegment(this.segments.shift(),t),!0)},AnimationItem.prototype.destroy=function(t){t&&this.name!=t||!this.renderer||(this.renderer.destroy(),this.imagePreloader.destroy(),this.trigger("destroy"),this._cbs=null,this.onEnterFrame=this.onLoopComplete=this.onComplete=this.onSegmentStart=this.onDestroy=null,this.renderer=null)},AnimationItem.prototype.setCurrentRawFrameValue=function(t){this.currentRawFrame=t,this.gotoFrame()},AnimationItem.prototype.setSpeed=function(t){this.playSpeed=t,this.updaFrameModifier()},AnimationItem.prototype.setDirection=function(t){this.playDirection=t<0?-1:1,this.updaFrameModifier()},AnimationItem.prototype.updaFrameModifier=function(){this.frameModifier=this.frameMult*this.playSpeed*this.playDirection},AnimationItem.prototype.getPath=function(){return this.path},AnimationItem.prototype.getAssetsPath=function(t){var e="";if(t.e)e=t.p;else if(this.assetsPath){var r=t.p;-1!==r.indexOf("images/")&&(r=r.split("/")[1]),e=this.assetsPath+r}else e=this.path,e+=t.u?t.u:"",e+=t.p;return e},AnimationItem.prototype.getAssetData=function(t){for(var e=0,r=this.assets.length;e<r;){if(t==this.assets[e].id)return this.assets[e];e+=1}},AnimationItem.prototype.hide=function(){this.renderer.hide()},AnimationItem.prototype.show=function(){this.renderer.show()},AnimationItem.prototype.getDuration=function(t){return t?this.totalFrames:this.totalFrames/this.frameRate},AnimationItem.prototype.trigger=function(t){if(this._cbs&&this._cbs[t])switch(t){case"enterFrame":this.triggerEvent(t,new BMEnterFrameEvent(t,this.currentFrame,this.totalFrames,this.frameModifier));break;case"loopComplete":this.triggerEvent(t,new BMCompleteLoopEvent(t,this.loop,this.playCount,this.frameMult));break;case"complete":this.triggerEvent(t,new BMCompleteEvent(t,this.frameMult));break;case"segmentStart":this.triggerEvent(t,new BMSegmentStartEvent(t,this.firstFrame,this.totalFrames));break;case"destroy":this.triggerEvent(t,new BMDestroyEvent(t,this));break;default:this.triggerEvent(t)}"enterFrame"===t&&this.onEnterFrame&&this.onEnterFrame.call(this,new BMEnterFrameEvent(t,this.currentFrame,this.totalFrames,this.frameMult)),"loopComplete"===t&&this.onLoopComplete&&this.onLoopComplete.call(this,new BMCompleteLoopEvent(t,this.loop,this.playCount,this.frameMult)),"complete"===t&&this.onComplete&&this.onComplete.call(this,new BMCompleteEvent(t,this.frameMult)),"segmentStart"===t&&this.onSegmentStart&&this.onSegmentStart.call(this,new BMSegmentStartEvent(t,this.firstFrame,this.totalFrames)),"destroy"===t&&this.onDestroy&&this.onDestroy.call(this,new BMDestroyEvent(t,this))},AnimationItem.prototype.setParams=function(t){t.context&&(this.context=t.context);var e=t.animType?t.animType:t.renderer?t.renderer:"svg";switch(e){case"canvas":this.renderer=new CanvasRenderer(this,t.rendererSettings);break;default:throw new Error("Only canvas renderer is supported when using worker.")}if(this.renderer.setProjectInterface(this.projectInterface),this.animType=e,""===t.loop||null===t.loop||(!1===t.loop?this.loop=!1:!0===t.loop?this.loop=!0:this.loop=parseInt(t.loop)),this.autoplay=!("autoplay"in t)||t.autoplay,this.name=t.name?t.name:"",this.autoloadSegments=!t.hasOwnProperty("autoloadSegments")||t.autoloadSegments,this.assetsPath=null,t.animationData)this.configAnimation(t.animationData);else if(t.path)throw new Error("Canvas worker renderer cannot load animation from url")},AnimationItem.prototype.setData=function(t,e){throw new Error("Cannot set data on wrapper for canvas worker renderer")},AnimationItem.prototype.includeLayers=function(t){t.op>this.animationData.op&&(this.animationData.op=t.op,this.totalFrames=Math.floor(t.op-this.animationData.ip));var e,r,i=this.animationData.layers,s=i.length,a=t.layers,n=a.length;for(r=0;r<n;r+=1)for(e=0;e<s;){if(i[e].id==a[r].id){i[e]=a[r];break}e+=1}this.animationData.__complete=!1,dataManager.completeData(this.animationData,this.renderer.globalData.fontManager),this.renderer.includeLayers(t.layers),expressionsPlugin&&expressionsPlugin.initExpressions(this),this.loadNextSegment()},AnimationItem.prototype.loadNextSegment=function(){var t=this.animationData.segments;if(t&&0!==t.length&&this.autoloadSegments)throw new Error("Cannot load multiple segments in worker.");this.timeCompleted=this.totalFrames},AnimationItem.prototype.loadSegments=function(){this.animationData.segments||(this.timeCompleted=this.totalFrames),this.loadNextSegment()},AnimationItem.prototype.imagesLoaded=null,AnimationItem.prototype.preloadImages=null,AnimationItem.prototype.configAnimation=function(t){this.renderer&&(this.animationData=t,this.totalFrames=Math.floor(this.animationData.op-this.animationData.ip),this.renderer.configAnimation(t),t.assets||(t.assets=[]),this.renderer.searchExtraCompositions(t.assets),this.assets=this.animationData.assets,this.frameRate=this.animationData.fr,this.firstFrame=Math.round(this.animationData.ip),this.frameMult=this.animationData.fr/1e3,this.loadSegments(),this.updaFrameModifier(),this.checkLoaded())},AnimationItem.prototype.waitForFontsLoaded=null,AnimationItem.prototype.checkLoaded=function(){this.isLoaded||(this.isLoaded=!0,dataManager.completeData(this.animationData,null),expressionsPlugin&&expressionsPlugin.initExpressions(this),this.renderer.initItems(),this.gotoFrame())},AnimationItem.prototype.destroy=function(t){t&&this.name!=t||!this.renderer||(this.renderer.destroy(),this._cbs=null,this.onEnterFrame=this.onLoopComplete=this.onComplete=this.onSegmentStart=this.onDestroy=null,this.renderer=null)},AnimationItem.prototype.getPath=null;var Expressions=(xN={},xN.initExpressions=function(t){var e=0,r=[];t.renderer.compInterface=CompExpressionInterface(t.renderer),t.renderer.globalData.projectInterface.registerComposition(t.renderer),t.renderer.globalData.pushExpression=function(){e+=1},t.renderer.globalData.popExpression=function(){0==(e-=1)&&function(){var t,e=r.length;for(t=0;t<e;t+=1)r[t].release();r.length=0}()},t.renderer.globalData.registerExpressionProperty=function(t){-1===r.indexOf(t)&&r.push(t)}},xN),xN;expressionsPlugin=Expressions;var ExpressionManager=function(){var ob={},Math=BMMath,window=null,document=null;function $bm_isInstanceOfArray(t){return t.constructor===Array||t.constructor===Float32Array}function isNumerable(t,e){return"number"===t||"boolean"===t||"string"===t||e instanceof Number}function $bm_neg(t){var e=typeof t;if("number"==e||"boolean"==e||t instanceof Number)return-t;if($bm_isInstanceOfArray(t)){var r,i=t.length,s=[];for(r=0;r<i;r+=1)s[r]=-t[r];return s}return t.propType?t.v:void 0}var easeInBez=BezierFactory.getBezierEasing(.333,0,.833,.833,"easeIn").get,easeOutBez=BezierFactory.getBezierEasing(.167,.167,.667,1,"easeOut").get,easeInOutBez=BezierFactory.getBezierEasing(.33,0,.667,1,"easeInOut").get;function sum(t,e){var r=typeof t,i=typeof e;if("string"==r||"string"==i)return t+e;if(isNumerable(r,t)&&isNumerable(i,e))return t+e;if($bm_isInstanceOfArray(t)&&isNumerable(i,e))return(t=t.slice(0))[0]=t[0]+e,t;if(isNumerable(r,t)&&$bm_isInstanceOfArray(e))return(e=e.slice(0))[0]=t+e[0],e;if($bm_isInstanceOfArray(t)&&$bm_isInstanceOfArray(e)){for(var s=0,a=t.length,n=e.length,o=[];s<a||s<n;)("number"==typeof t[s]||t[s]instanceof Number)&&("number"==typeof e[s]||e[s]instanceof Number)?o[s]=t[s]+e[s]:o[s]=void 0===e[s]?t[s]:t[s]||e[s],s+=1;return o}return 0}var add=sum;function sub(t,e){var r=typeof t,i=typeof e;if(isNumerable(r,t)&&isNumerable(i,e))return"string"==r&&(t=parseInt(t)),"string"==i&&(e=parseInt(e)),t-e;if($bm_isInstanceOfArray(t)&&isNumerable(i,e))return(t=t.slice(0))[0]=t[0]-e,t;if(isNumerable(r,t)&&$bm_isInstanceOfArray(e))return(e=e.slice(0))[0]=t-e[0],e;if($bm_isInstanceOfArray(t)&&$bm_isInstanceOfArray(e)){for(var s=0,a=t.length,n=e.length,o=[];s<a||s<n;)("number"==typeof t[s]||t[s]instanceof Number)&&("number"==typeof e[s]||e[s]instanceof Number)?o[s]=t[s]-e[s]:o[s]=void 0===e[s]?t[s]:t[s]||e[s],s+=1;return o}return 0}function mul(t,e){var r,i,s,a=typeof t,n=typeof e;if(isNumerable(a,t)&&isNumerable(n,e))return t*e;if($bm_isInstanceOfArray(t)&&isNumerable(n,e)){for(s=t.length,r=createTypedArray("float32",s),i=0;i<s;i+=1)r[i]=t[i]*e;return r}if(isNumerable(a,t)&&$bm_isInstanceOfArray(e)){for(s=e.length,r=createTypedArray("float32",s),i=0;i<s;i+=1)r[i]=t*e[i];return r}return 0}function div(t,e){var r,i,s,a=typeof t,n=typeof e;if(isNumerable(a,t)&&isNumerable(n,e))return t/e;if($bm_isInstanceOfArray(t)&&isNumerable(n,e)){for(s=t.length,r=createTypedArray("float32",s),i=0;i<s;i+=1)r[i]=t[i]/e;return r}if(isNumerable(a,t)&&$bm_isInstanceOfArray(e)){for(s=e.length,r=createTypedArray("float32",s),i=0;i<s;i+=1)r[i]=t/e[i];return r}return 0}function mod(t,e){return"string"==typeof t&&(t=parseInt(t)),"string"==typeof e&&(e=parseInt(e)),t%e}var $bm_sum=sum,$bm_sub=sub,$bm_mul=mul,$bm_div=div,$bm_mod=mod;function clamp(t,e,r){if(r<e){var i=r;r=e,e=i}return Math.min(Math.max(t,e),r)}function radiansToDegrees(t){return t/degToRads}var radians_to_degrees=radiansToDegrees;function degreesToRadians(t){return t*degToRads}var degrees_to_radians=radiansToDegrees,helperLengthArray=[0,0,0,0,0,0];function length(t,e){if("number"==typeof t||t instanceof Number)return e=e||0,Math.abs(t-e);e||(e=helperLengthArray);var r,i=Math.min(t.length,e.length),s=0;for(r=0;r<i;r+=1)s+=Math.pow(e[r]-t[r],2);return Math.sqrt(s)}function normalize(t){return div(t,length(t))}function rgbToHsl(t){var e,r,i=t[0],s=t[1],a=t[2],n=Math.max(i,s,a),o=Math.min(i,s,a),h=(n+o)/2;if(n==o)e=r=0;else{var p=n-o;switch(r=.5<h?p/(2-n-o):p/(n+o),n){case i:e=(s-a)/p+(s<a?6:0);break;case s:e=(a-i)/p+2;break;case a:e=(i-s)/p+4}e/=6}return[e,r,h,t[3]]}function hue2rgb(t,e,r){return r<0&&(r+=1),1<r&&(r-=1),r<1/6?t+6*(e-t)*r:r<.5?e:r<2/3?t+(e-t)*(2/3-r)*6:t}function hslToRgb(t){var e,r,i,s=t[0],a=t[1],n=t[2];if(0===a)e=r=i=n;else{var o=n<.5?n*(1+a):n+a-n*a,h=2*n-o;e=hue2rgb(h,o,s+1/3),r=hue2rgb(h,o,s),i=hue2rgb(h,o,s-1/3)}return[e,r,i,t[3]]}function linear(t,e,r,i,s){if(void 0!==i&&void 0!==s||(i=e,s=r,e=0,r=1),r<e){var a=r;r=e,e=a}if(t<=e)return i;if(r<=t)return s;var n=r===e?0:(t-e)/(r-e);if(!i.length)return i+(s-i)*n;var o,h=i.length,p=createTypedArray("float32",h);for(o=0;o<h;o+=1)p[o]=i[o]+(s[o]-i[o])*n;return p}function random(t,e){if(void 0===e&&(void 0===t?(t=0,e=1):(e=t,t=void 0)),e.length){var r,i=e.length;t||(t=createTypedArray("float32",i));var s=createTypedArray("float32",i),a=BMMath.random();for(r=0;r<i;r+=1)s[r]=t[r]+a*(e[r]-t[r]);return s}return void 0===t&&(t=0),t+BMMath.random()*(e-t)}function createPath(t,e,r,i){var s,a=t.length,n=shape_pool.newElement();n.setPathData(!!i,a);var o,h,p=[0,0];for(s=0;s<a;s+=1)o=e&&e[s]?e[s]:p,h=r&&r[s]?r[s]:p,n.setTripleAt(t[s][0],t[s][1],h[0]+t[s][0],h[1]+t[s][1],o[0]+t[s][0],o[1]+t[s][1],s,!0);return n}function initiateExpression(elem,data,property){var val=data.x,needsVelocity=/velocity(?![\w\d])/.test(val),_needsRandom=-1!==val.indexOf("random"),elemType=elem.data.ty,transform,$bm_transform,content,effect,thisProperty=property;thisProperty.valueAtTime=thisProperty.getValueAtTime,Object.defineProperty(thisProperty,"value",{get:function(){return thisProperty.v}}),elem.comp.frameDuration=1/elem.comp.globalData.frameRate,elem.comp.displayStartTime=0;var inPoint=elem.data.ip/elem.comp.globalData.frameRate,outPoint=elem.data.op/elem.comp.globalData.frameRate,width=elem.data.sw?elem.data.sw:0,height=elem.data.sh?elem.data.sh:0,name=elem.data.nm,loopIn,loop_in,loopOut,loop_out,smooth,toWorld,fromWorld,fromComp,toComp,fromCompToSurface,position,rotation,anchorPoint,scale,thisLayer,thisComp,mask,valueAtTime,velocityAtTime,__expression_functions=[],scoped_bm_rt;if(data.xf){var i,len=data.xf.length;for(i=0;i<len;i+=1)__expression_functions[i]=eval("(function(){ return "+data.xf[i]+"}())")}var expression_function=eval("[function _expression_function(){"+val+";scoped_bm_rt=$bm_rt}]")[0],numKeys=property.kf?data.k.length:0,active=!this.data||!0!==this.data.hd,wiggle=function(t,e){var r,i,s=this.pv.length?this.pv.length:1,a=createTypedArray("float32",s);var n=Math.floor(5*time);for(i=r=0;r<n;){for(i=0;i<s;i+=1)a[i]+=-e+2*e*BMMath.random();r+=1}var o=5*time,h=o-Math.floor(o),p=createTypedArray("float32",s);if(1<s){for(i=0;i<s;i+=1)p[i]=this.pv[i]+a[i]+(-e+2*e*BMMath.random())*h;return p}return this.pv+a[0]+(-e+2*e*BMMath.random())*h}.bind(this);function loopInDuration(t,e){return loopIn(t,e,!0)}function loopOutDuration(t,e){return loopOut(t,e,!0)}thisProperty.loopIn&&(loopIn=thisProperty.loopIn.bind(thisProperty),loop_in=loopIn),thisProperty.loopOut&&(loopOut=thisProperty.loopOut.bind(thisProperty),loop_out=loopOut),thisProperty.smooth&&(smooth=thisProperty.smooth.bind(thisProperty)),this.getValueAtTime&&(valueAtTime=this.getValueAtTime.bind(this)),this.getVelocityAtTime&&(velocityAtTime=this.getVelocityAtTime.bind(this));var comp=elem.comp.globalData.projectInterface.bind(elem.comp.globalData.projectInterface),time,velocity,value,text,textIndex,textTotal,selectorValue;function lookAt(t,e){var r=[e[0]-t[0],e[1]-t[1],e[2]-t[2]],i=Math.atan2(r[0],Math.sqrt(r[1]*r[1]+r[2]*r[2]))/degToRads;return[-Math.atan2(r[1],r[2])/degToRads,i,0]}function easeOut(t,e,r,i,s){return applyEase(easeOutBez,t,e,r,i,s)}function easeIn(t,e,r,i,s){return applyEase(easeInBez,t,e,r,i,s)}function ease(t,e,r,i,s){return applyEase(easeInOutBez,t,e,r,i,s)}function applyEase(t,e,r,i,s,a){void 0===s?(s=r,a=i):e=(e-r)/(i-r);var n=t(e=1<e?1:e<0?0:e);if($bm_isInstanceOfArray(s)){var o,h=s.length,p=createTypedArray("float32",h);for(o=0;o<h;o+=1)p[o]=(a[o]-s[o])*n+s[o];return p}return(a-s)*n+s}function nearestKey(t){var e,r,i,s=data.k.length;if(data.k.length&&"number"!=typeof data.k[0])if(r=-1,(t*=elem.comp.globalData.frameRate)<data.k[0].t)r=1,i=data.k[0].t;else{for(e=0;e<s-1;e+=1){if(t===data.k[e].t){r=e+1,i=data.k[e].t;break}if(t>data.k[e].t&&t<data.k[e+1].t){i=t-data.k[e].t>data.k[e+1].t-t?(r=e+2,data.k[e+1].t):(r=e+1,data.k[e].t);break}}-1===r&&(r=e+1,i=data.k[e].t)}else i=r=0;var a={};return a.index=r,a.time=i/elem.comp.globalData.frameRate,a}function key(t){var e,r,i,s;if(!data.k.length||"number"==typeof data.k[0])throw new Error("The property has no keyframe at index "+t);for(t-=1,e={time:data.k[t].t/elem.comp.globalData.frameRate,value:[]},i=(s=t!==data.k.length-1||data.k[t].h?data.k[t].s:data.k[t].s||0===data.k[t].s?data.k[t-1].s:data.k[t].e).length,r=0;r<i;r+=1)e[r]=s[r],e.value[r]=s[r];return e}function framesToTime(t,e){return e||(e=elem.comp.globalData.frameRate),t/e}function timeToFrames(t,e){return t||0===t||(t=time),e||(e=elem.comp.globalData.frameRate),t*e}function seedRandom(t){BMMath.seedrandom(randSeed+t)}function sourceRectAtTime(){return elem.sourceRectAtTime()}function substring(t,e){return"string"==typeof value?void 0===e?value.substring(t):value.substring(t,e):""}function substr(t,e){return"string"==typeof value?void 0===e?value.substr(t):value.substr(t,e):""}var index=elem.data.ind,hasParent=!(!elem.hierarchy||!elem.hierarchy.length),parent,randSeed=Math.floor(1e6*Math.random()),globalData=elem.globalData;function executeExpression(t){return value=t,_needsRandom&&seedRandom(randSeed),this.frameExpressionId===elem.globalData.frameId&&"textSelector"!==this.propType?value:("textSelector"===this.propType&&(textIndex=this.textIndex,textTotal=this.textTotal,selectorValue=this.selectorValue),thisLayer||(text=elem.layerInterface.text,thisLayer=elem.layerInterface,thisComp=elem.comp.compInterface,toWorld=thisLayer.toWorld.bind(thisLayer),fromWorld=thisLayer.fromWorld.bind(thisLayer),fromComp=thisLayer.fromComp.bind(thisLayer),toComp=thisLayer.toComp.bind(thisLayer),mask=thisLayer.mask?thisLayer.mask.bind(thisLayer):null,fromCompToSurface=fromComp),transform||(transform=elem.layerInterface("ADBE Transform Group"),($bm_transform=transform)&&(anchorPoint=transform.anchorPoint)),4!==elemType||content||(content=thisLayer("ADBE Root Vectors Group")),effect||(effect=thisLayer(4)),(hasParent=!(!elem.hierarchy||!elem.hierarchy.length))&&!parent&&(parent=elem.hierarchy[0].layerInterface),time=this.comp.renderedFrame/this.comp.globalData.frameRate,needsVelocity&&(velocity=velocityAtTime(time)),expression_function(),this.frameExpressionId=elem.globalData.frameId,"shape"===scoped_bm_rt.propType&&(scoped_bm_rt=scoped_bm_rt.v),scoped_bm_rt)}return executeExpression}return ob.initiateExpression=initiateExpression,ob}(),expressionHelpers={searchExpressions:function(t,e,r){e.x&&(r.k=!0,r.x=!0,r.initiateExpression=ExpressionManager.initiateExpression,r.effectsSequence.push(r.initiateExpression(t,e,r).bind(r)))},getSpeedAtTime:function(t){var e=this.getValueAtTime(t),r=this.getValueAtTime(t+-.01),i=0;if(e.length){var s;for(s=0;s<e.length;s+=1)i+=Math.pow(r[s]-e[s],2);i=100*Math.sqrt(i)}else i=0;return i},getVelocityAtTime:function(t){if(void 0!==this.vel)return this.vel;var e,r,i=this.getValueAtTime(t),s=this.getValueAtTime(t+-.001);if(i.length)for(e=createTypedArray("float32",i.length),r=0;r<i.length;r+=1)e[r]=(s[r]-i[r])/-.001;else e=(s-i)/-.001;return e},getValueAtTime:function(t){return t*=this.elem.globalData.frameRate,(t-=this.offsetTime)!==this._cachingAtTime.lastFrame&&(this._cachingAtTime.lastIndex=this._cachingAtTime.lastFrame<t?this._cachingAtTime.lastIndex:0,this._cachingAtTime.value=this.interpolateValue(t,this._cachingAtTime),this._cachingAtTime.lastFrame=t),this._cachingAtTime.value},getStaticValueAtTime:function(){return this.pv},setGroupProperty:function(t){this.propertyGroup=t}};!function(){function o(t,e,r){if(!this.k||!this.keyframes)return this.pv;t=t?t.toLowerCase():"";var i,s,a,n,o,h=this.comp.renderedFrame,p=this.keyframes,l=p[p.length-1].t;if(h<=l)return this.pv;if(r?s=l-(i=e?Math.abs(l-elem.comp.globalData.frameRate*e):Math.max(0,l-this.elem.data.ip)):((!e||e>p.length-1)&&(e=p.length-1),i=l-(s=p[p.length-1-e].t)),"pingpong"===t){if(Math.floor((h-s)/i)%2!=0)return this.getValueAtTime((i-(h-s)%i+s)/this.comp.globalData.frameRate,0)}else{if("offset"===t){var m=this.getValueAtTime(s/this.comp.globalData.frameRate,0),f=this.getValueAtTime(l/this.comp.globalData.frameRate,0),c=this.getValueAtTime(((h-s)%i+s)/this.comp.globalData.frameRate,0),d=Math.floor((h-s)/i);if(this.pv.length){for(n=(o=new Array(m.length)).length,a=0;a<n;a+=1)o[a]=(f[a]-m[a])*d+c[a];return o}return(f-m)*d+c}if("continue"===t){var u=this.getValueAtTime(l/this.comp.globalData.frameRate,0),y=this.getValueAtTime((l-.001)/this.comp.globalData.frameRate,0);if(this.pv.length){for(n=(o=new Array(u.length)).length,a=0;a<n;a+=1)o[a]=u[a]+(u[a]-y[a])*((h-l)/this.comp.globalData.frameRate)/5e-4;return o}return u+(h-l)/.001*(u-y)}}return this.getValueAtTime(((h-s)%i+s)/this.comp.globalData.frameRate,0)}function h(t,e,r){if(!this.k)return this.pv;t=t?t.toLowerCase():"";var i,s,a,n,o,h=this.comp.renderedFrame,p=this.keyframes,l=p[0].t;if(l<=h)return this.pv;if(r?s=l+(i=e?Math.abs(elem.comp.globalData.frameRate*e):Math.max(0,this.elem.data.op-l)):((!e||e>p.length-1)&&(e=p.length-1),i=(s=p[e].t)-l),"pingpong"===t){if(Math.floor((l-h)/i)%2==0)return this.getValueAtTime(((l-h)%i+l)/this.comp.globalData.frameRate,0)}else{if("offset"===t){var m=this.getValueAtTime(l/this.comp.globalData.frameRate,0),f=this.getValueAtTime(s/this.comp.globalData.frameRate,0),c=this.getValueAtTime((i-(l-h)%i+l)/this.comp.globalData.frameRate,0),d=Math.floor((l-h)/i)+1;if(this.pv.length){for(n=(o=new Array(m.length)).length,a=0;a<n;a+=1)o[a]=c[a]-(f[a]-m[a])*d;return o}return c-(f-m)*d}if("continue"===t){var u=this.getValueAtTime(l/this.comp.globalData.frameRate,0),y=this.getValueAtTime((l+.001)/this.comp.globalData.frameRate,0);if(this.pv.length){for(n=(o=new Array(u.length)).length,a=0;a<n;a+=1)o[a]=u[a]+(u[a]-y[a])*(l-h)/.001;return o}return u+(u-y)*(l-h)/.001}}return this.getValueAtTime((i-(l-h)%i+l)/this.comp.globalData.frameRate,0)}function p(t,e){if(!this.k)return this.pv;if(t=.5*(t||.4),(e=Math.floor(e||5))<=1)return this.pv;var r,i,s=this.comp.renderedFrame/this.comp.globalData.frameRate,a=s-t,n=1<e?(s+t-a)/(e-1):1,o=0,h=0;for(r=this.pv.length?createTypedArray("float32",this.pv.length):0;o<e;){if(i=this.getValueAtTime(a+o*n),this.pv.length)for(h=0;h<this.pv.length;h+=1)r[h]+=i[h];else r+=i;o+=1}if(this.pv.length)for(h=0;h<this.pv.length;h+=1)r[h]/=e;else r/=e;return r}var s=TransformPropertyFactory.getTransformProperty;TransformPropertyFactory.getTransformProperty=function(t,e,r){var i=s(t,e,r);return i.dynamicProperties.length?i.getValueAtTime=function(t){console.warn("Transform at time not supported")}.bind(i):i.getValueAtTime=function(t){}.bind(i),i.setGroupProperty=expressionHelpers.setGroupProperty,i};var l=PropertyFactory.getProp;PropertyFactory.getProp=function(t,e,r,i,s){var a=l(t,e,r,i,s);a.kf?a.getValueAtTime=expressionHelpers.getValueAtTime.bind(a):a.getValueAtTime=expressionHelpers.getStaticValueAtTime.bind(a),a.setGroupProperty=expressionHelpers.setGroupProperty,a.loopOut=o,a.loopIn=h,a.smooth=p,a.getVelocityAtTime=expressionHelpers.getVelocityAtTime.bind(a),a.getSpeedAtTime=expressionHelpers.getSpeedAtTime.bind(a),a.numKeys=1===e.a?e.k.length:0,a.propertyIndex=e.ix;var n=0;return 0!==r&&(n=createTypedArray("float32",1===e.a?e.k[0].s.length:e.k.length)),a._cachingAtTime={lastFrame:initialDefaultFrame,lastIndex:0,value:n},expressionHelpers.searchExpressions(t,e,a),a.k&&s.addDynamicProperty(a),a};var t=ShapePropertyFactory.getConstructorFunction(),e=ShapePropertyFactory.getKeyframedConstructorFunction();function r(){}r.prototype={vertices:function(t,e){this.k&&this.getValue();var r=this.v;void 0!==e&&(r=this.getValueAtTime(e,0));var i,s=r._length,a=r[t],n=r.v,o=createSizedArray(s);for(i=0;i<s;i+=1)o[i]="i"===t||"o"===t?[a[i][0]-n[i][0],a[i][1]-n[i][1]]:[a[i][0],a[i][1]];return o},points:function(t){return this.vertices("v",t)},inTangents:function(t){return this.vertices("i",t)},outTangents:function(t){return this.vertices("o",t)},isClosed:function(){return this.v.c},pointOnPath:function(t,e){var r=this.v;void 0!==e&&(r=this.getValueAtTime(e,0)),this._segmentsLength||(this._segmentsLength=bez.getSegmentsLength(r));for(var i,s=this._segmentsLength,a=s.lengths,n=s.totalLength*t,o=0,h=a.length,p=0;o<h;){if(p+a[o].addedLength>n){var l=o,m=r.c&&o===h-1?0:o+1,f=(n-p)/a[o].addedLength;i=bez.getPointInSegment(r.v[l],r.v[m],r.o[l],r.i[m],f,a[o]);break}p+=a[o].addedLength,o+=1}return i||(i=r.c?[r.v[0][0],r.v[0][1]]:[r.v[r._length-1][0],r.v[r._length-1][1]]),i},vectorOnPath:function(t,e,r){t=1==t?this.v.c?0:.999:t;var i=this.pointOnPath(t,e),s=this.pointOnPath(t+.001,e),a=s[0]-i[0],n=s[1]-i[1],o=Math.sqrt(Math.pow(a,2)+Math.pow(n,2));return"tangent"===r?[a/o,n/o]:[-n/o,a/o]},tangentOnPath:function(t,e){return this.vectorOnPath(t,e,"tangent")},normalOnPath:function(t,e){return this.vectorOnPath(t,e,"normal")},setGroupProperty:expressionHelpers.setGroupProperty,getValueAtTime:expressionHelpers.getStaticValueAtTime},extendPrototype([r],t),extendPrototype([r],e),e.prototype.getValueAtTime=function(t){return this._cachingAtTime||(this._cachingAtTime={shapeValue:shape_pool.clone(this.pv),lastIndex:0,lastTime:initialDefaultFrame}),t*=this.elem.globalData.frameRate,(t-=this.offsetTime)!==this._cachingAtTime.lastTime&&(this._cachingAtTime.lastIndex=this._cachingAtTime.lastTime<t?this._caching.lastIndex:0,this._cachingAtTime.lastTime=t,this.interpolateShape(t,this._cachingAtTime.shapeValue,this._cachingAtTime)),this._cachingAtTime.shapeValue},e.prototype.initiateExpression=ExpressionManager.initiateExpression;var n=ShapePropertyFactory.getShapeProp;ShapePropertyFactory.getShapeProp=function(t,e,r,i,s){var a=n(t,e,r,i,s);return a.propertyIndex=e.ix,a.lock=!1,3===r?expressionHelpers.searchExpressions(t,e.pt,a):4===r&&expressionHelpers.searchExpressions(t,e.ks,a),a.k&&t.addDynamicProperty(a),a}}(),TextProperty.prototype.getExpressionValue=function(t,e){var r=this.calculateExpression(e);if(t.t===r)return t;var i={};return this.copyData(i,t),i.t=r.toString(),i.__complete=!1,i},TextProperty.prototype.searchProperty=function(){var t=this.searchKeyframes(),e=this.searchExpressions();return this.kf=t||e,this.kf},TextProperty.prototype.searchExpressions=function(){if(this.data.d.x)return this.calculateExpression=ExpressionManager.initiateExpression.bind(this)(this.elem,this.data.d,this),this.addEffect(this.getExpressionValue.bind(this)),!0};var ShapeExpressionInterface=function(t,e,r){var i;function s(t){if("number"==typeof t)return i[t-1];for(var e=0,r=i.length;e<r;){if(i[e]._name===t)return i[e];e+=1}}return s.propertyGroup=r,i=DT(t,e,s),s.numProperties=i.length,s};function DT(t,e,r){var i,s=[],a=t?t.length:0;for(i=0;i<a;i+=1)"gr"==t[i].ty?s.push(FT(t[i],e[i],r)):"fl"==t[i].ty?s.push(GT(t[i],e[i],r)):"st"==t[i].ty?s.push(HT(t[i],e[i],r)):"tm"==t[i].ty?s.push(IT(t[i],e[i],r)):"tr"==t[i].ty||("el"==t[i].ty?s.push(KT(t[i],e[i],r)):"sr"==t[i].ty?s.push(LT(t[i],e[i],r)):"sh"==t[i].ty?s.push(PT(t[i],e[i],r)):"rc"==t[i].ty?s.push(MT(t[i],e[i],r)):"rd"==t[i].ty?s.push(NT(t[i],e[i],r)):"rp"==t[i].ty&&s.push(OT(t[i],e[i],r)));return s}function FT(t,e,r){var i=function(t){switch(t){case"ADBE Vectors Group":case"Contents":case 2:return i.content;default:return i.transform}};i.propertyGroup=function(t){return 1===t?i:r(t-1)};var s=function(t,e,r){function i(t){for(var e=0,r=s.length;e<r;){if(s[e]._name===t||s[e].mn===t||s[e].propertyIndex===t||s[e].ix===t||s[e].ind===t)return s[e];e+=1}if("number"==typeof t)return s[t-1]}var s;return i.propertyGroup=function(t){return 1===t?i:r(t-1)},s=DT(t.it,e.it,i.propertyGroup),i.numProperties=s.length,i.propertyIndex=t.cix,i._name=t.nm,i}(t,e,i.propertyGroup),a=function(e,t,r){function i(t){return 1==t?s:r(--t)}t.transform.mProps.o.setGroupProperty(i),t.transform.mProps.p.setGroupProperty(i),t.transform.mProps.a.setGroupProperty(i),t.transform.mProps.s.setGroupProperty(i),t.transform.mProps.r.setGroupProperty(i),t.transform.mProps.sk&&(t.transform.mProps.sk.setGroupProperty(i),t.transform.mProps.sa.setGroupProperty(i));function s(t){return e.a.ix===t||"Anchor Point"===t?s.anchorPoint:e.o.ix===t||"Opacity"===t?s.opacity:e.p.ix===t||"Position"===t?s.position:e.r.ix===t||"Rotation"===t||"ADBE Vector Rotation"===t?s.rotation:e.s.ix===t||"Scale"===t?s.scale:e.sk&&e.sk.ix===t||"Skew"===t?s.skew:e.sa&&e.sa.ix===t||"Skew Axis"===t?s.skewAxis:void 0}return t.transform.op.setGroupProperty(i),Object.defineProperties(s,{opacity:{get:ExpressionPropertyInterface(t.transform.mProps.o)},position:{get:ExpressionPropertyInterface(t.transform.mProps.p)},anchorPoint:{get:ExpressionPropertyInterface(t.transform.mProps.a)},scale:{get:ExpressionPropertyInterface(t.transform.mProps.s)},rotation:{get:ExpressionPropertyInterface(t.transform.mProps.r)},skew:{get:ExpressionPropertyInterface(t.transform.mProps.sk)},skewAxis:{get:ExpressionPropertyInterface(t.transform.mProps.sa)},_name:{value:e.nm}}),s.ty="tr",s.mn=e.mn,s.propertyGroup=r,s}(t.it[t.it.length-1],e.it[e.it.length-1],i.propertyGroup);return i.content=s,i.transform=a,Object.defineProperty(i,"_name",{get:function(){return t.nm}}),i.numProperties=t.np,i.propertyIndex=t.ix,i.nm=t.nm,i.mn=t.mn,i}function GT(t,e,r){function i(t){return"Color"===t||"color"===t?i.color:"Opacity"===t||"opacity"===t?i.opacity:void 0}return Object.defineProperties(i,{color:{get:ExpressionPropertyInterface(e.c)},opacity:{get:ExpressionPropertyInterface(e.o)},_name:{value:t.nm},mn:{value:t.mn}}),e.c.setGroupProperty(r),e.o.setGroupProperty(r),i}function HT(t,e,r){function i(t){return 1===t?ob:r(t-1)}function s(t){return 1===t?h:i(t-1)}var a,n,o=t.d?t.d.length:0,h={};for(a=0;a<o;a+=1)n=a,Object.defineProperty(h,t.d[n].nm,{get:ExpressionPropertyInterface(e.d.dataProps[n].p)}),e.d.dataProps[a].p.setGroupProperty(s);function p(t){return"Color"===t||"color"===t?p.color:"Opacity"===t||"opacity"===t?p.opacity:"Stroke Width"===t||"stroke width"===t?p.strokeWidth:void 0}return Object.defineProperties(p,{color:{get:ExpressionPropertyInterface(e.c)},opacity:{get:ExpressionPropertyInterface(e.o)},strokeWidth:{get:ExpressionPropertyInterface(e.w)},dash:{get:function(){return h}},_name:{value:t.nm},mn:{value:t.mn}}),e.c.setGroupProperty(i),e.o.setGroupProperty(i),e.w.setGroupProperty(i),p}function IT(e,t,r){function i(t){return 1==t?s:r(--t)}function s(t){return t===e.e.ix||"End"===t||"end"===t?s.end:t===e.s.ix?s.start:t===e.o.ix?s.offset:void 0}return s.propertyIndex=e.ix,t.s.setGroupProperty(i),t.e.setGroupProperty(i),t.o.setGroupProperty(i),s.propertyIndex=e.ix,s.propertyGroup=r,Object.defineProperties(s,{start:{get:ExpressionPropertyInterface(t.s)},end:{get:ExpressionPropertyInterface(t.e)},offset:{get:ExpressionPropertyInterface(t.o)},_name:{value:e.nm}}),s.mn=e.mn,s}function KT(e,t,r){function i(t){return 1==t?a:r(--t)}a.propertyIndex=e.ix;var s="tm"===t.sh.ty?t.sh.prop:t.sh;function a(t){return e.p.ix===t?a.position:e.s.ix===t?a.size:void 0}return s.s.setGroupProperty(i),s.p.setGroupProperty(i),Object.defineProperties(a,{size:{get:ExpressionPropertyInterface(s.s)},position:{get:ExpressionPropertyInterface(s.p)},_name:{value:e.nm}}),a.mn=e.mn,a}function LT(e,t,r){function i(t){return 1==t?a:r(--t)}var s="tm"===t.sh.ty?t.sh.prop:t.sh;function a(t){return e.p.ix===t?a.position:e.r.ix===t?a.rotation:e.pt.ix===t?a.points:e.or.ix===t||"ADBE Vector Star Outer Radius"===t?a.outerRadius:e.os.ix===t?a.outerRoundness:!e.ir||e.ir.ix!==t&&"ADBE Vector Star Inner Radius"!==t?e.is&&e.is.ix===t?a.innerRoundness:void 0:a.innerRadius}return a.propertyIndex=e.ix,s.or.setGroupProperty(i),s.os.setGroupProperty(i),s.pt.setGroupProperty(i),s.p.setGroupProperty(i),s.r.setGroupProperty(i),e.ir&&(s.ir.setGroupProperty(i),s.is.setGroupProperty(i)),Object.defineProperties(a,{position:{get:ExpressionPropertyInterface(s.p)},rotation:{get:ExpressionPropertyInterface(s.r)},points:{get:ExpressionPropertyInterface(s.pt)},outerRadius:{get:ExpressionPropertyInterface(s.or)},outerRoundness:{get:ExpressionPropertyInterface(s.os)},innerRadius:{get:ExpressionPropertyInterface(s.ir)},innerRoundness:{get:ExpressionPropertyInterface(s.is)},_name:{value:e.nm}}),a.mn=e.mn,a}function MT(e,t,r){function i(t){return 1==t?a:r(--t)}var s="tm"===t.sh.ty?t.sh.prop:t.sh;function a(t){return e.p.ix===t?a.position:e.r.ix===t?a.roundness:e.s.ix===t||"Size"===t||"ADBE Vector Rect Size"===t?a.size:void 0}return a.propertyIndex=e.ix,s.p.setGroupProperty(i),s.s.setGroupProperty(i),s.r.setGroupProperty(i),Object.defineProperties(a,{position:{get:ExpressionPropertyInterface(s.p)},roundness:{get:ExpressionPropertyInterface(s.r)},size:{get:ExpressionPropertyInterface(s.s)},_name:{value:e.nm}}),a.mn=e.mn,a}function NT(e,t,r){var i=t;function s(t){if(e.r.ix===t||"Round Corners 1"===t)return s.radius}return s.propertyIndex=e.ix,i.rd.setGroupProperty(function(t){return 1==t?s:r(--t)}),Object.defineProperties(s,{radius:{get:ExpressionPropertyInterface(i.rd)},_name:{value:e.nm}}),s.mn=e.mn,s}function OT(e,t,r){function i(t){return 1==t?a:r(--t)}var s=t;function a(t){return e.c.ix===t||"Copies"===t?a.copies:e.o.ix===t||"Offset"===t?a.offset:void 0}return a.propertyIndex=e.ix,s.c.setGroupProperty(i),s.o.setGroupProperty(i),Object.defineProperties(a,{copies:{get:ExpressionPropertyInterface(s.c)},offset:{get:ExpressionPropertyInterface(s.o)},_name:{value:e.nm}}),a.mn=e.mn,a}function PT(t,e,r){var i=e.sh;function s(t){if("Shape"===t||"shape"===t||"Path"===t||"path"===t||"ADBE Vector Shape"===t||2===t)return s.path}return i.setGroupProperty(function(t){return 1==t?s:r(--t)}),Object.defineProperties(s,{path:{get:function(){return i.k&&i.getValue(),i}},shape:{get:function(){return i.k&&i.getValue(),i}},_name:{value:t.nm},ix:{value:t.ix},mn:{value:t.mn}}),s}var TextExpressionInterface=function(e){var r;function t(){}return Object.defineProperty(t,"sourceText",{get:function(){e.textProperty.getValue();var t=e.textProperty.currentData.t;return void 0!==t&&(e.textProperty.currentData.t=void 0,(r=new String(t)).value=t||new String(t)),r}}),t},LayerExpressionInterface=function(e){var r;function i(t){switch(t){case"ADBE Root Vectors Group":case"Contents":case 2:return i.shapeInterface;case 1:case 6:case"Transform":case"transform":case"ADBE Transform Group":return r;case 4:case"ADBE Effect Parade":case"effects":case"Effects":return i.effect}}i.toWorld=_V,i.fromWorld=aW,i.toComp=_V,i.fromComp=bW,i.sampleImage=cW,i.sourceRectAtTime=e.sourceRectAtTime.bind(e);var t=getDescriptor(r=TransformExpressionInterface((i._elem=e).finalTransform.mProp),"anchorPoint");return Object.defineProperties(i,{hasParent:{get:function(){return e.hierarchy.length}},parent:{get:function(){return e.hierarchy[0].layerInterface}},rotation:getDescriptor(r,"rotation"),scale:getDescriptor(r,"scale"),position:getDescriptor(r,"position"),opacity:getDescriptor(r,"opacity"),anchorPoint:t,anchor_point:t,transform:{get:function(){return r}},active:{get:function(){return e.isInRange}}}),i.startTime=e.data.st,i.index=e.data.ind,i.source=e.data.refId,i.height=0===e.data.ty?e.data.h:100,i.width=0===e.data.ty?e.data.w:100,i.inPoint=e.data.ip/e.comp.globalData.frameRate,i.outPoint=e.data.op/e.comp.globalData.frameRate,i._name=e.data.nm,i.registerMaskInterface=function(t){i.mask=new MaskManagerInterface(t,e)},i.registerEffectsInterface=function(t){i.effect=t},i};function _V(t,e){var r=new Matrix;if(r.reset(),this._elem.finalTransform.mProp.applyToMatrix(r),this._elem.hierarchy&&this._elem.hierarchy.length){var i,s=this._elem.hierarchy.length;for(i=0;i<s;i+=1)this._elem.hierarchy[i].finalTransform.mProp.applyToMatrix(r);return r.applyToPointArray(t[0],t[1],t[2]||0)}return r.applyToPointArray(t[0],t[1],t[2]||0)}function aW(t,e){var r=new Matrix;if(r.reset(),this._elem.finalTransform.mProp.applyToMatrix(r),this._elem.hierarchy&&this._elem.hierarchy.length){var i,s=this._elem.hierarchy.length;for(i=0;i<s;i+=1)this._elem.hierarchy[i].finalTransform.mProp.applyToMatrix(r);return r.inversePoint(t)}return r.inversePoint(t)}function bW(t){var e=new Matrix;if(e.reset(),this._elem.finalTransform.mProp.applyToMatrix(e),this._elem.hierarchy&&this._elem.hierarchy.length){var r,i=this._elem.hierarchy.length;for(r=0;r<i;r+=1)this._elem.hierarchy[r].finalTransform.mProp.applyToMatrix(e);return e.inversePoint(t)}return e.inversePoint(t)}function cW(){return[1,1,1,1]}var CompExpressionInterface=function(i){function t(t){for(var e=0,r=i.layers.length;e<r;){if(i.layers[e].nm===t||i.layers[e].ind===t)return i.elements[e].layerInterface;e+=1}return null}return Object.defineProperty(t,"_name",{value:i.data.nm}),(t.layer=t).pixelAspect=1,t.height=i.data.h||i.globalData.compSize.h,t.width=i.data.w||i.globalData.compSize.w,t.pixelAspect=1,t.frameDuration=1/i.globalData.frameRate,t.displayStartTime=0,t.numLayers=i.layers.length,t},TransformExpressionInterface=function(t){function e(t){switch(t){case"scale":case"Scale":case"ADBE Scale":case 6:return e.scale;case"rotation":case"Rotation":case"ADBE Rotation":case"ADBE Rotate Z":case 10:return e.rotation;case"ADBE Rotate X":return e.xRotation;case"ADBE Rotate Y":return e.yRotation;case"position":case"Position":case"ADBE Position":case 2:return e.position;case"ADBE Position_0":return e.xPosition;case"ADBE Position_1":return e.yPosition;case"ADBE Position_2":return e.zPosition;case"anchorPoint":case"AnchorPoint":case"Anchor Point":case"ADBE AnchorPoint":case 1:return e.anchorPoint;case"opacity":case"Opacity":case 11:return e.opacity}}if(Object.defineProperty(e,"rotation",{get:ExpressionPropertyInterface(t.r||t.rz)}),Object.defineProperty(e,"zRotation",{get:ExpressionPropertyInterface(t.rz||t.r)}),Object.defineProperty(e,"xRotation",{get:ExpressionPropertyInterface(t.rx)}),Object.defineProperty(e,"yRotation",{get:ExpressionPropertyInterface(t.ry)}),Object.defineProperty(e,"scale",{get:ExpressionPropertyInterface(t.s)}),t.p)var r=ExpressionPropertyInterface(t.p);return Object.defineProperty(e,"position",{get:function(){return t.p?r():[t.px.v,t.py.v,t.pz?t.pz.v:0]}}),Object.defineProperty(e,"xPosition",{get:ExpressionPropertyInterface(t.px)}),Object.defineProperty(e,"yPosition",{get:ExpressionPropertyInterface(t.py)}),Object.defineProperty(e,"zPosition",{get:ExpressionPropertyInterface(t.pz)}),Object.defineProperty(e,"anchorPoint",{get:ExpressionPropertyInterface(t.a)}),Object.defineProperty(e,"opacity",{get:ExpressionPropertyInterface(t.o)}),Object.defineProperty(e,"skew",{get:ExpressionPropertyInterface(t.sk)}),Object.defineProperty(e,"skewAxis",{get:ExpressionPropertyInterface(t.sa)}),Object.defineProperty(e,"orientation",{get:ExpressionPropertyInterface(t.or)}),e},ProjectInterface=function(){function t(t){for(var e=0,r=this.compositions.length;e<r;){if(this.compositions[e].data&&this.compositions[e].data.nm===t)return this.compositions[e].prepareFrame&&this.compositions[e].data.xt&&this.compositions[e].prepareFrame(this.currentFrame),this.compositions[e].compInterface;e+=1}}return t.compositions=[],t.currentFrame=0,t.registerComposition=LW,t};function LW(t){this.compositions.push(t)}var EffectsExpressionInterface={createEffectsInterface:function(s,t){if(s.effectsManager){var e,a=[],r=s.data.ef,i=s.effectsManager.effectElements.length;for(e=0;e<i;e+=1)a.push(TW(r[e],s.effectsManager.effectElements[e],t,s));return function(t){for(var e=s.data.ef||[],r=0,i=e.length;r<i;){if(t===e[r].nm||t===e[r].mn||t===e[r].ix)return a[r];r+=1}}}}};function TW(s,t,e,r){var i,a=[],n=s.ef.length;for(i=0;i<n;i+=1)5===s.ef[i].ty?a.push(TW(s.ef[i],t.effectElements[i],t.effectElements[i].propertyGroup,r)):a.push(UW(t.effectElements[i],s.ef[i].ty,r,o));function o(t){return 1===t?h:e(t-1)}var h=function(t){for(var e=s.ef,r=0,i=e.length;r<i;){if(t===e[r].nm||t===e[r].mn||t===e[r].ix)return 5===e[r].ty?a[r]:a[r]();r+=1}return a[0]()};return h.propertyGroup=o,"ADBE Color Control"===s.mn&&Object.defineProperty(h,"color",{get:function(){return a[0]()}}),Object.defineProperty(h,"numProperties",{get:function(){return s.np}}),h.active=h.enabled=0!==s.en,h}function UW(t,e,r,i){var s=ExpressionPropertyInterface(t.p);return t.p.setGroupProperty&&t.p.setGroupProperty(i),function(){return 10===e?r.comp.compInterface(t.p.v):s()}}var MaskManagerInterface=function(){function a(t,e){this._mask=t,this._data=e}Object.defineProperty(a.prototype,"maskPath",{get:function(){return this._mask.prop.k&&this._mask.prop.getValue(),this._mask.prop}});return function(e,t){var r,i=createSizedArray(e.viewData.length),s=e.viewData.length;for(r=0;r<s;r+=1)i[r]=new a(e.viewData[r],e.masksProperties[r]);return function(t){for(r=0;r<s;){if(e.masksProperties[r].nm===t)return i[r];r+=1}}}}(),ExpressionPropertyInterface=(KX={pv:0,v:0,mult:1},LX={pv:[0,0,0],v:[0,0,0],mult:1},function(t){return t?"unidimensional"===t.propType?function(t){t&&"pv"in t||(t=KX);var e=1/t.mult,r=t.pv*e,i=new Number(r);return i.value=r,MX(i,t,"unidimensional"),function(){return t.k&&t.getValue(),r=t.v*e,i.value!==r&&((i=new Number(r)).value=r,MX(i,t,"unidimensional")),i}}(t):function(e){e&&"pv"in e||(e=LX);var r=1/e.mult,i=e.pv.length,s=createTypedArray("float32",i),a=createTypedArray("float32",i);return s.value=a,MX(s,e,"multidimensional"),function(){e.k&&e.getValue();for(var t=0;t<i;t+=1)s[t]=a[t]=e.v[t]*r;return s}}(t):PX}),KX,LX,fY,gY;function MX(i,s,a){Object.defineProperty(i,"velocity",{get:function(){return s.getVelocityAtTime(s.comp.currentFrame)}}),i.numKeys=s.keyframes?s.keyframes.length:0,i.key=function(t){if(i.numKeys){var e="";e="s"in s.keyframes[t-1]?s.keyframes[t-1].s:"e"in s.keyframes[t-2]?s.keyframes[t-2].e:s.keyframes[t-2].s;var r="unidimensional"===a?new Number(e):Object.assign({},e);return r.time=s.keyframes[t-1].t/s.elem.comp.globalData.frameRate,r}return 0},i.valueAtTime=s.getValueAtTime,i.speedAtTime=s.getSpeedAtTime,i.velocityAtTime=s.getVelocityAtTime,i.propertyGroup=s.propertyGroup}function PX(){return KX}function hY(t,e){return this.textIndex=t+1,this.textTotal=e,this.v=this.getValue()*this.mult,this.v}function SliderEffect(t,e,r){this.p=PropertyFactory.getProp(e,t.v,0,0,r)}function AngleEffect(t,e,r){this.p=PropertyFactory.getProp(e,t.v,0,0,r)}function ColorEffect(t,e,r){this.p=PropertyFactory.getProp(e,t.v,1,0,r)}function PointEffect(t,e,r){this.p=PropertyFactory.getProp(e,t.v,1,0,r)}function LayerIndexEffect(t,e,r){this.p=PropertyFactory.getProp(e,t.v,0,0,r)}function MaskIndexEffect(t,e,r){this.p=PropertyFactory.getProp(e,t.v,0,0,r)}function CheckboxEffect(t,e,r){this.p=PropertyFactory.getProp(e,t.v,0,0,r)}function NoValueEffect(){this.p={}}function EffectsManager(t,e){var r=t.ef||[];this.effectElements=[];var i,s,a=r.length;for(i=0;i<a;i++)s=new GroupEffect(r[i],e),this.effectElements.push(s)}function GroupEffect(t,e){this.init(t,e)}fY=function(t,e){this.pv=1,this.comp=t.comp,this.elem=t,this.mult=.01,this.propType="textSelector",this.textTotal=e.totalChars,this.selectorValue=100,this.lastValue=[1,1,1],this.k=!0,this.x=!0,this.getValue=ExpressionManager.initiateExpression.bind(this)(t,e,this),this.getMult=hY,this.getVelocityAtTime=expressionHelpers.getVelocityAtTime,this.kf?this.getValueAtTime=expressionHelpers.getValueAtTime.bind(this):this.getValueAtTime=expressionHelpers.getStaticValueAtTime.bind(this),this.setGroupProperty=expressionHelpers.setGroupProperty},gY=TextSelectorProp.getTextSelectorProp,TextSelectorProp.getTextSelectorProp=function(t,e,r){return 1===e.t?new fY(t,e,r):gY(t,e,r)},extendPrototype([DynamicPropertyContainer],GroupEffect),GroupEffect.prototype.getValue=GroupEffect.prototype.iterateDynamicProperties,GroupEffect.prototype.init=function(t,e){this.data=t,this.effectElements=[],this.initDynamicPropertyContainer(e);var r,i,s=this.data.ef.length,a=this.data.ef;for(r=0;r<s;r+=1){switch(i=null,a[r].ty){case 0:i=new SliderEffect(a[r],e,this);break;case 1:i=new AngleEffect(a[r],e,this);break;case 2:i=new ColorEffect(a[r],e,this);break;case 3:i=new PointEffect(a[r],e,this);break;case 4:case 7:i=new CheckboxEffect(a[r],e,this);break;case 10:i=new LayerIndexEffect(a[r],e,this);break;case 11:i=new MaskIndexEffect(a[r],e,this);break;case 5:i=new EffectsManager(a[r],e,this);break;default:i=new NoValueEffect(a[r],e,this)}i&&this.effectElements.push(i)}};var lottiejs={},_isFrozen=!1;function loadAnimation(t){return animationManager.loadAnimation(t)}function setQuality(t){if("string"==typeof t)switch(t){case"high":defaultCurveSegments=200;break;case"medium":defaultCurveSegments=50;break;case"low":defaultCurveSegments=10}else!isNaN(t)&&1<t&&(defaultCurveSegments=t);roundValues(!(50<=defaultCurveSegments))}lottiejs.play=animationManager.play,lottiejs.pause=animationManager.pause,lottiejs.togglePause=animationManager.togglePause,lottiejs.setSpeed=animationManager.setSpeed,lottiejs.setDirection=animationManager.setDirection,lottiejs.stop=animationManager.stop,lottiejs.registerAnimation=animationManager.registerAnimation,lottiejs.loadAnimation=loadAnimation,lottiejs.resize=animationManager.resize,lottiejs.goToAndStop=animationManager.goToAndStop,lottiejs.destroy=animationManager.destroy,lottiejs.setQuality=setQuality,lottiejs.freeze=animationManager.freeze,lottiejs.unfreeze=animationManager.unfreeze,lottiejs.getRegisteredAnimations=animationManager.getRegisteredAnimations,lottiejs.version="5.5.2";var renderer="";return lottiejs}({}),currentAnimation=null,events={INITIALIZED:"initialized",RESIZED:"resized",PLAYING:"playing"};getCurrentCanvasSize=function(){var t=currentAnimation.renderer.canvasContext.canvas;return{height:t.height,width:t.width}},sendResizeEvent=function(){currentAnimation.renderer.canvasContext.canvas;postMessage({name:events.RESIZED,size:getCurrentCanvasSize()})},sendPlayEvent=function(){postMessage({name:events.PLAYING})},sendInitializedEvent=function(){currentAnimation.renderer.canvasContext.canvas;postMessage({name:events.INITIALIZED,success:currentAnimation.isLoaded})},initAnimation=function(t,e,r){if(!currentAnimation&&t&&e){var i=r.getContext("2d");currentAnimation=lottiejs.loadAnimation({renderer:"canvas",loop:e.loop,autoplay:e.autoplay,animationData:t,rendererSettings:{context:i,scaleMode:"noScale",clearCanvas:!0}}),sendInitializedEvent(),e.autoplay&&currentAnimation.play(),currentAnimation.isLoaded&&!currentAnimation.isPaused&&sendPlayEvent()}},updateCanvasSize=function(t,e){e&&t&&(0<e.height&&0<e.width&&(t.height=e.height,t.width=e.width),currentAnimation&&(currentAnimation.resize(),sendResizeEvent()))},onmessage=function(t){if(t&&t.data){var e=null;if(currentAnimation)e=currentAnimation.renderer.canvasContext.canvas;else{if(!t.data.canvas)return;e=t.data.canvas}updateCanvasSize(e,t.data.drawSize),initAnimation(t.data.animationData,t.data.params,e)}};
\ No newline at end of file
+var lottiejs=function(window){"use strict";var svgNS="http://www.w3.org/2000/svg",locationHref="",initialDefaultFrame=-999999,subframeEnabled=!0,expressionsPlugin,isSafari=/^((?!chrome|android).)*safari/i.test(navigator.userAgent),cachedColors={},bm_rounder=Math.round,bm_rnd,bm_pow=Math.pow,bm_sqrt=Math.sqrt,bm_abs=Math.abs,bm_floor=Math.floor,bm_max=Math.max,bm_min=Math.min,blitter=10,BMMath={};function ProjectInterface(){return{}}!function(){var t,e=["abs","acos","acosh","asin","asinh","atan","atanh","atan2","ceil","cbrt","expm1","clz32","cos","cosh","exp","floor","fround","hypot","imul","log","log1p","log2","log10","max","min","pow","random","round","sign","sin","sinh","sqrt","tan","tanh","trunc","E","LN10","LN2","LOG10E","LOG2E","PI","SQRT1_2","SQRT2"],r=e.length;for(t=0;t<r;t+=1)BMMath[e[t]]=Math[e[t]]}(),BMMath.random=Math.random,BMMath.abs=function(t){if("object"==typeof t&&t.length){var e,r=createSizedArray(t.length),i=t.length;for(e=0;e<i;e+=1)r[e]=Math.abs(t[e]);return r}return Math.abs(t)};var defaultCurveSegments=150,degToRads=Math.PI/180,roundCorner=.5519;function roundValues(t){bm_rnd=t?Math.round:function(t){return t}}function styleDiv(t){t.style.position="absolute",t.style.top=0,t.style.left=0,t.style.display="block",t.style.transformOrigin=t.style.webkitTransformOrigin="0 0",t.style.backfaceVisibility=t.style.webkitBackfaceVisibility="visible",t.style.transformStyle=t.style.webkitTransformStyle=t.style.mozTransformStyle="preserve-3d"}function BMEnterFrameEvent(t,e,r,i){this.type=t,this.currentTime=e,this.totalTime=r,this.direction=i<0?-1:1}function BMCompleteEvent(t,e){this.type=t,this.direction=e<0?-1:1}function BMCompleteLoopEvent(t,e,r,i){this.type=t,this.currentLoop=r,this.totalLoops=e,this.direction=i<0?-1:1}function BMSegmentStartEvent(t,e,r){this.type=t,this.firstFrame=e,this.totalFrames=r}function BMDestroyEvent(t,e){this.type=t,this.target=e}roundValues(!1);var createElementID=(B=0,function(){return"__lottie_element_"+ ++B}),B;function HSVtoRGB(t,e,r){var i,s,a,n,o,h,p,l;switch(h=r*(1-e),p=r*(1-(o=6*t-(n=Math.floor(6*t)))*e),l=r*(1-(1-o)*e),n%6){case 0:i=r,s=l,a=h;break;case 1:i=p,s=r,a=h;break;case 2:i=h,s=r,a=l;break;case 3:i=h,s=p,a=r;break;case 4:i=l,s=h,a=r;break;case 5:i=r,s=h,a=p}return[i,s,a]}function RGBtoHSV(t,e,r){var i,s=Math.max(t,e,r),a=Math.min(t,e,r),n=s-a,o=0===s?0:n/s,h=s/255;switch(s){case a:i=0;break;case t:i=e-r+n*(e<r?6:0),i/=6*n;break;case e:i=r-t+2*n,i/=6*n;break;case r:i=t-e+4*n,i/=6*n}return[i,o,h]}function addSaturationToRGB(t,e){var r=RGBtoHSV(255*t[0],255*t[1],255*t[2]);return r[1]+=e,1<r[1]?r[1]=1:r[1]<=0&&(r[1]=0),HSVtoRGB(r[0],r[1],r[2])}function addBrightnessToRGB(t,e){var r=RGBtoHSV(255*t[0],255*t[1],255*t[2]);return r[2]+=e,1<r[2]?r[2]=1:r[2]<0&&(r[2]=0),HSVtoRGB(r[0],r[1],r[2])}function addHueToRGB(t,e){var r=RGBtoHSV(255*t[0],255*t[1],255*t[2]);return r[0]+=e/360,1<r[0]?r[0]-=1:r[0]<0&&(r[0]+=1),HSVtoRGB(r[0],r[1],r[2])}var rgbToHex=function(){var t,e,i=[];for(t=0;t<256;t+=1)e=t.toString(16),i[t]=1==e.length?"0"+e:e;return function(t,e,r){return t<0&&(t=0),e<0&&(e=0),r<0&&(r=0),"#"+i[t]+i[e]+i[r]}}();function BaseEvent(){}BaseEvent.prototype={triggerEvent:function(t,e){if(this._cbs[t])for(var r=this._cbs[t].length,i=0;i<r;i++)this._cbs[t][i](e)},addEventListener:function(t,e){return this._cbs[t]||(this._cbs[t]=[]),this._cbs[t].push(e),function(){this.removeEventListener(t,e)}.bind(this)},removeEventListener:function(t,e){if(e){if(this._cbs[t]){for(var r=0,i=this._cbs[t].length;r<i;)this._cbs[t][r]===e&&(this._cbs[t].splice(r,1),r-=1,i-=1),r+=1;this._cbs[t].length||(this._cbs[t]=null)}}else this._cbs[t]=null}};var createTypedArray="function"==typeof Uint8ClampedArray&&"function"==typeof Float32Array?function(t,e){return"float32"===t?new Float32Array(e):"int16"===t?new Int16Array(e):"uint8c"===t?new Uint8ClampedArray(e):void 0}:function(t,e){var r,i=0,s=[];switch(t){case"int16":case"uint8c":r=1;break;default:r=1.1}for(i=0;i<e;i+=1)s.push(r);return s};function createSizedArray(t){return Array.apply(null,{length:t})}function createTag(t){return document.createElement(t)}function DynamicPropertyContainer(){}DynamicPropertyContainer.prototype={addDynamicProperty:function(t){-1===this.dynamicProperties.indexOf(t)&&(this.dynamicProperties.push(t),this.container.addDynamicProperty(this),this._isAnimated=!0)},iterateDynamicProperties:function(){this._mdf=!1;var t,e=this.dynamicProperties.length;for(t=0;t<e;t+=1)this.dynamicProperties[t].getValue(),this.dynamicProperties[t]._mdf&&(this._mdf=!0)},initDynamicPropertyContainer:function(t){this.container=t,this.dynamicProperties=[],this._mdf=!1,this._isAnimated=!1}};var getBlendMode=(Ja={0:"source-over",1:"multiply",2:"screen",3:"overlay",4:"darken",5:"lighten",6:"color-dodge",7:"color-burn",8:"hard-light",9:"soft-light",10:"difference",11:"exclusion",12:"hue",13:"saturation",14:"color",15:"luminosity"},function(t){return Ja[t]||""}),Ja,Matrix=(La=Math.cos,Ma=Math.sin,Na=Math.tan,Oa=Math.round,function(){this.reset=Pa,this.rotate=Qa,this.rotateX=Ra,this.rotateY=Sa,this.rotateZ=Ta,this.skew=Va,this.skewFromAxis=Wa,this.shear=Ua,this.scale=Xa,this.setTransform=Ya,this.translate=Za,this.transform=$a,this.applyToPoint=db,this.applyToX=eb,this.applyToY=fb,this.applyToZ=gb,this.applyToPointArray=kb,this.applyToTriplePoints=jb,this.applyToPointStringified=lb,this.toCSS=mb,this.to2dCSS=pb,this.clone=bb,this.cloneFromProps=cb,this.equals=ab,this.inversePoints=ib,this.inversePoint=hb,this._t=this.transform,this.isIdentity=_a,this._identity=!0,this._identityCalculated=!1,this.props=createTypedArray("float32",16),this.reset()}),La,Ma,Na,Oa;function Pa(){return this.props[0]=1,this.props[1]=0,this.props[2]=0,this.props[3]=0,this.props[4]=0,this.props[5]=1,this.props[6]=0,this.props[7]=0,this.props[8]=0,this.props[9]=0,this.props[10]=1,this.props[11]=0,this.props[12]=0,this.props[13]=0,this.props[14]=0,this.props[15]=1,this}function Qa(t){if(0===t)return this;var e=La(t),r=Ma(t);return this._t(e,-r,0,0,r,e,0,0,0,0,1,0,0,0,0,1)}function Ra(t){if(0===t)return this;var e=La(t),r=Ma(t);return this._t(1,0,0,0,0,e,-r,0,0,r,e,0,0,0,0,1)}function Sa(t){if(0===t)return this;var e=La(t),r=Ma(t);return this._t(e,0,r,0,0,1,0,0,-r,0,e,0,0,0,0,1)}function Ta(t){if(0===t)return this;var e=La(t),r=Ma(t);return this._t(e,-r,0,0,r,e,0,0,0,0,1,0,0,0,0,1)}function Ua(t,e){return this._t(1,e,t,1,0,0)}function Va(t,e){return this.shear(Na(t),Na(e))}function Wa(t,e){var r=La(e),i=Ma(e);return this._t(r,i,0,0,-i,r,0,0,0,0,1,0,0,0,0,1)._t(1,0,0,0,Na(t),1,0,0,0,0,1,0,0,0,0,1)._t(r,-i,0,0,i,r,0,0,0,0,1,0,0,0,0,1)}function Xa(t,e,r){return r||0===r||(r=1),1===t&&1===e&&1===r?this:this._t(t,0,0,0,0,e,0,0,0,0,r,0,0,0,0,1)}function Ya(t,e,r,i,s,a,n,o,h,p,l,m,f,c,d,u){return this.props[0]=t,this.props[1]=e,this.props[2]=r,this.props[3]=i,this.props[4]=s,this.props[5]=a,this.props[6]=n,this.props[7]=o,this.props[8]=h,this.props[9]=p,this.props[10]=l,this.props[11]=m,this.props[12]=f,this.props[13]=c,this.props[14]=d,this.props[15]=u,this}function Za(t,e,r){return r=r||0,0!==t||0!==e||0!==r?this._t(1,0,0,0,0,1,0,0,0,0,1,0,t,e,r,1):this}function $a(t,e,r,i,s,a,n,o,h,p,l,m,f,c,d,u){var y=this.props;if(1===t&&0===e&&0===r&&0===i&&0===s&&1===a&&0===n&&0===o&&0===h&&0===p&&1===l&&0===m)return y[12]=y[12]*t+y[15]*f,y[13]=y[13]*a+y[15]*c,y[14]=y[14]*l+y[15]*d,y[15]=y[15]*u,this._identityCalculated=!1,this;var g=y[0],v=y[1],P=y[2],b=y[3],x=y[4],_=y[5],S=y[6],T=y[7],A=y[8],E=y[9],C=y[10],k=y[11],D=y[12],I=y[13],M=y[14],w=y[15];return y[0]=g*t+v*s+P*h+b*f,y[1]=g*e+v*a+P*p+b*c,y[2]=g*r+v*n+P*l+b*d,y[3]=g*i+v*o+P*m+b*u,y[4]=x*t+_*s+S*h+T*f,y[5]=x*e+_*a+S*p+T*c,y[6]=x*r+_*n+S*l+T*d,y[7]=x*i+_*o+S*m+T*u,y[8]=A*t+E*s+C*h+k*f,y[9]=A*e+E*a+C*p+k*c,y[10]=A*r+E*n+C*l+k*d,y[11]=A*i+E*o+C*m+k*u,y[12]=D*t+I*s+M*h+w*f,y[13]=D*e+I*a+M*p+w*c,y[14]=D*r+I*n+M*l+w*d,y[15]=D*i+I*o+M*m+w*u,this._identityCalculated=!1,this}function _a(){return this._identityCalculated||(this._identity=!(1!==this.props[0]||0!==this.props[1]||0!==this.props[2]||0!==this.props[3]||0!==this.props[4]||1!==this.props[5]||0!==this.props[6]||0!==this.props[7]||0!==this.props[8]||0!==this.props[9]||1!==this.props[10]||0!==this.props[11]||0!==this.props[12]||0!==this.props[13]||0!==this.props[14]||1!==this.props[15]),this._identityCalculated=!0),this._identity}function ab(t){for(var e=0;e<16;){if(t.props[e]!==this.props[e])return!1;e+=1}return!0}function bb(t){var e;for(e=0;e<16;e+=1)t.props[e]=this.props[e]}function cb(t){var e;for(e=0;e<16;e+=1)this.props[e]=t[e]}function db(t,e,r){return{x:t*this.props[0]+e*this.props[4]+r*this.props[8]+this.props[12],y:t*this.props[1]+e*this.props[5]+r*this.props[9]+this.props[13],z:t*this.props[2]+e*this.props[6]+r*this.props[10]+this.props[14]}}function eb(t,e,r){return t*this.props[0]+e*this.props[4]+r*this.props[8]+this.props[12]}function fb(t,e,r){return t*this.props[1]+e*this.props[5]+r*this.props[9]+this.props[13]}function gb(t,e,r){return t*this.props[2]+e*this.props[6]+r*this.props[10]+this.props[14]}function hb(t){var e=this.props[0]*this.props[5]-this.props[1]*this.props[4],r=this.props[5]/e,i=-this.props[1]/e,s=-this.props[4]/e,a=this.props[0]/e,n=(this.props[4]*this.props[13]-this.props[5]*this.props[12])/e,o=-(this.props[0]*this.props[13]-this.props[1]*this.props[12])/e;return[t[0]*r+t[1]*s+n,t[0]*i+t[1]*a+o,0]}function ib(t){var e,r=t.length,i=[];for(e=0;e<r;e+=1)i[e]=hb(t[e]);return i}function jb(t,e,r){var i=createTypedArray("float32",6);if(this.isIdentity())i[0]=t[0],i[1]=t[1],i[2]=e[0],i[3]=e[1],i[4]=r[0],i[5]=r[1];else{var s=this.props[0],a=this.props[1],n=this.props[4],o=this.props[5],h=this.props[12],p=this.props[13];i[0]=t[0]*s+t[1]*n+h,i[1]=t[0]*a+t[1]*o+p,i[2]=e[0]*s+e[1]*n+h,i[3]=e[0]*a+e[1]*o+p,i[4]=r[0]*s+r[1]*n+h,i[5]=r[0]*a+r[1]*o+p}return i}function kb(t,e,r){return this.isIdentity()?[t,e,r]:[t*this.props[0]+e*this.props[4]+r*this.props[8]+this.props[12],t*this.props[1]+e*this.props[5]+r*this.props[9]+this.props[13],t*this.props[2]+e*this.props[6]+r*this.props[10]+this.props[14]]}function lb(t,e){if(this.isIdentity())return t+","+e;var r=this.props;return Math.round(100*(t*r[0]+e*r[4]+r[12]))/100+","+Math.round(100*(t*r[1]+e*r[5]+r[13]))/100}function mb(){for(var t=0,e=this.props,r="matrix3d(";t<16;)r+=Oa(1e4*e[t])/1e4,r+=15===t?")":",",t+=1;return r}function nb(t){return t<1e-6&&0<t||-1e-6<t&&t<0?Oa(1e4*t)/1e4:t}function pb(){var t=this.props;return"matrix("+nb(t[0])+","+nb(t[1])+","+nb(t[4])+","+nb(t[5])+","+nb(t[12])+","+nb(t[13])+")"}!function(o,h){var p,l=this,m=256,f=6,c="random",d=h.pow(m,f),u=h.pow(2,52),y=2*u,g=m-1;function v(t){var e,r=t.length,n=this,i=0,s=n.i=n.j=0,a=n.S=[];for(r||(t=[r++]);i<m;)a[i]=i++;for(i=0;i<m;i++)a[i]=a[s=g&s+t[i%r]+(e=a[i])],a[s]=e;n.g=function(t){for(var e,r=0,i=n.i,s=n.j,a=n.S;t--;)e=a[i=g&i+1],r=r*m+a[g&(a[i]=a[s=g&s+e])+(a[s]=e)];return n.i=i,n.j=s,r}}function P(t,e){return e.i=t.i,e.j=t.j,e.S=t.S.slice(),e}function b(t,e){for(var r,i=t+"",s=0;s<i.length;)e[g&s]=g&(r^=19*e[g&s])+i.charCodeAt(s++);return x(e)}function x(t){return String.fromCharCode.apply(0,t)}h["seed"+c]=function(t,e,r){function i(){for(var t=n.g(f),e=d,r=0;t<u;)t=(t+r)*m,e*=m,r=n.g(1);for(;y<=t;)t/=2,e/=2,r>>>=1;return(t+r)/e}var s=[],a=b(function t(e,r){var i,s=[],a=typeof e;if(r&&"object"==a)for(i in e)try{s.push(t(e[i],r-1))}catch(t){}return s.length?s:"string"==a?e:e+"\0"}((e=!0===e?{entropy:!0}:e||{}).entropy?[t,x(o)]:null===t?function(){try{if(p)return x(p.randomBytes(m));var t=new Uint8Array(m);return(l.crypto||l.msCrypto).getRandomValues(t),x(t)}catch(t){var e=l.navigator,r=e&&e.plugins;return[+new Date,l,r,l.screen,x(o)]}}():t,3),s),n=new v(s);return i.int32=function(){return 0|n.g(4)},i.quick=function(){return n.g(4)/4294967296},i.double=i,b(x(n.S),o),(e.pass||r||function(t,e,r,i){return i&&(i.S&&P(i,n),t.state=function(){return P(n,{})}),r?(h[c]=t,e):t})(i,a,"global"in e?e.global:this==h,e.state)},b(h.random(),o)}([],BMMath);var BezierFactory=(_e={getBezierEasing:function(t,e,r,i,s){var a=s||("bez_"+t+"_"+e+"_"+r+"_"+i).replace(/\./g,"p");if(af[a])return af[a];var n=new rf([t,e,r,i]);return af[a]=n}},af={},gf=11,hf=1/(gf-1),jf="function"==typeof Float32Array,rf.prototype={get:function(t){var e=this._p[0],r=this._p[1],i=this._p[2],s=this._p[3];return this._precomputed||this._precompute(),e===r&&i===s?t:0===t?0:1===t?1:nf(this._getTForX(t),r,s)},_precompute:function(){var t=this._p[0],e=this._p[1],r=this._p[2],i=this._p[3];this._precomputed=!0,t===e&&r===i||this._calcSampleValues()},_calcSampleValues:function(){for(var t=this._p[0],e=this._p[2],r=0;r<gf;++r)this._mSampleValues[r]=nf(r*hf,t,e)},_getTForX:function(t){for(var e=this._p[0],r=this._p[2],i=this._mSampleValues,s=0,a=1,n=gf-1;a!==n&&i[a]<=t;++a)s+=hf;var o=s+(t-i[--a])/(i[a+1]-i[a])*hf,h=of(o,e,r);return.001<=h?function(t,e,r,i){for(var s=0;s<4;++s){var a=of(e,r,i);if(0===a)return e;e-=(nf(e,r,i)-t)/a}return e}(t,o,e,r):0===h?o:function(t,e,r,i,s){for(var a,n,o=0;0<(a=nf(n=e+(r-e)/2,i,s)-t)?r=n:e=n,1e-7<Math.abs(a)&&++o<10;);return n}(t,s,s+hf,e,r)}},_e),_e,af,gf,hf,jf;function kf(t,e){return 1-3*e+3*t}function lf(t,e){return 3*e-6*t}function mf(t){return 3*t}function nf(t,e,r){return((kf(e,r)*t+lf(e,r))*t+mf(e))*t}function of(t,e,r){return 3*kf(e,r)*t*t+2*lf(e,r)*t+mf(e)}function rf(t){this._p=t,this._mSampleValues=jf?new Float32Array(gf):new Array(gf),this._precomputed=!1,this.get=this.get.bind(this)}function extendPrototype(t,e){var r,i,s=t.length;for(r=0;r<s;r+=1)for(var a in i=t[r].prototype)i.hasOwnProperty(a)&&(e.prototype[a]=i[a])}function getDescriptor(t,e){return Object.getOwnPropertyDescriptor(t,e)}function createProxyFunction(t){function e(){}return e.prototype=t,e}function bezFunction(){Math;function y(t,e,r,i,s,a){var n=t*i+e*s+r*a-s*i-a*t-r*e;return-.001<n&&n<.001}var l=function(t,e,r,i){var s,a,n,o,h,p,l=defaultCurveSegments,m=0,f=[],c=[],d=bezier_length_pool.newElement();for(n=r.length,s=0;s<l;s+=1){for(h=s/(l-1),a=p=0;a<n;a+=1)o=bm_pow(1-h,3)*t[a]+3*bm_pow(1-h,2)*h*r[a]+3*(1-h)*bm_pow(h,2)*i[a]+bm_pow(h,3)*e[a],f[a]=o,null!==c[a]&&(p+=bm_pow(f[a]-c[a],2)),c[a]=f[a];p&&(m+=p=bm_sqrt(p)),d.percents[s]=h,d.lengths[s]=m}return d.addedLength=m,d};function g(t){this.segmentLength=0,this.points=new Array(t)}function v(t,e){this.partialLength=t,this.point=e}var P,t=(P={},function(t,e,r,i){var s=(t[0]+"_"+t[1]+"_"+e[0]+"_"+e[1]+"_"+r[0]+"_"+r[1]+"_"+i[0]+"_"+i[1]).replace(/\./g,"p");if(!P[s]){var a,n,o,h,p,l,m,f=defaultCurveSegments,c=0,d=null;2===t.length&&(t[0]!=e[0]||t[1]!=e[1])&&y(t[0],t[1],e[0],e[1],t[0]+r[0],t[1]+r[1])&&y(t[0],t[1],e[0],e[1],e[0]+i[0],e[1]+i[1])&&(f=2);var u=new g(f);for(o=r.length,a=0;a<f;a+=1){for(m=createSizedArray(o),p=a/(f-1),n=l=0;n<o;n+=1)h=bm_pow(1-p,3)*t[n]+3*bm_pow(1-p,2)*p*(t[n]+r[n])+3*(1-p)*bm_pow(p,2)*(e[n]+i[n])+bm_pow(p,3)*e[n],m[n]=h,null!==d&&(l+=bm_pow(m[n]-d[n],2));c+=l=bm_sqrt(l),u.points[a]=new v(l,m),d=m}u.segmentLength=c,P[s]=u}return P[s]});function D(t,e){var r=e.percents,i=e.lengths,s=r.length,a=bm_floor((s-1)*t),n=t*e.addedLength,o=0;if(a===s-1||0===a||n===i[a])return r[a];for(var h=i[a]>n?-1:1,p=!0;p;)if(i[a]<=n&&i[a+1]>n?(o=(n-i[a])/(i[a+1]-i[a]),p=!1):a+=h,a<0||s-1<=a){if(a===s-1)return r[a];p=!1}return r[a]+(r[a+1]-r[a])*o}var I=createTypedArray("float32",8);return{getSegmentsLength:function(t){var e,r=segments_length_pool.newElement(),i=t.c,s=t.v,a=t.o,n=t.i,o=t._length,h=r.lengths,p=0;for(e=0;e<o-1;e+=1)h[e]=l(s[e],s[e+1],a[e],n[e+1]),p+=h[e].addedLength;return i&&o&&(h[e]=l(s[e],s[0],a[e],n[0]),p+=h[e].addedLength),r.totalLength=p,r},getNewSegment:function(t,e,r,i,s,a,n){var o,h=D(s=s<0?0:1<s?1:s,n),p=D(a=1<a?1:a,n),l=t.length,m=1-h,f=1-p,c=m*m*m,d=h*m*m*3,u=h*h*m*3,y=h*h*h,g=m*m*f,v=h*m*f+m*h*f+m*m*p,P=h*h*f+m*h*p+h*m*p,b=h*h*p,x=m*f*f,_=h*f*f+m*p*f+m*f*p,S=h*p*f+m*p*p+h*f*p,T=h*p*p,A=f*f*f,E=p*f*f+f*p*f+f*f*p,C=p*p*f+f*p*p+p*f*p,k=p*p*p;for(o=0;o<l;o+=1)I[4*o]=Math.round(1e3*(c*t[o]+d*r[o]+u*i[o]+y*e[o]))/1e3,I[4*o+1]=Math.round(1e3*(g*t[o]+v*r[o]+P*i[o]+b*e[o]))/1e3,I[4*o+2]=Math.round(1e3*(x*t[o]+_*r[o]+S*i[o]+T*e[o]))/1e3,I[4*o+3]=Math.round(1e3*(A*t[o]+E*r[o]+C*i[o]+k*e[o]))/1e3;return I},getPointInSegment:function(t,e,r,i,s,a){var n=D(s,a),o=1-n;return[Math.round(1e3*(o*o*o*t[0]+(n*o*o+o*n*o+o*o*n)*r[0]+(n*n*o+o*n*n+n*o*n)*i[0]+n*n*n*e[0]))/1e3,Math.round(1e3*(o*o*o*t[1]+(n*o*o+o*n*o+o*o*n)*r[1]+(n*n*o+o*n*n+n*o*n)*i[1]+n*n*n*e[1]))/1e3]},buildBezierData:t,pointOnLine2D:y,pointOnLine3D:function(t,e,r,i,s,a,n,o,h){if(0===r&&0===a&&0===h)return y(t,e,i,s,n,o);var p,l=Math.sqrt(Math.pow(i-t,2)+Math.pow(s-e,2)+Math.pow(a-r,2)),m=Math.sqrt(Math.pow(n-t,2)+Math.pow(o-e,2)+Math.pow(h-r,2)),f=Math.sqrt(Math.pow(n-i,2)+Math.pow(o-s,2)+Math.pow(h-a,2));return-1e-4<(p=m<l?f<l?l-m-f:f-m-l:m<f?f-m-l:m-l-f)&&p<1e-4}}}!function(){for(var a=0,t=["ms","moz","webkit","o"],e=0;e<t.length&&!window.requestAnimationFrame;++e)window.requestAnimationFrame=window[t[e]+"RequestAnimationFrame"],window.cancelAnimationFrame=window[t[e]+"CancelAnimationFrame"]||window[t[e]+"CancelRequestAnimationFrame"];window.requestAnimationFrame||(window.requestAnimationFrame=function(t,e){var r=(new Date).getTime(),i=Math.max(0,16-(r-a)),s=setTimeout(function(){t(r+i)},i);return a=r+i,s}),window.cancelAnimationFrame||(window.cancelAnimationFrame=function(t){clearTimeout(t)})}();var bez=bezFunction();function dataFunctionManager(){function m(t,e,r){var i,s,a,n,o,h,p=t.length;for(s=0;s<p;s+=1)if("ks"in(i=t[s])&&!i.completed){if(i.completed=!0,i.tt&&(t[s-1].td=i.tt),[],-1,i.hasMask){var l=i.masksProperties;for(n=l.length,a=0;a<n;a+=1)if(l[a].pt.k.i)d(l[a].pt.k);else for(h=l[a].pt.k.length,o=0;o<h;o+=1)l[a].pt.k[o].s&&d(l[a].pt.k[o].s[0]),l[a].pt.k[o].e&&d(l[a].pt.k[o].e[0])}0===i.ty?(i.layers=f(i.refId,e),m(i.layers,e,r)):4===i.ty?c(i.shapes):5==i.ty&&b(i,r)}}function f(t,e){for(var r=0,i=e.length;r<i;){if(e[r].id===t)return e[r].layers.__used?JSON.parse(JSON.stringify(e[r].layers)):(e[r].layers.__used=!0,e[r].layers);r+=1}}function c(t){var e,r,i;for(e=t.length-1;0<=e;e-=1)if("sh"==t[e].ty){if(t[e].ks.k.i)d(t[e].ks.k);else for(i=t[e].ks.k.length,r=0;r<i;r+=1)t[e].ks.k[r].s&&d(t[e].ks.k[r].s[0]),t[e].ks.k[r].e&&d(t[e].ks.k[r].e[0]);!0}else"gr"==t[e].ty&&c(t[e].it)}function d(t){var e,r=t.i.length;for(e=0;e<r;e+=1)t.i[e][0]+=t.v[e][0],t.i[e][1]+=t.v[e][1],t.o[e][0]+=t.v[e][0],t.o[e][1]+=t.v[e][1]}function o(t,e){var r=e?e.split("."):[100,100,100];return t[0]>r[0]||!(r[0]>t[0])&&(t[1]>r[1]||!(r[1]>t[1])&&(t[2]>r[2]||!(r[2]>t[2])&&void 0))}var i,r=(i=[4,4,14],function(t){if(o(i,t.v)&&(s(t.layers),t.assets)){var e,r=t.assets.length;for(e=0;e<r;e+=1)t.assets[e].layers&&s(t.assets[e].layers)}});function s(t){var e,r,i,s=t.length;for(e=0;e<s;e+=1)5===t[e].ty&&(r=t[e],void 0,i=r.t.d,r.t.d={k:[{s:i,t:0}]})}var h,a,n=(h=[4,7,99],function(t){if(t.chars&&!o(h,t.v)){var e,r,i,s,a,n=t.chars.length;for(e=0;e<n;e+=1)if(t.chars[e].data&&t.chars[e].data.shapes)for(i=(a=t.chars[e].data.shapes[0].it).length,r=0;r<i;r+=1)(s=a[r].ks.k).__converted||(d(a[r].ks.k),s.__converted=!0)}}),p=(a=[4,1,9],function(t){if(o(a,t.v)&&(u(t.layers),t.assets)){var e,r=t.assets.length;for(e=0;e<r;e+=1)t.assets[e].layers&&u(t.assets[e].layers)}});function l(t){var e,r,i,s=t.length;for(e=0;e<s;e+=1)if("gr"===t[e].ty)l(t[e].it);else if("fl"===t[e].ty||"st"===t[e].ty)if(t[e].c.k&&t[e].c.k[0].i)for(i=t[e].c.k.length,r=0;r<i;r+=1)t[e].c.k[r].s&&(t[e].c.k[r].s[0]/=255,t[e].c.k[r].s[1]/=255,t[e].c.k[r].s[2]/=255,t[e].c.k[r].s[3]/=255),t[e].c.k[r].e&&(t[e].c.k[r].e[0]/=255,t[e].c.k[r].e[1]/=255,t[e].c.k[r].e[2]/=255,t[e].c.k[r].e[3]/=255);else t[e].c.k[0]/=255,t[e].c.k[1]/=255,t[e].c.k[2]/=255,t[e].c.k[3]/=255}function u(t){var e,r=t.length;for(e=0;e<r;e+=1)4===t[e].ty&&l(t[e].shapes)}var y,g=(y=[4,4,18],function(t){if(o(y,t.v)&&(P(t.layers),t.assets)){var e,r=t.assets.length;for(e=0;e<r;e+=1)t.assets[e].layers&&P(t.assets[e].layers)}});function v(t){var e,r,i;for(e=t.length-1;0<=e;e-=1)if("sh"==t[e].ty){if(t[e].ks.k.i)t[e].ks.k.c=t[e].closed;else for(i=t[e].ks.k.length,r=0;r<i;r+=1)t[e].ks.k[r].s&&(t[e].ks.k[r].s[0].c=t[e].closed),t[e].ks.k[r].e&&(t[e].ks.k[r].e[0].c=t[e].closed);!0}else"gr"==t[e].ty&&v(t[e].it)}function P(t){var e,r,i,s,a,n,o=t.length;for(r=0;r<o;r+=1){if((e=t[r]).hasMask){var h=e.masksProperties;for(s=h.length,i=0;i<s;i+=1)if(h[i].pt.k.i)h[i].pt.k.c=h[i].cl;else for(n=h[i].pt.k.length,a=0;a<n;a+=1)h[i].pt.k[a].s&&(h[i].pt.k[a].s[0].c=h[i].cl),h[i].pt.k[a].e&&(h[i].pt.k[a].e[0].c=h[i].cl)}4===e.ty&&v(e.shapes)}}function b(t,e){0!==t.t.a.length||"m"in t.t.p||(t.singleShape=!0)}var t={completeData:function(t,e){t.__complete||(p(t),r(t),n(t),g(t),m(t.layers,t.assets,e),t.__complete=!0)}};return t.checkColors=p,t.checkChars=n,t.checkShapes=g,t.completeLayers=m,t}var dataManager=dataFunctionManager();dataManager.completeData=function(t,e){t.__complete||(this.checkColors(t),this.checkChars(t),this.checkShapes(t),this.completeLayers(t.layers,t.assets,e),t.__complete=!0)};var FontManager=function(){var a={w:0,size:0,shapes:[]},t=[];function u(t,e){var r=createTag("span");r.style.fontFamily=e;var i=createTag("span");i.innerHTML="giItT1WQy@!-/#",r.style.position="absolute",r.style.left="-10000px",r.style.top="-10000px",r.style.fontSize="300px",r.style.fontVariant="normal",r.style.fontStyle="normal",r.style.fontWeight="normal",r.style.letterSpacing="0",r.appendChild(i),document.body.appendChild(r);var s=i.offsetWidth;return i.style.fontFamily=t+", "+e,{node:i,w:s,parent:r}}t=t.concat([2304,2305,2306,2307,2362,2363,2364,2364,2366,2367,2368,2369,2370,2371,2372,2373,2374,2375,2376,2377,2378,2379,2380,2381,2382,2383,2387,2388,2389,2390,2391,2402,2403]);function e(){this.fonts=[],this.chars=null,this.typekitLoaded=0,this.isLoaded=!1,this.initTime=Date.now()}return e.getCombinedCharacterCodes=function(){return t},e.prototype.addChars=function(t){if(t){this.chars||(this.chars=[]);var e,r,i,s=t.length,a=this.chars.length;for(e=0;e<s;e+=1){for(r=0,i=!1;r<a;)this.chars[r].style===t[e].style&&this.chars[r].fFamily===t[e].fFamily&&this.chars[r].ch===t[e].ch&&(i=!0),r+=1;i||(this.chars.push(t[e]),a+=1)}}},e.prototype.addFonts=function(t,e){if(t){if(this.chars)return this.isLoaded=!0,void(this.fonts=t.list);var r,i,s,a,n=t.list,o=n.length,h=o;for(r=0;r<o;r+=1){var p,l,m=!0;if(n[r].loaded=!1,n[r].monoCase=u(n[r].fFamily,"monospace"),n[r].sansCase=u(n[r].fFamily,"sans-serif"),n[r].fPath){if("p"===n[r].fOrigin||3===n[r].origin){if(0<(p=document.querySelectorAll('style[f-forigin="p"][f-family="'+n[r].fFamily+'"], style[f-origin="3"][f-family="'+n[r].fFamily+'"]')).length&&(m=!1),m){var f=createTag("style");f.setAttribute("f-forigin",n[r].fOrigin),f.setAttribute("f-origin",n[r].origin),f.setAttribute("f-family",n[r].fFamily),f.type="text/css",f.innerHTML="@font-face {font-family: "+n[r].fFamily+"; font-style: normal; src: url('"+n[r].fPath+"');}",e.appendChild(f)}}else if("g"===n[r].fOrigin||1===n[r].origin){for(p=document.querySelectorAll('link[f-forigin="g"], link[f-origin="1"]'),l=0;l<p.length;l++)-1!==p[l].href.indexOf(n[r].fPath)&&(m=!1);if(m){var c=createTag("link");c.setAttribute("f-forigin",n[r].fOrigin),c.setAttribute("f-origin",n[r].origin),c.type="text/css",c.rel="stylesheet",c.href=n[r].fPath,document.body.appendChild(c)}}else if("t"===n[r].fOrigin||2===n[r].origin){for(p=document.querySelectorAll('script[f-forigin="t"], script[f-origin="2"]'),l=0;l<p.length;l++)n[r].fPath===p[l].src&&(m=!1);if(m){var d=createTag("link");d.setAttribute("f-forigin",n[r].fOrigin),d.setAttribute("f-origin",n[r].origin),d.setAttribute("rel","stylesheet"),d.setAttribute("href",n[r].fPath),e.appendChild(d)}}}else n[r].loaded=!0,h-=1;n[r].helper=(i=e,s=n[r],a=void 0,(a=createNS("text")).style.fontSize="100px",a.setAttribute("font-family",s.fFamily),a.setAttribute("font-style",s.fStyle),a.setAttribute("font-weight",s.fWeight),a.textContent="1",s.fClass?(a.style.fontFamily="inherit",a.setAttribute("class",s.fClass)):a.style.fontFamily=s.fFamily,i.appendChild(a),createTag("canvas").getContext("2d").font=s.fWeight+" "+s.fStyle+" 100px "+s.fFamily,a),n[r].cache={},this.fonts.push(n[r])}0===h?this.isLoaded=!0:setTimeout(this.checkLoadedFonts.bind(this),100)}else this.isLoaded=!0},e.prototype.getCharData=function(t,e,r){for(var i=0,s=this.chars.length;i<s;){if(this.chars[i].ch===t&&this.chars[i].style===e&&this.chars[i].fFamily===r)return this.chars[i];i+=1}return console&&console.warn&&console.warn("Missing character from exported characters list: ",t,e,r),a},e.prototype.getFontByName=function(t){for(var e=0,r=this.fonts.length;e<r;){if(this.fonts[e].fName===t)return this.fonts[e];e+=1}return this.fonts[0]},e.prototype.measureText=function(t,e,r){var i=this.getFontByName(e),s=t.charCodeAt(0);if(!i.cache[s+1]){var a=i.helper;if(" "===t){a.textContent="|"+t+"|";var n=a.getComputedTextLength();a.textContent="||";var o=a.getComputedTextLength();i.cache[s+1]=(n-o)/100}else a.textContent=t,i.cache[s+1]=a.getComputedTextLength()/100}return i.cache[s+1]*r},e.prototype.checkLoadedFonts=function(){var t,e,r,i=this.fonts.length,s=i;for(t=0;t<i;t+=1)this.fonts[t].loaded?s-=1:"n"===this.fonts[t].fOrigin||0===this.fonts[t].origin?this.fonts[t].loaded=!0:(e=this.fonts[t].monoCase.node,r=this.fonts[t].monoCase.w,e.offsetWidth!==r?(s-=1,this.fonts[t].loaded=!0):(e=this.fonts[t].sansCase.node,r=this.fonts[t].sansCase.w,e.offsetWidth!==r&&(s-=1,this.fonts[t].loaded=!0)),this.fonts[t].loaded&&(this.fonts[t].sansCase.parent.parentNode.removeChild(this.fonts[t].sansCase.parent),this.fonts[t].monoCase.parent.parentNode.removeChild(this.fonts[t].monoCase.parent)));0!==s&&Date.now()-this.initTime<5e3?setTimeout(this.checkLoadedFonts.bind(this),20):setTimeout(function(){this.isLoaded=!0}.bind(this),0)},e.prototype.loaded=function(){return this.isLoaded},e}();FontManager=function(){this.fonts=[],this.chars=null,this.typekitLoaded=0,this.isLoaded=!1,this.initTime=Date.now()};var PropertyFactory=(km=initialDefaultFrame,lm=Math.abs,{getProp:function(t,e,r,i,s){var a;if(e.k.length)if("number"==typeof e.k[0])a=new vm(t,e,i,s);else switch(r){case 0:a=new wm(t,e,i,s);break;case 1:a=new xm(t,e,i,s)}else a=new um(t,e,i,s);return a.effectsSequence.length&&s.addDynamicProperty(a),a}}),km,lm;function mm(t,e){var r,i=this.offsetTime;"multidimensional"===this.propType&&(r=createTypedArray("float32",this.pv.length));for(var s,a,n,o,h,p,l,m,f=e.lastIndex,c=f,d=this.keyframes.length-1,u=!0;u;){if(s=this.keyframes[c],a=this.keyframes[c+1],c===d-1&&t>=a.t-i){s.h&&(s=a),f=0;break}if(a.t-i>t){f=c;break}c<d-1?c+=1:(f=0,u=!1)}var y,g=a.t-i,v=s.t-i;if(s.to){s.bezierData||(s.bezierData=bez.buildBezierData(s.s,a.s||s.e,s.to,s.ti));var P=s.bezierData;if(g<=t||t<v){var b=g<=t?P.points.length-1:0;for(o=P.points[b].point.length,n=0;n<o;n+=1)r[n]=P.points[b].point[n]}else{s.__fnct?m=s.__fnct:(m=BezierFactory.getBezierEasing(s.o.x,s.o.y,s.i.x,s.i.y,s.n).get,s.__fnct=m),h=m((t-v)/(g-v));var x,_=P.segmentLength*h,S=e.lastFrame<t&&e._lastKeyframeIndex===c?e._lastAddedLength:0;for(l=e.lastFrame<t&&e._lastKeyframeIndex===c?e._lastPoint:0,u=!0,p=P.points.length;u;){if(S+=P.points[l].partialLength,0==_||0===h||l===P.points.length-1){for(o=P.points[l].point.length,n=0;n<o;n+=1)r[n]=P.points[l].point[n];break}if(S<=_&&_<S+P.points[l+1].partialLength){for(x=(_-S)/P.points[l+1].partialLength,o=P.points[l].point.length,n=0;n<o;n+=1)r[n]=P.points[l].point[n]+(P.points[l+1].point[n]-P.points[l].point[n])*x;break}l<p-1?l+=1:u=!1}e._lastPoint=l,e._lastAddedLength=S-P.points[l].partialLength,e._lastKeyframeIndex=c}}else{var T,A,E,C,k;if(d=s.s.length,y=a.s||s.e,this.sh&&1!==s.h)if(g<=t)r[0]=y[0],r[1]=y[1],r[2]=y[2];else if(t<=v)r[0]=s.s[0],r[1]=s.s[1],r[2]=s.s[2];else{!function(t,e){var r=e[0],i=e[1],s=e[2],a=e[3],n=Math.atan2(2*i*a-2*r*s,1-2*i*i-2*s*s),o=Math.asin(2*r*i+2*s*a),h=Math.atan2(2*r*a-2*i*s,1-2*r*r-2*s*s);t[0]=n/degToRads,t[1]=o/degToRads,t[2]=h/degToRads}(r,function(t,e,r){var i,s,a,n,o,h=[],p=t[0],l=t[1],m=t[2],f=t[3],c=e[0],d=e[1],u=e[2],y=e[3];(s=p*c+l*d+m*u+f*y)<0&&(s=-s,c=-c,d=-d,u=-u,y=-y);o=1e-6<1-s?(i=Math.acos(s),a=Math.sin(i),n=Math.sin((1-r)*i)/a,Math.sin(r*i)/a):(n=1-r,r);return h[0]=n*p+o*c,h[1]=n*l+o*d,h[2]=n*m+o*u,h[3]=n*f+o*y,h}(pm(s.s),pm(y),(t-v)/(g-v)))}else for(c=0;c<d;c+=1)1!==s.h&&(h=g<=t?1:t<v?0:(s.o.x.constructor===Array?(s.__fnct||(s.__fnct=[]),s.__fnct[c]?m=s.__fnct[c]:(T=void 0===s.o.x[c]?s.o.x[0]:s.o.x[c],A=void 0===s.o.y[c]?s.o.y[0]:s.o.y[c],E=void 0===s.i.x[c]?s.i.x[0]:s.i.x[c],C=void 0===s.i.y[c]?s.i.y[0]:s.i.y[c],m=BezierFactory.getBezierEasing(T,A,E,C).get,s.__fnct[c]=m)):s.__fnct?m=s.__fnct:(T=s.o.x,A=s.o.y,E=s.i.x,C=s.i.y,m=BezierFactory.getBezierEasing(T,A,E,C).get,s.__fnct=m),m((t-v)/(g-v)))),y=a.s||s.e,k=1===s.h?s.s[c]:s.s[c]+(y[c]-s.s[c])*h,1===d?r=k:r[c]=k}return e.lastIndex=f,r}function pm(t){var e=t[0]*degToRads,r=t[1]*degToRads,i=t[2]*degToRads,s=Math.cos(e/2),a=Math.cos(r/2),n=Math.cos(i/2),o=Math.sin(e/2),h=Math.sin(r/2),p=Math.sin(i/2);return[o*h*n+s*a*p,o*a*n+s*h*p,s*h*n-o*a*p,s*a*n-o*h*p]}function qm(){var t=this.comp.renderedFrame-this.offsetTime,e=this.keyframes[0].t-this.offsetTime,r=this.keyframes[this.keyframes.length-1].t-this.offsetTime;if(!(t===this._caching.lastFrame||this._caching.lastFrame!==km&&(this._caching.lastFrame>=r&&r<=t||this._caching.lastFrame<e&&t<e))){this._caching.lastFrame>=t&&(this._caching._lastKeyframeIndex=-1,this._caching.lastIndex=0);var i=this.interpolateValue(t,this._caching);this.pv=i}return this._caching.lastFrame=t,this.pv}function rm(t){var e;if("unidimensional"===this.propType)e=t*this.mult,1e-5<lm(this.v-e)&&(this.v=e,this._mdf=!0);else for(var r=0,i=this.v.length;r<i;)e=t[r]*this.mult,1e-5<lm(this.v[r]-e)&&(this.v[r]=e,this._mdf=!0),r+=1}function sm(){if(this.elem.globalData.frameId!==this.frameId&&this.effectsSequence.length)if(this.lock)this.setVValue(this.pv);else{this.lock=!0,this._mdf=this._isFirstFrame;var t,e=this.effectsSequence.length,r=this.kf?this.pv:this.data.k;for(t=0;t<e;t+=1)r=this.effectsSequence[t](r);this.setVValue(r),this._isFirstFrame=!1,this.lock=!1,this.frameId=this.elem.globalData.frameId}}function tm(t){this.effectsSequence.push(t),this.container.addDynamicProperty(this)}function um(t,e,r,i){this.propType="unidimensional",this.mult=r||1,this.data=e,this.v=r?e.k*r:e.k,this.pv=e.k,this._mdf=!1,this.elem=t,this.container=i,this.comp=t.comp,this.k=!1,this.kf=!1,this.vel=0,this.effectsSequence=[],this._isFirstFrame=!0,this.getValue=sm,this.setVValue=rm,this.addEffect=tm}function vm(t,e,r,i){this.propType="multidimensional",this.mult=r||1,this.data=e,this._mdf=!1,this.elem=t,this.container=i,this.comp=t.comp,this.k=!1,this.kf=!1,this.frameId=-1;var s,a=e.k.length;this.v=createTypedArray("float32",a),this.pv=createTypedArray("float32",a);createTypedArray("float32",a);for(this.vel=createTypedArray("float32",a),s=0;s<a;s+=1)this.v[s]=e.k[s]*this.mult,this.pv[s]=e.k[s];this._isFirstFrame=!0,this.effectsSequence=[],this.getValue=sm,this.setVValue=rm,this.addEffect=tm}function wm(t,e,r,i){this.propType="unidimensional",this.keyframes=e.k,this.offsetTime=t.data.st,this.frameId=-1,this._caching={lastFrame:km,lastIndex:0,value:0,_lastKeyframeIndex:-1},this.k=!0,this.kf=!0,this.data=e,this.mult=r||1,this.elem=t,this.container=i,this.comp=t.comp,this.v=km,this.pv=km,this._isFirstFrame=!0,this.getValue=sm,this.setVValue=rm,this.interpolateValue=mm,this.effectsSequence=[qm.bind(this)],this.addEffect=tm}function xm(t,e,r,i){this.propType="multidimensional";var s,a,n,o,h,p=e.k.length;for(s=0;s<p-1;s+=1)e.k[s].to&&e.k[s].s&&e.k[s].e&&(a=e.k[s].s,n=e.k[s].e,o=e.k[s].to,h=e.k[s].ti,(2===a.length&&(a[0]!==n[0]||a[1]!==n[1])&&bez.pointOnLine2D(a[0],a[1],n[0],n[1],a[0]+o[0],a[1]+o[1])&&bez.pointOnLine2D(a[0],a[1],n[0],n[1],n[0]+h[0],n[1]+h[1])||3===a.length&&(a[0]!==n[0]||a[1]!==n[1]||a[2]!==n[2])&&bez.pointOnLine3D(a[0],a[1],a[2],n[0],n[1],n[2],a[0]+o[0],a[1]+o[1],a[2]+o[2])&&bez.pointOnLine3D(a[0],a[1],a[2],n[0],n[1],n[2],n[0]+h[0],n[1]+h[1],n[2]+h[2]))&&(e.k[s].to=null,e.k[s].ti=null),a[0]===n[0]&&a[1]===n[1]&&0===o[0]&&0===o[1]&&0===h[0]&&0===h[1]&&(2===a.length||a[2]===n[2]&&0===o[2]&&0===h[2])&&(e.k[s].to=null,e.k[s].ti=null));this.effectsSequence=[qm.bind(this)],this.keyframes=e.k,this.offsetTime=t.data.st,this.k=!0,this.kf=!0,this._isFirstFrame=!0,this.mult=r||1,this.elem=t,this.container=i,this.comp=t.comp,this.getValue=sm,this.setVValue=rm,this.interpolateValue=mm,this.frameId=-1;var l=e.k[0].s.length;for(this.v=createTypedArray("float32",l),this.pv=createTypedArray("float32",l),s=0;s<l;s+=1)this.v[s]=km,this.pv[s]=km;this._caching={lastFrame:km,lastIndex:0,value:createTypedArray("float32",l)},this.addEffect=tm}var TransformPropertyFactory=(Qo.prototype={applyToMatrix:function(t){var e=this._mdf;this.iterateDynamicProperties(),this._mdf=this._mdf||e,this.a&&t.translate(-this.a.v[0],-this.a.v[1],this.a.v[2]),this.s&&t.scale(this.s.v[0],this.s.v[1],this.s.v[2]),this.sk&&t.skewFromAxis(-this.sk.v,this.sa.v),this.r?t.rotate(-this.r.v):t.rotateZ(-this.rz.v).rotateY(this.ry.v).rotateX(this.rx.v).rotateZ(-this.or.v[2]).rotateY(this.or.v[1]).rotateX(this.or.v[0]),this.data.p.s?this.data.p.z?t.translate(this.px.v,this.py.v,-this.pz.v):t.translate(this.px.v,this.py.v,0):t.translate(this.p.v[0],this.p.v[1],-this.p.v[2])},getValue:function(t){if(this.elem.globalData.frameId!==this.frameId){if(this._isDirty&&(this.precalculateMatrix(),this._isDirty=!1),this.iterateDynamicProperties(),this._mdf||t){if(this.v.cloneFromProps(this.pre.props),this.appliedTransformations<1&&this.v.translate(-this.a.v[0],-this.a.v[1],this.a.v[2]),this.appliedTransformations<2&&this.v.scale(this.s.v[0],this.s.v[1],this.s.v[2]),this.sk&&this.appliedTransformations<3&&this.v.skewFromAxis(-this.sk.v,this.sa.v),this.r&&this.appliedTransformations<4?this.v.rotate(-this.r.v):!this.r&&this.appliedTransformations<4&&this.v.rotateZ(-this.rz.v).rotateY(this.ry.v).rotateX(this.rx.v).rotateZ(-this.or.v[2]).rotateY(this.or.v[1]).rotateX(this.or.v[0]),this.autoOriented){var e,r,i=this.elem.globalData.frameRate;if(this.p&&this.p.keyframes&&this.p.getValueAtTime)r=this.p._caching.lastFrame+this.p.offsetTime<=this.p.keyframes[0].t?(e=this.p.getValueAtTime((this.p.keyframes[0].t+.01)/i,0),this.p.getValueAtTime(this.p.keyframes[0].t/i,0)):this.p._caching.lastFrame+this.p.offsetTime>=this.p.keyframes[this.p.keyframes.length-1].t?(e=this.p.getValueAtTime(this.p.keyframes[this.p.keyframes.length-1].t/i,0),this.p.getValueAtTime((this.p.keyframes[this.p.keyframes.length-1].t-.01)/i,0)):(e=this.p.pv,this.p.getValueAtTime((this.p._caching.lastFrame+this.p.offsetTime-.01)/i,this.p.offsetTime));else if(this.px&&this.px.keyframes&&this.py.keyframes&&this.px.getValueAtTime&&this.py.getValueAtTime){e=[],r=[];var s=this.px,a=this.py;s._caching.lastFrame+s.offsetTime<=s.keyframes[0].t?(e[0]=s.getValueAtTime((s.keyframes[0].t+.01)/i,0),e[1]=a.getValueAtTime((a.keyframes[0].t+.01)/i,0),r[0]=s.getValueAtTime(s.keyframes[0].t/i,0),r[1]=a.getValueAtTime(a.keyframes[0].t/i,0)):s._caching.lastFrame+s.offsetTime>=s.keyframes[s.keyframes.length-1].t?(e[0]=s.getValueAtTime(s.keyframes[s.keyframes.length-1].t/i,0),e[1]=a.getValueAtTime(a.keyframes[a.keyframes.length-1].t/i,0),r[0]=s.getValueAtTime((s.keyframes[s.keyframes.length-1].t-.01)/i,0),r[1]=a.getValueAtTime((a.keyframes[a.keyframes.length-1].t-.01)/i,0)):(e=[s.pv,a.pv],r[0]=s.getValueAtTime((s._caching.lastFrame+s.offsetTime-.01)/i,s.offsetTime),r[1]=a.getValueAtTime((a._caching.lastFrame+a.offsetTime-.01)/i,a.offsetTime))}this.v.rotate(-Math.atan2(e[1]-r[1],e[0]-r[0]))}this.data.p&&this.data.p.s?this.data.p.z?this.v.translate(this.px.v,this.py.v,-this.pz.v):this.v.translate(this.px.v,this.py.v,0):this.v.translate(this.p.v[0],this.p.v[1],-this.p.v[2])}this.frameId=this.elem.globalData.frameId}},precalculateMatrix:function(){if(!this.a.k&&(this.pre.translate(-this.a.v[0],-this.a.v[1],this.a.v[2]),this.appliedTransformations=1,!this.s.effectsSequence.length)){if(this.pre.scale(this.s.v[0],this.s.v[1],this.s.v[2]),this.appliedTransformations=2,this.sk){if(this.sk.effectsSequence.length||this.sa.effectsSequence.length)return;this.pre.skewFromAxis(-this.sk.v,this.sa.v),this.appliedTransformations=3}if(this.r){if(this.r.effectsSequence.length)return;this.pre.rotate(-this.r.v),this.appliedTransformations=4}else this.rz.effectsSequence.length||this.ry.effectsSequence.length||this.rx.effectsSequence.length||this.or.effectsSequence.length||(this.pre.rotateZ(-this.rz.v).rotateY(this.ry.v).rotateX(this.rx.v).rotateZ(-this.or.v[2]).rotateY(this.or.v[1]).rotateX(this.or.v[0]),this.appliedTransformations=4)}},autoOrient:function(){}},extendPrototype([DynamicPropertyContainer],Qo),Qo.prototype.addDynamicProperty=function(t){this._addDynamicProperty(t),this.elem.addDynamicProperty(t),this._isDirty=!0},Qo.prototype._addDynamicProperty=DynamicPropertyContainer.prototype.addDynamicProperty,{getTransformProperty:function(t,e,r){return new Qo(t,e,r)}});function Qo(t,e,r){if(this.elem=t,this.frameId=-1,this.propType="transform",this.data=e,this.v=new Matrix,this.pre=new Matrix,this.appliedTransformations=0,this.initDynamicPropertyContainer(r||t),e.p&&e.p.s?(this.px=PropertyFactory.getProp(t,e.p.x,0,0,this),this.py=PropertyFactory.getProp(t,e.p.y,0,0,this),e.p.z&&(this.pz=PropertyFactory.getProp(t,e.p.z,0,0,this))):this.p=PropertyFactory.getProp(t,e.p||{k:[0,0,0]},1,0,this),e.rx){if(this.rx=PropertyFactory.getProp(t,e.rx,0,degToRads,this),this.ry=PropertyFactory.getProp(t,e.ry,0,degToRads,this),this.rz=PropertyFactory.getProp(t,e.rz,0,degToRads,this),e.or.k[0].ti){var i,s=e.or.k.length;for(i=0;i<s;i+=1)e.or.k[i].to=e.or.k[i].ti=null}this.or=PropertyFactory.getProp(t,e.or,1,degToRads,this),this.or.sh=!0}else this.r=PropertyFactory.getProp(t,e.r||{k:0},0,degToRads,this);e.sk&&(this.sk=PropertyFactory.getProp(t,e.sk,0,degToRads,this),this.sa=PropertyFactory.getProp(t,e.sa,0,degToRads,this)),this.a=PropertyFactory.getProp(t,e.a||{k:[0,0,0]},1,0,this),this.s=PropertyFactory.getProp(t,e.s||{k:[100,100,100]},1,.01,this),e.o?this.o=PropertyFactory.getProp(t,e.o,0,.01,t):this.o={_mdf:!1,v:1},this._isDirty=!0,this.dynamicProperties.length||this.getValue(!0)}function ShapePath(){this.c=!1,this._length=0,this._maxLength=8,this.v=createSizedArray(this._maxLength),this.o=createSizedArray(this._maxLength),this.i=createSizedArray(this._maxLength)}ShapePath.prototype.setPathData=function(t,e){this.c=t,this.setLength(e);for(var r=0;r<e;)this.v[r]=point_pool.newElement(),this.o[r]=point_pool.newElement(),this.i[r]=point_pool.newElement(),r+=1},ShapePath.prototype.setLength=function(t){for(;this._maxLength<t;)this.doubleArrayLength();this._length=t},ShapePath.prototype.doubleArrayLength=function(){this.v=this.v.concat(createSizedArray(this._maxLength)),this.i=this.i.concat(createSizedArray(this._maxLength)),this.o=this.o.concat(createSizedArray(this._maxLength)),this._maxLength*=2},ShapePath.prototype.setXYAt=function(t,e,r,i,s){var a;switch(this._length=Math.max(this._length,i+1),this._length>=this._maxLength&&this.doubleArrayLength(),r){case"v":a=this.v;break;case"i":a=this.i;break;case"o":a=this.o}a[i]&&(!a[i]||s)||(a[i]=point_pool.newElement()),a[i][0]=t,a[i][1]=e},ShapePath.prototype.setTripleAt=function(t,e,r,i,s,a,n,o){this.setXYAt(t,e,"v",n,o),this.setXYAt(r,i,"o",n,o),this.setXYAt(s,a,"i",n,o)},ShapePath.prototype.reverse=function(){var t=new ShapePath;t.setPathData(this.c,this._length);var e=this.v,r=this.o,i=this.i,s=0;this.c&&(t.setTripleAt(e[0][0],e[0][1],i[0][0],i[0][1],r[0][0],r[0][1],0,!1),s=1);var a,n=this._length-1,o=this._length;for(a=s;a<o;a+=1)t.setTripleAt(e[n][0],e[n][1],i[n][0],i[n][1],r[n][0],r[n][1],a,!1),n-=1;return t};var ShapePropertyFactory=function(){var s=-999999;function t(t,e,r){var i,s,a,n,o,h,p,l,m,f=r.lastIndex,c=this.keyframes;if(t<c[0].t-this.offsetTime)i=c[0].s[0],a=!0,f=0;else if(t>=c[c.length-1].t-this.offsetTime)i=c[c.length-1].s?c[c.length-1].s[0]:c[c.length-2].e[0],a=!0;else{for(var d,u,y=f,g=c.length-1,v=!0;v&&(d=c[y],!((u=c[y+1]).t-this.offsetTime>t));)y<g-1?y+=1:v=!1;if(f=y,!(a=1===d.h)){if(t>=u.t-this.offsetTime)l=1;else if(t<d.t-this.offsetTime)l=0;else{var P;d.__fnct?P=d.__fnct:(P=BezierFactory.getBezierEasing(d.o.x,d.o.y,d.i.x,d.i.y).get,d.__fnct=P),l=P((t-(d.t-this.offsetTime))/(u.t-this.offsetTime-(d.t-this.offsetTime)))}s=u.s?u.s[0]:d.e[0]}i=d.s[0]}for(h=e._length,p=i.i[0].length,r.lastIndex=f,n=0;n<h;n+=1)for(o=0;o<p;o+=1)m=a?i.i[n][o]:i.i[n][o]+(s.i[n][o]-i.i[n][o])*l,e.i[n][o]=m,m=a?i.o[n][o]:i.o[n][o]+(s.o[n][o]-i.o[n][o])*l,e.o[n][o]=m,m=a?i.v[n][o]:i.v[n][o]+(s.v[n][o]-i.v[n][o])*l,e.v[n][o]=m}function a(){this.paths=this.localShapeCollection}function e(t){!function(t,e){if(t._length!==e._length||t.c!==e.c)return!1;var r,i=t._length;for(r=0;r<i;r+=1)if(t.v[r][0]!==e.v[r][0]||t.v[r][1]!==e.v[r][1]||t.o[r][0]!==e.o[r][0]||t.o[r][1]!==e.o[r][1]||t.i[r][0]!==e.i[r][0]||t.i[r][1]!==e.i[r][1])return!1;return!0}(this.v,t)&&(this.v=shape_pool.clone(t),this.localShapeCollection.releaseShapes(),this.localShapeCollection.addShape(this.v),this._mdf=!0,this.paths=this.localShapeCollection)}function r(){if(this.elem.globalData.frameId!==this.frameId&&this.effectsSequence.length)if(this.lock)this.setVValue(this.pv);else{this.lock=!0,this._mdf=!1;var t,e=this.kf?this.pv:this.data.ks?this.data.ks.k:this.data.pt.k,r=this.effectsSequence.length;for(t=0;t<r;t+=1)e=this.effectsSequence[t](e);this.setVValue(e),this.lock=!1,this.frameId=this.elem.globalData.frameId}}function n(t,e,r){this.propType="shape",this.comp=t.comp,this.container=t,this.elem=t,this.data=e,this.k=!1,this.kf=!1,this._mdf=!1;var i=3===r?e.pt.k:e.ks.k;this.v=shape_pool.clone(i),this.pv=shape_pool.clone(this.v),this.localShapeCollection=shapeCollection_pool.newShapeCollection(),this.paths=this.localShapeCollection,this.paths.addShape(this.v),this.reset=a,this.effectsSequence=[]}function i(t){this.effectsSequence.push(t),this.container.addDynamicProperty(this)}function o(t,e,r){this.propType="shape",this.comp=t.comp,this.elem=t,this.container=t,this.offsetTime=t.data.st,this.keyframes=3===r?e.pt.k:e.ks.k,this.k=!0,this.kf=!0;var i=this.keyframes[0].s[0].i.length;this.keyframes[0].s[0].i[0].length;this.v=shape_pool.newElement(),this.v.setPathData(this.keyframes[0].s[0].c,i),this.pv=shape_pool.clone(this.v),this.localShapeCollection=shapeCollection_pool.newShapeCollection(),this.paths=this.localShapeCollection,this.paths.addShape(this.v),this.lastFrame=s,this.reset=a,this._caching={lastFrame:s,lastIndex:0},this.effectsSequence=[function(){var t=this.comp.renderedFrame-this.offsetTime,e=this.keyframes[0].t-this.offsetTime,r=this.keyframes[this.keyframes.length-1].t-this.offsetTime,i=this._caching.lastFrame;return i!==s&&(i<e&&t<e||r<i&&r<t)||(this._caching.lastIndex=i<t?this._caching.lastIndex:0,this.interpolateShape(t,this.pv,this._caching)),this._caching.lastFrame=t,this.pv}.bind(this)]}n.prototype.interpolateShape=t,n.prototype.getValue=r,n.prototype.setVValue=e,n.prototype.addEffect=i,o.prototype.getValue=r,o.prototype.interpolateShape=t,o.prototype.setVValue=e,o.prototype.addEffect=i;var h,p=(h=roundCorner,l.prototype={reset:a,getValue:function(){this.elem.globalData.frameId!==this.frameId&&(this.frameId=this.elem.globalData.frameId,this.iterateDynamicProperties(),this._mdf&&this.convertEllToPath())},convertEllToPath:function(){var t=this.p.v[0],e=this.p.v[1],r=this.s.v[0]/2,i=this.s.v[1]/2,s=3!==this.d,a=this.v;a.v[0][0]=t,a.v[0][1]=e-i,a.v[1][0]=s?t+r:t-r,a.v[1][1]=e,a.v[2][0]=t,a.v[2][1]=e+i,a.v[3][0]=s?t-r:t+r,a.v[3][1]=e,a.i[0][0]=s?t-r*h:t+r*h,a.i[0][1]=e-i,a.i[1][0]=s?t+r:t-r,a.i[1][1]=e-i*h,a.i[2][0]=s?t+r*h:t-r*h,a.i[2][1]=e+i,a.i[3][0]=s?t-r:t+r,a.i[3][1]=e+i*h,a.o[0][0]=s?t+r*h:t-r*h,a.o[0][1]=e-i,a.o[1][0]=s?t+r:t-r,a.o[1][1]=e+i*h,a.o[2][0]=s?t-r*h:t+r*h,a.o[2][1]=e+i,a.o[3][0]=s?t-r:t+r,a.o[3][1]=e-i*h}},extendPrototype([DynamicPropertyContainer],l),l);function l(t,e){this.v=shape_pool.newElement(),this.v.setPathData(!0,4),this.localShapeCollection=shapeCollection_pool.newShapeCollection(),this.paths=this.localShapeCollection,this.localShapeCollection.addShape(this.v),this.d=e.d,this.elem=t,this.comp=t.comp,this.frameId=-1,this.initDynamicPropertyContainer(t),this.p=PropertyFactory.getProp(t,e.p,1,0,this),this.s=PropertyFactory.getProp(t,e.s,1,0,this),this.dynamicProperties.length?this.k=!0:(this.k=!1,this.convertEllToPath())}var m=(f.prototype={reset:a,getValue:function(){this.elem.globalData.frameId!==this.frameId&&(this.frameId=this.elem.globalData.frameId,this.iterateDynamicProperties(),this._mdf&&this.convertToPath())},convertStarToPath:function(){var t,e,r,i,s=2*Math.floor(this.pt.v),a=2*Math.PI/s,n=!0,o=this.or.v,h=this.ir.v,p=this.os.v,l=this.is.v,m=2*Math.PI*o/(2*s),f=2*Math.PI*h/(2*s),c=-Math.PI/2;c+=this.r.v;var d=3===this.data.d?-1:1;for(t=this.v._length=0;t<s;t+=1){r=n?p:l,i=n?m:f;var u=(e=n?o:h)*Math.cos(c),y=e*Math.sin(c),g=0===u&&0===y?0:y/Math.sqrt(u*u+y*y),v=0===u&&0===y?0:-u/Math.sqrt(u*u+y*y);u+=+this.p.v[0],y+=+this.p.v[1],this.v.setTripleAt(u,y,u-g*i*r*d,y-v*i*r*d,u+g*i*r*d,y+v*i*r*d,t,!0),n=!n,c+=a*d}},convertPolygonToPath:function(){var t,e=Math.floor(this.pt.v),r=2*Math.PI/e,i=this.or.v,s=this.os.v,a=2*Math.PI*i/(4*e),n=-Math.PI/2,o=3===this.data.d?-1:1;for(n+=this.r.v,t=this.v._length=0;t<e;t+=1){var h=i*Math.cos(n),p=i*Math.sin(n),l=0===h&&0===p?0:p/Math.sqrt(h*h+p*p),m=0===h&&0===p?0:-h/Math.sqrt(h*h+p*p);h+=+this.p.v[0],p+=+this.p.v[1],this.v.setTripleAt(h,p,h-l*a*s*o,p-m*a*s*o,h+l*a*s*o,p+m*a*s*o,t,!0),n+=r*o}this.paths.length=0,this.paths[0]=this.v}},extendPrototype([DynamicPropertyContainer],f),f);function f(t,e){this.v=shape_pool.newElement(),this.v.setPathData(!0,0),this.elem=t,this.comp=t.comp,this.data=e,this.frameId=-1,this.d=e.d,this.initDynamicPropertyContainer(t),1===e.sy?(this.ir=PropertyFactory.getProp(t,e.ir,0,0,this),this.is=PropertyFactory.getProp(t,e.is,0,.01,this),this.convertToPath=this.convertStarToPath):this.convertToPath=this.convertPolygonToPath,this.pt=PropertyFactory.getProp(t,e.pt,0,0,this),this.p=PropertyFactory.getProp(t,e.p,1,0,this),this.r=PropertyFactory.getProp(t,e.r,0,degToRads,this),this.or=PropertyFactory.getProp(t,e.or,0,0,this),this.os=PropertyFactory.getProp(t,e.os,0,.01,this),this.localShapeCollection=shapeCollection_pool.newShapeCollection(),this.localShapeCollection.addShape(this.v),this.paths=this.localShapeCollection,this.dynamicProperties.length?this.k=!0:(this.k=!1,this.convertToPath())}var c=(d.prototype={convertRectToPath:function(){var t=this.p.v[0],e=this.p.v[1],r=this.s.v[0]/2,i=this.s.v[1]/2,s=bm_min(r,i,this.r.v),a=s*(1-roundCorner);this.v._length=0,2===this.d||1===this.d?(this.v.setTripleAt(t+r,e-i+s,t+r,e-i+s,t+r,e-i+a,0,!0),this.v.setTripleAt(t+r,e+i-s,t+r,e+i-a,t+r,e+i-s,1,!0),0!==s?(this.v.setTripleAt(t+r-s,e+i,t+r-s,e+i,t+r-a,e+i,2,!0),this.v.setTripleAt(t-r+s,e+i,t-r+a,e+i,t-r+s,e+i,3,!0),this.v.setTripleAt(t-r,e+i-s,t-r,e+i-s,t-r,e+i-a,4,!0),this.v.setTripleAt(t-r,e-i+s,t-r,e-i+a,t-r,e-i+s,5,!0),this.v.setTripleAt(t-r+s,e-i,t-r+s,e-i,t-r+a,e-i,6,!0),this.v.setTripleAt(t+r-s,e-i,t+r-a,e-i,t+r-s,e-i,7,!0)):(this.v.setTripleAt(t-r,e+i,t-r+a,e+i,t-r,e+i,2),this.v.setTripleAt(t-r,e-i,t-r,e-i+a,t-r,e-i,3))):(this.v.setTripleAt(t+r,e-i+s,t+r,e-i+a,t+r,e-i+s,0,!0),0!==s?(this.v.setTripleAt(t+r-s,e-i,t+r-s,e-i,t+r-a,e-i,1,!0),this.v.setTripleAt(t-r+s,e-i,t-r+a,e-i,t-r+s,e-i,2,!0),this.v.setTripleAt(t-r,e-i+s,t-r,e-i+s,t-r,e-i+a,3,!0),this.v.setTripleAt(t-r,e+i-s,t-r,e+i-a,t-r,e+i-s,4,!0),this.v.setTripleAt(t-r+s,e+i,t-r+s,e+i,t-r+a,e+i,5,!0),this.v.setTripleAt(t+r-s,e+i,t+r-a,e+i,t+r-s,e+i,6,!0),this.v.setTripleAt(t+r,e+i-s,t+r,e+i-s,t+r,e+i-a,7,!0)):(this.v.setTripleAt(t-r,e-i,t-r+a,e-i,t-r,e-i,1,!0),this.v.setTripleAt(t-r,e+i,t-r,e+i-a,t-r,e+i,2,!0),this.v.setTripleAt(t+r,e+i,t+r-a,e+i,t+r,e+i,3,!0)))},getValue:function(t){this.elem.globalData.frameId!==this.frameId&&(this.frameId=this.elem.globalData.frameId,this.iterateDynamicProperties(),this._mdf&&this.convertRectToPath())},reset:a},extendPrototype([DynamicPropertyContainer],d),d);function d(t,e){this.v=shape_pool.newElement(),this.v.c=!0,this.localShapeCollection=shapeCollection_pool.newShapeCollection(),this.localShapeCollection.addShape(this.v),this.paths=this.localShapeCollection,this.elem=t,this.comp=t.comp,this.frameId=-1,this.d=e.d,this.initDynamicPropertyContainer(t),this.p=PropertyFactory.getProp(t,e.p,1,0,this),this.s=PropertyFactory.getProp(t,e.s,1,0,this),this.r=PropertyFactory.getProp(t,e.r,0,0,this),this.dynamicProperties.length?this.k=!0:(this.k=!1,this.convertRectToPath())}var u={getShapeProp:function(t,e,r){var i;return 3===r||4===r?i=(3===r?e.pt:e.ks).k.length?new o(t,e,r):new n(t,e,r):5===r?i=new c(t,e):6===r?i=new p(t,e):7===r&&(i=new m(t,e)),i.k&&t.addDynamicProperty(i),i},getConstructorFunction:function(){return n},getKeyframedConstructorFunction:function(){return o}};return u}(),ShapeModifiers=(Tr={},Ur={},Tr.registerModifier=function(t,e){Ur[t]||(Ur[t]=e)},Tr.getModifier=function(t,e,r){return new Ur[t](e,r)},Tr),Tr,Ur;function ShapeModifier(){}function TrimModifier(){}function RoundCornersModifier(){}function RepeaterModifier(){}function ShapeCollection(){this._length=0,this._maxLength=4,this.shapes=createSizedArray(this._maxLength)}function DashProperty(t,e,r,i){this.elem=t,this.frameId=-1,this.dataProps=createSizedArray(e.length),this.renderer=r,this.k=!1,this.dashStr="",this.dashArray=createTypedArray("float32",e.length?e.length-1:0),this.dashoffset=createTypedArray("float32",1),this.initDynamicPropertyContainer(i);var s,a,n=e.length||0;for(s=0;s<n;s+=1)a=PropertyFactory.getProp(t,e[s].v,0,0,this),this.k=a.k||this.k,this.dataProps[s]={n:e[s].n,p:a};this.k||this.getValue(!0),this._isAnimated=this.k}function GradientProperty(t,e,r){this.data=e,this.c=createTypedArray("uint8c",4*e.p);var i=e.k.k[0].s?e.k.k[0].s.length-4*e.p:e.k.k.length-4*e.p;this.o=createTypedArray("float32",i),this._cmdf=!1,this._omdf=!1,this._collapsable=this.checkCollapsable(),this._hasOpacity=i,this.initDynamicPropertyContainer(r),this.prop=PropertyFactory.getProp(t,e.k,1,null,this),this.k=this.prop.k,this.getValue(!0)}ShapeModifier.prototype.initModifierProperties=function(){},ShapeModifier.prototype.addShapeToModifier=function(){},ShapeModifier.prototype.addShape=function(t){if(!this.closed){var e={shape:t.sh,data:t,localShapeCollection:shapeCollection_pool.newShapeCollection()};this.shapes.push(e),this.addShapeToModifier(e),this._isAnimated&&t.setAsAnimated()}},ShapeModifier.prototype.init=function(t,e){this.shapes=[],this.elem=t,this.initDynamicPropertyContainer(t),this.initModifierProperties(t,e),this.frameId=initialDefaultFrame,this.closed=!1,this.k=!1,this.dynamicProperties.length?this.k=!0:this.getValue(!0)},ShapeModifier.prototype.processKeys=function(){this.elem.globalData.frameId!==this.frameId&&(this.frameId=this.elem.globalData.frameId,this.iterateDynamicProperties())},extendPrototype([DynamicPropertyContainer],ShapeModifier),extendPrototype([ShapeModifier],TrimModifier),TrimModifier.prototype.initModifierProperties=function(t,e){this.s=PropertyFactory.getProp(t,e.s,0,.01,this),this.e=PropertyFactory.getProp(t,e.e,0,.01,this),this.o=PropertyFactory.getProp(t,e.o,0,0,this),this.sValue=0,this.eValue=0,this.getValue=this.processKeys,this.m=e.m,this._isAnimated=!!this.s.effectsSequence.length||!!this.e.effectsSequence.length||!!this.o.effectsSequence.length},TrimModifier.prototype.addShapeToModifier=function(t){t.pathsData=[]},TrimModifier.prototype.calculateShapeEdges=function(t,e,r,i,s){var a=[];e<=1?a.push({s:t,e:e}):1<=t?a.push({s:t-1,e:e-1}):(a.push({s:t,e:1}),a.push({s:0,e:e-1}));var n,o,h=[],p=a.length;for(n=0;n<p;n+=1){var l,m;if((o=a[n]).e*s<i||o.s*s>i+r);else l=o.s*s<=i?0:(o.s*s-i)/r,m=o.e*s>=i+r?1:(o.e*s-i)/r,h.push([l,m])}return h.length||h.push([0,0]),h},TrimModifier.prototype.releasePathsData=function(t){var e,r=t.length;for(e=0;e<r;e+=1)segments_length_pool.release(t[e]);return t.length=0,t},TrimModifier.prototype.processShapes=function(t){var e,r,i;if(this._mdf||t){var s=this.o.v%360/360;if(s<0&&(s+=1),e=(1<this.s.v?1:this.s.v<0?0:this.s.v)+s,(r=(1<this.e.v?1:this.e.v<0?0:this.e.v)+s)<e){var a=e;e=r,r=a}e=1e-4*Math.round(1e4*e),r=1e-4*Math.round(1e4*r),this.sValue=e,this.eValue=r}else e=this.sValue,r=this.eValue;var n,o,h,p,l,m,f=this.shapes.length,c=0;if(r===e)for(n=0;n<f;n+=1)this.shapes[n].localShapeCollection.releaseShapes(),this.shapes[n].shape._mdf=!0,this.shapes[n].shape.paths=this.shapes[n].localShapeCollection;else if(1===r&&0===e||0===r&&1===e){if(this._mdf)for(n=0;n<f;n+=1)this.shapes[n].pathsData.length=0,this.shapes[n].shape._mdf=!0}else{var d,u,y=[];for(n=0;n<f;n+=1)if((d=this.shapes[n]).shape._mdf||this._mdf||t||2===this.m){if(h=(i=d.shape.paths)._length,m=0,!d.shape._mdf&&d.pathsData.length)m=d.totalShapeLength;else{for(p=this.releasePathsData(d.pathsData),o=0;o<h;o+=1)l=bez.getSegmentsLength(i.shapes[o]),p.push(l),m+=l.totalLength;d.totalShapeLength=m,d.pathsData=p}c+=m,d.shape._mdf=!0}else d.shape.paths=d.localShapeCollection;var g,v=e,P=r,b=0;for(n=f-1;0<=n;n-=1)if((d=this.shapes[n]).shape._mdf){for((u=d.localShapeCollection).releaseShapes(),2===this.m&&1<f?(g=this.calculateShapeEdges(e,r,d.totalShapeLength,b,c),b+=d.totalShapeLength):g=[[v,P]],h=g.length,o=0;o<h;o+=1){v=g[o][0],P=g[o][1],y.length=0,P<=1?y.push({s:d.totalShapeLength*v,e:d.totalShapeLength*P}):1<=v?y.push({s:d.totalShapeLength*(v-1),e:d.totalShapeLength*(P-1)}):(y.push({s:d.totalShapeLength*v,e:d.totalShapeLength}),y.push({s:0,e:d.totalShapeLength*(P-1)}));var x=this.addShapes(d,y[0]);if(y[0].s!==y[0].e){if(1<y.length)if(d.shape.paths.shapes[d.shape.paths._length-1].c){var _=x.pop();this.addPaths(x,u),x=this.addShapes(d,y[1],_)}else this.addPaths(x,u),x=this.addShapes(d,y[1]);this.addPaths(x,u)}}d.shape.paths=u}}},TrimModifier.prototype.addPaths=function(t,e){var r,i=t.length;for(r=0;r<i;r+=1)e.addShape(t[r])},TrimModifier.prototype.addSegment=function(t,e,r,i,s,a,n){s.setXYAt(e[0],e[1],"o",a),s.setXYAt(r[0],r[1],"i",a+1),n&&s.setXYAt(t[0],t[1],"v",a),s.setXYAt(i[0],i[1],"v",a+1)},TrimModifier.prototype.addSegmentFromArray=function(t,e,r,i){e.setXYAt(t[1],t[5],"o",r),e.setXYAt(t[2],t[6],"i",r+1),i&&e.setXYAt(t[0],t[4],"v",r),e.setXYAt(t[3],t[7],"v",r+1)},TrimModifier.prototype.addShapes=function(t,e,r){var i,s,a,n,o,h,p,l,m=t.pathsData,f=t.shape.paths.shapes,c=t.shape.paths._length,d=0,u=[],y=!0;for(l=r?(o=r._length,r._length):(r=shape_pool.newElement(),o=0),u.push(r),i=0;i<c;i+=1){for(h=m[i].lengths,r.c=f[i].c,a=f[i].c?h.length:h.length+1,s=1;s<a;s+=1)if(d+(n=h[s-1]).addedLength<e.s)d+=n.addedLength,r.c=!1;else{if(d>e.e){r.c=!1;break}e.s<=d&&e.e>=d+n.addedLength?(this.addSegment(f[i].v[s-1],f[i].o[s-1],f[i].i[s],f[i].v[s],r,o,y),y=!1):(p=bez.getNewSegment(f[i].v[s-1],f[i].v[s],f[i].o[s-1],f[i].i[s],(e.s-d)/n.addedLength,(e.e-d)/n.addedLength,h[s-1]),this.addSegmentFromArray(p,r,o,y),y=!1,r.c=!1),d+=n.addedLength,o+=1}if(f[i].c&&h.length){if(n=h[s-1],d<=e.e){var g=h[s-1].addedLength;e.s<=d&&e.e>=d+g?(this.addSegment(f[i].v[s-1],f[i].o[s-1],f[i].i[0],f[i].v[0],r,o,y),y=!1):(p=bez.getNewSegment(f[i].v[s-1],f[i].v[0],f[i].o[s-1],f[i].i[0],(e.s-d)/g,(e.e-d)/g,h[s-1]),this.addSegmentFromArray(p,r,o,y),y=!1,r.c=!1)}else r.c=!1;d+=n.addedLength,o+=1}if(r._length&&(r.setXYAt(r.v[l][0],r.v[l][1],"i",l),r.setXYAt(r.v[r._length-1][0],r.v[r._length-1][1],"o",r._length-1)),d>e.e)break;i<c-1&&(r=shape_pool.newElement(),y=!0,u.push(r),o=0)}return u},ShapeModifiers.registerModifier("tm",TrimModifier),extendPrototype([ShapeModifier],RoundCornersModifier),RoundCornersModifier.prototype.initModifierProperties=function(t,e){this.getValue=this.processKeys,this.rd=PropertyFactory.getProp(t,e.r,0,null,this),this._isAnimated=!!this.rd.effectsSequence.length},RoundCornersModifier.prototype.processPath=function(t,e){var r=shape_pool.newElement();r.c=t.c;var i,s,a,n,o,h,p,l,m,f,c,d,u,y=t._length,g=0;for(i=0;i<y;i+=1)s=t.v[i],n=t.o[i],a=t.i[i],s[0]===n[0]&&s[1]===n[1]&&s[0]===a[0]&&s[1]===a[1]?0!==i&&i!==y-1||t.c?(o=0===i?t.v[y-1]:t.v[i-1],p=(h=Math.sqrt(Math.pow(s[0]-o[0],2)+Math.pow(s[1]-o[1],2)))?Math.min(h/2,e)/h:0,l=d=s[0]+(o[0]-s[0])*p,m=u=s[1]-(s[1]-o[1])*p,f=l-(l-s[0])*roundCorner,c=m-(m-s[1])*roundCorner,r.setTripleAt(l,m,f,c,d,u,g),g+=1,o=i===y-1?t.v[0]:t.v[i+1],p=(h=Math.sqrt(Math.pow(s[0]-o[0],2)+Math.pow(s[1]-o[1],2)))?Math.min(h/2,e)/h:0,l=f=s[0]+(o[0]-s[0])*p,m=c=s[1]+(o[1]-s[1])*p,d=l-(l-s[0])*roundCorner,u=m-(m-s[1])*roundCorner,r.setTripleAt(l,m,f,c,d,u,g)):r.setTripleAt(s[0],s[1],n[0],n[1],a[0],a[1],g):r.setTripleAt(t.v[i][0],t.v[i][1],t.o[i][0],t.o[i][1],t.i[i][0],t.i[i][1],g),g+=1;return r},RoundCornersModifier.prototype.processShapes=function(t){var e,r,i,s,a,n,o=this.shapes.length,h=this.rd.v;if(0!==h)for(r=0;r<o;r+=1){if((a=this.shapes[r]).shape.paths,n=a.localShapeCollection,a.shape._mdf||this._mdf||t)for(n.releaseShapes(),a.shape._mdf=!0,e=a.shape.paths.shapes,s=a.shape.paths._length,i=0;i<s;i+=1)n.addShape(this.processPath(e[i],h));a.shape.paths=a.localShapeCollection}this.dynamicProperties.length||(this._mdf=!1)},ShapeModifiers.registerModifier("rd",RoundCornersModifier),extendPrototype([ShapeModifier],RepeaterModifier),RepeaterModifier.prototype.initModifierProperties=function(t,e){this.getValue=this.processKeys,this.c=PropertyFactory.getProp(t,e.c,0,null,this),this.o=PropertyFactory.getProp(t,e.o,0,null,this),this.tr=TransformPropertyFactory.getTransformProperty(t,e.tr,this),this.so=PropertyFactory.getProp(t,e.tr.so,0,.01,this),this.eo=PropertyFactory.getProp(t,e.tr.eo,0,.01,this),this.data=e,this.dynamicProperties.length||this.getValue(!0),this._isAnimated=!!this.dynamicProperties.length,this.pMatrix=new Matrix,this.rMatrix=new Matrix,this.sMatrix=new Matrix,this.tMatrix=new Matrix,this.matrix=new Matrix},RepeaterModifier.prototype.applyTransforms=function(t,e,r,i,s,a){var n=a?-1:1,o=i.s.v[0]+(1-i.s.v[0])*(1-s),h=i.s.v[1]+(1-i.s.v[1])*(1-s);t.translate(i.p.v[0]*n*s,i.p.v[1]*n*s,i.p.v[2]),e.translate(-i.a.v[0],-i.a.v[1],i.a.v[2]),e.rotate(-i.r.v*n*s),e.translate(i.a.v[0],i.a.v[1],i.a.v[2]),r.translate(-i.a.v[0],-i.a.v[1],i.a.v[2]),r.scale(a?1/o:o,a?1/h:h),r.translate(i.a.v[0],i.a.v[1],i.a.v[2])},RepeaterModifier.prototype.init=function(t,e,r,i){this.elem=t,this.arr=e,this.pos=r,this.elemsData=i,this._currentCopies=0,this._elements=[],this._groups=[],this.frameId=-1,this.initDynamicPropertyContainer(t),this.initModifierProperties(t,e[r]);for(;0<r;)r-=1,this._elements.unshift(e[r]),1;this.dynamicProperties.length?this.k=!0:this.getValue(!0)},RepeaterModifier.prototype.resetElements=function(t){var e,r=t.length;for(e=0;e<r;e+=1)t[e]._processed=!1,"gr"===t[e].ty&&this.resetElements(t[e].it)},RepeaterModifier.prototype.cloneElements=function(t){t.length;var e=JSON.parse(JSON.stringify(t));return this.resetElements(e),e},RepeaterModifier.prototype.changeGroupRender=function(t,e){var r,i=t.length;for(r=0;r<i;r+=1)t[r]._render=e,"gr"===t[r].ty&&this.changeGroupRender(t[r].it,e)},RepeaterModifier.prototype.processShapes=function(t){var e,r,i,s,a;if(this._mdf||t){var n,o=Math.ceil(this.c.v);if(this._groups.length<o){for(;this._groups.length<o;){var h={it:this.cloneElements(this._elements),ty:"gr"};h.it.push({a:{a:0,ix:1,k:[0,0]},nm:"Transform",o:{a:0,ix:7,k:100},p:{a:0,ix:2,k:[0,0]},r:{a:1,ix:6,k:[{s:0,e:0,t:0},{s:0,e:0,t:1}]},s:{a:0,ix:3,k:[100,100]},sa:{a:0,ix:5,k:0},sk:{a:0,ix:4,k:0},ty:"tr"}),this.arr.splice(0,0,h),this._groups.splice(0,0,h),this._currentCopies+=1}this.elem.reloadShapes()}for(i=a=0;i<=this._groups.length-1;i+=1)n=a<o,this._groups[i]._render=n,this.changeGroupRender(this._groups[i].it,n),a+=1;this._currentCopies=o;var p=this.o.v,l=p%1,m=0<p?Math.floor(p):Math.ceil(p),f=(this.tr.v.props,this.pMatrix.props),c=this.rMatrix.props,d=this.sMatrix.props;this.pMatrix.reset(),this.rMatrix.reset(),this.sMatrix.reset(),this.tMatrix.reset(),this.matrix.reset();var u,y,g=0;if(0<p){for(;g<m;)this.applyTransforms(this.pMatrix,this.rMatrix,this.sMatrix,this.tr,1,!1),g+=1;l&&(this.applyTransforms(this.pMatrix,this.rMatrix,this.sMatrix,this.tr,l,!1),g+=l)}else if(p<0){for(;m<g;)this.applyTransforms(this.pMatrix,this.rMatrix,this.sMatrix,this.tr,1,!0),g-=1;l&&(this.applyTransforms(this.pMatrix,this.rMatrix,this.sMatrix,this.tr,-l,!0),g-=l)}for(i=1===this.data.m?0:this._currentCopies-1,s=1===this.data.m?1:-1,a=this._currentCopies;a;){if(y=(r=(e=this.elemsData[i].it)[e.length-1].transform.mProps.v.props).length,e[e.length-1].transform.mProps._mdf=!0,e[e.length-1].transform.op._mdf=!0,e[e.length-1].transform.op.v=this.so.v+(this.eo.v-this.so.v)*(i/(this._currentCopies-1)),0!==g){for((0!==i&&1===s||i!==this._currentCopies-1&&-1===s)&&this.applyTransforms(this.pMatrix,this.rMatrix,this.sMatrix,this.tr,1,!1),this.matrix.transform(c[0],c[1],c[2],c[3],c[4],c[5],c[6],c[7],c[8],c[9],c[10],c[11],c[12],c[13],c[14],c[15]),this.matrix.transform(d[0],d[1],d[2],d[3],d[4],d[5],d[6],d[7],d[8],d[9],d[10],d[11],d[12],d[13],d[14],d[15]),this.matrix.transform(f[0],f[1],f[2],f[3],f[4],f[5],f[6],f[7],f[8],f[9],f[10],f[11],f[12],f[13],f[14],f[15]),u=0;u<y;u+=1)r[u]=this.matrix.props[u];this.matrix.reset()}else for(this.matrix.reset(),u=0;u<y;u+=1)r[u]=this.matrix.props[u];g+=1,a-=1,i+=s}}else for(a=this._currentCopies,i=0,s=1;a;)r=(e=this.elemsData[i].it)[e.length-1].transform.mProps.v.props,e[e.length-1].transform.mProps._mdf=!1,e[e.length-1].transform.op._mdf=!1,a-=1,i+=s},RepeaterModifier.prototype.addShape=function(){},ShapeModifiers.registerModifier("rp",RepeaterModifier),ShapeCollection.prototype.addShape=function(t){this._length===this._maxLength&&(this.shapes=this.shapes.concat(createSizedArray(this._maxLength)),this._maxLength*=2),this.shapes[this._length]=t,this._length+=1},ShapeCollection.prototype.releaseShapes=function(){var t;for(t=0;t<this._length;t+=1)shape_pool.release(this.shapes[t]);this._length=0},DashProperty.prototype.getValue=function(t){if((this.elem.globalData.frameId!==this.frameId||t)&&(this.frameId=this.elem.globalData.frameId,this.iterateDynamicProperties(),this._mdf=this._mdf||t,this._mdf)){var e=0,r=this.dataProps.length;for("svg"===this.renderer&&(this.dashStr=""),e=0;e<r;e+=1)"o"!=this.dataProps[e].n?"svg"===this.renderer?this.dashStr+=" "+this.dataProps[e].p.v:this.dashArray[e]=this.dataProps[e].p.v:this.dashoffset[0]=this.dataProps[e].p.v}},extendPrototype([DynamicPropertyContainer],DashProperty),GradientProperty.prototype.comparePoints=function(t,e){for(var r=0,i=this.o.length/2;r<i;){if(.01<Math.abs(t[4*r]-t[4*e+2*r]))return!1;r+=1}return!0},GradientProperty.prototype.checkCollapsable=function(){if(this.o.length/2!=this.c.length/4)return!1;if(this.data.k.k[0].s)for(var t=0,e=this.data.k.k.length;t<e;){if(!this.comparePoints(this.data.k.k[t].s,this.data.p))return!1;t+=1}else if(!this.comparePoints(this.data.k.k,this.data.p))return!1;return!0},GradientProperty.prototype.getValue=function(t){if(this.prop.getValue(),this._mdf=!1,this._cmdf=!1,this._omdf=!1,this.prop._mdf||t){var e,r,i,s=4*this.data.p;for(e=0;e<s;e+=1)r=e%4==0?100:255,i=Math.round(this.prop.v[e]*r),this.c[e]!==i&&(this.c[e]=i,this._cmdf=!t);if(this.o.length)for(s=this.prop.v.length,e=4*this.data.p;e<s;e+=1)r=e%2==0?100:1,i=e%2==0?Math.round(100*this.prop.v[e]):this.prop.v[e],this.o[e-4*this.data.p]!==i&&(this.o[e-4*this.data.p]=i,this._omdf=!t);this._mdf=!t}},extendPrototype([DynamicPropertyContainer],GradientProperty);var buildShapeString=function(t,e,r,i){if(0===e)return"";var s,a=t.o,n=t.i,o=t.v,h=" M"+i.applyToPointStringified(o[0][0],o[0][1]);for(s=1;s<e;s+=1)h+=" C"+i.applyToPointStringified(a[s-1][0],a[s-1][1])+" "+i.applyToPointStringified(n[s][0],n[s][1])+" "+i.applyToPointStringified(o[s][0],o[s][1]);return r&&e&&(h+=" C"+i.applyToPointStringified(a[s-1][0],a[s-1][1])+" "+i.applyToPointStringified(n[0][0],n[0][1])+" "+i.applyToPointStringified(o[0][0],o[0][1]),h+="z"),h},ImagePreloader=function(){},featureSupport=(Iv={maskType:!0},(/MSIE 10/i.test(navigator.userAgent)||/MSIE 9/i.test(navigator.userAgent)||/rv:11.0/i.test(navigator.userAgent)||/Edge\/\d./i.test(navigator.userAgent))&&(Iv.maskType=!1),Iv),Iv,filtersFactory=(Jv={},Jv.createFilter=function(t){var e=createNS("filter");return e.setAttribute("id",t),e.setAttribute("filterUnits","objectBoundingBox"),e.setAttribute("x","0%"),e.setAttribute("y","0%"),e.setAttribute("width","100%"),e.setAttribute("height","100%"),e},Jv.createAlphaToLuminanceFilter=function(){var t=createNS("feColorMatrix");return t.setAttribute("type","matrix"),t.setAttribute("color-interpolation-filters","sRGB"),t.setAttribute("values","0 0 0 1 0  0 0 0 1 0  0 0 0 1 0  0 0 0 1 1"),t},Jv),Jv,assetLoader={load:function(t,e,r){var i,s=new XMLHttpRequest;s.open("GET",t,!0);try{s.responseType="json"}catch(t){}s.send(),s.onreadystatechange=function(){if(4==s.readyState)if(200==s.status)i=Pv(s),e(i);else try{i=Pv(s),e(i)}catch(t){r&&r(t)}}}};function Pv(t){return t.response&&"object"==typeof t.response?t.response:t.response&&"string"==typeof t.response?JSON.parse(t.response):t.responseText?JSON.parse(t.responseText):void 0}var assetLoader=null;function TextAnimatorProperty(t,e,r){this._isFirstFrame=!0,this._hasMaskedPath=!1,this._frameId=-1,this._textData=t,this._renderType=e,this._elem=r,this._animatorsData=createSizedArray(this._textData.a.length),this._pathData={},this._moreOptions={alignment:{}},this.renderedLetters=[],this.lettersChangedFlag=!1,this.initDynamicPropertyContainer(r)}function TextAnimatorDataProperty(t,e,r){var i={propType:!1},s=PropertyFactory.getProp,a=e.a;this.a={r:a.r?s(t,a.r,0,degToRads,r):i,rx:a.rx?s(t,a.rx,0,degToRads,r):i,ry:a.ry?s(t,a.ry,0,degToRads,r):i,sk:a.sk?s(t,a.sk,0,degToRads,r):i,sa:a.sa?s(t,a.sa,0,degToRads,r):i,s:a.s?s(t,a.s,1,.01,r):i,a:a.a?s(t,a.a,1,0,r):i,o:a.o?s(t,a.o,0,.01,r):i,p:a.p?s(t,a.p,1,0,r):i,sw:a.sw?s(t,a.sw,0,0,r):i,sc:a.sc?s(t,a.sc,1,0,r):i,fc:a.fc?s(t,a.fc,1,0,r):i,fh:a.fh?s(t,a.fh,0,0,r):i,fs:a.fs?s(t,a.fs,0,.01,r):i,fb:a.fb?s(t,a.fb,0,.01,r):i,t:a.t?s(t,a.t,0,0,r):i},this.s=TextSelectorProp.getTextSelectorProp(t,e.s,r),this.s.t=e.s.t}function LetterProps(t,e,r,i,s,a){this.o=t,this.sw=e,this.sc=r,this.fc=i,this.m=s,this.p=a,this._mdf={o:!0,sw:!!e,sc:!!r,fc:!!i,m:!0,p:!0}}function TextProperty(t,e){this._frameId=initialDefaultFrame,this.pv="",this.v="",this.kf=!1,this._isFirstFrame=!0,this._mdf=!1,this.data=e,this.elem=t,this.comp=this.elem.comp,this.keysIndex=0,this.canResize=!1,this.minimumFontSize=1,this.effectsSequence=[],this.currentData={ascent:0,boxWidth:this.defaultBoxWidth,f:"",fStyle:"",fWeight:"",fc:"",j:"",justifyOffset:"",l:[],lh:0,lineWidths:[],ls:"",of:"",s:"",sc:"",sw:0,t:0,tr:0,sz:0,ps:null,fillColorAnim:!1,strokeColorAnim:!1,strokeWidthAnim:!1,yOffset:0,finalSize:0,finalText:[],finalLineHeight:0,__complete:!1},this.copyData(this.currentData,this.data.d.k[0].s),this.searchProperty()||this.completeTextData(this.currentData)}TextAnimatorProperty.prototype.searchProperties=function(){var t,e,r=this._textData.a.length,i=PropertyFactory.getProp;for(t=0;t<r;t+=1)e=this._textData.a[t],this._animatorsData[t]=new TextAnimatorDataProperty(this._elem,e,this);this._textData.p&&"m"in this._textData.p?(this._pathData={f:i(this._elem,this._textData.p.f,0,0,this),l:i(this._elem,this._textData.p.l,0,0,this),r:this._textData.p.r,m:this._elem.maskManager.getMaskProperty(this._textData.p.m)},this._hasMaskedPath=!0):this._hasMaskedPath=!1,this._moreOptions.alignment=i(this._elem,this._textData.m.a,1,0,this)},TextAnimatorProperty.prototype.getMeasures=function(t,e){if(this.lettersChangedFlag=e,this._mdf||this._isFirstFrame||e||this._hasMaskedPath&&this._pathData.m._mdf){this._isFirstFrame=!1;var r,i,s,a,n,o,h,p,l,m,f,c,d,u,y,g,v,P,b,x=this._moreOptions.alignment.v,_=this._animatorsData,S=this._textData,T=this.mHelper,A=this._renderType,E=this.renderedLetters.length,C=(this.data,t.l);if(this._hasMaskedPath){if(b=this._pathData.m,!this._pathData.n||this._pathData._mdf){var k,D=b.v;for(this._pathData.r&&(D=D.reverse()),n={tLength:0,segments:[]},a=D._length-1,s=g=0;s<a;s+=1)k=bez.buildBezierData(D.v[s],D.v[s+1],[D.o[s][0]-D.v[s][0],D.o[s][1]-D.v[s][1]],[D.i[s+1][0]-D.v[s+1][0],D.i[s+1][1]-D.v[s+1][1]]),n.tLength+=k.segmentLength,n.segments.push(k),g+=k.segmentLength;s=a,b.v.c&&(k=bez.buildBezierData(D.v[s],D.v[0],[D.o[s][0]-D.v[s][0],D.o[s][1]-D.v[s][1]],[D.i[0][0]-D.v[0][0],D.i[0][1]-D.v[0][1]]),n.tLength+=k.segmentLength,n.segments.push(k),g+=k.segmentLength),this._pathData.pi=n}if(n=this._pathData.pi,o=this._pathData.f.v,m=1,l=!(p=f=0),u=n.segments,o<0&&b.v.c)for(n.tLength<Math.abs(o)&&(o=-Math.abs(o)%n.tLength),m=(d=u[f=u.length-1].points).length-1;o<0;)o+=d[m].partialLength,(m-=1)<0&&(m=(d=u[f-=1].points).length-1);c=(d=u[f].points)[m-1],y=(h=d[m]).partialLength}a=C.length,i=r=0;var I,M,w,F,V=1.2*t.finalSize*.714,R=!0;w=_.length;var L,z,O,B,N,G,j,J,K,q,H,W,Y,X=-1,Q=o,$=f,U=m,Z=-1,tt="",et=this.defaultPropsArray;if(2===t.j||1===t.j){var rt=0,it=0,st=2===t.j?-.5:-1,at=0,nt=!0;for(s=0;s<a;s+=1)if(C[s].n){for(rt&&(rt+=it);at<s;)C[at].animatorJustifyOffset=rt,at+=1;nt=!(rt=0)}else{for(M=0;M<w;M+=1)(I=_[M].a).t.propType&&(nt&&2===t.j&&(it+=I.t.v*st),(L=_[M].s.getMult(C[s].anIndexes[M],S.a[M].s.totalChars)).length?rt+=I.t.v*L[0]*st:rt+=I.t.v*L*st);nt=!1}for(rt&&(rt+=it);at<s;)C[at].animatorJustifyOffset=rt,at+=1}for(s=0;s<a;s+=1){if(T.reset(),N=1,C[s].n)r=0,i+=t.yOffset,i+=R?1:0,o=Q,R=!1,0,this._hasMaskedPath&&(m=U,c=(d=u[f=$].points)[m-1],y=(h=d[m]).partialLength,p=0),Y=q=W=tt="",et=this.defaultPropsArray;else{if(this._hasMaskedPath){if(Z!==C[s].line){switch(t.j){case 1:o+=g-t.lineWidths[C[s].line];break;case 2:o+=(g-t.lineWidths[C[s].line])/2}Z=C[s].line}X!==C[s].ind&&(C[X]&&(o+=C[X].extra),o+=C[s].an/2,X=C[s].ind),o+=x[0]*C[s].an/200;var ot=0;for(M=0;M<w;M+=1)(I=_[M].a).p.propType&&((L=_[M].s.getMult(C[s].anIndexes[M],S.a[M].s.totalChars)).length?ot+=I.p.v[0]*L[0]:ot+=I.p.v[0]*L),I.a.propType&&((L=_[M].s.getMult(C[s].anIndexes[M],S.a[M].s.totalChars)).length?ot+=I.a.v[0]*L[0]:ot+=I.a.v[0]*L);for(l=!0;l;)o+ot<=p+y||!d?(v=(o+ot-p)/h.partialLength,O=c.point[0]+(h.point[0]-c.point[0])*v,B=c.point[1]+(h.point[1]-c.point[1])*v,T.translate(-x[0]*C[s].an/200,-x[1]*V/100),l=!1):d&&(p+=h.partialLength,(m+=1)>=d.length&&(m=0,d=u[f+=1]?u[f].points:b.v.c?u[f=m=0].points:(p-=h.partialLength,null)),d&&(c=h,y=(h=d[m]).partialLength));z=C[s].an/2-C[s].add,T.translate(-z,0,0)}else z=C[s].an/2-C[s].add,T.translate(-z,0,0),T.translate(-x[0]*C[s].an/200,-x[1]*V/100,0);for(C[s].l/2,M=0;M<w;M+=1)(I=_[M].a).t.propType&&(L=_[M].s.getMult(C[s].anIndexes[M],S.a[M].s.totalChars),0===r&&0===t.j||(this._hasMaskedPath?L.length?o+=I.t.v*L[0]:o+=I.t.v*L:L.length?r+=I.t.v*L[0]:r+=I.t.v*L));for(C[s].l/2,t.strokeWidthAnim&&(j=t.sw||0),t.strokeColorAnim&&(G=t.sc?[t.sc[0],t.sc[1],t.sc[2]]:[0,0,0]),t.fillColorAnim&&t.fc&&(J=[t.fc[0],t.fc[1],t.fc[2]]),M=0;M<w;M+=1)(I=_[M].a).a.propType&&((L=_[M].s.getMult(C[s].anIndexes[M],S.a[M].s.totalChars)).length?T.translate(-I.a.v[0]*L[0],-I.a.v[1]*L[1],I.a.v[2]*L[2]):T.translate(-I.a.v[0]*L,-I.a.v[1]*L,I.a.v[2]*L));for(M=0;M<w;M+=1)(I=_[M].a).s.propType&&((L=_[M].s.getMult(C[s].anIndexes[M],S.a[M].s.totalChars)).length?T.scale(1+(I.s.v[0]-1)*L[0],1+(I.s.v[1]-1)*L[1],1):T.scale(1+(I.s.v[0]-1)*L,1+(I.s.v[1]-1)*L,1));for(M=0;M<w;M+=1){if(I=_[M].a,L=_[M].s.getMult(C[s].anIndexes[M],S.a[M].s.totalChars),I.sk.propType&&(L.length?T.skewFromAxis(-I.sk.v*L[0],I.sa.v*L[1]):T.skewFromAxis(-I.sk.v*L,I.sa.v*L)),I.r.propType&&(L.length?T.rotateZ(-I.r.v*L[2]):T.rotateZ(-I.r.v*L)),I.ry.propType&&(L.length?T.rotateY(I.ry.v*L[1]):T.rotateY(I.ry.v*L)),I.rx.propType&&(L.length?T.rotateX(I.rx.v*L[0]):T.rotateX(I.rx.v*L)),I.o.propType&&(L.length?N+=(I.o.v*L[0]-N)*L[0]:N+=(I.o.v*L-N)*L),t.strokeWidthAnim&&I.sw.propType&&(L.length?j+=I.sw.v*L[0]:j+=I.sw.v*L),t.strokeColorAnim&&I.sc.propType)for(K=0;K<3;K+=1)L.length?G[K]=G[K]+(I.sc.v[K]-G[K])*L[0]:G[K]=G[K]+(I.sc.v[K]-G[K])*L;if(t.fillColorAnim&&t.fc){if(I.fc.propType)for(K=0;K<3;K+=1)L.length?J[K]=J[K]+(I.fc.v[K]-J[K])*L[0]:J[K]=J[K]+(I.fc.v[K]-J[K])*L;I.fh.propType&&(J=L.length?addHueToRGB(J,I.fh.v*L[0]):addHueToRGB(J,I.fh.v*L)),I.fs.propType&&(J=L.length?addSaturationToRGB(J,I.fs.v*L[0]):addSaturationToRGB(J,I.fs.v*L)),I.fb.propType&&(J=L.length?addBrightnessToRGB(J,I.fb.v*L[0]):addBrightnessToRGB(J,I.fb.v*L))}}for(M=0;M<w;M+=1)(I=_[M].a).p.propType&&(L=_[M].s.getMult(C[s].anIndexes[M],S.a[M].s.totalChars),this._hasMaskedPath?L.length?T.translate(0,I.p.v[1]*L[0],-I.p.v[2]*L[1]):T.translate(0,I.p.v[1]*L,-I.p.v[2]*L):L.length?T.translate(I.p.v[0]*L[0],I.p.v[1]*L[1],-I.p.v[2]*L[2]):T.translate(I.p.v[0]*L,I.p.v[1]*L,-I.p.v[2]*L));if(t.strokeWidthAnim&&(q=j<0?0:j),t.strokeColorAnim&&(H="rgb("+Math.round(255*G[0])+","+Math.round(255*G[1])+","+Math.round(255*G[2])+")"),t.fillColorAnim&&t.fc&&(W="rgb("+Math.round(255*J[0])+","+Math.round(255*J[1])+","+Math.round(255*J[2])+")"),this._hasMaskedPath){if(T.translate(0,-t.ls),T.translate(0,x[1]*V/100+i,0),S.p.p){P=(h.point[1]-c.point[1])/(h.point[0]-c.point[0]);var ht=180*Math.atan(P)/Math.PI;h.point[0]<c.point[0]&&(ht+=180),T.rotate(-ht*Math.PI/180)}T.translate(O,B,0),o-=x[0]*C[s].an/200,C[s+1]&&X!==C[s+1].ind&&(o+=C[s].an/2,o+=t.tr/1e3*t.finalSize)}else{switch(T.translate(r,i,0),t.ps&&T.translate(t.ps[0],t.ps[1]+t.ascent,0),t.j){case 1:T.translate(C[s].animatorJustifyOffset+t.justifyOffset+(t.boxWidth-t.lineWidths[C[s].line]),0,0);break;case 2:T.translate(C[s].animatorJustifyOffset+t.justifyOffset+(t.boxWidth-t.lineWidths[C[s].line])/2,0,0)}T.translate(0,-t.ls),T.translate(z,0,0),T.translate(x[0]*C[s].an/200,x[1]*V/100,0),r+=C[s].l+t.tr/1e3*t.finalSize}"html"===A?tt=T.toCSS():"svg"===A?tt=T.to2dCSS():et=[T.props[0],T.props[1],T.props[2],T.props[3],T.props[4],T.props[5],T.props[6],T.props[7],T.props[8],T.props[9],T.props[10],T.props[11],T.props[12],T.props[13],T.props[14],T.props[15]],Y=N}E<=s?(F=new LetterProps(Y,q,H,W,tt,et),this.renderedLetters.push(F),E+=1,this.lettersChangedFlag=!0):(F=this.renderedLetters[s],this.lettersChangedFlag=F.update(Y,q,H,W,tt,et)||this.lettersChangedFlag)}}},TextAnimatorProperty.prototype.getValue=function(){this._elem.globalData.frameId!==this._frameId&&(this._frameId=this._elem.globalData.frameId,this.iterateDynamicProperties())},TextAnimatorProperty.prototype.mHelper=new Matrix,TextAnimatorProperty.prototype.defaultPropsArray=[],extendPrototype([DynamicPropertyContainer],TextAnimatorProperty),LetterProps.prototype.update=function(t,e,r,i,s,a){this._mdf.o=!1,this._mdf.sw=!1,this._mdf.sc=!1,this._mdf.fc=!1,this._mdf.m=!1;var n=this._mdf.p=!1;return this.o!==t&&(this.o=t,n=this._mdf.o=!0),this.sw!==e&&(this.sw=e,n=this._mdf.sw=!0),this.sc!==r&&(this.sc=r,n=this._mdf.sc=!0),this.fc!==i&&(this.fc=i,n=this._mdf.fc=!0),this.m!==s&&(this.m=s,n=this._mdf.m=!0),!a.length||this.p[0]===a[0]&&this.p[1]===a[1]&&this.p[4]===a[4]&&this.p[5]===a[5]&&this.p[12]===a[12]&&this.p[13]===a[13]||(this.p=a,n=this._mdf.p=!0),n},TextProperty.prototype.defaultBoxWidth=[0,0],TextProperty.prototype.copyData=function(t,e){for(var r in e)e.hasOwnProperty(r)&&(t[r]=e[r]);return t},TextProperty.prototype.setCurrentData=function(t){t.__complete||this.completeTextData(t),this.currentData=t,this.currentData.boxWidth=this.currentData.boxWidth||this.defaultBoxWidth,this._mdf=!0},TextProperty.prototype.searchProperty=function(){return this.searchKeyframes()},TextProperty.prototype.searchKeyframes=function(){return this.kf=1<this.data.d.k.length,this.kf&&this.addEffect(this.getKeyframeValue.bind(this)),this.kf},TextProperty.prototype.addEffect=function(t){this.effectsSequence.push(t),this.elem.addDynamicProperty(this)},TextProperty.prototype.getValue=function(t){if(this.elem.globalData.frameId!==this.frameId&&this.effectsSequence.length||t){this.currentData.t=this.data.d.k[this.keysIndex].s.t;var e=this.currentData,r=this.keysIndex;if(this.lock)this.setCurrentData(this.currentData);else{this.lock=!0,this._mdf=!1;var i,s=this.effectsSequence.length,a=t||this.data.d.k[this.keysIndex].s;for(i=0;i<s;i+=1)a=r!==this.keysIndex?this.effectsSequence[i](a,a.t):this.effectsSequence[i](this.currentData,a.t);e!==a&&this.setCurrentData(a),this.pv=this.v=this.currentData,this.lock=!1,this.frameId=this.elem.globalData.frameId}}},TextProperty.prototype.getKeyframeValue=function(){for(var t=this.data.d.k,e=this.elem.comp.renderedFrame,r=0,i=t.length;r<=i-1&&(t[r].s,!(r===i-1||t[r+1].t>e));)r+=1;return this.keysIndex!==r&&(this.keysIndex=r),this.data.d.k[this.keysIndex].s},TextProperty.prototype.buildFinalText=function(t){for(var e=FontManager.getCombinedCharacterCodes(),r=[],i=0,s=t.length;i<s;)-1!==e.indexOf(t.charCodeAt(i))?r[r.length-1]+=t.charAt(i):r.push(t.charAt(i)),i+=1;return r},TextProperty.prototype.completeTextData=function(t){t.__complete=!0;var e,r,i,s,a,n,o,h=this.elem.globalData.fontManager,p=this.data,l=[],m=0,f=p.m.g,c=0,d=0,u=0,y=[],g=0,v=0,P=h.getFontByName(t.f),b=0,x=P.fStyle?P.fStyle.split(" "):[],_="normal",S="normal";for(r=x.length,e=0;e<r;e+=1)switch(x[e].toLowerCase()){case"italic":S="italic";break;case"bold":_="700";break;case"black":_="900";break;case"medium":_="500";break;case"regular":case"normal":_="400";break;case"light":case"thin":_="200"}t.fWeight=P.fWeight||_,t.fStyle=S,r=t.t.length,t.finalSize=t.s,t.finalText=this.buildFinalText(t.t),t.finalLineHeight=t.lh;var T,A=t.tr/1e3*t.finalSize;if(t.sz)for(var E,C,k=!0,D=t.sz[0],I=t.sz[1];k;){g=E=0,r=(C=this.buildFinalText(t.t)).length,A=t.tr/1e3*t.finalSize;var M=-1;for(e=0;e<r;e+=1)T=C[e].charCodeAt(0),i=!1," "===C[e]?M=e:13!==T&&3!==T||(i=!(g=0),E+=t.finalLineHeight||1.2*t.finalSize),D<g+(b=h.chars?(o=h.getCharData(C[e],P.fStyle,P.fFamily),i?0:o.w*t.finalSize/100):h.measureText(C[e],t.f,t.finalSize))&&" "!==C[e]?(-1===M?r+=1:e=M,E+=t.finalLineHeight||1.2*t.finalSize,C.splice(e,M===e?1:0,"\r"),M=-1,g=0):(g+=b,g+=A);E+=P.ascent*t.finalSize/100,this.canResize&&t.finalSize>this.minimumFontSize&&I<E?(t.finalSize-=1,t.finalLineHeight=t.finalSize*t.lh/t.s):(t.finalText=C,r=t.finalText.length,k=!1)}g=-A;var w,F=b=0;for(e=0;e<r;e+=1)if(i=!1,T=(w=t.finalText[e]).charCodeAt(0)," "===w?s="\xa0":13===T||3===T?(F=0,y.push(g),v=v<g?g:v,g=-2*A,i=!(s=""),u+=1):s=t.finalText[e],b=h.chars?(o=h.getCharData(w,P.fStyle,h.getFontByName(t.f).fFamily),i?0:o.w*t.finalSize/100):h.measureText(s,t.f,t.finalSize)," "===w?F+=b+A:(g+=b+A+F,F=0),l.push({l:b,an:b,add:c,n:i,anIndexes:[],val:s,line:u,animatorJustifyOffset:0}),2==f){if(c+=b,""===s||"\xa0"===s||e===r-1){for(""!==s&&"\xa0"!==s||(c-=b);d<=e;)l[d].an=c,l[d].ind=m,l[d].extra=b,d+=1;m+=1,c=0}}else if(3==f){if(c+=b,""===s||e===r-1){for(""===s&&(c-=b);d<=e;)l[d].an=c,l[d].ind=m,l[d].extra=b,d+=1;c=0,m+=1}}else l[m].ind=m,l[m].extra=0,m+=1;if(t.l=l,v=v<g?g:v,y.push(g),t.sz)t.boxWidth=t.sz[0],t.justifyOffset=0;else switch(t.boxWidth=v,t.j){case 1:t.justifyOffset=-t.boxWidth;break;case 2:t.justifyOffset=-t.boxWidth/2;break;default:t.justifyOffset=0}t.lineWidths=y;var V,R,L=p.a;n=L.length;var z,O,B=[];for(a=0;a<n;a+=1){for((V=L[a]).a.sc&&(t.strokeColorAnim=!0),V.a.sw&&(t.strokeWidthAnim=!0),(V.a.fc||V.a.fh||V.a.fs||V.a.fb)&&(t.fillColorAnim=!0),O=0,z=V.s.b,e=0;e<r;e+=1)(R=l[e]).anIndexes[a]=O,(1==z&&""!==R.val||2==z&&""!==R.val&&"\xa0"!==R.val||3==z&&(R.n||"\xa0"==R.val||e==r-1)||4==z&&(R.n||e==r-1))&&(1===V.s.rn&&B.push(O),O+=1);p.a[a].s.totalChars=O;var N,G=-1;if(1===V.s.rn)for(e=0;e<r;e+=1)G!=(R=l[e]).anIndexes[a]&&(G=R.anIndexes[a],N=B.splice(Math.floor(Math.random()*B.length),1)[0]),R.anIndexes[a]=N}t.yOffset=t.finalLineHeight||1.2*t.finalSize,t.ls=t.ls||0,t.ascent=P.ascent*t.finalSize/100},TextProperty.prototype.updateDocumentData=function(t,e){e=void 0===e?this.keysIndex:e;var r=this.copyData({},this.data.d.k[e].s);r=this.copyData(r,t),this.data.d.k[e].s=r,this.recalculate(e),this.elem.addDynamicProperty(this)},TextProperty.prototype.recalculate=function(t){var e=this.data.d.k[t].s;e.__complete=!1,this.keysIndex=0,this._isFirstFrame=!0,this.getValue(e)},TextProperty.prototype.canResizeFont=function(t){this.canResize=t,this.recalculate(this.keysIndex),this.elem.addDynamicProperty(this)},TextProperty.prototype.setMinimumFontSize=function(t){this.minimumFontSize=Math.floor(t)||1,this.recalculate(this.keysIndex),this.elem.addDynamicProperty(this)};var TextSelectorProp=(cz=Math.max,dz=Math.min,ez=Math.floor,fz.prototype={getMult:function(t){this._currentTextLength!==this.elem.textProperty.currentData.l.length&&this.getValue();var e=BezierFactory.getBezierEasing(this.ne.v/100,0,1-this.xe.v/100,1).get,r=0,i=this.finalS,s=this.finalE,a=this.data.sh;if(2==a)r=e(r=s===i?s<=t?1:0:cz(0,dz(.5/(s-i)+(t-i)/(s-i),1)));else if(3==a)r=e(r=s===i?s<=t?0:1:1-cz(0,dz(.5/(s-i)+(t-i)/(s-i),1)));else if(4==a)s===i?r=0:(r=cz(0,dz(.5/(s-i)+(t-i)/(s-i),1)))<.5?r*=2:r=1-2*(r-.5),r=e(r);else if(5==a){if(s===i)r=0;else{var n=s-i,o=-n/2+(t=dz(cz(0,t+.5-i),s-i)),h=n/2;r=Math.sqrt(1-o*o/(h*h))}r=e(r)}else r=6==a?e(r=s===i?0:(t=dz(cz(0,t+.5-i),s-i),(1+Math.cos(Math.PI+2*Math.PI*t/(s-i)))/2)):(t>=ez(i)&&(r=t-i<0?1-(i-t):cz(0,dz(s-t,1))),e(r));return r*this.a.v},getValue:function(t){this.iterateDynamicProperties(),this._mdf=t||this._mdf,this._currentTextLength=this.elem.textProperty.currentData.l.length||0,t&&2===this.data.r&&(this.e.v=this._currentTextLength);var e=2===this.data.r?1:100/this.data.totalChars,r=this.o.v/e,i=this.s.v/e+r,s=this.e.v/e+r;if(s<i){var a=i;i=s,s=a}this.finalS=i,this.finalE=s}},extendPrototype([DynamicPropertyContainer],fz),{getTextSelectorProp:function(t,e,r){return new fz(t,e,r)}}),cz,dz,ez;function fz(t,e){this._currentTextLength=-1,this.k=!1,this.data=e,this.elem=t,this.comp=t.comp,this.finalS=0,this.finalE=0,this.initDynamicPropertyContainer(t),this.s=PropertyFactory.getProp(t,e.s||{k:0},0,0,this),this.e="e"in e?PropertyFactory.getProp(t,e.e,0,0,this):{v:100},this.o=PropertyFactory.getProp(t,e.o||{k:0},0,0,this),this.xe=PropertyFactory.getProp(t,e.xe||{k:0},0,0,this),this.ne=PropertyFactory.getProp(t,e.ne||{k:0},0,0,this),this.a=PropertyFactory.getProp(t,e.a,0,.01,this),this.dynamicProperties.length||this.getValue()}var pool_factory=function(t,e,r,i){var s=0,a=t,n=createSizedArray(a);function o(){return s?n[s-=1]:e()}return{newElement:o,release:function(t){s===a&&(n=pooling.double(n),a*=2),r&&r(t),n[s]=t,s+=1}}},pooling={double:function(t){return t.concat(createSizedArray(t.length))}},point_pool=pool_factory(8,function(){return createTypedArray("float32",2)}),shape_pool=(Vz=pool_factory(4,function(){return new ShapePath},function(t){var e,r=t._length;for(e=0;e<r;e+=1)point_pool.release(t.v[e]),point_pool.release(t.i[e]),point_pool.release(t.o[e]),t.v[e]=null,t.i[e]=null,t.o[e]=null;t._length=0,t.c=!1}),Vz.clone=function(t){var e,r=Vz.newElement(),i=void 0===t._length?t.v.length:t._length;for(r.setLength(i),r.c=t.c,e=0;e<i;e+=1)r.setTripleAt(t.v[e][0],t.v[e][1],t.o[e][0],t.o[e][1],t.i[e][0],t.i[e][1],e);return r},Vz),Vz,shapeCollection_pool=(cA={newShapeCollection:function(){var t;t=dA?fA[dA-=1]:new ShapeCollection;return t},release:function(t){var e,r=t._length;for(e=0;e<r;e+=1)shape_pool.release(t.shapes[e]);t._length=0,dA===eA&&(fA=pooling.double(fA),eA*=2);fA[dA]=t,dA+=1}},dA=0,eA=4,fA=createSizedArray(eA),cA),cA,dA,eA,fA,segments_length_pool=pool_factory(8,function(){return{lengths:[],totalLength:0}},function(t){var e,r=t.lengths.length;for(e=0;e<r;e+=1)bezier_length_pool.release(t.lengths[e]);t.lengths.length=0}),bezier_length_pool=pool_factory(8,function(){return{addedLength:0,percents:createTypedArray("float32",defaultCurveSegments),lengths:createTypedArray("float32",defaultCurveSegments)}});function BaseRenderer(){}function SVGRenderer(t,e){this.animationItem=t,this.layers=null,this.renderedFrame=-1,this.svgElement=createNS("svg");var r="";if(e&&e.title){var i=createNS("title"),s=createElementID();i.setAttribute("id",s),i.textContent=e.title,this.svgElement.appendChild(i),r+=s}if(e&&e.description){var a=createNS("desc"),n=createElementID();a.setAttribute("id",n),a.textContent=e.description,this.svgElement.appendChild(a),r+=" "+n}r&&this.svgElement.setAttribute("aria-labelledby",r);var o=createNS("defs");this.svgElement.appendChild(o);var h=createNS("g");this.svgElement.appendChild(h),this.layerElement=h,this.renderConfig={preserveAspectRatio:e&&e.preserveAspectRatio||"xMidYMid meet",imagePreserveAspectRatio:e&&e.imagePreserveAspectRatio||"xMidYMid slice",progressiveLoad:e&&e.progressiveLoad||!1,hideOnTransparent:!e||!1!==e.hideOnTransparent,viewBoxOnly:e&&e.viewBoxOnly||!1,viewBoxSize:e&&e.viewBoxSize||!1,className:e&&e.className||""},this.globalData={_mdf:!1,frameNum:-1,defs:o,renderConfig:this.renderConfig},this.elements=[],this.pendingElements=[],this.destroyed=!1,this.rendererType="svg"}function CanvasRenderer(t,e){this.animationItem=t,this.renderConfig={clearCanvas:!e||void 0===e.clearCanvas||e.clearCanvas,context:e&&e.context||null,progressiveLoad:e&&e.progressiveLoad||!1,preserveAspectRatio:e&&e.preserveAspectRatio||"xMidYMid meet",imagePreserveAspectRatio:e&&e.imagePreserveAspectRatio||"xMidYMid slice",className:e&&e.className||""},this.renderConfig.dpr=e&&e.dpr||1,this.animationItem.wrapper&&(this.renderConfig.dpr=e&&e.dpr||window.devicePixelRatio||1),this.renderedFrame=-1,this.globalData={frameNum:-1,_mdf:!1,renderConfig:this.renderConfig,currentGlobalAlpha:-1},this.contextData=new CVContextData,this.elements=[],this.pendingElements=[],this.transformMat=new Matrix,this.completeLayers=!1,this.rendererType="canvas"}function MaskElement(t,e,r){this.data=t,this.element=e,this.globalData=r,this.storedData=[],this.masksProperties=this.data.masksProperties||[],this.maskElement=null;var i,s=this.globalData.defs,a=this.masksProperties?this.masksProperties.length:0;this.viewData=createSizedArray(a),this.solidPath="";var n,o,h,p,l,m,f,c=this.masksProperties,d=0,u=[],y=createElementID(),g="clipPath",v="clip-path";for(i=0;i<a;i++)if(("a"!==c[i].mode&&"n"!==c[i].mode||c[i].inv||100!==c[i].o.k)&&(v=g="mask"),"s"!=c[i].mode&&"i"!=c[i].mode||0!==d?p=null:((p=createNS("rect")).setAttribute("fill","#ffffff"),p.setAttribute("width",this.element.comp.data.w||0),p.setAttribute("height",this.element.comp.data.h||0),u.push(p)),n=createNS("path"),"n"!=c[i].mode){var P;if(d+=1,n.setAttribute("fill","s"===c[i].mode?"#000000":"#ffffff"),n.setAttribute("clip-rule","nonzero"),0!==c[i].x.k?(v=g="mask",f=PropertyFactory.getProp(this.element,c[i].x,0,null,this.element),P=createElementID(),(l=createNS("filter")).setAttribute("id",P),(m=createNS("feMorphology")).setAttribute("operator","erode"),m.setAttribute("in","SourceGraphic"),m.setAttribute("radius","0"),l.appendChild(m),s.appendChild(l),n.setAttribute("stroke","s"===c[i].mode?"#000000":"#ffffff")):f=m=null,this.storedData[i]={elem:n,x:f,expan:m,lastPath:"",lastOperator:"",filterId:P,lastRadius:0},"i"==c[i].mode){h=u.length;var b=createNS("g");for(o=0;o<h;o+=1)b.appendChild(u[o]);var x=createNS("mask");x.setAttribute("mask-type","alpha"),x.setAttribute("id",y+"_"+d),x.appendChild(n),s.appendChild(x),b.setAttribute("mask","url("+locationHref+"#"+y+"_"+d+")"),u.length=0,u.push(b)}else u.push(n);c[i].inv&&!this.solidPath&&(this.solidPath=this.createLayerSolidPath()),this.viewData[i]={elem:n,lastPath:"",op:PropertyFactory.getProp(this.element,c[i].o,0,.01,this.element),prop:ShapePropertyFactory.getShapeProp(this.element,c[i],3),invRect:p},this.viewData[i].prop.k||this.drawPath(c[i],this.viewData[i].prop.v,this.viewData[i])}else this.viewData[i]={op:PropertyFactory.getProp(this.element,c[i].o,0,.01,this.element),prop:ShapePropertyFactory.getShapeProp(this.element,c[i],3),elem:n,lastPath:""},s.appendChild(n);for(this.maskElement=createNS(g),a=u.length,i=0;i<a;i+=1)this.maskElement.appendChild(u[i]);0<d&&(this.maskElement.setAttribute("id",y),this.element.maskedElement.setAttribute(v,"url("+locationHref+"#"+y+")"),s.appendChild(this.maskElement)),this.viewData.length&&this.element.addRenderableComponent(this)}function HierarchyElement(){}function FrameElement(){}function TransformElement(){}function RenderableElement(){}function RenderableDOMElement(){}function ProcessedElement(t,e){this.elem=t,this.pos=e}function SVGShapeData(t,e,r){this.caches=[],this.styles=[],this.transformers=t,this.lStr="",this.sh=r,this.lvl=e,this._isAnimated=!!r.k;for(var i=0,s=t.length;i<s;){if(t[i].mProps.dynamicProperties.length){this._isAnimated=!0;break}i+=1}}function ShapeGroupData(){this.it=[],this.prevViewData=[],this.gr=createNS("g")}function ShapeTransformManager(){this.sequences={},this.sequenceList=[],this.transform_key_count=0}function CVShapeData(t,e,r,i){this.styledShapes=[],this.tr=[0,0,0,0,0,0];var s=4;"rc"==e.ty?s=5:"el"==e.ty?s=6:"sr"==e.ty&&(s=7),this.sh=ShapePropertyFactory.getShapeProp(t,e,s,t);var a,n,o=r.length;for(a=0;a<o;a+=1)r[a].closed||(n={transforms:i.addTransformSequence(r[a].transforms),trNodes:[]},this.styledShapes.push(n),r[a].elements.push(n))}function BaseElement(){}function NullElement(t,e,r){this.initFrame(),this.initBaseData(t,e,r),this.initFrame(),this.initTransform(t,e,r),this.initHierarchy()}function SVGBaseElement(){}function IShapeElement(){}function ITextElement(){}function ICompElement(){}function IImageElement(t,e,r){this.assetData=e.getAssetData(t.refId),this.initElement(t,e,r),this.sourceRect={top:0,left:0,width:this.assetData.w,height:this.assetData.h}}function ISolidElement(t,e,r){this.initElement(t,e,r)}function SVGShapeElement(t,e,r){this.shapes=[],this.shapesData=t.shapes,this.stylesList=[],this.shapeModifiers=[],this.itemsData=[],this.processedElements=[],this.animatedContents=[],this.initElement(t,e,r),this.prevViewData=[]}function CVContextData(){this.saved=[],this.cArrPos=0,this.cTr=new Matrix,this.cO=1;var t;for(this.savedOp=createTypedArray("float32",15),t=0;t<15;t+=1)this.saved[t]=createTypedArray("float32",16);this._length=15}function CVBaseElement(){}function CVCompElement(t,e,r){this.completeLayers=!1,this.layers=t.layers,this.pendingElements=[],this.elements=createSizedArray(this.layers.length),this.initElement(t,e,r),this.tm=t.tm?PropertyFactory.getProp(this,t.tm,0,e.frameRate,this):{_placeholder:!0}}function CVMaskElement(t,e){this.data=t,this.element=e,this.masksProperties=this.data.masksProperties||[],this.viewData=createSizedArray(this.masksProperties.length);var r,i=this.masksProperties.length,s=!1;for(r=0;r<i;r++)"n"!==this.masksProperties[r].mode&&(s=!0),this.viewData[r]=ShapePropertyFactory.getShapeProp(this.element,this.masksProperties[r],3);(this.hasMasks=s)&&this.element.addRenderableComponent(this)}function CVShapeElement(t,e,r){this.shapes=[],this.shapesData=t.shapes,this.stylesList=[],this.itemsData=[],this.prevViewData=[],this.shapeModifiers=[],this.processedElements=[],this.transformsManager=new ShapeTransformManager,this.initElement(t,e,r)}function CVSolidElement(t,e,r){this.initElement(t,e,r)}function CVEffects(){}BaseRenderer.prototype.checkLayers=function(t){var e,r,i=this.layers.length;for(this.completeLayers=!0,e=i-1;0<=e;e--)this.elements[e]||(r=this.layers[e]).ip-r.st<=t-this.layers[e].st&&r.op-r.st>t-this.layers[e].st&&this.buildItem(e),this.completeLayers=!!this.elements[e]&&this.completeLayers;this.checkPendingElements()},BaseRenderer.prototype.createItem=function(t){switch(t.ty){case 2:return this.createImage(t);case 0:return this.createComp(t);case 1:return this.createSolid(t);case 3:return this.createNull(t);case 4:return this.createShape(t);case 5:return this.createText(t);case 13:return this.createCamera(t)}return this.createNull(t)},BaseRenderer.prototype.createCamera=function(){throw new Error("You're using a 3d camera. Try the html renderer.")},BaseRenderer.prototype.buildAllItems=function(){var t,e=this.layers.length;for(t=0;t<e;t+=1)this.buildItem(t);this.checkPendingElements()},BaseRenderer.prototype.includeLayers=function(t){this.completeLayers=!1;var e,r,i=t.length,s=this.layers.length;for(e=0;e<i;e+=1)for(r=0;r<s;){if(this.layers[r].id==t[e].id){this.layers[r]=t[e];break}r+=1}},BaseRenderer.prototype.setProjectInterface=function(t){this.globalData.projectInterface=t},BaseRenderer.prototype.initItems=function(){this.globalData.progressiveLoad||this.buildAllItems()},BaseRenderer.prototype.buildElementParenting=function(t,e,r){for(var i=this.elements,s=this.layers,a=0,n=s.length;a<n;)s[a].ind==e&&(i[a]&&!0!==i[a]?(r.push(i[a]),i[a].setAsParent(),void 0!==s[a].parent?this.buildElementParenting(t,s[a].parent,r):t.setHierarchy(r)):(this.buildItem(a),this.addPendingElement(t))),a+=1},BaseRenderer.prototype.addPendingElement=function(t){this.pendingElements.push(t)},BaseRenderer.prototype.searchExtraCompositions=function(t){var e,r=t.length;for(e=0;e<r;e+=1)if(t[e].xt){var i=this.createComp(t[e]);i.initExpressions(),this.globalData.projectInterface.registerComposition(i)}},BaseRenderer.prototype.setupGlobalData=function(t,e){this.globalData.fontManager=new FontManager,this.globalData.fontManager.addChars(t.chars),this.globalData.fontManager.addFonts(t.fonts,e),this.globalData.getAssetData=this.animationItem.getAssetData.bind(this.animationItem),this.globalData.getAssetsPath=this.animationItem.getAssetsPath.bind(this.animationItem),this.globalData.imageLoader=this.animationItem.imagePreloader,this.globalData.frameId=0,this.globalData.frameRate=t.fr,this.globalData.nm=t.nm,this.globalData.compSize={w:t.w,h:t.h}},extendPrototype([BaseRenderer],SVGRenderer),SVGRenderer.prototype.createNull=function(t){return new NullElement(t,this.globalData,this)},SVGRenderer.prototype.createShape=function(t){return new SVGShapeElement(t,this.globalData,this)},SVGRenderer.prototype.createText=function(t){return new SVGTextElement(t,this.globalData,this)},SVGRenderer.prototype.createImage=function(t){return new IImageElement(t,this.globalData,this)},SVGRenderer.prototype.createComp=function(t){return new SVGCompElement(t,this.globalData,this)},SVGRenderer.prototype.createSolid=function(t){return new ISolidElement(t,this.globalData,this)},SVGRenderer.prototype.configAnimation=function(t){this.svgElement.setAttribute("xmlns","http://www.w3.org/2000/svg"),this.renderConfig.viewBoxSize?this.svgElement.setAttribute("viewBox",this.renderConfig.viewBoxSize):this.svgElement.setAttribute("viewBox","0 0 "+t.w+" "+t.h),this.renderConfig.viewBoxOnly||(this.svgElement.setAttribute("width",t.w),this.svgElement.setAttribute("height",t.h),this.svgElement.style.width="100%",this.svgElement.style.height="100%",this.svgElement.style.transform="translate3d(0,0,0)"),this.renderConfig.className&&this.svgElement.setAttribute("class",this.renderConfig.className),this.svgElement.setAttribute("preserveAspectRatio",this.renderConfig.preserveAspectRatio),this.animationItem.wrapper.appendChild(this.svgElement);var e=this.globalData.defs;this.setupGlobalData(t,e),this.globalData.progressiveLoad=this.renderConfig.progressiveLoad,this.data=t;var r=createNS("clipPath"),i=createNS("rect");i.setAttribute("width",t.w),i.setAttribute("height",t.h),i.setAttribute("x",0),i.setAttribute("y",0);var s=createElementID();r.setAttribute("id",s),r.appendChild(i),this.layerElement.setAttribute("clip-path","url("+locationHref+"#"+s+")"),e.appendChild(r),this.layers=t.layers,this.elements=createSizedArray(t.layers.length)},SVGRenderer.prototype.destroy=function(){this.animationItem.wrapper.innerHTML="",this.layerElement=null,this.globalData.defs=null;var t,e=this.layers?this.layers.length:0;for(t=0;t<e;t++)this.elements[t]&&this.elements[t].destroy();this.elements.length=0,this.destroyed=!0,this.animationItem=null},SVGRenderer.prototype.updateContainerSize=function(){},SVGRenderer.prototype.buildItem=function(t){var e=this.elements;if(!e[t]&&99!=this.layers[t].ty){e[t]=!0;var r=this.createItem(this.layers[t]);e[t]=r,expressionsPlugin&&(0===this.layers[t].ty&&this.globalData.projectInterface.registerComposition(r),r.initExpressions()),this.appendElementInPos(r,t),this.layers[t].tt&&(this.elements[t-1]&&!0!==this.elements[t-1]?r.setMatte(e[t-1].layerId):(this.buildItem(t-1),this.addPendingElement(r)))}},SVGRenderer.prototype.checkPendingElements=function(){for(;this.pendingElements.length;){var t=this.pendingElements.pop();if(t.checkParenting(),t.data.tt)for(var e=0,r=this.elements.length;e<r;){if(this.elements[e]===t){t.setMatte(this.elements[e-1].layerId);break}e+=1}}},SVGRenderer.prototype.renderFrame=function(t){if(this.renderedFrame!==t&&!this.destroyed){null===t?t=this.renderedFrame:this.renderedFrame=t,this.globalData.frameNum=t,this.globalData.frameId+=1,this.globalData.projectInterface.currentFrame=t,this.globalData._mdf=!1;var e,r=this.layers.length;for(this.completeLayers||this.checkLayers(t),e=r-1;0<=e;e--)(this.completeLayers||this.elements[e])&&this.elements[e].prepareFrame(t-this.layers[e].st);if(this.globalData._mdf)for(e=0;e<r;e+=1)(this.completeLayers||this.elements[e])&&this.elements[e].renderFrame()}},SVGRenderer.prototype.appendElementInPos=function(t,e){var r=t.getBaseElement();if(r){for(var i,s=0;s<e;)this.elements[s]&&!0!==this.elements[s]&&this.elements[s].getBaseElement()&&(i=this.elements[s].getBaseElement()),s+=1;i?this.layerElement.insertBefore(r,i):this.layerElement.appendChild(r)}},SVGRenderer.prototype.hide=function(){this.layerElement.style.display="none"},SVGRenderer.prototype.show=function(){this.layerElement.style.display="block"},extendPrototype([BaseRenderer],CanvasRenderer),CanvasRenderer.prototype.createShape=function(t){return new CVShapeElement(t,this.globalData,this)},CanvasRenderer.prototype.createText=function(t){return new CVTextElement(t,this.globalData,this)},CanvasRenderer.prototype.createImage=function(t){return new CVImageElement(t,this.globalData,this)},CanvasRenderer.prototype.createComp=function(t){return new CVCompElement(t,this.globalData,this)},CanvasRenderer.prototype.createSolid=function(t){return new CVSolidElement(t,this.globalData,this)},CanvasRenderer.prototype.createNull=SVGRenderer.prototype.createNull,CanvasRenderer.prototype.ctxTransform=function(t){if(1!==t[0]||0!==t[1]||0!==t[4]||1!==t[5]||0!==t[12]||0!==t[13])if(this.renderConfig.clearCanvas){this.transformMat.cloneFromProps(t);var e=this.contextData.cTr.props;this.transformMat.transform(e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8],e[9],e[10],e[11],e[12],e[13],e[14],e[15]),this.contextData.cTr.cloneFromProps(this.transformMat.props);var r=this.contextData.cTr.props;this.canvasContext.setTransform(r[0],r[1],r[4],r[5],r[12],r[13])}else this.canvasContext.transform(t[0],t[1],t[4],t[5],t[12],t[13])},CanvasRenderer.prototype.ctxOpacity=function(t){if(!this.renderConfig.clearCanvas)return this.canvasContext.globalAlpha*=t<0?0:t,void(this.globalData.currentGlobalAlpha=this.contextData.cO);this.contextData.cO*=t<0?0:t,this.globalData.currentGlobalAlpha!==this.contextData.cO&&(this.canvasContext.globalAlpha=this.contextData.cO,this.globalData.currentGlobalAlpha=this.contextData.cO)},CanvasRenderer.prototype.reset=function(){this.renderConfig.clearCanvas?this.contextData.reset():this.canvasContext.restore()},CanvasRenderer.prototype.save=function(t){if(this.renderConfig.clearCanvas){t&&this.canvasContext.save();var e=this.contextData.cTr.props;this.contextData._length<=this.contextData.cArrPos&&this.contextData.duplicate();var r,i=this.contextData.saved[this.contextData.cArrPos];for(r=0;r<16;r+=1)i[r]=e[r];this.contextData.savedOp[this.contextData.cArrPos]=this.contextData.cO,this.contextData.cArrPos+=1}else this.canvasContext.save()},CanvasRenderer.prototype.restore=function(t){if(this.renderConfig.clearCanvas){t&&(this.canvasContext.restore(),this.globalData.blendMode="source-over"),this.contextData.cArrPos-=1;var e,r=this.contextData.saved[this.contextData.cArrPos],i=this.contextData.cTr.props;for(e=0;e<16;e+=1)i[e]=r[e];this.canvasContext.setTransform(r[0],r[1],r[4],r[5],r[12],r[13]),r=this.contextData.savedOp[this.contextData.cArrPos],this.contextData.cO=r,this.globalData.currentGlobalAlpha!==r&&(this.canvasContext.globalAlpha=r,this.globalData.currentGlobalAlpha=r)}else this.canvasContext.restore()},CanvasRenderer.prototype.configAnimation=function(t){this.animationItem.wrapper?(this.animationItem.container=createTag("canvas"),this.animationItem.container.style.width="100%",this.animationItem.container.style.height="100%",this.animationItem.container.style.transformOrigin=this.animationItem.container.style.mozTransformOrigin=this.animationItem.container.style.webkitTransformOrigin=this.animationItem.container.style["-webkit-transform"]="0px 0px 0px",this.animationItem.wrapper.appendChild(this.animationItem.container),this.canvasContext=this.animationItem.container.getContext("2d"),this.renderConfig.className&&this.animationItem.container.setAttribute("class",this.renderConfig.className)):this.canvasContext=this.renderConfig.context,this.data=t,this.layers=t.layers,this.transformCanvas={w:t.w,h:t.h,sx:0,sy:0,tx:0,ty:0},this.setupGlobalData(t,document.body),this.globalData.canvasContext=this.canvasContext,(this.globalData.renderer=this).globalData.isDashed=!1,this.globalData.progressiveLoad=this.renderConfig.progressiveLoad,this.globalData.transformCanvas=this.transformCanvas,this.elements=createSizedArray(t.layers.length),this.updateContainerSize()},CanvasRenderer.prototype.updateContainerSize=function(){var t,e,r,i;if(this.reset(),this.animationItem.wrapper&&this.animationItem.container?(t=this.animationItem.wrapper.offsetWidth,e=this.animationItem.wrapper.offsetHeight,this.animationItem.container.setAttribute("width",t*this.renderConfig.dpr),this.animationItem.container.setAttribute("height",e*this.renderConfig.dpr)):(t=this.canvasContext.canvas.width*this.renderConfig.dpr,e=this.canvasContext.canvas.height*this.renderConfig.dpr),-1!==this.renderConfig.preserveAspectRatio.indexOf("meet")||-1!==this.renderConfig.preserveAspectRatio.indexOf("slice")){var s=this.renderConfig.preserveAspectRatio.split(" "),a=s[1]||"meet",n=s[0]||"xMidYMid",o=n.substr(0,4),h=n.substr(4);(r=t/e)<(i=this.transformCanvas.w/this.transformCanvas.h)&&"meet"===a||i<r&&"slice"===a?(this.transformCanvas.sx=t/(this.transformCanvas.w/this.renderConfig.dpr),this.transformCanvas.sy=t/(this.transformCanvas.w/this.renderConfig.dpr)):(this.transformCanvas.sx=e/(this.transformCanvas.h/this.renderConfig.dpr),this.transformCanvas.sy=e/(this.transformCanvas.h/this.renderConfig.dpr)),this.transformCanvas.tx="xMid"===o&&(i<r&&"meet"===a||r<i&&"slice"===a)?(t-this.transformCanvas.w*(e/this.transformCanvas.h))/2*this.renderConfig.dpr:"xMax"===o&&(i<r&&"meet"===a||r<i&&"slice"===a)?(t-this.transformCanvas.w*(e/this.transformCanvas.h))*this.renderConfig.dpr:0,this.transformCanvas.ty="YMid"===h&&(r<i&&"meet"===a||i<r&&"slice"===a)?(e-this.transformCanvas.h*(t/this.transformCanvas.w))/2*this.renderConfig.dpr:"YMax"===h&&(r<i&&"meet"===a||i<r&&"slice"===a)?(e-this.transformCanvas.h*(t/this.transformCanvas.w))*this.renderConfig.dpr:0}else"none"==this.renderConfig.preserveAspectRatio?(this.transformCanvas.sx=t/(this.transformCanvas.w/this.renderConfig.dpr),this.transformCanvas.sy=e/(this.transformCanvas.h/this.renderConfig.dpr)):(this.transformCanvas.sx=this.renderConfig.dpr,this.transformCanvas.sy=this.renderConfig.dpr),this.transformCanvas.tx=0,this.transformCanvas.ty=0;this.transformCanvas.props=[this.transformCanvas.sx,0,0,0,0,this.transformCanvas.sy,0,0,0,0,1,0,this.transformCanvas.tx,this.transformCanvas.ty,0,1],this.ctxTransform(this.transformCanvas.props),this.canvasContext.beginPath(),this.canvasContext.rect(0,0,this.transformCanvas.w,this.transformCanvas.h),this.canvasContext.closePath(),this.canvasContext.clip(),this.renderFrame(this.renderedFrame,!0)},CanvasRenderer.prototype.destroy=function(){var t;for(this.renderConfig.clearCanvas&&(this.animationItem.wrapper.innerHTML=""),t=(this.layers?this.layers.length:0)-1;0<=t;t-=1)this.elements[t]&&this.elements[t].destroy();this.elements.length=0,this.globalData.canvasContext=null,this.animationItem.container=null,this.destroyed=!0},CanvasRenderer.prototype.renderFrame=function(t,e){if((this.renderedFrame!==t||!0!==this.renderConfig.clearCanvas||e)&&!this.destroyed&&-1!==t){this.renderedFrame=t,this.globalData.frameNum=t-this.animationItem._isFirstFrame,this.globalData.frameId+=1,this.globalData._mdf=!this.renderConfig.clearCanvas||e,this.globalData.projectInterface.currentFrame=t;var r,i=this.layers.length;for(this.completeLayers||this.checkLayers(t),r=0;r<i;r++)(this.completeLayers||this.elements[r])&&this.elements[r].prepareFrame(t-this.layers[r].st);if(this.globalData._mdf){for(!0===this.renderConfig.clearCanvas?this.canvasContext.clearRect(0,0,this.transformCanvas.w,this.transformCanvas.h):this.save(),r=i-1;0<=r;r-=1)(this.completeLayers||this.elements[r])&&this.elements[r].renderFrame();!0!==this.renderConfig.clearCanvas&&this.restore()}}},CanvasRenderer.prototype.buildItem=function(t){var e=this.elements;if(!e[t]&&99!=this.layers[t].ty){var r=this.createItem(this.layers[t],this,this.globalData);(e[t]=r).initExpressions()}},CanvasRenderer.prototype.checkPendingElements=function(){for(;this.pendingElements.length;){this.pendingElements.pop().checkParenting()}},CanvasRenderer.prototype.hide=function(){this.animationItem.container.style.display="none"},CanvasRenderer.prototype.show=function(){this.animationItem.container.style.display="block"},CanvasRenderer.prototype.configAnimation=function(t){this.animationItem.wrapper?(this.animationItem.container=createTag("canvas"),this.animationItem.container.style.width="100%",this.animationItem.container.style.height="100%",this.animationItem.container.style.transformOrigin=this.animationItem.container.style.mozTransformOrigin=this.animationItem.container.style.webkitTransformOrigin=this.animationItem.container.style["-webkit-transform"]="0px 0px 0px",this.animationItem.wrapper.appendChild(this.animationItem.container),this.canvasContext=this.animationItem.container.getContext("2d"),this.renderConfig.className&&this.animationItem.container.setAttribute("class",this.renderConfig.className)):this.canvasContext=this.renderConfig.context,this.data=t,this.layers=t.layers,this.transformCanvas={w:t.w,h:t.h,sx:0,sy:0,tx:0,ty:0},this.globalData.frameId=0,this.globalData.frameRate=t.fr,this.globalData.nm=t.nm,this.globalData.compSize={w:t.w,h:t.h},this.globalData.canvasContext=this.canvasContext,(this.globalData.renderer=this).globalData.isDashed=!1,this.globalData.progressiveLoad=this.renderConfig.progressiveLoad,this.globalData.transformCanvas=this.transformCanvas,this.elements=createSizedArray(t.layers.length),this.updateContainerSize()},MaskElement.prototype.getMaskProperty=function(t){return this.viewData[t].prop},MaskElement.prototype.renderFrame=function(t){var e,r=this.element.finalTransform.mat,i=this.masksProperties.length;for(e=0;e<i;e++)if((this.viewData[e].prop._mdf||t)&&this.drawPath(this.masksProperties[e],this.viewData[e].prop.v,this.viewData[e]),(this.viewData[e].op._mdf||t)&&this.viewData[e].elem.setAttribute("fill-opacity",this.viewData[e].op.v),"n"!==this.masksProperties[e].mode&&(this.viewData[e].invRect&&(this.element.finalTransform.mProp._mdf||t)&&(this.viewData[e].invRect.setAttribute("x",-r.props[12]),this.viewData[e].invRect.setAttribute("y",-r.props[13])),this.storedData[e].x&&(this.storedData[e].x._mdf||t))){var s=this.storedData[e].expan;this.storedData[e].x.v<0?("erode"!==this.storedData[e].lastOperator&&(this.storedData[e].lastOperator="erode",this.storedData[e].elem.setAttribute("filter","url("+locationHref+"#"+this.storedData[e].filterId+")")),s.setAttribute("radius",-this.storedData[e].x.v)):("dilate"!==this.storedData[e].lastOperator&&(this.storedData[e].lastOperator="dilate",this.storedData[e].elem.setAttribute("filter",null)),this.storedData[e].elem.setAttribute("stroke-width",2*this.storedData[e].x.v))}},MaskElement.prototype.getMaskelement=function(){return this.maskElement},MaskElement.prototype.createLayerSolidPath=function(){var t="M0,0 ";return t+=" h"+this.globalData.compSize.w,t+=" v"+this.globalData.compSize.h,t+=" h-"+this.globalData.compSize.w,t+=" v-"+this.globalData.compSize.h+" "},MaskElement.prototype.drawPath=function(t,e,r){var i,s,a=" M"+e.v[0][0]+","+e.v[0][1];for(s=e._length,i=1;i<s;i+=1)a+=" C"+e.o[i-1][0]+","+e.o[i-1][1]+" "+e.i[i][0]+","+e.i[i][1]+" "+e.v[i][0]+","+e.v[i][1];if(e.c&&1<s&&(a+=" C"+e.o[i-1][0]+","+e.o[i-1][1]+" "+e.i[0][0]+","+e.i[0][1]+" "+e.v[0][0]+","+e.v[0][1]),r.lastPath!==a){var n="";r.elem&&(e.c&&(n=t.inv?this.solidPath+a:a),r.elem.setAttribute("d",n)),r.lastPath=a}},MaskElement.prototype.destroy=function(){this.element=null,this.globalData=null,this.maskElement=null,this.data=null,this.masksProperties=null},HierarchyElement.prototype={initHierarchy:function(){this.hierarchy=[],this._isParent=!1,this.checkParenting()},setHierarchy:function(t){this.hierarchy=t},setAsParent:function(){this._isParent=!0},checkParenting:function(){void 0!==this.data.parent&&this.comp.buildElementParenting(this,this.data.parent,[])}},FrameElement.prototype={initFrame:function(){this._isFirstFrame=!1,this.dynamicProperties=[],this._mdf=!1},prepareProperties:function(t,e){var r,i=this.dynamicProperties.length;for(r=0;r<i;r+=1)(e||this._isParent&&"transform"===this.dynamicProperties[r].propType)&&(this.dynamicProperties[r].getValue(),this.dynamicProperties[r]._mdf&&(this.globalData._mdf=!0,this._mdf=!0))},addDynamicProperty:function(t){-1===this.dynamicProperties.indexOf(t)&&this.dynamicProperties.push(t)}},TransformElement.prototype={initTransform:function(){this.finalTransform={mProp:this.data.ks?TransformPropertyFactory.getTransformProperty(this,this.data.ks,this):{o:0},_matMdf:!1,_opMdf:!1,mat:new Matrix},this.data.ao&&(this.finalTransform.mProp.autoOriented=!0),this.data.ty},renderTransform:function(){if(this.finalTransform._opMdf=this.finalTransform.mProp.o._mdf||this._isFirstFrame,this.finalTransform._matMdf=this.finalTransform.mProp._mdf||this._isFirstFrame,this.hierarchy){var t,e=this.finalTransform.mat,r=0,i=this.hierarchy.length;if(!this.finalTransform._matMdf)for(;r<i;){if(this.hierarchy[r].finalTransform.mProp._mdf){this.finalTransform._matMdf=!0;break}r+=1}if(this.finalTransform._matMdf)for(t=this.finalTransform.mProp.v.props,e.cloneFromProps(t),r=0;r<i;r+=1)t=this.hierarchy[r].finalTransform.mProp.v.props,e.transform(t[0],t[1],t[2],t[3],t[4],t[5],t[6],t[7],t[8],t[9],t[10],t[11],t[12],t[13],t[14],t[15])}},globalToLocal:function(t){var e=[];e.push(this.finalTransform);for(var r=!0,i=this.comp;r;)i.finalTransform?(i.data.hasMask&&e.splice(0,0,i.finalTransform),i=i.comp):r=!1;var s,a,n=e.length;for(s=0;s<n;s+=1)a=e[s].mat.applyToPointArray(0,0,0),t=[t[0]-a[0],t[1]-a[1],0];return t},mHelper:new Matrix},RenderableElement.prototype={initRenderable:function(){this.isInRange=!1,this.hidden=!1,this.isTransparent=!1,this.renderableComponents=[]},addRenderableComponent:function(t){-1===this.renderableComponents.indexOf(t)&&this.renderableComponents.push(t)},removeRenderableComponent:function(t){-1!==this.renderableComponents.indexOf(t)&&this.renderableComponents.splice(this.renderableComponents.indexOf(t),1)},prepareRenderableFrame:function(t){this.checkLayerLimits(t)},checkTransparency:function(){this.finalTransform.mProp.o.v<=0?!this.isTransparent&&this.globalData.renderConfig.hideOnTransparent&&(this.isTransparent=!0,this.hide()):this.isTransparent&&(this.isTransparent=!1,this.show())},checkLayerLimits:function(t){this.data.ip-this.data.st<=t&&this.data.op-this.data.st>t?!0!==this.isInRange&&(this.globalData._mdf=!0,this._mdf=!0,this.isInRange=!0,this.show()):!1!==this.isInRange&&(this.globalData._mdf=!0,this.isInRange=!1,this.hide())},renderRenderable:function(){var t,e=this.renderableComponents.length;for(t=0;t<e;t+=1)this.renderableComponents[t].renderFrame(this._isFirstFrame)},sourceRectAtTime:function(){return{top:0,left:0,width:100,height:100}},getLayerSize:function(){return 5===this.data.ty?{w:this.data.textData.width,h:this.data.textData.height}:{w:this.data.width,h:this.data.height}}},extendPrototype([RenderableElement,createProxyFunction({initElement:function(t,e,r){this.initFrame(),this.initBaseData(t,e,r),this.initTransform(t,e,r),this.initHierarchy(),this.initRenderable(),this.initRendererElement(),this.createContainerElements(),this.createRenderableComponents(),this.createContent(),this.hide()},hide:function(){this.hidden||this.isInRange&&!this.isTransparent||((this.baseElement||this.layerElement).style.display="none",this.hidden=!0)},show:function(){this.isInRange&&!this.isTransparent&&(this.data.hd||((this.baseElement||this.layerElement).style.display="block"),this.hidden=!1,this._isFirstFrame=!0)},renderFrame:function(){this.data.hd||this.hidden||(this.renderTransform(),this.renderRenderable(),this.renderElement(),this.renderInnerContent(),this._isFirstFrame&&(this._isFirstFrame=!1))},renderInnerContent:function(){},prepareFrame:function(t){this._mdf=!1,this.prepareRenderableFrame(t),this.prepareProperties(t,this.isInRange),this.checkTransparency()},destroy:function(){this.innerElem=null,this.destroyBaseElement()}})],RenderableDOMElement),SVGShapeData.prototype.setAsAnimated=function(){this._isAnimated=!0},ShapeTransformManager.prototype={addTransformSequence:function(t){var e,r=t.length,i="_";for(e=0;e<r;e+=1)i+=t[e].transform.key+"_";var s=this.sequences[i];return s||(s={transforms:[].concat(t),finalTransform:new Matrix,_mdf:!1},this.sequences[i]=s,this.sequenceList.push(s)),s},processSequence:function(t,e){for(var r,i=0,s=t.transforms.length,a=e;i<s&&!e;){if(t.transforms[i].transform.mProps._mdf){a=!0;break}i+=1}if(a)for(t.finalTransform.reset(),i=s-1;0<=i;i-=1)r=t.transforms[i].transform.mProps.v.props,t.finalTransform.transform(r[0],r[1],r[2],r[3],r[4],r[5],r[6],r[7],r[8],r[9],r[10],r[11],r[12],r[13],r[14],r[15]);t._mdf=a},processSequences:function(t){var e,r=this.sequenceList.length;for(e=0;e<r;e+=1)this.processSequence(this.sequenceList[e],t)},getNewKey:function(){return"_"+this.transform_key_count++}},CVShapeData.prototype.setAsAnimated=SVGShapeData.prototype.setAsAnimated,BaseElement.prototype={checkMasks:function(){if(!this.data.hasMask)return!1;for(var t=0,e=this.data.masksProperties.length;t<e;){if("n"!==this.data.masksProperties[t].mode&&!1!==this.data.masksProperties[t].cl)return!0;t+=1}return!1},initExpressions:function(){this.layerInterface=LayerExpressionInterface(this),this.data.hasMask&&this.maskManager&&this.layerInterface.registerMaskInterface(this.maskManager);var t=EffectsExpressionInterface.createEffectsInterface(this,this.layerInterface);this.layerInterface.registerEffectsInterface(t),0===this.data.ty||this.data.xt?this.compInterface=CompExpressionInterface(this):4===this.data.ty?(this.layerInterface.shapeInterface=ShapeExpressionInterface(this.shapesData,this.itemsData,this.layerInterface),this.layerInterface.content=this.layerInterface.shapeInterface):5===this.data.ty&&(this.layerInterface.textInterface=TextExpressionInterface(this),this.layerInterface.text=this.layerInterface.textInterface)},setBlendMode:function(){var t=getBlendMode(this.data.bm);(this.baseElement||this.layerElement).style["mix-blend-mode"]=t},initBaseData:function(t,e,r){this.globalData=e,this.comp=r,this.data=t,this.layerId=createElementID(),this.data.sr||(this.data.sr=1),this.effectsManager=new EffectsManager(this.data,this,this.dynamicProperties)},getType:function(){return this.type},sourceRectAtTime:function(){}},NullElement.prototype.prepareFrame=function(t){this.prepareProperties(t,!0)},NullElement.prototype.renderFrame=function(){},NullElement.prototype.getBaseElement=function(){return null},NullElement.prototype.destroy=function(){},NullElement.prototype.sourceRectAtTime=function(){},NullElement.prototype.hide=function(){},extendPrototype([BaseElement,TransformElement,HierarchyElement,FrameElement],NullElement),SVGBaseElement.prototype={initRendererElement:function(){this.layerElement=createNS("g")},createContainerElements:function(){this.matteElement=createNS("g"),this.transformedElement=this.layerElement,this.maskedElement=this.layerElement,this._sizeChanged=!1;var t,e,r,i=null;if(this.data.td){if(3==this.data.td||1==this.data.td){var s=createNS("mask");s.setAttribute("id",this.layerId),s.setAttribute("mask-type",3==this.data.td?"luminance":"alpha"),s.appendChild(this.layerElement),i=s,this.globalData.defs.appendChild(s),featureSupport.maskType||1!=this.data.td||(s.setAttribute("mask-type","luminance"),t=createElementID(),e=filtersFactory.createFilter(t),this.globalData.defs.appendChild(e),e.appendChild(filtersFactory.createAlphaToLuminanceFilter()),(r=createNS("g")).appendChild(this.layerElement),i=r,s.appendChild(r),r.setAttribute("filter","url("+locationHref+"#"+t+")"))}else if(2==this.data.td){var a=createNS("mask");a.setAttribute("id",this.layerId),a.setAttribute("mask-type","alpha");var n=createNS("g");a.appendChild(n),t=createElementID(),e=filtersFactory.createFilter(t);var o=createNS("feComponentTransfer");o.setAttribute("in","SourceGraphic"),e.appendChild(o);var h=createNS("feFuncA");h.setAttribute("type","table"),h.setAttribute("tableValues","1.0 0.0"),o.appendChild(h),this.globalData.defs.appendChild(e);var p=createNS("rect");p.setAttribute("width",this.comp.data.w),p.setAttribute("height",this.comp.data.h),p.setAttribute("x","0"),p.setAttribute("y","0"),p.setAttribute("fill","#ffffff"),p.setAttribute("opacity","0"),n.setAttribute("filter","url("+locationHref+"#"+t+")"),n.appendChild(p),n.appendChild(this.layerElement),i=n,featureSupport.maskType||(a.setAttribute("mask-type","luminance"),e.appendChild(filtersFactory.createAlphaToLuminanceFilter()),r=createNS("g"),n.appendChild(p),r.appendChild(this.layerElement),i=r,n.appendChild(r)),this.globalData.defs.appendChild(a)}}else this.data.tt?(this.matteElement.appendChild(this.layerElement),i=this.matteElement,this.baseElement=this.matteElement):this.baseElement=this.layerElement;if(this.data.ln&&this.layerElement.setAttribute("id",this.data.ln),this.data.cl&&this.layerElement.setAttribute("class",this.data.cl),0===this.data.ty&&!this.data.hd){var l=createNS("clipPath"),m=createNS("path");m.setAttribute("d","M0,0 L"+this.data.w+",0 L"+this.data.w+","+this.data.h+" L0,"+this.data.h+"z");var f=createElementID();if(l.setAttribute("id",f),l.appendChild(m),this.globalData.defs.appendChild(l),this.checkMasks()){var c=createNS("g");c.setAttribute("clip-path","url("+locationHref+"#"+f+")"),c.appendChild(this.layerElement),this.transformedElement=c,i?i.appendChild(this.transformedElement):this.baseElement=this.transformedElement}else this.layerElement.setAttribute("clip-path","url("+locationHref+"#"+f+")")}0!==this.data.bm&&this.setBlendMode()},renderElement:function(){this.finalTransform._matMdf&&this.transformedElement.setAttribute("transform",this.finalTransform.mat.to2dCSS()),this.finalTransform._opMdf&&this.transformedElement.setAttribute("opacity",this.finalTransform.mProp.o.v)},destroyBaseElement:function(){this.layerElement=null,this.matteElement=null,this.maskManager.destroy()},getBaseElement:function(){return this.data.hd?null:this.baseElement},createRenderableComponents:function(){this.maskManager=new MaskElement(this.data,this,this.globalData),this.renderableEffectsManager=new SVGEffects(this)},setMatte:function(t){this.matteElement&&this.matteElement.setAttribute("mask","url("+locationHref+"#"+t+")")}},IShapeElement.prototype={addShapeToModifiers:function(t){var e,r=this.shapeModifiers.length;for(e=0;e<r;e+=1)this.shapeModifiers[e].addShape(t)},isShapeInAnimatedModifiers:function(t){for(var e=this.shapeModifiers.length;0<e;)if(this.shapeModifiers[0].isAnimatedWithShape(t))return!0;return!1},renderModifiers:function(){if(this.shapeModifiers.length){var t,e=this.shapes.length;for(t=0;t<e;t+=1)this.shapes[t].sh.reset();for(t=(e=this.shapeModifiers.length)-1;0<=t;t-=1)this.shapeModifiers[t].processShapes(this._isFirstFrame)}},lcEnum:{1:"butt",2:"round",3:"square"},ljEnum:{1:"miter",2:"round",3:"bevel"},searchProcessedElement:function(t){for(var e=this.processedElements,r=0,i=e.length;r<i;){if(e[r].elem===t)return e[r].pos;r+=1}return 0},addProcessedElement:function(t,e){for(var r=this.processedElements,i=r.length;i;)if(r[i-=1].elem===t)return void(r[i].pos=e);r.push(new ProcessedElement(t,e))},prepareFrame:function(t){this.prepareRenderableFrame(t),this.prepareProperties(t,this.isInRange)}},ITextElement.prototype.initElement=function(t,e,r){this.lettersChangedFlag=!0,this.initFrame(),this.initBaseData(t,e,r),this.textProperty=new TextProperty(this,t.t,this.dynamicProperties),this.textAnimator=new TextAnimatorProperty(t.t,this.renderType,this),this.initTransform(t,e,r),this.initHierarchy(),this.initRenderable(),this.initRendererElement(),this.createContainerElements(),this.createRenderableComponents(),this.createContent(),this.hide(),this.textAnimator.searchProperties(this.dynamicProperties)},ITextElement.prototype.prepareFrame=function(t){this._mdf=!1,this.prepareRenderableFrame(t),this.prepareProperties(t,this.isInRange),(this.textProperty._mdf||this.textProperty._isFirstFrame)&&(this.buildNewText(),this.textProperty._isFirstFrame=!1,this.textProperty._mdf=!1)},ITextElement.prototype.createPathShape=function(t,e){var r,i,s=e.length,a="";for(r=0;r<s;r+=1)i=e[r].ks.k,a+=buildShapeString(i,i.i.length,!0,t);return a},ITextElement.prototype.updateDocumentData=function(t,e){this.textProperty.updateDocumentData(t,e)},ITextElement.prototype.canResizeFont=function(t){this.textProperty.canResizeFont(t)},ITextElement.prototype.setMinimumFontSize=function(t){this.textProperty.setMinimumFontSize(t)},ITextElement.prototype.applyTextPropertiesToMatrix=function(t,e,r,i,s){switch(t.ps&&e.translate(t.ps[0],t.ps[1]+t.ascent,0),e.translate(0,-t.ls,0),t.j){case 1:e.translate(t.justifyOffset+(t.boxWidth-t.lineWidths[r]),0,0);break;case 2:e.translate(t.justifyOffset+(t.boxWidth-t.lineWidths[r])/2,0,0)}e.translate(i,s,0)},ITextElement.prototype.buildColor=function(t){return"rgb("+Math.round(255*t[0])+","+Math.round(255*t[1])+","+Math.round(255*t[2])+")"},ITextElement.prototype.emptyProp=new LetterProps,ITextElement.prototype.destroy=function(){},extendPrototype([BaseElement,TransformElement,HierarchyElement,FrameElement,RenderableDOMElement],ICompElement),ICompElement.prototype.initElement=function(t,e,r){this.initFrame(),this.initBaseData(t,e,r),this.initTransform(t,e,r),this.initRenderable(),this.initHierarchy(),this.initRendererElement(),this.createContainerElements(),this.createRenderableComponents(),!this.data.xt&&e.progressiveLoad||this.buildAllItems(),this.hide()},ICompElement.prototype.prepareFrame=function(t){if(this._mdf=!1,this.prepareRenderableFrame(t),this.prepareProperties(t,this.isInRange),this.isInRange||this.data.xt){if(this.tm._placeholder)this.renderedFrame=t/this.data.sr;else{var e=this.tm.v;e===this.data.op&&(e=this.data.op-1),this.renderedFrame=e}var r,i=this.elements.length;for(this.completeLayers||this.checkLayers(this.renderedFrame),r=i-1;0<=r;r-=1)(this.completeLayers||this.elements[r])&&(this.elements[r].prepareFrame(this.renderedFrame-this.layers[r].st),this.elements[r]._mdf&&(this._mdf=!0))}},ICompElement.prototype.renderInnerContent=function(){var t,e=this.layers.length;for(t=0;t<e;t+=1)(this.completeLayers||this.elements[t])&&this.elements[t].renderFrame()},ICompElement.prototype.setElements=function(t){this.elements=t},ICompElement.prototype.getElements=function(){return this.elements},ICompElement.prototype.destroyElements=function(){var t,e=this.layers.length;for(t=0;t<e;t+=1)this.elements[t]&&this.elements[t].destroy()},ICompElement.prototype.destroy=function(){this.destroyElements(),this.destroyBaseElement()},extendPrototype([BaseElement,TransformElement,SVGBaseElement,HierarchyElement,FrameElement,RenderableDOMElement],IImageElement),IImageElement.prototype.createContent=function(){var t=this.globalData.getAssetsPath(this.assetData);this.innerElem=createNS("image"),this.innerElem.setAttribute("width",this.assetData.w+"px"),this.innerElem.setAttribute("height",this.assetData.h+"px"),this.innerElem.setAttribute("preserveAspectRatio",this.assetData.pr||this.globalData.renderConfig.imagePreserveAspectRatio),this.innerElem.setAttributeNS("http://www.w3.org/1999/xlink","href",t),this.layerElement.appendChild(this.innerElem)},IImageElement.prototype.sourceRectAtTime=function(){return this.sourceRect},extendPrototype([IImageElement],ISolidElement),ISolidElement.prototype.createContent=function(){var t=createNS("rect");t.setAttribute("width",this.data.sw),t.setAttribute("height",this.data.sh),t.setAttribute("fill",this.data.sc),this.layerElement.appendChild(t)},extendPrototype([BaseElement,TransformElement,SVGBaseElement,IShapeElement,HierarchyElement,FrameElement,RenderableDOMElement],SVGShapeElement),SVGShapeElement.prototype.initSecondaryElement=function(){},SVGShapeElement.prototype.identityMatrix=new Matrix,SVGShapeElement.prototype.buildExpressionInterface=function(){},SVGShapeElement.prototype.createContent=function(){this.searchShapes(this.shapesData,this.itemsData,this.prevViewData,this.layerElement,0,[],!0),this.filterUniqueShapes()},SVGShapeElement.prototype.filterUniqueShapes=function(){var t,e,r,i,s=this.shapes.length,a=this.stylesList.length,n=[],o=!1;for(r=0;r<a;r+=1){for(i=this.stylesList[r],o=!1,t=n.length=0;t<s;t+=1)-1!==(e=this.shapes[t]).styles.indexOf(i)&&(n.push(e),o=e._isAnimated||o);1<n.length&&o&&this.setShapesAsAnimated(n)}},SVGShapeElement.prototype.setShapesAsAnimated=function(t){var e,r=t.length;for(e=0;e<r;e+=1)t[e].setAsAnimated()},SVGShapeElement.prototype.createStyleElement=function(t,e){var r,i=new SVGStyleData(t,e),s=i.pElem;if("st"===t.ty)r=new SVGStrokeStyleData(this,t,i);else if("fl"===t.ty)r=new SVGFillStyleData(this,t,i);else if("gf"===t.ty||"gs"===t.ty){r=new("gf"===t.ty?SVGGradientFillStyleData:SVGGradientStrokeStyleData)(this,t,i),this.globalData.defs.appendChild(r.gf),r.maskId&&(this.globalData.defs.appendChild(r.ms),this.globalData.defs.appendChild(r.of),s.setAttribute("mask","url("+locationHref+"#"+r.maskId+")"))}return"st"!==t.ty&&"gs"!==t.ty||(s.setAttribute("stroke-linecap",this.lcEnum[t.lc]||"round"),s.setAttribute("stroke-linejoin",this.ljEnum[t.lj]||"round"),s.setAttribute("fill-opacity","0"),1===t.lj&&s.setAttribute("stroke-miterlimit",t.ml)),2===t.r&&s.setAttribute("fill-rule","evenodd"),t.ln&&s.setAttribute("id",t.ln),t.cl&&s.setAttribute("class",t.cl),t.bm&&(s.style["mix-blend-mode"]=getBlendMode(t.bm)),this.stylesList.push(i),this.addToAnimatedContents(t,r),r},SVGShapeElement.prototype.createGroupElement=function(t){var e=new ShapeGroupData;return t.ln&&e.gr.setAttribute("id",t.ln),t.cl&&e.gr.setAttribute("class",t.cl),t.bm&&(e.gr.style["mix-blend-mode"]=getBlendMode(t.bm)),e},SVGShapeElement.prototype.createTransformElement=function(t,e){var r=TransformPropertyFactory.getTransformProperty(this,t,this),i=new SVGTransformData(r,r.o,e);return this.addToAnimatedContents(t,i),i},SVGShapeElement.prototype.createShapeElement=function(t,e,r){var i=4;"rc"===t.ty?i=5:"el"===t.ty?i=6:"sr"===t.ty&&(i=7);var s=new SVGShapeData(e,r,ShapePropertyFactory.getShapeProp(this,t,i,this));return this.shapes.push(s),this.addShapeToModifiers(s),this.addToAnimatedContents(t,s),s},SVGShapeElement.prototype.addToAnimatedContents=function(t,e){for(var r=0,i=this.animatedContents.length;r<i;){if(this.animatedContents[r].element===e)return;r+=1}this.animatedContents.push({fn:SVGElementsRenderer.createRenderFunction(t),element:e,data:t})},SVGShapeElement.prototype.setElementStyles=function(t){var e,r=t.styles,i=this.stylesList.length;for(e=0;e<i;e+=1)this.stylesList[e].closed||r.push(this.stylesList[e])},SVGShapeElement.prototype.reloadShapes=function(){this._isFirstFrame=!0;var t,e=this.itemsData.length;for(t=0;t<e;t+=1)this.prevViewData[t]=this.itemsData[t];for(this.searchShapes(this.shapesData,this.itemsData,this.prevViewData,this.layerElement,0,[],!0),this.filterUniqueShapes(),e=this.dynamicProperties.length,t=0;t<e;t+=1)this.dynamicProperties[t].getValue();this.renderModifiers()},SVGShapeElement.prototype.searchShapes=function(t,e,r,i,s,a,n){var o,h,p,l,m,f,c=[].concat(a),d=t.length-1,u=[],y=[];for(o=d;0<=o;o-=1){if((f=this.searchProcessedElement(t[o]))?e[o]=r[f-1]:t[o]._render=n,"fl"==t[o].ty||"st"==t[o].ty||"gf"==t[o].ty||"gs"==t[o].ty)f?e[o].style.closed=!1:e[o]=this.createStyleElement(t[o],s),t[o]._render&&i.appendChild(e[o].style.pElem),u.push(e[o].style);else if("gr"==t[o].ty){if(f)for(p=e[o].it.length,h=0;h<p;h+=1)e[o].prevViewData[h]=e[o].it[h];else e[o]=this.createGroupElement(t[o]);this.searchShapes(t[o].it,e[o].it,e[o].prevViewData,e[o].gr,s+1,c,n),t[o]._render&&i.appendChild(e[o].gr)}else"tr"==t[o].ty?(f||(e[o]=this.createTransformElement(t[o],i)),l=e[o].transform,c.push(l)):"sh"==t[o].ty||"rc"==t[o].ty||"el"==t[o].ty||"sr"==t[o].ty?(f||(e[o]=this.createShapeElement(t[o],c,s)),this.setElementStyles(e[o])):"tm"==t[o].ty||"rd"==t[o].ty||"ms"==t[o].ty?(f?(m=e[o]).closed=!1:((m=ShapeModifiers.getModifier(t[o].ty)).init(this,t[o]),e[o]=m,this.shapeModifiers.push(m)),y.push(m)):"rp"==t[o].ty&&(f?(m=e[o]).closed=!0:(m=ShapeModifiers.getModifier(t[o].ty),(e[o]=m).init(this,t,o,e),this.shapeModifiers.push(m),n=!1),y.push(m));this.addProcessedElement(t[o],o+1)}for(d=u.length,o=0;o<d;o+=1)u[o].closed=!0;for(d=y.length,o=0;o<d;o+=1)y[o].closed=!0},SVGShapeElement.prototype.renderInnerContent=function(){this.renderModifiers();var t,e=this.stylesList.length;for(t=0;t<e;t+=1)this.stylesList[t].reset();for(this.renderShape(),t=0;t<e;t+=1)(this.stylesList[t]._mdf||this._isFirstFrame)&&(this.stylesList[t].msElem&&(this.stylesList[t].msElem.setAttribute("d",this.stylesList[t].d),this.stylesList[t].d="M0 0"+this.stylesList[t].d),this.stylesList[t].pElem.setAttribute("d",this.stylesList[t].d||"M0 0"))},SVGShapeElement.prototype.renderShape=function(){var t,e,r=this.animatedContents.length;for(t=0;t<r;t+=1)e=this.animatedContents[t],(this._isFirstFrame||e.element._isAnimated)&&!0!==e.data&&e.fn(e.data,e.element,this._isFirstFrame)},SVGShapeElement.prototype.destroy=function(){this.destroyBaseElement(),this.shapesData=null,this.itemsData=null},CVContextData.prototype.duplicate=function(){var t=2*this._length,e=this.savedOp;this.savedOp=createTypedArray("float32",t),this.savedOp.set(e);var r=0;for(r=this._length;r<t;r+=1)this.saved[r]=createTypedArray("float32",16);this._length=t},CVContextData.prototype.reset=function(){this.cArrPos=0,this.cTr.reset(),this.cO=1},CVBaseElement.prototype={createElements:function(){},initRendererElement:function(){},createContainerElements:function(){this.canvasContext=this.globalData.canvasContext,this.renderableEffectsManager=new CVEffects(this)},createContent:function(){},setBlendMode:function(){var t=this.globalData;if(t.blendMode!==this.data.bm){t.blendMode=this.data.bm;var e=getBlendMode(this.data.bm);t.canvasContext.globalCompositeOperation=e}},createRenderableComponents:function(){this.maskManager=new CVMaskElement(this.data,this)},hideElement:function(){this.hidden||this.isInRange&&!this.isTransparent||(this.hidden=!0)},showElement:function(){this.isInRange&&!this.isTransparent&&(this.hidden=!1,this._isFirstFrame=!0,this.maskManager._isFirstFrame=!0)},renderFrame:function(){this.hidden||this.data.hd||(this.renderTransform(),this.renderRenderable(),this.setBlendMode(),this.globalData.renderer.save(),this.globalData.renderer.ctxTransform(this.finalTransform.mat.props),this.globalData.renderer.ctxOpacity(this.finalTransform.mProp.o.v),this.renderInnerContent(),this.globalData.renderer.restore(),this.maskManager.hasMasks&&this.globalData.renderer.restore(!0),this._isFirstFrame&&(this._isFirstFrame=!1))},destroy:function(){this.canvasContext=null,this.data=null,this.globalData=null,this.maskManager.destroy()},mHelper:new Matrix},CVBaseElement.prototype.hide=CVBaseElement.prototype.hideElement,CVBaseElement.prototype.show=CVBaseElement.prototype.showElement,extendPrototype([CanvasRenderer,ICompElement,CVBaseElement],CVCompElement),CVCompElement.prototype.renderInnerContent=function(){var t;for(t=this.layers.length-1;0<=t;t-=1)(this.completeLayers||this.elements[t])&&this.elements[t].renderFrame()},CVCompElement.prototype.destroy=function(){var t;for(t=this.layers.length-1;0<=t;t-=1)this.elements[t]&&this.elements[t].destroy();this.layers=null,this.elements=null},CVMaskElement.prototype.renderFrame=function(){if(this.hasMasks){var t,e,r,i,s=this.element.finalTransform.mat,a=this.element.canvasContext,n=this.masksProperties.length;for(a.beginPath(),t=0;t<n;t++)if("n"!==this.masksProperties[t].mode){this.masksProperties[t].inv&&(a.moveTo(0,0),a.lineTo(this.element.globalData.compSize.w,0),a.lineTo(this.element.globalData.compSize.w,this.element.globalData.compSize.h),a.lineTo(0,this.element.globalData.compSize.h),a.lineTo(0,0)),i=this.viewData[t].v,e=s.applyToPointArray(i.v[0][0],i.v[0][1],0),a.moveTo(e[0],e[1]);var o,h=i._length;for(o=1;o<h;o++)r=s.applyToTriplePoints(i.o[o-1],i.i[o],i.v[o]),a.bezierCurveTo(r[0],r[1],r[2],r[3],r[4],r[5]);r=s.applyToTriplePoints(i.o[o-1],i.i[0],i.v[0]),a.bezierCurveTo(r[0],r[1],r[2],r[3],r[4],r[5])}this.element.globalData.renderer.save(!0),a.clip()}},CVMaskElement.prototype.getMaskProperty=MaskElement.prototype.getMaskProperty,CVMaskElement.prototype.destroy=function(){this.element=null},extendPrototype([BaseElement,TransformElement,CVBaseElement,IShapeElement,HierarchyElement,FrameElement,RenderableElement],CVShapeElement),CVShapeElement.prototype.initElement=RenderableDOMElement.prototype.initElement,CVShapeElement.prototype.transformHelper={opacity:1,_opMdf:!1},CVShapeElement.prototype.dashResetter=[],CVShapeElement.prototype.createContent=function(){this.searchShapes(this.shapesData,this.itemsData,this.prevViewData,!0,[])},CVShapeElement.prototype.createStyleElement=function(t,e){var r={data:t,type:t.ty,preTransforms:this.transformsManager.addTransformSequence(e),transforms:[],elements:[],closed:!0===t.hd},i={};if("fl"==t.ty||"st"==t.ty?(i.c=PropertyFactory.getProp(this,t.c,1,255,this),i.c.k||(r.co="rgb("+bm_floor(i.c.v[0])+","+bm_floor(i.c.v[1])+","+bm_floor(i.c.v[2])+")")):"gf"!==t.ty&&"gs"!==t.ty||(i.s=PropertyFactory.getProp(this,t.s,1,null,this),i.e=PropertyFactory.getProp(this,t.e,1,null,this),i.h=PropertyFactory.getProp(this,t.h||{k:0},0,.01,this),i.a=PropertyFactory.getProp(this,t.a||{k:0},0,degToRads,this),i.g=new GradientProperty(this,t.g,this)),i.o=PropertyFactory.getProp(this,t.o,0,.01,this),"st"==t.ty||"gs"==t.ty){if(r.lc=this.lcEnum[t.lc]||"round",r.lj=this.ljEnum[t.lj]||"round",1==t.lj&&(r.ml=t.ml),i.w=PropertyFactory.getProp(this,t.w,0,null,this),i.w.k||(r.wi=i.w.v),t.d){var s=new DashProperty(this,t.d,"canvas",this);i.d=s,i.d.k||(r.da=i.d.dashArray,r.do=i.d.dashoffset[0])}}else r.r=2===t.r?"evenodd":"nonzero";return this.stylesList.push(r),i.style=r,i},CVShapeElement.prototype.createGroupElement=function(t){return{it:[],prevViewData:[]}},CVShapeElement.prototype.createTransformElement=function(t){return{transform:{opacity:1,_opMdf:!1,key:this.transformsManager.getNewKey(),op:PropertyFactory.getProp(this,t.o,0,.01,this),mProps:TransformPropertyFactory.getTransformProperty(this,t,this)}}},CVShapeElement.prototype.createShapeElement=function(t){var e=new CVShapeData(this,t,this.stylesList,this.transformsManager);return this.shapes.push(e),this.addShapeToModifiers(e),e},CVShapeElement.prototype.reloadShapes=function(){this._isFirstFrame=!0;var t,e=this.itemsData.length;for(t=0;t<e;t+=1)this.prevViewData[t]=this.itemsData[t];for(this.searchShapes(this.shapesData,this.itemsData,this.prevViewData,!0,[]),e=this.dynamicProperties.length,t=0;t<e;t+=1)this.dynamicProperties[t].getValue();this.renderModifiers(),this.transformsManager.processSequences(this._isFirstFrame)},CVShapeElement.prototype.addTransformToStyleList=function(t){var e,r=this.stylesList.length;for(e=0;e<r;e+=1)this.stylesList[e].closed||this.stylesList[e].transforms.push(t)},CVShapeElement.prototype.removeTransformFromStyleList=function(){var t,e=this.stylesList.length;for(t=0;t<e;t+=1)this.stylesList[t].closed||this.stylesList[t].transforms.pop()},CVShapeElement.prototype.closeStyles=function(t){var e,r=t.length;for(e=0;e<r;e+=1)t[e].closed=!0},CVShapeElement.prototype.searchShapes=function(t,e,r,i,s){var a,n,o,h,p,l,m=t.length-1,f=[],c=[],d=[].concat(s);for(a=m;0<=a;a-=1){if((h=this.searchProcessedElement(t[a]))?e[a]=r[h-1]:t[a]._shouldRender=i,"fl"==t[a].ty||"st"==t[a].ty||"gf"==t[a].ty||"gs"==t[a].ty)h?e[a].style.closed=!1:e[a]=this.createStyleElement(t[a],d),f.push(e[a].style);else if("gr"==t[a].ty){if(h)for(o=e[a].it.length,n=0;n<o;n+=1)e[a].prevViewData[n]=e[a].it[n];else e[a]=this.createGroupElement(t[a]);this.searchShapes(t[a].it,e[a].it,e[a].prevViewData,i,d)}else"tr"==t[a].ty?(h||(l=this.createTransformElement(t[a]),e[a]=l),d.push(e[a]),this.addTransformToStyleList(e[a])):"sh"==t[a].ty||"rc"==t[a].ty||"el"==t[a].ty||"sr"==t[a].ty?h||(e[a]=this.createShapeElement(t[a])):"tm"==t[a].ty||"rd"==t[a].ty?(h?(p=e[a]).closed=!1:((p=ShapeModifiers.getModifier(t[a].ty)).init(this,t[a]),e[a]=p,this.shapeModifiers.push(p)),c.push(p)):"rp"==t[a].ty&&(h?(p=e[a]).closed=!0:(p=ShapeModifiers.getModifier(t[a].ty),(e[a]=p).init(this,t,a,e),this.shapeModifiers.push(p),i=!1),c.push(p));this.addProcessedElement(t[a],a+1)}for(this.removeTransformFromStyleList(),this.closeStyles(f),m=c.length,a=0;a<m;a+=1)c[a].closed=!0},CVShapeElement.prototype.renderInnerContent=function(){this.transformHelper.opacity=1,this.transformHelper._opMdf=!1,this.renderModifiers(),this.transformsManager.processSequences(this._isFirstFrame),this.renderShape(this.transformHelper,this.shapesData,this.itemsData,!0)},CVShapeElement.prototype.renderShapeTransform=function(t,e){(t._opMdf||e.op._mdf||this._isFirstFrame)&&(e.opacity=t.opacity,e.opacity*=e.op.v,e._opMdf=!0)},CVShapeElement.prototype.drawLayer=function(){var t,e,r,i,s,a,n,o,h,p=this.stylesList.length,l=this.globalData.renderer,m=this.globalData.canvasContext;for(t=0;t<p;t+=1)if(("st"!==(o=(h=this.stylesList[t]).type)&&"gs"!==o||0!==h.wi)&&h.data._shouldRender&&0!==h.coOp&&0!==this.globalData.currentGlobalAlpha){for(l.save(),a=h.elements,"st"===o||"gs"===o?(m.strokeStyle="st"===o?h.co:h.grd,m.lineWidth=h.wi,m.lineCap=h.lc,m.lineJoin=h.lj,m.miterLimit=h.ml||0):m.fillStyle="fl"===o?h.co:h.grd,l.ctxOpacity(h.coOp),"st"!==o&&"gs"!==o&&m.beginPath(),l.ctxTransform(h.preTransforms.finalTransform.props),r=a.length,e=0;e<r;e+=1){for("st"!==o&&"gs"!==o||(m.beginPath(),h.da&&(m.setLineDash(h.da),m.lineDashOffset=h.do)),s=(n=a[e].trNodes).length,i=0;i<s;i+=1)"m"==n[i].t?m.moveTo(n[i].p[0],n[i].p[1]):"c"==n[i].t?m.bezierCurveTo(n[i].pts[0],n[i].pts[1],n[i].pts[2],n[i].pts[3],n[i].pts[4],n[i].pts[5]):m.closePath();"st"!==o&&"gs"!==o||(m.stroke(),h.da&&m.setLineDash(this.dashResetter))}"st"!==o&&"gs"!==o&&m.fill(h.r),l.restore()}},CVShapeElement.prototype.renderShape=function(t,e,r,i){var s,a;for(a=t,s=e.length-1;0<=s;s-=1)"tr"==e[s].ty?(a=r[s].transform,this.renderShapeTransform(t,a)):"sh"==e[s].ty||"el"==e[s].ty||"rc"==e[s].ty||"sr"==e[s].ty?this.renderPath(e[s],r[s]):"fl"==e[s].ty?this.renderFill(e[s],r[s],a):"st"==e[s].ty?this.renderStroke(e[s],r[s],a):"gf"==e[s].ty||"gs"==e[s].ty?this.renderGradientFill(e[s],r[s],a):"gr"==e[s].ty?this.renderShape(a,e[s].it,r[s].it):e[s].ty;i&&this.drawLayer()},CVShapeElement.prototype.renderStyledShape=function(t,e){if(this._isFirstFrame||e._mdf||t.transforms._mdf){var r,i,s,a=t.trNodes,n=e.paths,o=n._length;a.length=0;var h=t.transforms.finalTransform;for(s=0;s<o;s+=1){var p=n.shapes[s];if(p&&p.v){for(i=p._length,r=1;r<i;r+=1)1===r&&a.push({t:"m",p:h.applyToPointArray(p.v[0][0],p.v[0][1],0)}),a.push({t:"c",pts:h.applyToTriplePoints(p.o[r-1],p.i[r],p.v[r])});1===i&&a.push({t:"m",p:h.applyToPointArray(p.v[0][0],p.v[0][1],0)}),p.c&&i&&(a.push({t:"c",pts:h.applyToTriplePoints(p.o[r-1],p.i[0],p.v[0])}),a.push({t:"z"}))}}t.trNodes=a}},CVShapeElement.prototype.renderPath=function(t,e){if(!0!==t.hd&&t._shouldRender){var r,i=e.styledShapes.length;for(r=0;r<i;r+=1)this.renderStyledShape(e.styledShapes[r],e.sh)}},CVShapeElement.prototype.renderFill=function(t,e,r){var i=e.style;(e.c._mdf||this._isFirstFrame)&&(i.co="rgb("+bm_floor(e.c.v[0])+","+bm_floor(e.c.v[1])+","+bm_floor(e.c.v[2])+")"),(e.o._mdf||r._opMdf||this._isFirstFrame)&&(i.coOp=e.o.v*r.opacity)},CVShapeElement.prototype.renderGradientFill=function(t,e,r){var i=e.style;if(!i.grd||e.g._mdf||e.s._mdf||e.e._mdf||1!==t.t&&(e.h._mdf||e.a._mdf)){var s=this.globalData.canvasContext,a=e.s.v,n=e.e.v;if(1===t.t)f=s.createLinearGradient(a[0],a[1],n[0],n[1]);else var o=Math.sqrt(Math.pow(a[0]-n[0],2)+Math.pow(a[1]-n[1],2)),h=Math.atan2(n[1]-a[1],n[0]-a[0]),p=o*(1<=e.h.v?.99:e.h.v<=-1?-.99:e.h.v),l=Math.cos(h+e.a.v)*p+a[0],m=Math.sin(h+e.a.v)*p+a[1],f=s.createRadialGradient(l,m,0,a[0],a[1],o);var c,d=t.g.p,u=e.g.c,y=1;for(c=0;c<d;c+=1)e.g._hasOpacity&&e.g._collapsable&&(y=e.g.o[2*c+1]),f.addColorStop(u[4*c]/100,"rgba("+u[4*c+1]+","+u[4*c+2]+","+u[4*c+3]+","+y+")");i.grd=f}i.coOp=e.o.v*r.opacity},CVShapeElement.prototype.renderStroke=function(t,e,r){var i=e.style,s=e.d;s&&(s._mdf||this._isFirstFrame)&&(i.da=s.dashArray,i.do=s.dashoffset[0]),(e.c._mdf||this._isFirstFrame)&&(i.co="rgb("+bm_floor(e.c.v[0])+","+bm_floor(e.c.v[1])+","+bm_floor(e.c.v[2])+")"),(e.o._mdf||r._opMdf||this._isFirstFrame)&&(i.coOp=e.o.v*r.opacity),(e.w._mdf||this._isFirstFrame)&&(i.wi=e.w.v)},CVShapeElement.prototype.destroy=function(){this.shapesData=null,this.globalData=null,this.canvasContext=null,this.stylesList.length=0,this.itemsData.length=0},extendPrototype([BaseElement,TransformElement,CVBaseElement,HierarchyElement,FrameElement,RenderableElement],CVSolidElement),CVSolidElement.prototype.initElement=SVGShapeElement.prototype.initElement,CVSolidElement.prototype.prepareFrame=IImageElement.prototype.prepareFrame,CVSolidElement.prototype.renderInnerContent=function(){var t=this.canvasContext;t.fillStyle=this.data.sc,t.fillRect(0,0,this.data.sw,this.data.sh)},CVEffects.prototype.renderFrame=function(){};var animationManager=(tJ={},uJ=[],vJ=0,wJ=0,xJ=0,yJ=!0,zJ=!1,tJ.registerAnimation=BJ,tJ.loadAnimation=function(t){var e=new AnimationItem;return FJ(e,null),e.setParams(t),e},tJ.setSpeed=function(t,e){var r;for(r=0;r<wJ;r+=1)uJ[r].animation.setSpeed(t,e)},tJ.setDirection=function(t,e){var r;for(r=0;r<wJ;r+=1)uJ[r].animation.setDirection(t,e)},tJ.play=function(t){var e;for(e=0;e<wJ;e+=1)uJ[e].animation.play(t)},tJ.pause=function(t){var e;for(e=0;e<wJ;e+=1)uJ[e].animation.pause(t)},tJ.stop=function(t){var e;for(e=0;e<wJ;e+=1)uJ[e].animation.stop(t)},tJ.togglePause=function(t){var e;for(e=0;e<wJ;e+=1)uJ[e].animation.togglePause(t)},tJ.searchAnimations=function(t,e,r){var i,s=[].concat([].slice.call(document.getElementsByClassName("lottie")),[].slice.call(document.getElementsByClassName("bodymovin"))),a=s.length;for(i=0;i<a;i+=1)r&&s[i].setAttribute("data-bm-type",r),BJ(s[i],t);if(e&&0===a){r||(r="svg");var n=document.getElementsByTagName("body")[0];n.innerHTML="";var o=createTag("div");o.style.width="100%",o.style.height="100%",o.setAttribute("data-bm-type",r),n.appendChild(o),BJ(o,t)}},tJ.resize=function(){var t;for(t=0;t<wJ;t+=1)uJ[t].animation.resize()},tJ.goToAndStop=function(t,e,r){var i;for(i=0;i<wJ;i+=1)uJ[i].animation.goToAndStop(t,e,r)},tJ.destroy=function(t){var e;for(e=wJ-1;0<=e;e-=1)uJ[e].animation.destroy(t)},tJ.freeze=function(){zJ=!0},tJ.unfreeze=function(){zJ=!1,TJ()},tJ.getRegisteredAnimations=function(){var t,e=uJ.length,r=[];for(t=0;t<e;t+=1)r.push(uJ[t].animation);return r},tJ),tJ,uJ,vJ,wJ,xJ,yJ,zJ,PK,QK,RK,SK,TK,UK,VK;function AJ(t){for(var e=0,r=t.target;e<wJ;)uJ[e].animation===r&&(uJ.splice(e,1),e-=1,wJ-=1,r.isPaused||EJ()),e+=1}function BJ(t,e){if(!t)return null;for(var r=0;r<wJ;){if(uJ[r].elem==t&&null!==uJ[r].elem)return uJ[r].animation;r+=1}var i=new AnimationItem;return FJ(i,t),i.setData(t,e),i}function DJ(){xJ+=1,TJ()}function EJ(){xJ-=1}function FJ(t,e){t.addEventListener("destroy",AJ),t.addEventListener("_active",DJ),t.addEventListener("_idle",EJ),uJ.push({elem:e,animation:t}),wJ+=1}function KJ(t){var e,r=t-vJ;for(e=0;e<wJ;e+=1)uJ[e].animation.advanceTime(r);vJ=t,xJ&&!zJ?window.requestAnimationFrame(KJ):yJ=!0}function LJ(t){vJ=t,window.requestAnimationFrame(KJ)}function TJ(){!zJ&&xJ&&yJ&&(window.requestAnimationFrame(LJ),yJ=!1)}function WK(t){for(var e=0,r=t.target;e<SK;)QK[e].animation===r&&(QK.splice(e,1),e-=1,SK-=1,r.isPaused||$K()),e+=1}function ZK(){TK+=1,nL()}function $K(){TK-=1}function _K(t,e){t.addEventListener("destroy",WK),t.addEventListener("_active",ZK),t.addEventListener("_idle",$K),QK.push({elem:e,animation:t}),SK+=1}function eL(t){var e,r=t-RK;for(e=0;e<SK;e+=1)QK[e].animation.advanceTime(r);RK=t,TK&&!VK?requestAnimationFrame(eL):UK=!0}function fL(t){RK=t,requestAnimationFrame(eL)}function nL(){!VK&&TK&&UK&&(requestAnimationFrame(fL),UK=!1)}PK={},QK=[],RK=0,SK=0,TK=0,UK=!0,VK=!1,PK.registerAnimation=function(t,e){if(!t)return null;for(var r=0;r<SK;){if(QK[r].elem==t&&null!==QK[r].elem)return QK[r].animation;r+=1}var i=new AnimationItem;return _K(i,t),i.setData(t,e),i},PK.loadAnimation=function(t){var e=new AnimationItem;return _K(e,null),e.setParams(t),e},PK.setSpeed=function(t,e){var r;for(r=0;r<SK;r+=1)QK[r].animation.setSpeed(t,e)},PK.setDirection=function(t,e){var r;for(r=0;r<SK;r+=1)QK[r].animation.setDirection(t,e)},PK.play=function(t){var e;for(e=0;e<SK;e+=1)QK[e].animation.play(t)},PK.pause=function(t){var e;for(e=0;e<SK;e+=1)QK[e].animation.pause(t)},PK.stop=function(t){var e;for(e=0;e<SK;e+=1)QK[e].animation.stop(t)},PK.togglePause=function(t){var e;for(e=0;e<SK;e+=1)QK[e].animation.togglePause(t)},PK.searchAnimations=function(t,e,r){throw new Error("Cannot access DOM from worker thread")},PK.resize=function(){var t;for(t=0;t<SK;t+=1)QK[t].animation.resize()},PK.goToAndStop=function(t,e,r){var i;for(i=0;i<SK;i+=1)QK[i].animation.goToAndStop(t,e,r)},PK.destroy=function(t){var e;for(e=SK-1;0<=e;e-=1)QK[e].animation.destroy(t)},PK.freeze=function(){VK=!0},PK.unfreeze=function(){VK=!1,nL()},PK.getRegisteredAnimations=function(){var t,e=QK.length,r=[];for(t=0;t<e;t+=1)r.push(QK[t].animation);return r},animationManager=PK;var AnimationItem=function(){this._cbs=[],this.name="",this.path="",this.isLoaded=!1,this.currentFrame=0,this.currentRawFrame=0,this.totalFrames=0,this.frameRate=0,this.frameMult=0,this.playSpeed=1,this.playDirection=1,this.playCount=0,this.animationData={},this.assets=[],this.isPaused=!0,this.autoplay=!1,this.loop=!0,this.renderer=null,this.animationID=createElementID(),this.assetsPath="",this.timeCompleted=0,this.segmentPos=0,this.subframeEnabled=subframeEnabled,this.segments=[],this._idle=!0,this._completedLoop=!1,this.projectInterface=ProjectInterface(),this.imagePreloader=new ImagePreloader};extendPrototype([BaseEvent],AnimationItem),AnimationItem.prototype.setParams=function(t){t.context&&(this.context=t.context),(t.wrapper||t.container)&&(this.wrapper=t.wrapper||t.container);var e=t.animType?t.animType:t.renderer?t.renderer:"svg";switch(e){case"canvas":this.renderer=new CanvasRenderer(this,t.rendererSettings);break;case"svg":this.renderer=new SVGRenderer(this,t.rendererSettings);break;default:this.renderer=new HybridRenderer(this,t.rendererSettings)}this.renderer.setProjectInterface(this.projectInterface),this.animType=e,""===t.loop||null===t.loop||(!1===t.loop?this.loop=!1:!0===t.loop?this.loop=!0:this.loop=parseInt(t.loop)),this.autoplay=!("autoplay"in t)||t.autoplay,this.name=t.name?t.name:"",this.autoloadSegments=!t.hasOwnProperty("autoloadSegments")||t.autoloadSegments,this.assetsPath=t.assetsPath,t.animationData?this.configAnimation(t.animationData):t.path&&("json"!=t.path.substr(-4)&&("/"!=t.path.substr(-1,1)&&(t.path+="/"),t.path+="data.json"),-1!=t.path.lastIndexOf("\\")?this.path=t.path.substr(0,t.path.lastIndexOf("\\")+1):this.path=t.path.substr(0,t.path.lastIndexOf("/")+1),this.fileName=t.path.substr(t.path.lastIndexOf("/")+1),this.fileName=this.fileName.substr(0,this.fileName.lastIndexOf(".json")),assetLoader.load(t.path,this.configAnimation.bind(this),function(){this.trigger("data_failed")}.bind(this)))},AnimationItem.prototype.setData=function(t,e){var r={wrapper:t,animationData:e?"object"==typeof e?e:JSON.parse(e):null},i=t.attributes;r.path=i.getNamedItem("data-animation-path")?i.getNamedItem("data-animation-path").value:i.getNamedItem("data-bm-path")?i.getNamedItem("data-bm-path").value:i.getNamedItem("bm-path")?i.getNamedItem("bm-path").value:"",r.animType=i.getNamedItem("data-anim-type")?i.getNamedItem("data-anim-type").value:i.getNamedItem("data-bm-type")?i.getNamedItem("data-bm-type").value:i.getNamedItem("bm-type")?i.getNamedItem("bm-type").value:i.getNamedItem("data-bm-renderer")?i.getNamedItem("data-bm-renderer").value:i.getNamedItem("bm-renderer")?i.getNamedItem("bm-renderer").value:"canvas";var s=i.getNamedItem("data-anim-loop")?i.getNamedItem("data-anim-loop").value:i.getNamedItem("data-bm-loop")?i.getNamedItem("data-bm-loop").value:i.getNamedItem("bm-loop")?i.getNamedItem("bm-loop").value:"";""===s||(r.loop="false"!==s&&("true"===s||parseInt(s)));var a=i.getNamedItem("data-anim-autoplay")?i.getNamedItem("data-anim-autoplay").value:i.getNamedItem("data-bm-autoplay")?i.getNamedItem("data-bm-autoplay").value:!i.getNamedItem("bm-autoplay")||i.getNamedItem("bm-autoplay").value;r.autoplay="false"!==a,r.name=i.getNamedItem("data-name")?i.getNamedItem("data-name").value:i.getNamedItem("data-bm-name")?i.getNamedItem("data-bm-name").value:i.getNamedItem("bm-name")?i.getNamedItem("bm-name").value:"","false"===(i.getNamedItem("data-anim-prerender")?i.getNamedItem("data-anim-prerender").value:i.getNamedItem("data-bm-prerender")?i.getNamedItem("data-bm-prerender").value:i.getNamedItem("bm-prerender")?i.getNamedItem("bm-prerender").value:"")&&(r.prerender=!1),this.setParams(r)},AnimationItem.prototype.includeLayers=function(t){t.op>this.animationData.op&&(this.animationData.op=t.op,this.totalFrames=Math.floor(t.op-this.animationData.ip));var e,r,i=this.animationData.layers,s=i.length,a=t.layers,n=a.length;for(r=0;r<n;r+=1)for(e=0;e<s;){if(i[e].id==a[r].id){i[e]=a[r];break}e+=1}if((t.chars||t.fonts)&&(this.renderer.globalData.fontManager.addChars(t.chars),this.renderer.globalData.fontManager.addFonts(t.fonts,this.renderer.globalData.defs)),t.assets)for(s=t.assets.length,e=0;e<s;e+=1)this.animationData.assets.push(t.assets[e]);this.animationData.__complete=!1,dataManager.completeData(this.animationData,this.renderer.globalData.fontManager),this.renderer.includeLayers(t.layers),expressionsPlugin&&expressionsPlugin.initExpressions(this),this.loadNextSegment()},AnimationItem.prototype.loadNextSegment=function(){var t=this.animationData.segments;if(!t||0===t.length||!this.autoloadSegments)return this.trigger("data_ready"),void(this.timeCompleted=this.totalFrames);var e=t.shift();this.timeCompleted=e.time*this.frameRate;var r=this.path+this.fileName+"_"+this.segmentPos+".json";this.segmentPos+=1,assetLoader.load(r,this.includeLayers.bind(this),function(){this.trigger("data_failed")}.bind(this))},AnimationItem.prototype.loadSegments=function(){this.animationData.segments||(this.timeCompleted=this.totalFrames),this.loadNextSegment()},AnimationItem.prototype.imagesLoaded=function(){this.trigger("loaded_images"),this.checkLoaded()},AnimationItem.prototype.preloadImages=function(){this.imagePreloader.setAssetsPath(this.assetsPath),this.imagePreloader.setPath(this.path),this.imagePreloader.loadAssets(this.animationData.assets,this.imagesLoaded.bind(this))},AnimationItem.prototype.configAnimation=function(t){this.renderer&&(this.animationData=t,this.totalFrames=Math.floor(this.animationData.op-this.animationData.ip),this.renderer.configAnimation(t),t.assets||(t.assets=[]),this.renderer.searchExtraCompositions(t.assets),this.assets=this.animationData.assets,this.frameRate=this.animationData.fr,this.firstFrame=Math.round(this.animationData.ip),this.frameMult=this.animationData.fr/1e3,this.trigger("config_ready"),this.preloadImages(),this.loadSegments(),this.updaFrameModifier(),this.waitForFontsLoaded())},AnimationItem.prototype.waitForFontsLoaded=function(){this.renderer&&(this.renderer.globalData.fontManager.loaded()?this.checkLoaded():setTimeout(this.waitForFontsLoaded.bind(this),20))},AnimationItem.prototype.checkLoaded=function(){this.isLoaded||!this.renderer.globalData.fontManager.loaded()||!this.imagePreloader.loaded()&&"canvas"===this.renderer.rendererType||(this.isLoaded=!0,dataManager.completeData(this.animationData,this.renderer.globalData.fontManager),expressionsPlugin&&expressionsPlugin.initExpressions(this),this.renderer.initItems(),setTimeout(function(){this.trigger("DOMLoaded")}.bind(this),0),this.gotoFrame(),this.autoplay&&this.play())},AnimationItem.prototype.resize=function(){this.renderer.updateContainerSize()},AnimationItem.prototype.setSubframe=function(t){this.subframeEnabled=!!t},AnimationItem.prototype.gotoFrame=function(){this.currentFrame=this.subframeEnabled?this.currentRawFrame:~~this.currentRawFrame,this.timeCompleted!==this.totalFrames&&this.currentFrame>this.timeCompleted&&(this.currentFrame=this.timeCompleted),this.trigger("enterFrame"),this.renderFrame()},AnimationItem.prototype.renderFrame=function(){!1!==this.isLoaded&&this.renderer.renderFrame(this.currentFrame+this.firstFrame)},AnimationItem.prototype.play=function(t){t&&this.name!=t||!0===this.isPaused&&(this.isPaused=!1,this._idle&&(this._idle=!1,this.trigger("_active")))},AnimationItem.prototype.pause=function(t){t&&this.name!=t||!1===this.isPaused&&(this.isPaused=!0,this._idle=!0,this.trigger("_idle"))},AnimationItem.prototype.togglePause=function(t){t&&this.name!=t||(!0===this.isPaused?this.play():this.pause())},AnimationItem.prototype.stop=function(t){t&&this.name!=t||(this.pause(),this.playCount=0,this._completedLoop=!1,this.setCurrentRawFrameValue(0))},AnimationItem.prototype.goToAndStop=function(t,e,r){r&&this.name!=r||(e?this.setCurrentRawFrameValue(t):this.setCurrentRawFrameValue(t*this.frameModifier),this.pause())},AnimationItem.prototype.goToAndPlay=function(t,e,r){this.goToAndStop(t,e,r),this.play()},AnimationItem.prototype.advanceTime=function(t){if(!0!==this.isPaused&&!1!==this.isLoaded){var e=this.currentRawFrame+t*this.frameModifier,r=!1;e>=this.totalFrames-1&&0<this.frameModifier?this.loop&&this.playCount!==this.loop?e>=this.totalFrames?(this.playCount+=1,this.checkSegments(e%this.totalFrames)||(this.setCurrentRawFrameValue(e%this.totalFrames),this._completedLoop=!0,this.trigger("loopComplete"))):this.setCurrentRawFrameValue(e):this.checkSegments(e>this.totalFrames?e%this.totalFrames:0)||(r=!0,e=this.totalFrames-1):e<0?this.checkSegments(e%this.totalFrames)||(!this.loop||this.playCount--<=0&&!0!==this.loop?(r=!0,e=0):(this.setCurrentRawFrameValue(this.totalFrames+e%this.totalFrames),this._completedLoop?this.trigger("loopComplete"):this._completedLoop=!0)):this.setCurrentRawFrameValue(e),r&&(this.setCurrentRawFrameValue(e),this.pause(),this.trigger("complete"))}},AnimationItem.prototype.adjustSegment=function(t,e){this.playCount=0,t[1]<t[0]?(0<this.frameModifier&&(this.playSpeed<0?this.setSpeed(-this.playSpeed):this.setDirection(-1)),this.timeCompleted=this.totalFrames=t[0]-t[1],this.firstFrame=t[1],this.setCurrentRawFrameValue(this.totalFrames-.001-e)):t[1]>t[0]&&(this.frameModifier<0&&(this.playSpeed<0?this.setSpeed(-this.playSpeed):this.setDirection(1)),this.timeCompleted=this.totalFrames=t[1]-t[0],this.firstFrame=t[0],this.setCurrentRawFrameValue(.001+e)),this.trigger("segmentStart")},AnimationItem.prototype.setSegment=function(t,e){var r=-1;this.isPaused&&(this.currentRawFrame+this.firstFrame<t?r=t:this.currentRawFrame+this.firstFrame>e&&(r=e-t)),this.firstFrame=t,this.timeCompleted=this.totalFrames=e-t,-1!==r&&this.goToAndStop(r,!0)},AnimationItem.prototype.playSegments=function(t,e){if(e&&(this.segments.length=0),"object"==typeof t[0]){var r,i=t.length;for(r=0;r<i;r+=1)this.segments.push(t[r])}else this.segments.push(t);this.segments.length&&e&&this.adjustSegment(this.segments.shift(),0),this.isPaused&&this.play()},AnimationItem.prototype.resetSegments=function(t){this.segments.length=0,this.segments.push([this.animationData.ip,this.animationData.op]),t&&this.checkSegments(0)},AnimationItem.prototype.checkSegments=function(t){return!!this.segments.length&&(this.adjustSegment(this.segments.shift(),t),!0)},AnimationItem.prototype.destroy=function(t){t&&this.name!=t||!this.renderer||(this.renderer.destroy(),this.imagePreloader.destroy(),this.trigger("destroy"),this._cbs=null,this.onEnterFrame=this.onLoopComplete=this.onComplete=this.onSegmentStart=this.onDestroy=null,this.renderer=null)},AnimationItem.prototype.setCurrentRawFrameValue=function(t){this.currentRawFrame=t,this.gotoFrame()},AnimationItem.prototype.setSpeed=function(t){this.playSpeed=t,this.updaFrameModifier()},AnimationItem.prototype.setDirection=function(t){this.playDirection=t<0?-1:1,this.updaFrameModifier()},AnimationItem.prototype.updaFrameModifier=function(){this.frameModifier=this.frameMult*this.playSpeed*this.playDirection},AnimationItem.prototype.getPath=function(){return this.path},AnimationItem.prototype.getAssetsPath=function(t){var e="";if(t.e)e=t.p;else if(this.assetsPath){var r=t.p;-1!==r.indexOf("images/")&&(r=r.split("/")[1]),e=this.assetsPath+r}else e=this.path,e+=t.u?t.u:"",e+=t.p;return e},AnimationItem.prototype.getAssetData=function(t){for(var e=0,r=this.assets.length;e<r;){if(t==this.assets[e].id)return this.assets[e];e+=1}},AnimationItem.prototype.hide=function(){this.renderer.hide()},AnimationItem.prototype.show=function(){this.renderer.show()},AnimationItem.prototype.getDuration=function(t){return t?this.totalFrames:this.totalFrames/this.frameRate},AnimationItem.prototype.trigger=function(t){if(this._cbs&&this._cbs[t])switch(t){case"enterFrame":this.triggerEvent(t,new BMEnterFrameEvent(t,this.currentFrame,this.totalFrames,this.frameModifier));break;case"loopComplete":this.triggerEvent(t,new BMCompleteLoopEvent(t,this.loop,this.playCount,this.frameMult));break;case"complete":this.triggerEvent(t,new BMCompleteEvent(t,this.frameMult));break;case"segmentStart":this.triggerEvent(t,new BMSegmentStartEvent(t,this.firstFrame,this.totalFrames));break;case"destroy":this.triggerEvent(t,new BMDestroyEvent(t,this));break;default:this.triggerEvent(t)}"enterFrame"===t&&this.onEnterFrame&&this.onEnterFrame.call(this,new BMEnterFrameEvent(t,this.currentFrame,this.totalFrames,this.frameMult)),"loopComplete"===t&&this.onLoopComplete&&this.onLoopComplete.call(this,new BMCompleteLoopEvent(t,this.loop,this.playCount,this.frameMult)),"complete"===t&&this.onComplete&&this.onComplete.call(this,new BMCompleteEvent(t,this.frameMult)),"segmentStart"===t&&this.onSegmentStart&&this.onSegmentStart.call(this,new BMSegmentStartEvent(t,this.firstFrame,this.totalFrames)),"destroy"===t&&this.onDestroy&&this.onDestroy.call(this,new BMDestroyEvent(t,this))},AnimationItem.prototype.setParams=function(t){t.context&&(this.context=t.context);var e=t.animType?t.animType:t.renderer?t.renderer:"svg";switch(e){case"canvas":this.renderer=new CanvasRenderer(this,t.rendererSettings);break;default:throw new Error("Only canvas renderer is supported when using worker.")}if(this.renderer.setProjectInterface(this.projectInterface),this.animType=e,""===t.loop||null===t.loop||(!1===t.loop?this.loop=!1:!0===t.loop?this.loop=!0:this.loop=parseInt(t.loop)),this.autoplay=!("autoplay"in t)||t.autoplay,this.name=t.name?t.name:"",this.autoloadSegments=!t.hasOwnProperty("autoloadSegments")||t.autoloadSegments,this.assetsPath=null,t.animationData)this.configAnimation(t.animationData);else if(t.path)throw new Error("Canvas worker renderer cannot load animation from url")},AnimationItem.prototype.setData=function(t,e){throw new Error("Cannot set data on wrapper for canvas worker renderer")},AnimationItem.prototype.includeLayers=function(t){t.op>this.animationData.op&&(this.animationData.op=t.op,this.totalFrames=Math.floor(t.op-this.animationData.ip));var e,r,i=this.animationData.layers,s=i.length,a=t.layers,n=a.length;for(r=0;r<n;r+=1)for(e=0;e<s;){if(i[e].id==a[r].id){i[e]=a[r];break}e+=1}this.animationData.__complete=!1,dataManager.completeData(this.animationData,this.renderer.globalData.fontManager),this.renderer.includeLayers(t.layers),expressionsPlugin&&expressionsPlugin.initExpressions(this),this.loadNextSegment()},AnimationItem.prototype.loadNextSegment=function(){var t=this.animationData.segments;if(t&&0!==t.length&&this.autoloadSegments)throw new Error("Cannot load multiple segments in worker.");this.timeCompleted=this.totalFrames},AnimationItem.prototype.loadSegments=function(){this.animationData.segments||(this.timeCompleted=this.totalFrames),this.loadNextSegment()},AnimationItem.prototype.imagesLoaded=null,AnimationItem.prototype.preloadImages=null,AnimationItem.prototype.configAnimation=function(t){this.renderer&&(this.animationData=t,this.totalFrames=Math.floor(this.animationData.op-this.animationData.ip),this.renderer.configAnimation(t),t.assets||(t.assets=[]),this.renderer.searchExtraCompositions(t.assets),this.assets=this.animationData.assets,this.frameRate=this.animationData.fr,this.firstFrame=Math.round(this.animationData.ip),this.frameMult=this.animationData.fr/1e3,this.loadSegments(),this.updaFrameModifier(),this.checkLoaded())},AnimationItem.prototype.waitForFontsLoaded=null,AnimationItem.prototype.checkLoaded=function(){this.isLoaded||(this.isLoaded=!0,dataManager.completeData(this.animationData,null),expressionsPlugin&&expressionsPlugin.initExpressions(this),this.renderer.initItems(),this.gotoFrame())},AnimationItem.prototype.destroy=function(t){t&&this.name!=t||!this.renderer||(this.renderer.destroy(),this._cbs=null,this.onEnterFrame=this.onLoopComplete=this.onComplete=this.onSegmentStart=this.onDestroy=null,this.renderer=null)},AnimationItem.prototype.getPath=null;var Expressions=(xN={},xN.initExpressions=function(t){var e=0,r=[];t.renderer.compInterface=CompExpressionInterface(t.renderer),t.renderer.globalData.projectInterface.registerComposition(t.renderer),t.renderer.globalData.pushExpression=function(){e+=1},t.renderer.globalData.popExpression=function(){0==(e-=1)&&function(){var t,e=r.length;for(t=0;t<e;t+=1)r[t].release();r.length=0}()},t.renderer.globalData.registerExpressionProperty=function(t){-1===r.indexOf(t)&&r.push(t)}},xN),xN;expressionsPlugin=Expressions;var ExpressionManager=function(){var ob={},Math=BMMath,window=null,document=null;function $bm_isInstanceOfArray(t){return t.constructor===Array||t.constructor===Float32Array}function isNumerable(t,e){return"number"===t||"boolean"===t||"string"===t||e instanceof Number}function $bm_neg(t){var e=typeof t;if("number"==e||"boolean"==e||t instanceof Number)return-t;if($bm_isInstanceOfArray(t)){var r,i=t.length,s=[];for(r=0;r<i;r+=1)s[r]=-t[r];return s}return t.propType?t.v:void 0}var easeInBez=BezierFactory.getBezierEasing(.333,0,.833,.833,"easeIn").get,easeOutBez=BezierFactory.getBezierEasing(.167,.167,.667,1,"easeOut").get,easeInOutBez=BezierFactory.getBezierEasing(.33,0,.667,1,"easeInOut").get;function sum(t,e){var r=typeof t,i=typeof e;if("string"==r||"string"==i)return t+e;if(isNumerable(r,t)&&isNumerable(i,e))return t+e;if($bm_isInstanceOfArray(t)&&isNumerable(i,e))return(t=t.slice(0))[0]=t[0]+e,t;if(isNumerable(r,t)&&$bm_isInstanceOfArray(e))return(e=e.slice(0))[0]=t+e[0],e;if($bm_isInstanceOfArray(t)&&$bm_isInstanceOfArray(e)){for(var s=0,a=t.length,n=e.length,o=[];s<a||s<n;)("number"==typeof t[s]||t[s]instanceof Number)&&("number"==typeof e[s]||e[s]instanceof Number)?o[s]=t[s]+e[s]:o[s]=void 0===e[s]?t[s]:t[s]||e[s],s+=1;return o}return 0}var add=sum;function sub(t,e){var r=typeof t,i=typeof e;if(isNumerable(r,t)&&isNumerable(i,e))return"string"==r&&(t=parseInt(t)),"string"==i&&(e=parseInt(e)),t-e;if($bm_isInstanceOfArray(t)&&isNumerable(i,e))return(t=t.slice(0))[0]=t[0]-e,t;if(isNumerable(r,t)&&$bm_isInstanceOfArray(e))return(e=e.slice(0))[0]=t-e[0],e;if($bm_isInstanceOfArray(t)&&$bm_isInstanceOfArray(e)){for(var s=0,a=t.length,n=e.length,o=[];s<a||s<n;)("number"==typeof t[s]||t[s]instanceof Number)&&("number"==typeof e[s]||e[s]instanceof Number)?o[s]=t[s]-e[s]:o[s]=void 0===e[s]?t[s]:t[s]||e[s],s+=1;return o}return 0}function mul(t,e){var r,i,s,a=typeof t,n=typeof e;if(isNumerable(a,t)&&isNumerable(n,e))return t*e;if($bm_isInstanceOfArray(t)&&isNumerable(n,e)){for(s=t.length,r=createTypedArray("float32",s),i=0;i<s;i+=1)r[i]=t[i]*e;return r}if(isNumerable(a,t)&&$bm_isInstanceOfArray(e)){for(s=e.length,r=createTypedArray("float32",s),i=0;i<s;i+=1)r[i]=t*e[i];return r}return 0}function div(t,e){var r,i,s,a=typeof t,n=typeof e;if(isNumerable(a,t)&&isNumerable(n,e))return t/e;if($bm_isInstanceOfArray(t)&&isNumerable(n,e)){for(s=t.length,r=createTypedArray("float32",s),i=0;i<s;i+=1)r[i]=t[i]/e;return r}if(isNumerable(a,t)&&$bm_isInstanceOfArray(e)){for(s=e.length,r=createTypedArray("float32",s),i=0;i<s;i+=1)r[i]=t/e[i];return r}return 0}function mod(t,e){return"string"==typeof t&&(t=parseInt(t)),"string"==typeof e&&(e=parseInt(e)),t%e}var $bm_sum=sum,$bm_sub=sub,$bm_mul=mul,$bm_div=div,$bm_mod=mod;function clamp(t,e,r){if(r<e){var i=r;r=e,e=i}return Math.min(Math.max(t,e),r)}function radiansToDegrees(t){return t/degToRads}var radians_to_degrees=radiansToDegrees;function degreesToRadians(t){return t*degToRads}var degrees_to_radians=radiansToDegrees,helperLengthArray=[0,0,0,0,0,0];function length(t,e){if("number"==typeof t||t instanceof Number)return e=e||0,Math.abs(t-e);e||(e=helperLengthArray);var r,i=Math.min(t.length,e.length),s=0;for(r=0;r<i;r+=1)s+=Math.pow(e[r]-t[r],2);return Math.sqrt(s)}function normalize(t){return div(t,length(t))}function rgbToHsl(t){var e,r,i=t[0],s=t[1],a=t[2],n=Math.max(i,s,a),o=Math.min(i,s,a),h=(n+o)/2;if(n==o)e=r=0;else{var p=n-o;switch(r=.5<h?p/(2-n-o):p/(n+o),n){case i:e=(s-a)/p+(s<a?6:0);break;case s:e=(a-i)/p+2;break;case a:e=(i-s)/p+4}e/=6}return[e,r,h,t[3]]}function hue2rgb(t,e,r){return r<0&&(r+=1),1<r&&(r-=1),r<1/6?t+6*(e-t)*r:r<.5?e:r<2/3?t+(e-t)*(2/3-r)*6:t}function hslToRgb(t){var e,r,i,s=t[0],a=t[1],n=t[2];if(0===a)e=r=i=n;else{var o=n<.5?n*(1+a):n+a-n*a,h=2*n-o;e=hue2rgb(h,o,s+1/3),r=hue2rgb(h,o,s),i=hue2rgb(h,o,s-1/3)}return[e,r,i,t[3]]}function linear(t,e,r,i,s){if(void 0!==i&&void 0!==s||(i=e,s=r,e=0,r=1),r<e){var a=r;r=e,e=a}if(t<=e)return i;if(r<=t)return s;var n=r===e?0:(t-e)/(r-e);if(!i.length)return i+(s-i)*n;var o,h=i.length,p=createTypedArray("float32",h);for(o=0;o<h;o+=1)p[o]=i[o]+(s[o]-i[o])*n;return p}function random(t,e){if(void 0===e&&(void 0===t?(t=0,e=1):(e=t,t=void 0)),e.length){var r,i=e.length;t||(t=createTypedArray("float32",i));var s=createTypedArray("float32",i),a=BMMath.random();for(r=0;r<i;r+=1)s[r]=t[r]+a*(e[r]-t[r]);return s}return void 0===t&&(t=0),t+BMMath.random()*(e-t)}function createPath(t,e,r,i){var s,a=t.length,n=shape_pool.newElement();n.setPathData(!!i,a);var o,h,p=[0,0];for(s=0;s<a;s+=1)o=e&&e[s]?e[s]:p,h=r&&r[s]?r[s]:p,n.setTripleAt(t[s][0],t[s][1],h[0]+t[s][0],h[1]+t[s][1],o[0]+t[s][0],o[1]+t[s][1],s,!0);return n}function initiateExpression(elem,data,property){var val=data.x,needsVelocity=/velocity(?![\w\d])/.test(val),_needsRandom=-1!==val.indexOf("random"),elemType=elem.data.ty,transform,$bm_transform,content,effect,thisProperty=property;thisProperty.valueAtTime=thisProperty.getValueAtTime,Object.defineProperty(thisProperty,"value",{get:function(){return thisProperty.v}}),elem.comp.frameDuration=1/elem.comp.globalData.frameRate,elem.comp.displayStartTime=0;var inPoint=elem.data.ip/elem.comp.globalData.frameRate,outPoint=elem.data.op/elem.comp.globalData.frameRate,width=elem.data.sw?elem.data.sw:0,height=elem.data.sh?elem.data.sh:0,name=elem.data.nm,loopIn,loop_in,loopOut,loop_out,smooth,toWorld,fromWorld,fromComp,toComp,fromCompToSurface,position,rotation,anchorPoint,scale,thisLayer,thisComp,mask,valueAtTime,velocityAtTime,__expression_functions=[],scoped_bm_rt;if(data.xf){var i,len=data.xf.length;for(i=0;i<len;i+=1)__expression_functions[i]=eval("(function(){ return "+data.xf[i]+"}())")}var expression_function=eval("[function _expression_function(){"+val+";scoped_bm_rt=$bm_rt}]")[0],numKeys=property.kf?data.k.length:0,active=!this.data||!0!==this.data.hd,wiggle=function(t,e){var r,i,s=this.pv.length?this.pv.length:1,a=createTypedArray("float32",s);var n=Math.floor(5*time);for(i=r=0;r<n;){for(i=0;i<s;i+=1)a[i]+=-e+2*e*BMMath.random();r+=1}var o=5*time,h=o-Math.floor(o),p=createTypedArray("float32",s);if(1<s){for(i=0;i<s;i+=1)p[i]=this.pv[i]+a[i]+(-e+2*e*BMMath.random())*h;return p}return this.pv+a[0]+(-e+2*e*BMMath.random())*h}.bind(this);function loopInDuration(t,e){return loopIn(t,e,!0)}function loopOutDuration(t,e){return loopOut(t,e,!0)}thisProperty.loopIn&&(loopIn=thisProperty.loopIn.bind(thisProperty),loop_in=loopIn),thisProperty.loopOut&&(loopOut=thisProperty.loopOut.bind(thisProperty),loop_out=loopOut),thisProperty.smooth&&(smooth=thisProperty.smooth.bind(thisProperty)),this.getValueAtTime&&(valueAtTime=this.getValueAtTime.bind(this)),this.getVelocityAtTime&&(velocityAtTime=this.getVelocityAtTime.bind(this));var comp=elem.comp.globalData.projectInterface.bind(elem.comp.globalData.projectInterface),time,velocity,value,text,textIndex,textTotal,selectorValue;function lookAt(t,e){var r=[e[0]-t[0],e[1]-t[1],e[2]-t[2]],i=Math.atan2(r[0],Math.sqrt(r[1]*r[1]+r[2]*r[2]))/degToRads;return[-Math.atan2(r[1],r[2])/degToRads,i,0]}function easeOut(t,e,r,i,s){return applyEase(easeOutBez,t,e,r,i,s)}function easeIn(t,e,r,i,s){return applyEase(easeInBez,t,e,r,i,s)}function ease(t,e,r,i,s){return applyEase(easeInOutBez,t,e,r,i,s)}function applyEase(t,e,r,i,s,a){void 0===s?(s=r,a=i):e=(e-r)/(i-r);var n=t(e=1<e?1:e<0?0:e);if($bm_isInstanceOfArray(s)){var o,h=s.length,p=createTypedArray("float32",h);for(o=0;o<h;o+=1)p[o]=(a[o]-s[o])*n+s[o];return p}return(a-s)*n+s}function nearestKey(t){var e,r,i,s=data.k.length;if(data.k.length&&"number"!=typeof data.k[0])if(r=-1,(t*=elem.comp.globalData.frameRate)<data.k[0].t)r=1,i=data.k[0].t;else{for(e=0;e<s-1;e+=1){if(t===data.k[e].t){r=e+1,i=data.k[e].t;break}if(t>data.k[e].t&&t<data.k[e+1].t){i=t-data.k[e].t>data.k[e+1].t-t?(r=e+2,data.k[e+1].t):(r=e+1,data.k[e].t);break}}-1===r&&(r=e+1,i=data.k[e].t)}else i=r=0;var a={};return a.index=r,a.time=i/elem.comp.globalData.frameRate,a}function key(t){var e,r,i,s;if(!data.k.length||"number"==typeof data.k[0])throw new Error("The property has no keyframe at index "+t);for(t-=1,e={time:data.k[t].t/elem.comp.globalData.frameRate,value:[]},i=(s=t!==data.k.length-1||data.k[t].h?data.k[t].s:data.k[t].s||0===data.k[t].s?data.k[t-1].s:data.k[t].e).length,r=0;r<i;r+=1)e[r]=s[r],e.value[r]=s[r];return e}function framesToTime(t,e){return e||(e=elem.comp.globalData.frameRate),t/e}function timeToFrames(t,e){return t||0===t||(t=time),e||(e=elem.comp.globalData.frameRate),t*e}function seedRandom(t){BMMath.seedrandom(randSeed+t)}function sourceRectAtTime(){return elem.sourceRectAtTime()}function substring(t,e){return"string"==typeof value?void 0===e?value.substring(t):value.substring(t,e):""}function substr(t,e){return"string"==typeof value?void 0===e?value.substr(t):value.substr(t,e):""}var index=elem.data.ind,hasParent=!(!elem.hierarchy||!elem.hierarchy.length),parent,randSeed=Math.floor(1e6*Math.random()),globalData=elem.globalData;function executeExpression(t){return value=t,_needsRandom&&seedRandom(randSeed),this.frameExpressionId===elem.globalData.frameId&&"textSelector"!==this.propType?value:("textSelector"===this.propType&&(textIndex=this.textIndex,textTotal=this.textTotal,selectorValue=this.selectorValue),thisLayer||(text=elem.layerInterface.text,thisLayer=elem.layerInterface,thisComp=elem.comp.compInterface,toWorld=thisLayer.toWorld.bind(thisLayer),fromWorld=thisLayer.fromWorld.bind(thisLayer),fromComp=thisLayer.fromComp.bind(thisLayer),toComp=thisLayer.toComp.bind(thisLayer),mask=thisLayer.mask?thisLayer.mask.bind(thisLayer):null,fromCompToSurface=fromComp),transform||(transform=elem.layerInterface("ADBE Transform Group"),($bm_transform=transform)&&(anchorPoint=transform.anchorPoint)),4!==elemType||content||(content=thisLayer("ADBE Root Vectors Group")),effect||(effect=thisLayer(4)),(hasParent=!(!elem.hierarchy||!elem.hierarchy.length))&&!parent&&(parent=elem.hierarchy[0].layerInterface),time=this.comp.renderedFrame/this.comp.globalData.frameRate,needsVelocity&&(velocity=velocityAtTime(time)),expression_function(),this.frameExpressionId=elem.globalData.frameId,"shape"===scoped_bm_rt.propType&&(scoped_bm_rt=scoped_bm_rt.v),scoped_bm_rt)}return executeExpression}return ob.initiateExpression=initiateExpression,ob}(),expressionHelpers={searchExpressions:function(t,e,r){e.x&&(r.k=!0,r.x=!0,r.initiateExpression=ExpressionManager.initiateExpression,r.effectsSequence.push(r.initiateExpression(t,e,r).bind(r)))},getSpeedAtTime:function(t){var e=this.getValueAtTime(t),r=this.getValueAtTime(t+-.01),i=0;if(e.length){var s;for(s=0;s<e.length;s+=1)i+=Math.pow(r[s]-e[s],2);i=100*Math.sqrt(i)}else i=0;return i},getVelocityAtTime:function(t){if(void 0!==this.vel)return this.vel;var e,r,i=this.getValueAtTime(t),s=this.getValueAtTime(t+-.001);if(i.length)for(e=createTypedArray("float32",i.length),r=0;r<i.length;r+=1)e[r]=(s[r]-i[r])/-.001;else e=(s-i)/-.001;return e},getValueAtTime:function(t){return t*=this.elem.globalData.frameRate,(t-=this.offsetTime)!==this._cachingAtTime.lastFrame&&(this._cachingAtTime.lastIndex=this._cachingAtTime.lastFrame<t?this._cachingAtTime.lastIndex:0,this._cachingAtTime.value=this.interpolateValue(t,this._cachingAtTime),this._cachingAtTime.lastFrame=t),this._cachingAtTime.value},getStaticValueAtTime:function(){return this.pv},setGroupProperty:function(t){this.propertyGroup=t}};!function(){function o(t,e,r){if(!this.k||!this.keyframes)return this.pv;t=t?t.toLowerCase():"";var i,s,a,n,o,h=this.comp.renderedFrame,p=this.keyframes,l=p[p.length-1].t;if(h<=l)return this.pv;if(r?s=l-(i=e?Math.abs(l-elem.comp.globalData.frameRate*e):Math.max(0,l-this.elem.data.ip)):((!e||e>p.length-1)&&(e=p.length-1),i=l-(s=p[p.length-1-e].t)),"pingpong"===t){if(Math.floor((h-s)/i)%2!=0)return this.getValueAtTime((i-(h-s)%i+s)/this.comp.globalData.frameRate,0)}else{if("offset"===t){var m=this.getValueAtTime(s/this.comp.globalData.frameRate,0),f=this.getValueAtTime(l/this.comp.globalData.frameRate,0),c=this.getValueAtTime(((h-s)%i+s)/this.comp.globalData.frameRate,0),d=Math.floor((h-s)/i);if(this.pv.length){for(n=(o=new Array(m.length)).length,a=0;a<n;a+=1)o[a]=(f[a]-m[a])*d+c[a];return o}return(f-m)*d+c}if("continue"===t){var u=this.getValueAtTime(l/this.comp.globalData.frameRate,0),y=this.getValueAtTime((l-.001)/this.comp.globalData.frameRate,0);if(this.pv.length){for(n=(o=new Array(u.length)).length,a=0;a<n;a+=1)o[a]=u[a]+(u[a]-y[a])*((h-l)/this.comp.globalData.frameRate)/5e-4;return o}return u+(h-l)/.001*(u-y)}}return this.getValueAtTime(((h-s)%i+s)/this.comp.globalData.frameRate,0)}function h(t,e,r){if(!this.k)return this.pv;t=t?t.toLowerCase():"";var i,s,a,n,o,h=this.comp.renderedFrame,p=this.keyframes,l=p[0].t;if(l<=h)return this.pv;if(r?s=l+(i=e?Math.abs(elem.comp.globalData.frameRate*e):Math.max(0,this.elem.data.op-l)):((!e||e>p.length-1)&&(e=p.length-1),i=(s=p[e].t)-l),"pingpong"===t){if(Math.floor((l-h)/i)%2==0)return this.getValueAtTime(((l-h)%i+l)/this.comp.globalData.frameRate,0)}else{if("offset"===t){var m=this.getValueAtTime(l/this.comp.globalData.frameRate,0),f=this.getValueAtTime(s/this.comp.globalData.frameRate,0),c=this.getValueAtTime((i-(l-h)%i+l)/this.comp.globalData.frameRate,0),d=Math.floor((l-h)/i)+1;if(this.pv.length){for(n=(o=new Array(m.length)).length,a=0;a<n;a+=1)o[a]=c[a]-(f[a]-m[a])*d;return o}return c-(f-m)*d}if("continue"===t){var u=this.getValueAtTime(l/this.comp.globalData.frameRate,0),y=this.getValueAtTime((l+.001)/this.comp.globalData.frameRate,0);if(this.pv.length){for(n=(o=new Array(u.length)).length,a=0;a<n;a+=1)o[a]=u[a]+(u[a]-y[a])*(l-h)/.001;return o}return u+(u-y)*(l-h)/.001}}return this.getValueAtTime((i-(l-h)%i+l)/this.comp.globalData.frameRate,0)}function p(t,e){if(!this.k)return this.pv;if(t=.5*(t||.4),(e=Math.floor(e||5))<=1)return this.pv;var r,i,s=this.comp.renderedFrame/this.comp.globalData.frameRate,a=s-t,n=1<e?(s+t-a)/(e-1):1,o=0,h=0;for(r=this.pv.length?createTypedArray("float32",this.pv.length):0;o<e;){if(i=this.getValueAtTime(a+o*n),this.pv.length)for(h=0;h<this.pv.length;h+=1)r[h]+=i[h];else r+=i;o+=1}if(this.pv.length)for(h=0;h<this.pv.length;h+=1)r[h]/=e;else r/=e;return r}var s=TransformPropertyFactory.getTransformProperty;TransformPropertyFactory.getTransformProperty=function(t,e,r){var i=s(t,e,r);return i.dynamicProperties.length?i.getValueAtTime=function(t){console.warn("Transform at time not supported")}.bind(i):i.getValueAtTime=function(t){}.bind(i),i.setGroupProperty=expressionHelpers.setGroupProperty,i};var l=PropertyFactory.getProp;PropertyFactory.getProp=function(t,e,r,i,s){var a=l(t,e,r,i,s);a.kf?a.getValueAtTime=expressionHelpers.getValueAtTime.bind(a):a.getValueAtTime=expressionHelpers.getStaticValueAtTime.bind(a),a.setGroupProperty=expressionHelpers.setGroupProperty,a.loopOut=o,a.loopIn=h,a.smooth=p,a.getVelocityAtTime=expressionHelpers.getVelocityAtTime.bind(a),a.getSpeedAtTime=expressionHelpers.getSpeedAtTime.bind(a),a.numKeys=1===e.a?e.k.length:0,a.propertyIndex=e.ix;var n=0;return 0!==r&&(n=createTypedArray("float32",1===e.a?e.k[0].s.length:e.k.length)),a._cachingAtTime={lastFrame:initialDefaultFrame,lastIndex:0,value:n},expressionHelpers.searchExpressions(t,e,a),a.k&&s.addDynamicProperty(a),a};var t=ShapePropertyFactory.getConstructorFunction(),e=ShapePropertyFactory.getKeyframedConstructorFunction();function r(){}r.prototype={vertices:function(t,e){this.k&&this.getValue();var r=this.v;void 0!==e&&(r=this.getValueAtTime(e,0));var i,s=r._length,a=r[t],n=r.v,o=createSizedArray(s);for(i=0;i<s;i+=1)o[i]="i"===t||"o"===t?[a[i][0]-n[i][0],a[i][1]-n[i][1]]:[a[i][0],a[i][1]];return o},points:function(t){return this.vertices("v",t)},inTangents:function(t){return this.vertices("i",t)},outTangents:function(t){return this.vertices("o",t)},isClosed:function(){return this.v.c},pointOnPath:function(t,e){var r=this.v;void 0!==e&&(r=this.getValueAtTime(e,0)),this._segmentsLength||(this._segmentsLength=bez.getSegmentsLength(r));for(var i,s=this._segmentsLength,a=s.lengths,n=s.totalLength*t,o=0,h=a.length,p=0;o<h;){if(p+a[o].addedLength>n){var l=o,m=r.c&&o===h-1?0:o+1,f=(n-p)/a[o].addedLength;i=bez.getPointInSegment(r.v[l],r.v[m],r.o[l],r.i[m],f,a[o]);break}p+=a[o].addedLength,o+=1}return i||(i=r.c?[r.v[0][0],r.v[0][1]]:[r.v[r._length-1][0],r.v[r._length-1][1]]),i},vectorOnPath:function(t,e,r){t=1==t?this.v.c?0:.999:t;var i=this.pointOnPath(t,e),s=this.pointOnPath(t+.001,e),a=s[0]-i[0],n=s[1]-i[1],o=Math.sqrt(Math.pow(a,2)+Math.pow(n,2));return"tangent"===r?[a/o,n/o]:[-n/o,a/o]},tangentOnPath:function(t,e){return this.vectorOnPath(t,e,"tangent")},normalOnPath:function(t,e){return this.vectorOnPath(t,e,"normal")},setGroupProperty:expressionHelpers.setGroupProperty,getValueAtTime:expressionHelpers.getStaticValueAtTime},extendPrototype([r],t),extendPrototype([r],e),e.prototype.getValueAtTime=function(t){return this._cachingAtTime||(this._cachingAtTime={shapeValue:shape_pool.clone(this.pv),lastIndex:0,lastTime:initialDefaultFrame}),t*=this.elem.globalData.frameRate,(t-=this.offsetTime)!==this._cachingAtTime.lastTime&&(this._cachingAtTime.lastIndex=this._cachingAtTime.lastTime<t?this._caching.lastIndex:0,this._cachingAtTime.lastTime=t,this.interpolateShape(t,this._cachingAtTime.shapeValue,this._cachingAtTime)),this._cachingAtTime.shapeValue},e.prototype.initiateExpression=ExpressionManager.initiateExpression;var n=ShapePropertyFactory.getShapeProp;ShapePropertyFactory.getShapeProp=function(t,e,r,i,s){var a=n(t,e,r,i,s);return a.propertyIndex=e.ix,a.lock=!1,3===r?expressionHelpers.searchExpressions(t,e.pt,a):4===r&&expressionHelpers.searchExpressions(t,e.ks,a),a.k&&t.addDynamicProperty(a),a}}(),TextProperty.prototype.getExpressionValue=function(t,e){var r=this.calculateExpression(e);if(t.t===r)return t;var i={};return this.copyData(i,t),i.t=r.toString(),i.__complete=!1,i},TextProperty.prototype.searchProperty=function(){var t=this.searchKeyframes(),e=this.searchExpressions();return this.kf=t||e,this.kf},TextProperty.prototype.searchExpressions=function(){if(this.data.d.x)return this.calculateExpression=ExpressionManager.initiateExpression.bind(this)(this.elem,this.data.d,this),this.addEffect(this.getExpressionValue.bind(this)),!0};var ShapeExpressionInterface=function(t,e,r){var i;function s(t){if("number"==typeof t)return i[t-1];for(var e=0,r=i.length;e<r;){if(i[e]._name===t)return i[e];e+=1}}return s.propertyGroup=r,i=DT(t,e,s),s.numProperties=i.length,s};function DT(t,e,r){var i,s=[],a=t?t.length:0;for(i=0;i<a;i+=1)"gr"==t[i].ty?s.push(FT(t[i],e[i],r)):"fl"==t[i].ty?s.push(GT(t[i],e[i],r)):"st"==t[i].ty?s.push(HT(t[i],e[i],r)):"tm"==t[i].ty?s.push(IT(t[i],e[i],r)):"tr"==t[i].ty||("el"==t[i].ty?s.push(KT(t[i],e[i],r)):"sr"==t[i].ty?s.push(LT(t[i],e[i],r)):"sh"==t[i].ty?s.push(PT(t[i],e[i],r)):"rc"==t[i].ty?s.push(MT(t[i],e[i],r)):"rd"==t[i].ty?s.push(NT(t[i],e[i],r)):"rp"==t[i].ty&&s.push(OT(t[i],e[i],r)));return s}function FT(t,e,r){var i=function(t){switch(t){case"ADBE Vectors Group":case"Contents":case 2:return i.content;default:return i.transform}};i.propertyGroup=function(t){return 1===t?i:r(t-1)};var s=function(t,e,r){function i(t){for(var e=0,r=s.length;e<r;){if(s[e]._name===t||s[e].mn===t||s[e].propertyIndex===t||s[e].ix===t||s[e].ind===t)return s[e];e+=1}if("number"==typeof t)return s[t-1]}var s;return i.propertyGroup=function(t){return 1===t?i:r(t-1)},s=DT(t.it,e.it,i.propertyGroup),i.numProperties=s.length,i.propertyIndex=t.cix,i._name=t.nm,i}(t,e,i.propertyGroup),a=function(e,t,r){function i(t){return 1==t?s:r(--t)}t.transform.mProps.o.setGroupProperty(i),t.transform.mProps.p.setGroupProperty(i),t.transform.mProps.a.setGroupProperty(i),t.transform.mProps.s.setGroupProperty(i),t.transform.mProps.r.setGroupProperty(i),t.transform.mProps.sk&&(t.transform.mProps.sk.setGroupProperty(i),t.transform.mProps.sa.setGroupProperty(i));function s(t){return e.a.ix===t||"Anchor Point"===t?s.anchorPoint:e.o.ix===t||"Opacity"===t?s.opacity:e.p.ix===t||"Position"===t?s.position:e.r.ix===t||"Rotation"===t||"ADBE Vector Rotation"===t?s.rotation:e.s.ix===t||"Scale"===t?s.scale:e.sk&&e.sk.ix===t||"Skew"===t?s.skew:e.sa&&e.sa.ix===t||"Skew Axis"===t?s.skewAxis:void 0}return t.transform.op.setGroupProperty(i),Object.defineProperties(s,{opacity:{get:ExpressionPropertyInterface(t.transform.mProps.o)},position:{get:ExpressionPropertyInterface(t.transform.mProps.p)},anchorPoint:{get:ExpressionPropertyInterface(t.transform.mProps.a)},scale:{get:ExpressionPropertyInterface(t.transform.mProps.s)},rotation:{get:ExpressionPropertyInterface(t.transform.mProps.r)},skew:{get:ExpressionPropertyInterface(t.transform.mProps.sk)},skewAxis:{get:ExpressionPropertyInterface(t.transform.mProps.sa)},_name:{value:e.nm}}),s.ty="tr",s.mn=e.mn,s.propertyGroup=r,s}(t.it[t.it.length-1],e.it[e.it.length-1],i.propertyGroup);return i.content=s,i.transform=a,Object.defineProperty(i,"_name",{get:function(){return t.nm}}),i.numProperties=t.np,i.propertyIndex=t.ix,i.nm=t.nm,i.mn=t.mn,i}function GT(t,e,r){function i(t){return"Color"===t||"color"===t?i.color:"Opacity"===t||"opacity"===t?i.opacity:void 0}return Object.defineProperties(i,{color:{get:ExpressionPropertyInterface(e.c)},opacity:{get:ExpressionPropertyInterface(e.o)},_name:{value:t.nm},mn:{value:t.mn}}),e.c.setGroupProperty(r),e.o.setGroupProperty(r),i}function HT(t,e,r){function i(t){return 1===t?ob:r(t-1)}function s(t){return 1===t?h:i(t-1)}var a,n,o=t.d?t.d.length:0,h={};for(a=0;a<o;a+=1)n=a,Object.defineProperty(h,t.d[n].nm,{get:ExpressionPropertyInterface(e.d.dataProps[n].p)}),e.d.dataProps[a].p.setGroupProperty(s);function p(t){return"Color"===t||"color"===t?p.color:"Opacity"===t||"opacity"===t?p.opacity:"Stroke Width"===t||"stroke width"===t?p.strokeWidth:void 0}return Object.defineProperties(p,{color:{get:ExpressionPropertyInterface(e.c)},opacity:{get:ExpressionPropertyInterface(e.o)},strokeWidth:{get:ExpressionPropertyInterface(e.w)},dash:{get:function(){return h}},_name:{value:t.nm},mn:{value:t.mn}}),e.c.setGroupProperty(i),e.o.setGroupProperty(i),e.w.setGroupProperty(i),p}function IT(e,t,r){function i(t){return 1==t?s:r(--t)}function s(t){return t===e.e.ix||"End"===t||"end"===t?s.end:t===e.s.ix?s.start:t===e.o.ix?s.offset:void 0}return s.propertyIndex=e.ix,t.s.setGroupProperty(i),t.e.setGroupProperty(i),t.o.setGroupProperty(i),s.propertyIndex=e.ix,s.propertyGroup=r,Object.defineProperties(s,{start:{get:ExpressionPropertyInterface(t.s)},end:{get:ExpressionPropertyInterface(t.e)},offset:{get:ExpressionPropertyInterface(t.o)},_name:{value:e.nm}}),s.mn=e.mn,s}function KT(e,t,r){function i(t){return 1==t?a:r(--t)}a.propertyIndex=e.ix;var s="tm"===t.sh.ty?t.sh.prop:t.sh;function a(t){return e.p.ix===t?a.position:e.s.ix===t?a.size:void 0}return s.s.setGroupProperty(i),s.p.setGroupProperty(i),Object.defineProperties(a,{size:{get:ExpressionPropertyInterface(s.s)},position:{get:ExpressionPropertyInterface(s.p)},_name:{value:e.nm}}),a.mn=e.mn,a}function LT(e,t,r){function i(t){return 1==t?a:r(--t)}var s="tm"===t.sh.ty?t.sh.prop:t.sh;function a(t){return e.p.ix===t?a.position:e.r.ix===t?a.rotation:e.pt.ix===t?a.points:e.or.ix===t||"ADBE Vector Star Outer Radius"===t?a.outerRadius:e.os.ix===t?a.outerRoundness:!e.ir||e.ir.ix!==t&&"ADBE Vector Star Inner Radius"!==t?e.is&&e.is.ix===t?a.innerRoundness:void 0:a.innerRadius}return a.propertyIndex=e.ix,s.or.setGroupProperty(i),s.os.setGroupProperty(i),s.pt.setGroupProperty(i),s.p.setGroupProperty(i),s.r.setGroupProperty(i),e.ir&&(s.ir.setGroupProperty(i),s.is.setGroupProperty(i)),Object.defineProperties(a,{position:{get:ExpressionPropertyInterface(s.p)},rotation:{get:ExpressionPropertyInterface(s.r)},points:{get:ExpressionPropertyInterface(s.pt)},outerRadius:{get:ExpressionPropertyInterface(s.or)},outerRoundness:{get:ExpressionPropertyInterface(s.os)},innerRadius:{get:ExpressionPropertyInterface(s.ir)},innerRoundness:{get:ExpressionPropertyInterface(s.is)},_name:{value:e.nm}}),a.mn=e.mn,a}function MT(e,t,r){function i(t){return 1==t?a:r(--t)}var s="tm"===t.sh.ty?t.sh.prop:t.sh;function a(t){return e.p.ix===t?a.position:e.r.ix===t?a.roundness:e.s.ix===t||"Size"===t||"ADBE Vector Rect Size"===t?a.size:void 0}return a.propertyIndex=e.ix,s.p.setGroupProperty(i),s.s.setGroupProperty(i),s.r.setGroupProperty(i),Object.defineProperties(a,{position:{get:ExpressionPropertyInterface(s.p)},roundness:{get:ExpressionPropertyInterface(s.r)},size:{get:ExpressionPropertyInterface(s.s)},_name:{value:e.nm}}),a.mn=e.mn,a}function NT(e,t,r){var i=t;function s(t){if(e.r.ix===t||"Round Corners 1"===t)return s.radius}return s.propertyIndex=e.ix,i.rd.setGroupProperty(function(t){return 1==t?s:r(--t)}),Object.defineProperties(s,{radius:{get:ExpressionPropertyInterface(i.rd)},_name:{value:e.nm}}),s.mn=e.mn,s}function OT(e,t,r){function i(t){return 1==t?a:r(--t)}var s=t;function a(t){return e.c.ix===t||"Copies"===t?a.copies:e.o.ix===t||"Offset"===t?a.offset:void 0}return a.propertyIndex=e.ix,s.c.setGroupProperty(i),s.o.setGroupProperty(i),Object.defineProperties(a,{copies:{get:ExpressionPropertyInterface(s.c)},offset:{get:ExpressionPropertyInterface(s.o)},_name:{value:e.nm}}),a.mn=e.mn,a}function PT(t,e,r){var i=e.sh;function s(t){if("Shape"===t||"shape"===t||"Path"===t||"path"===t||"ADBE Vector Shape"===t||2===t)return s.path}return i.setGroupProperty(function(t){return 1==t?s:r(--t)}),Object.defineProperties(s,{path:{get:function(){return i.k&&i.getValue(),i}},shape:{get:function(){return i.k&&i.getValue(),i}},_name:{value:t.nm},ix:{value:t.ix},mn:{value:t.mn}}),s}var TextExpressionInterface=function(e){var r;function t(){}return Object.defineProperty(t,"sourceText",{get:function(){e.textProperty.getValue();var t=e.textProperty.currentData.t;return void 0!==t&&(e.textProperty.currentData.t=void 0,(r=new String(t)).value=t||new String(t)),r}}),t},LayerExpressionInterface=function(e){var r;function i(t){switch(t){case"ADBE Root Vectors Group":case"Contents":case 2:return i.shapeInterface;case 1:case 6:case"Transform":case"transform":case"ADBE Transform Group":return r;case 4:case"ADBE Effect Parade":case"effects":case"Effects":return i.effect}}i.toWorld=_V,i.fromWorld=aW,i.toComp=_V,i.fromComp=bW,i.sampleImage=cW,i.sourceRectAtTime=e.sourceRectAtTime.bind(e);var t=getDescriptor(r=TransformExpressionInterface((i._elem=e).finalTransform.mProp),"anchorPoint");return Object.defineProperties(i,{hasParent:{get:function(){return e.hierarchy.length}},parent:{get:function(){return e.hierarchy[0].layerInterface}},rotation:getDescriptor(r,"rotation"),scale:getDescriptor(r,"scale"),position:getDescriptor(r,"position"),opacity:getDescriptor(r,"opacity"),anchorPoint:t,anchor_point:t,transform:{get:function(){return r}},active:{get:function(){return e.isInRange}}}),i.startTime=e.data.st,i.index=e.data.ind,i.source=e.data.refId,i.height=0===e.data.ty?e.data.h:100,i.width=0===e.data.ty?e.data.w:100,i.inPoint=e.data.ip/e.comp.globalData.frameRate,i.outPoint=e.data.op/e.comp.globalData.frameRate,i._name=e.data.nm,i.registerMaskInterface=function(t){i.mask=new MaskManagerInterface(t,e)},i.registerEffectsInterface=function(t){i.effect=t},i};function _V(t,e){var r=new Matrix;if(r.reset(),this._elem.finalTransform.mProp.applyToMatrix(r),this._elem.hierarchy&&this._elem.hierarchy.length){var i,s=this._elem.hierarchy.length;for(i=0;i<s;i+=1)this._elem.hierarchy[i].finalTransform.mProp.applyToMatrix(r);return r.applyToPointArray(t[0],t[1],t[2]||0)}return r.applyToPointArray(t[0],t[1],t[2]||0)}function aW(t,e){var r=new Matrix;if(r.reset(),this._elem.finalTransform.mProp.applyToMatrix(r),this._elem.hierarchy&&this._elem.hierarchy.length){var i,s=this._elem.hierarchy.length;for(i=0;i<s;i+=1)this._elem.hierarchy[i].finalTransform.mProp.applyToMatrix(r);return r.inversePoint(t)}return r.inversePoint(t)}function bW(t){var e=new Matrix;if(e.reset(),this._elem.finalTransform.mProp.applyToMatrix(e),this._elem.hierarchy&&this._elem.hierarchy.length){var r,i=this._elem.hierarchy.length;for(r=0;r<i;r+=1)this._elem.hierarchy[r].finalTransform.mProp.applyToMatrix(e);return e.inversePoint(t)}return e.inversePoint(t)}function cW(){return[1,1,1,1]}var CompExpressionInterface=function(i){function t(t){for(var e=0,r=i.layers.length;e<r;){if(i.layers[e].nm===t||i.layers[e].ind===t)return i.elements[e].layerInterface;e+=1}return null}return Object.defineProperty(t,"_name",{value:i.data.nm}),(t.layer=t).pixelAspect=1,t.height=i.data.h||i.globalData.compSize.h,t.width=i.data.w||i.globalData.compSize.w,t.pixelAspect=1,t.frameDuration=1/i.globalData.frameRate,t.displayStartTime=0,t.numLayers=i.layers.length,t},TransformExpressionInterface=function(t){function e(t){switch(t){case"scale":case"Scale":case"ADBE Scale":case 6:return e.scale;case"rotation":case"Rotation":case"ADBE Rotation":case"ADBE Rotate Z":case 10:return e.rotation;case"ADBE Rotate X":return e.xRotation;case"ADBE Rotate Y":return e.yRotation;case"position":case"Position":case"ADBE Position":case 2:return e.position;case"ADBE Position_0":return e.xPosition;case"ADBE Position_1":return e.yPosition;case"ADBE Position_2":return e.zPosition;case"anchorPoint":case"AnchorPoint":case"Anchor Point":case"ADBE AnchorPoint":case 1:return e.anchorPoint;case"opacity":case"Opacity":case 11:return e.opacity}}if(Object.defineProperty(e,"rotation",{get:ExpressionPropertyInterface(t.r||t.rz)}),Object.defineProperty(e,"zRotation",{get:ExpressionPropertyInterface(t.rz||t.r)}),Object.defineProperty(e,"xRotation",{get:ExpressionPropertyInterface(t.rx)}),Object.defineProperty(e,"yRotation",{get:ExpressionPropertyInterface(t.ry)}),Object.defineProperty(e,"scale",{get:ExpressionPropertyInterface(t.s)}),t.p)var r=ExpressionPropertyInterface(t.p);return Object.defineProperty(e,"position",{get:function(){return t.p?r():[t.px.v,t.py.v,t.pz?t.pz.v:0]}}),Object.defineProperty(e,"xPosition",{get:ExpressionPropertyInterface(t.px)}),Object.defineProperty(e,"yPosition",{get:ExpressionPropertyInterface(t.py)}),Object.defineProperty(e,"zPosition",{get:ExpressionPropertyInterface(t.pz)}),Object.defineProperty(e,"anchorPoint",{get:ExpressionPropertyInterface(t.a)}),Object.defineProperty(e,"opacity",{get:ExpressionPropertyInterface(t.o)}),Object.defineProperty(e,"skew",{get:ExpressionPropertyInterface(t.sk)}),Object.defineProperty(e,"skewAxis",{get:ExpressionPropertyInterface(t.sa)}),Object.defineProperty(e,"orientation",{get:ExpressionPropertyInterface(t.or)}),e},ProjectInterface=function(){function t(t){for(var e=0,r=this.compositions.length;e<r;){if(this.compositions[e].data&&this.compositions[e].data.nm===t)return this.compositions[e].prepareFrame&&this.compositions[e].data.xt&&this.compositions[e].prepareFrame(this.currentFrame),this.compositions[e].compInterface;e+=1}}return t.compositions=[],t.currentFrame=0,t.registerComposition=LW,t};function LW(t){this.compositions.push(t)}var EffectsExpressionInterface={createEffectsInterface:function(s,t){if(s.effectsManager){var e,a=[],r=s.data.ef,i=s.effectsManager.effectElements.length;for(e=0;e<i;e+=1)a.push(TW(r[e],s.effectsManager.effectElements[e],t,s));return function(t){for(var e=s.data.ef||[],r=0,i=e.length;r<i;){if(t===e[r].nm||t===e[r].mn||t===e[r].ix)return a[r];r+=1}}}}};function TW(s,t,e,r){var i,a=[],n=s.ef.length;for(i=0;i<n;i+=1)5===s.ef[i].ty?a.push(TW(s.ef[i],t.effectElements[i],t.effectElements[i].propertyGroup,r)):a.push(UW(t.effectElements[i],s.ef[i].ty,r,o));function o(t){return 1===t?h:e(t-1)}var h=function(t){for(var e=s.ef,r=0,i=e.length;r<i;){if(t===e[r].nm||t===e[r].mn||t===e[r].ix)return 5===e[r].ty?a[r]:a[r]();r+=1}return a[0]()};return h.propertyGroup=o,"ADBE Color Control"===s.mn&&Object.defineProperty(h,"color",{get:function(){return a[0]()}}),Object.defineProperty(h,"numProperties",{get:function(){return s.np}}),h.active=h.enabled=0!==s.en,h}function UW(t,e,r,i){var s=ExpressionPropertyInterface(t.p);return t.p.setGroupProperty&&t.p.setGroupProperty(i),function(){return 10===e?r.comp.compInterface(t.p.v):s()}}var MaskManagerInterface=function(){function a(t,e){this._mask=t,this._data=e}Object.defineProperty(a.prototype,"maskPath",{get:function(){return this._mask.prop.k&&this._mask.prop.getValue(),this._mask.prop}});return function(e,t){var r,i=createSizedArray(e.viewData.length),s=e.viewData.length;for(r=0;r<s;r+=1)i[r]=new a(e.viewData[r],e.masksProperties[r]);return function(t){for(r=0;r<s;){if(e.masksProperties[r].nm===t)return i[r];r+=1}}}}(),ExpressionPropertyInterface=(KX={pv:0,v:0,mult:1},LX={pv:[0,0,0],v:[0,0,0],mult:1},function(t){return t?"unidimensional"===t.propType?function(t){t&&"pv"in t||(t=KX);var e=1/t.mult,r=t.pv*e,i=new Number(r);return i.value=r,MX(i,t,"unidimensional"),function(){return t.k&&t.getValue(),r=t.v*e,i.value!==r&&((i=new Number(r)).value=r,MX(i,t,"unidimensional")),i}}(t):function(e){e&&"pv"in e||(e=LX);var r=1/e.mult,i=e.pv.length,s=createTypedArray("float32",i),a=createTypedArray("float32",i);return s.value=a,MX(s,e,"multidimensional"),function(){e.k&&e.getValue();for(var t=0;t<i;t+=1)s[t]=a[t]=e.v[t]*r;return s}}(t):PX}),KX,LX,fY,gY;function MX(i,s,a){Object.defineProperty(i,"velocity",{get:function(){return s.getVelocityAtTime(s.comp.currentFrame)}}),i.numKeys=s.keyframes?s.keyframes.length:0,i.key=function(t){if(i.numKeys){var e="";e="s"in s.keyframes[t-1]?s.keyframes[t-1].s:"e"in s.keyframes[t-2]?s.keyframes[t-2].e:s.keyframes[t-2].s;var r="unidimensional"===a?new Number(e):Object.assign({},e);return r.time=s.keyframes[t-1].t/s.elem.comp.globalData.frameRate,r}return 0},i.valueAtTime=s.getValueAtTime,i.speedAtTime=s.getSpeedAtTime,i.velocityAtTime=s.getVelocityAtTime,i.propertyGroup=s.propertyGroup}function PX(){return KX}function hY(t,e){return this.textIndex=t+1,this.textTotal=e,this.v=this.getValue()*this.mult,this.v}function SliderEffect(t,e,r){this.p=PropertyFactory.getProp(e,t.v,0,0,r)}function AngleEffect(t,e,r){this.p=PropertyFactory.getProp(e,t.v,0,0,r)}function ColorEffect(t,e,r){this.p=PropertyFactory.getProp(e,t.v,1,0,r)}function PointEffect(t,e,r){this.p=PropertyFactory.getProp(e,t.v,1,0,r)}function LayerIndexEffect(t,e,r){this.p=PropertyFactory.getProp(e,t.v,0,0,r)}function MaskIndexEffect(t,e,r){this.p=PropertyFactory.getProp(e,t.v,0,0,r)}function CheckboxEffect(t,e,r){this.p=PropertyFactory.getProp(e,t.v,0,0,r)}function NoValueEffect(){this.p={}}function EffectsManager(t,e){var r=t.ef||[];this.effectElements=[];var i,s,a=r.length;for(i=0;i<a;i++)s=new GroupEffect(r[i],e),this.effectElements.push(s)}function GroupEffect(t,e){this.init(t,e)}fY=function(t,e){this.pv=1,this.comp=t.comp,this.elem=t,this.mult=.01,this.propType="textSelector",this.textTotal=e.totalChars,this.selectorValue=100,this.lastValue=[1,1,1],this.k=!0,this.x=!0,this.getValue=ExpressionManager.initiateExpression.bind(this)(t,e,this),this.getMult=hY,this.getVelocityAtTime=expressionHelpers.getVelocityAtTime,this.kf?this.getValueAtTime=expressionHelpers.getValueAtTime.bind(this):this.getValueAtTime=expressionHelpers.getStaticValueAtTime.bind(this),this.setGroupProperty=expressionHelpers.setGroupProperty},gY=TextSelectorProp.getTextSelectorProp,TextSelectorProp.getTextSelectorProp=function(t,e,r){return 1===e.t?new fY(t,e,r):gY(t,e,r)},extendPrototype([DynamicPropertyContainer],GroupEffect),GroupEffect.prototype.getValue=GroupEffect.prototype.iterateDynamicProperties,GroupEffect.prototype.init=function(t,e){this.data=t,this.effectElements=[],this.initDynamicPropertyContainer(e);var r,i,s=this.data.ef.length,a=this.data.ef;for(r=0;r<s;r+=1){switch(i=null,a[r].ty){case 0:i=new SliderEffect(a[r],e,this);break;case 1:i=new AngleEffect(a[r],e,this);break;case 2:i=new ColorEffect(a[r],e,this);break;case 3:i=new PointEffect(a[r],e,this);break;case 4:case 7:i=new CheckboxEffect(a[r],e,this);break;case 10:i=new LayerIndexEffect(a[r],e,this);break;case 11:i=new MaskIndexEffect(a[r],e,this);break;case 5:i=new EffectsManager(a[r],e,this);break;default:i=new NoValueEffect(a[r],e,this)}i&&this.effectElements.push(i)}};var lottiejs={},_isFrozen=!1;function loadAnimation(t){return animationManager.loadAnimation(t)}function setQuality(t){if("string"==typeof t)switch(t){case"high":defaultCurveSegments=200;break;case"medium":defaultCurveSegments=50;break;case"low":defaultCurveSegments=10}else!isNaN(t)&&1<t&&(defaultCurveSegments=t);roundValues(!(50<=defaultCurveSegments))}lottiejs.play=animationManager.play,lottiejs.pause=animationManager.pause,lottiejs.togglePause=animationManager.togglePause,lottiejs.setSpeed=animationManager.setSpeed,lottiejs.setDirection=animationManager.setDirection,lottiejs.stop=animationManager.stop,lottiejs.registerAnimation=animationManager.registerAnimation,lottiejs.loadAnimation=loadAnimation,lottiejs.resize=animationManager.resize,lottiejs.goToAndStop=animationManager.goToAndStop,lottiejs.destroy=animationManager.destroy,lottiejs.setQuality=setQuality,lottiejs.freeze=animationManager.freeze,lottiejs.unfreeze=animationManager.unfreeze,lottiejs.getRegisteredAnimations=animationManager.getRegisteredAnimations,lottiejs.version="5.5.2";var renderer="";return lottiejs}({}),currentAnimation=null,events={INITIALIZED:"initialized",RESIZED:"resized",PLAYING:"playing",PAUSED:"paused"};getCurrentCanvasSize=function(){var t=currentAnimation.renderer.canvasContext.canvas;return{height:t.height,width:t.width}},sendResizeEvent=function(){currentAnimation.renderer.canvasContext.canvas;postMessage({name:events.RESIZED,size:getCurrentCanvasSize()})},sendPlayEvent=function(){postMessage({name:events.PLAYING})},sendPauseEvent=function(){postMessage({name:events.PAUSED})},sendInitializedEvent=function(){currentAnimation.renderer.canvasContext.canvas;postMessage({name:events.INITIALIZED,success:currentAnimation.isLoaded})},initAnimation=function(t,e,r){if(!currentAnimation&&t&&e){var i=r.getContext("2d");currentAnimation=lottiejs.loadAnimation({renderer:"canvas",loop:e.loop,autoplay:e.autoplay,animationData:t,rendererSettings:{context:i,scaleMode:"noScale",clearCanvas:!0}}),sendInitializedEvent(),e.autoplay&&currentAnimation.play(),currentAnimation.isLoaded&&!currentAnimation.isPaused&&sendPlayEvent()}},updateCanvasSize=function(t,e){e&&t&&(0<e.height&&0<e.width&&(t.height=e.height,t.width=e.width),currentAnimation&&(currentAnimation.resize(),sendResizeEvent()))},updateAnimationState=function(t){t&&(t.play&&currentAnimation.isPaused?(currentAnimation.play(),sendPlayEvent()):t.play||currentAnimation.isPaused||(currentAnimation.pause(),sendPauseEvent()))},onmessage=function(t){if(t&&t.data){var e=null;if(currentAnimation)e=currentAnimation.renderer.canvasContext.canvas;else{if(!t.data.canvas)return;e=t.data.canvas}updateCanvasSize(e,t.data.drawSize),initAnimation(t.data.animationData,t.data.params,e),updateAnimationState(t.data.control)}};
\ No newline at end of file
diff --git a/tools/android/checkstyle/chromium-style-5.0.xml b/tools/android/checkstyle/chromium-style-5.0.xml
index e790323..534539c 100644
--- a/tools/android/checkstyle/chromium-style-5.0.xml
+++ b/tools/android/checkstyle/chromium-style-5.0.xml
@@ -104,6 +104,7 @@
       <property name="severity" value="info"/>
     </module>
     <module name="NeedBraces">
+      <property name="severity" value="error"/>
       <property name="allowSingleLineStatement" value="true"/>
     </module>
     <module name="RegexpSinglelineJava">
diff --git a/tools/mb/mb_config.pyl b/tools/mb/mb_config.pyl
index 135c98933..083e5ec 100644
--- a/tools/mb/mb_config.pyl
+++ b/tools/mb/mb_config.pyl
@@ -16,6 +16,7 @@
     'chrome': {
       'chromeos-amd64-generic-google-rel': 'official_cros_chrome_sdk',
       'chromeos-betty-google-rel': 'official_cros_chrome_sdk_headless_ozone',
+      'chromeos-betty-pi-arc-google-rel': 'official_cros_chrome_sdk_headless_ozone',
       'chromeos-kevin-google-rel': 'official_cros_chrome_sdk_headless_ozone',
       'linux-chromeos-google-rel': 'official_goma_chromeos_minimal_symbols',
       'linux-google-rel': 'official_goma',
@@ -713,6 +714,7 @@
 
     'tryserver.chrome': {
       'chromeos-betty-chrome': 'official_cros_chrome_sdk_headless_ozone',
+      'chromeos-betty-pi-arc-chrome': 'official_cros_chrome_sdk_headless_ozone',
       'chromeos-kevin-chrome': 'official_cros_chrome_sdk_headless_ozone',
       'linux-chrome': 'official_goma',
       'linux-chromeos-chrome': 'official_goma_chromeos_minimal_symbols',
diff --git a/tools/metrics/actions/actions.xml b/tools/metrics/actions/actions.xml
index 04a353b..c32e12a 100644
--- a/tools/metrics/actions/actions.xml
+++ b/tools/metrics/actions/actions.xml
@@ -1363,6 +1363,42 @@
   <description>A Chrome OS user manually starts Select To Speak.</description>
 </action>
 
+<action name="Accessibility.NativeApi.DoDefault">
+  <owner>aleventhal@chromium.org</owner>
+  <owner>dmazzoni@chromium.org</owner>
+  <description>
+    The DoDefault action (for example, to click on a button or link) has been
+    called on an accessibility node using a native accessibility API.
+  </description>
+</action>
+
+<action name="Accessibility.NativeApi.HitTest">
+  <owner>aleventhal@chromium.org</owner>
+  <owner>dmazzoni@chromium.org</owner>
+  <description>
+    The HitTest action has been called on an accessibility node using a native
+    accessibility API.
+  </description>
+</action>
+
+<action name="Accessibility.NativeApi.ScrollToMakeVisible">
+  <owner>aleventhal@chromium.org</owner>
+  <owner>dmazzoni@chromium.org</owner>
+  <description>
+    The ScrollToMakeVisible action has been called on an accessibility node
+    using a native accessibility API.
+  </description>
+</action>
+
+<action name="Accessibility.NativeApi.SetFocus">
+  <owner>aleventhal@chromium.org</owner>
+  <owner>dmazzoni@chromium.org</owner>
+  <description>
+    The SetFocus action has been called on an accessibility node using a native
+    accessibility API.
+  </description>
+</action>
+
 <action name="Accessibility.TwoFingersHeldDown">
   <owner>dmazzoni@chromium.org</owner>
   <description>
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml
index 7f80e98c..afa6cd1c 100644
--- a/tools/metrics/histograms/enums.xml
+++ b/tools/metrics/histograms/enums.xml
@@ -24650,6 +24650,7 @@
   <int value="3030" label="DelegateFocus"/>
   <int value="3031" label="DelegateFocusNotFirstInFlatTree"/>
   <int value="3032" label="ThirdPartySharedWorker"/>
+  <int value="3033" label="ThirdPartyBroadcastChannel"/>
 </enum>
 
 <enum name="FeaturePolicyAllowlistType">
@@ -41326,6 +41327,11 @@
   <int value="3" label="Navigation not intercepted"/>
 </enum>
 
+<enum name="NavigationIsLockedProcess">
+  <int value="0" label="Process is not locked to origin"/>
+  <int value="1" label="Process is locked to origin"/>
+</enum>
+
 <enum name="NavigationIsSameBrowsingInstance">
   <int value="0" label="Cross BrowsingInstance navigation"/>
   <int value="1" label="Same BrowsingInstance navigation"/>
@@ -41379,6 +41385,11 @@
              foreground until the previous preconnect expired."/>
 </enum>
 
+<enum name="NavigationRequiresDedicatedProcess">
+  <int value="0" label="Does not require dedicated process"/>
+  <int value="1" label="Requires dedicated process"/>
+</enum>
+
 <enum name="NavigationScheme">
   <int value="0" label="(Unknown)"/>
   <int value="1" label="http"/>
diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml
index a643d08..233541e 100644
--- a/tools/metrics/histograms/histograms.xml
+++ b/tools/metrics/histograms/histograms.xml
@@ -70873,6 +70873,17 @@
   </summary>
 </histogram>
 
+<histogram name="Navigation.IsLockedProcess" enum="NavigationIsLockedProcess"
+    expires_after="2020-12-31">
+  <owner>alexmos@chromium.org</owner>
+  <owner>lukasza@chromium.org</owner>
+  <summary>
+    Whether the navigation commits in a process that is locked to an origin.
+    Logged at ready-to-commit time for every navigation excluding same-document
+    navigations and errors.
+  </summary>
+</histogram>
+
 <histogram name="Navigation.IsMobileOptimized" enum="BooleanIsMobileOptimized"
     expires_after="2018-03-05">
   <obsolete>
@@ -71134,6 +71145,17 @@
   </summary>
 </histogram>
 
+<histogram name="Navigation.RequiresDedicatedProcess"
+    enum="NavigationRequiresDedicatedProcess" expires_after="2020-12-31">
+  <owner>alexmos@chromium.org</owner>
+  <owner>lukasza@chromium.org</owner>
+  <summary>
+    Whether the navigation commits in a SiteInstance that requires a dedicated
+    process. Logged at ready-to-commit time for every navigation excluding
+    same-document navigations and errors.
+  </summary>
+</histogram>
+
 <histogram
     name="Navigation.ResourceHandler.ProceedWithResponseUntilFirstReadCompleted"
     units="ms">
@@ -75000,8 +75022,8 @@
   </summary>
 </histogram>
 
-<histogram base="true" name="Net.DNS.SecureDnsMode.Automatic.TotalTime"
-    units="ms" expires_after="M81">
+<histogram name="Net.DNS.SecureDnsMode.Automatic.TotalTime" units="ms"
+    expires_after="M81">
   <owner>dalyk@google.com</owner>
   <owner>doh-core@google.com</owner>
   <summary>
@@ -75012,7 +75034,7 @@
   </summary>
 </histogram>
 
-<histogram base="true" name="Net.DNS.SecureDnsMode.Off.TotalTime" units="ms"
+<histogram name="Net.DNS.SecureDnsMode.Off.TotalTime" units="ms"
     expires_after="M81">
   <owner>dalyk@google.com</owner>
   <owner>doh-core@google.com</owner>
@@ -75024,7 +75046,7 @@
   </summary>
 </histogram>
 
-<histogram base="true" name="Net.DNS.SecureDnsMode.Secure.TotalTime" units="ms"
+<histogram name="Net.DNS.SecureDnsMode.Secure.TotalTime" units="ms"
     expires_after="M81">
   <owner>dalyk@google.com</owner>
   <owner>doh-core@google.com</owner>
diff --git a/tools/metrics/ukm/ukm.xml b/tools/metrics/ukm/ukm.xml
index 3b36acb4..3743330c 100644
--- a/tools/metrics/ukm/ukm.xml
+++ b/tools/metrics/ukm/ukm.xml
@@ -1068,6 +1068,15 @@
     <summary>
       The system which generated the prediction: heuristics, server, overall.
     </summary>
+    <aggregation>
+      <history>
+        <index fields="metrics.ActualType,metrics.PredictedType"/>
+        <index fields="metrics.PredictedType"/>
+        <statistics>
+          <enumeration/>
+        </statistics>
+      </history>
+    </aggregation>
   </metric>
   <metric name="ValidationEvent" enum="AutofillQualitiyMetricType">
     <summary>
diff --git a/tools/polymer/polymer.py b/tools/polymer/polymer.py
index 4b12b7c..d6b8ea1 100644
--- a/tools/polymer/polymer.py
+++ b/tools/polymer/polymer.py
@@ -294,28 +294,45 @@
   out_filename = os.path.basename(js_file)
   return lines, out_filename
 
-
 def _process_dom_module(js_file, html_file):
   html_template = _extract_template(html_file, 'dom-module')
   js_imports = _generate_js_imports(html_file)
 
+  # Remove IFFE opening/closing lines.
   IIFE_OPENING = '(function() {\n'
   IIFE_OPENING_ARROW = '(() => {\n'
   IIFE_CLOSING = '})();'
 
+  # Remove this line.
+  CR_DEFINE_START_REGEX = 'cr.define\('
+  # Ignore all lines after this comment, including the line it appears on.
+  CR_DEFINE_END_REGEX = r'\s*// #cr_define_end'
+
+  # Replace export annotations with 'export'.
+  EXPORT_LINE_REGEX = '/* #export */'
+
   with open(js_file) as f:
     lines = f.readlines()
 
   imports_added = False
   iife_found = False
+  cr_define_found = False
+  cr_define_end_line = -1
 
   for i, line in enumerate(lines):
     if not imports_added:
       if line.startswith(IIFE_OPENING) or line.startswith(IIFE_OPENING_ARROW):
+        assert not cr_define_found, 'cr.define() and IFFE in the same file'
         # Replace the IIFE opening line with the JS imports.
         line = '\n'.join(js_imports) + '\n\n'
         imports_added = True
         iife_found = True
+      elif re.match(CR_DEFINE_START_REGEX, line):
+        assert not cr_define_found, 'Multiple cr.define()s are not supported'
+        assert not iife_found, 'cr.define() and IFFE in the same file'
+        line = '\n'.join(js_imports) + '\n\n'
+        cr_define_found = True
+        imports_added = True
       elif line.startswith('Polymer({\n'):
         # Place the JS imports right before the opening "Polymer({" line.
         line = line.replace(
@@ -329,12 +346,23 @@
         r'Polymer({',
         'Polymer({\n  _template: html`%s`,' % html_template)
 
+    line = line.replace(EXPORT_LINE_REGEX, 'export')
+
     if line.startswith('cr.exportPath('):
       line = ''
 
+    if re.match(CR_DEFINE_END_REGEX, line):
+      assert cr_define_found, 'Found cr_define_end without cr.define()'
+      cr_define_end_line = i
+      break
+
     line = _rewrite_namespaces(line)
     lines[i] = line
 
+  if cr_define_found:
+    assert cr_define_end_line != -1, 'No cr_define_end found'
+    lines = lines[0:cr_define_end_line]
+
   if iife_found:
     last_line = lines[-1]
     assert last_line.startswith(IIFE_CLOSING), 'Could not detect IIFE closing'
diff --git a/tools/polymer/polymer_test.py b/tools/polymer/polymer_test.py
index 2c0a5f6f..587491ce 100755
--- a/tools/polymer/polymer_test.py
+++ b/tools/polymer/polymer_test.py
@@ -35,7 +35,8 @@
       '--js_file',  js_file,
       '--html_file',  html_file,
       '--html_type',  html_type,
-      '--namespace_rewrites',  'Polymer.PaperRippleBehavior|PaperRippleBehavior',
+      '--namespace_rewrites',
+      'Polymer.PaperRippleBehavior|PaperRippleBehavior',
       '--auto_imports',
       'ui/webui/resources/html/polymer.html|Polymer,html',
       'third_party/polymer/v1_0/components-chromium/paper-behaviors/paper-ripple-behavior.html|PaperRippleBehavior',
@@ -66,6 +67,13 @@
         'dom-module', 'dom_module.html', 'dom_module_iife_arrow.js',
         'dom_module_iife_arrow.m.js', 'dom_module_iife_expected.js')
 
+  # Test case where HTML is extracted from a Polymer2 <dom-module> that also
+  # has a 'cr.define()' in its JS file.
+  def testDomModuleWithDefine(self):
+    self._run_test(
+        'dom-module', 'dom_module.html', 'dom_module_with_define.js',
+        'dom_module_with_define.m.js', 'dom_module_with_define_expected.js')
+
   # Test case where HTML is extracted from a Polymer2 style module.
   def testStyleModule(self):
     self._run_test(
diff --git a/tools/polymer/tests/dom_module_with_define.js b/tools/polymer/tests/dom_module_with_define.js
new file mode 100644
index 0000000..8e2cfe0e
--- /dev/null
+++ b/tools/polymer/tests/dom_module_with_define.js
@@ -0,0 +1,32 @@
+cr.define('cr.testFoo', () => {
+  let instance_ = null;
+
+  let bar_ = 1;
+
+  /* #export */ const someExport = true;
+
+  /* #export */ function getInstance() {
+    return assert(instance_);
+  }
+
+  function getBarInternal_() {
+    return bar_;
+  }
+
+  /* #export */ function getBar(isTest) {
+    return isTest ? 0 : getBarInternal_();
+  }
+
+  /* #export */ let CrTestFooElement = Polymer({
+    is: 'cr-test-foo',
+    behaviors: [Polymer.PaperRippleBehavior],
+  });
+
+  // #cr_define_end
+  return {
+    CrTestFooElement: CrTestFooElement,
+    someExport: someExport,
+    getInstance: getInstance,
+    getBar: getBar,
+  };
+});
diff --git a/tools/polymer/tests/dom_module_with_define_expected.js b/tools/polymer/tests/dom_module_with_define_expected.js
new file mode 100644
index 0000000..a2625ca7
--- /dev/null
+++ b/tools/polymer/tests/dom_module_with_define_expected.js
@@ -0,0 +1,36 @@
+import {Polymer, html} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
+import {PaperRippleBehavior} from 'chrome://resources/polymer/v3_0/paper-behaviors/paper-ripple-behavior.js';
+import '../shared_vars_css.m.js';
+import './foo.m.js';
+
+  let instance_ = null;
+
+  let bar_ = 1;
+
+  export const someExport = true;
+
+  export function getInstance() {
+    return assert(instance_);
+  }
+
+  function getBarInternal_() {
+    return bar_;
+  }
+
+  export function getBar(isTest) {
+    return isTest ? 0 : getBarInternal_();
+  }
+
+  export let CrTestFooElement = Polymer({
+  _template: html`
+    <style>
+      div {
+        font-size: 2rem;
+      }
+    </style>
+    <div>Hello world</div>
+`,
+    is: 'cr-test-foo',
+    behaviors: [PaperRippleBehavior],
+  });
+
diff --git a/ui/accessibility/platform/ax_platform_node_mac.mm b/ui/accessibility/platform/ax_platform_node_mac.mm
index fb4bab7..d0f9db58 100644
--- a/ui/accessibility/platform/ax_platform_node_mac.mm
+++ b/ui/accessibility/platform/ax_platform_node_mac.mm
@@ -311,11 +311,6 @@
 }
 
 void NotifyMacEvent(AXPlatformNodeCocoa* target, ax::mojom::Event event_type) {
-  NSString* announcement_text = [target announcementTextForEvent:event_type];
-  if (announcement_text) {
-    PostAnnouncementNotification(announcement_text);
-    return;
-  }
   NSString* notification =
       [AXPlatformNodeCocoa nativeNotificationFromAXEvent:event_type];
   if (notification)
@@ -1150,27 +1145,21 @@
 
 void AXPlatformNodeMac::NotifyAccessibilityEvent(ax::mojom::Event event_type) {
   GetNativeViewAccessible();
-  // Add mappings between ax::mojom::Event and NSAccessibility notifications
-  // using the EventMap above. This switch contains exceptions to those
-  // mappings.
-  switch (event_type) {
-    case ax::mojom::Event::kTextChanged:
-      // If the view is a user-editable textfield, this should change the value.
-      if (GetData().role == ax::mojom::Role::kTextField) {
-        NotifyMacEvent(native_node_, ax::mojom::Event::kValueChanged);
-        return;
-      }
-      break;
-    case ax::mojom::Event::kSelection:
-      // On Mac, map menu item selection to a focus event.
-      if (ui::IsMenuItem(GetData().role)) {
-        NotifyMacEvent(native_node_, ax::mojom::Event::kFocus);
-        return;
-      }
-      break;
-    default:
-      break;
+  // Handle special cases.
+  NSString* announcement_text =
+      [native_node_ announcementTextForEvent:event_type];
+  if (announcement_text) {
+    PostAnnouncementNotification(announcement_text);
+    return;
   }
+  if (event_type == ax::mojom::Event::kSelection &&
+      ui::IsMenuItem(GetData().role)) {
+    // On Mac, map menu item selection to a focus event.
+    NotifyMacEvent(native_node_, ax::mojom::Event::kFocus);
+    return;
+  }
+  // Otherwise, use mappings between ax::mojom::Event and NSAccessibility
+  // notifications from the EventMap above.
   NotifyMacEvent(native_node_, event_type);
 }
 
diff --git a/ui/accessibility/platform/ax_platform_node_win.cc b/ui/accessibility/platform/ax_platform_node_win.cc
index 9d54e2b1..d264047 100644
--- a/ui/accessibility/platform/ax_platform_node_win.cc
+++ b/ui/accessibility/platform/ax_platform_node_win.cc
@@ -1115,9 +1115,8 @@
 
 IFACEMETHODIMP AXPlatformNodeWin::get_accHelp(VARIANT var_id, BSTR* help) {
   WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_GET_ACC_HELP);
-  AXPlatformNodeWin* target;
-  COM_OBJECT_VALIDATE_VAR_ID_1_ARG_AND_GET_TARGET(var_id, help, target);
-  return target->GetHelpText(help);
+  COM_OBJECT_VALIDATE_1_ARG(help);
+  return S_FALSE;
 }
 
 IFACEMETHODIMP AXPlatformNodeWin::get_accValue(VARIANT var_id, BSTR* value) {
@@ -3829,8 +3828,20 @@
       break;
 
     case UIA_HelpTextPropertyId:
-      V_VT(result) = VT_BSTR;
-      GetHelpText(&V_BSTR(result));
+      if (HasStringAttribute(ax::mojom::StringAttribute::kPlaceholder)) {
+        V_VT(result) = VT_BSTR;
+        GetStringAttributeAsBstr(ax::mojom::StringAttribute::kPlaceholder,
+                                 &V_BSTR(result));
+      } else if (data.GetNameFrom() == ax::mojom::NameFrom::kPlaceholder ||
+                 data.GetNameFrom() == ax::mojom::NameFrom::kTitle) {
+        V_VT(result) = VT_BSTR;
+        GetStringAttributeAsBstr(ax::mojom::StringAttribute::kName,
+                                 &V_BSTR(result));
+      } else if (HasStringAttribute(ax::mojom::StringAttribute::kTooltip)) {
+        V_VT(result) = VT_BSTR;
+        GetStringAttributeAsBstr(ax::mojom::StringAttribute::kTooltip,
+                                 &V_BSTR(result));
+      }
       break;
 
     case UIA_IsContentElementPropertyId:
@@ -6938,21 +6949,6 @@
   return S_OK;
 }
 
-HRESULT AXPlatformNodeWin::GetHelpText(BSTR* helpText) {
-  if (HasStringAttribute(ax::mojom::StringAttribute::kPlaceholder)) {
-    return GetStringAttributeAsBstr(ax::mojom::StringAttribute::kPlaceholder,
-                                    helpText);
-  } else if (GetData().GetNameFrom() == ax::mojom::NameFrom::kPlaceholder ||
-             GetData().GetNameFrom() == ax::mojom::NameFrom::kTitle) {
-    return GetStringAttributeAsBstr(ax::mojom::StringAttribute::kName,
-                                    helpText);
-  } else if (HasStringAttribute(ax::mojom::StringAttribute::kTooltip)) {
-    return GetStringAttributeAsBstr(ax::mojom::StringAttribute::kTooltip,
-                                    helpText);
-  }
-  return S_FALSE;
-}
-
 // TODO(dmazzoni): Remove this function once combo box refactoring is
 // complete.
 bool AXPlatformNodeWin::IsAncestorComboBox() {
diff --git a/ui/accessibility/platform/ax_platform_node_win.h b/ui/accessibility/platform/ax_platform_node_win.h
index 66c70956..0b0189c7 100644
--- a/ui/accessibility/platform/ax_platform_node_win.h
+++ b/ui/accessibility/platform/ax_platform_node_win.h
@@ -1235,9 +1235,6 @@
   // Helper method for mutating the ISelectionItemProvider selected state
   HRESULT ISelectionItemProviderSetSelected(bool selected);
 
-  // Helper method for getting the help text property.
-  HRESULT GetHelpText(BSTR* helpText);
-
   //
   // Getters for UIA GetTextAttributeValue
   //
diff --git a/ui/accessibility/platform/ax_platform_node_win_unittest.cc b/ui/accessibility/platform/ax_platform_node_win_unittest.cc
index 5fdc1f4..a79d784a 100644
--- a/ui/accessibility/platform/ax_platform_node_win_unittest.cc
+++ b/ui/accessibility/platform/ax_platform_node_win_unittest.cc
@@ -547,101 +547,6 @@
             root_obj->get_accKeyboardShortcut(bad_id, k2.Receive()));
 }
 
-TEST_F(AXPlatformNodeWinTest, TestIAccessibleHelpText) {
-  AXNodeData root;
-  root.id = 1;
-
-  // Test Placeholder StringAttribute is exposed.
-  AXNodeData node1;
-  node1.id = 2;
-  node1.SetName("name-from-title");
-  node1.AddIntAttribute(ax::mojom::IntAttribute::kNameFrom,
-                        static_cast<int>(ax::mojom::NameFrom::kTitle));
-  node1.AddStringAttribute(ax::mojom::StringAttribute::kPlaceholder,
-                           "placeholder");
-  root.child_ids.push_back(node1.id);
-
-  // Test NameFrom Title is exposed.
-  AXNodeData node2;
-  node2.id = 3;
-  node2.SetName("name-from-title");
-  node2.AddIntAttribute(ax::mojom::IntAttribute::kNameFrom,
-                        static_cast<int>(ax::mojom::NameFrom::kTitle));
-  root.child_ids.push_back(node2.id);
-
-  // Test NameFrom Placeholder is exposed.
-  AXNodeData node3;
-  node3.id = 4;
-  node3.SetName("name-from-placeholder");
-  node3.AddIntAttribute(ax::mojom::IntAttribute::kNameFrom,
-                        static_cast<int>(ax::mojom::NameFrom::kPlaceholder));
-  root.child_ids.push_back(node3.id);
-
-  // Test Tooltip StringAttribute is exposed.
-  AXNodeData node4;
-  node4.id = 5;
-  node4.SetName("name-from-attribute");
-  node4.AddIntAttribute(ax::mojom::IntAttribute::kNameFrom,
-                        static_cast<int>(ax::mojom::NameFrom::kAttribute));
-  node4.AddStringAttribute(ax::mojom::StringAttribute::kTooltip, "tooltip");
-  root.child_ids.push_back(node4.id);
-
-  // Test StringAttribute is not exposed without explicit
-  // Placeholder / Title / Tooltip.
-  AXNodeData node5;
-  node5.id = 6;
-  node5.SetName("name-from-attribute");
-  node5.AddIntAttribute(ax::mojom::IntAttribute::kNameFrom,
-                        static_cast<int>(ax::mojom::NameFrom::kAttribute));
-  root.child_ids.push_back(node5.id);
-
-  Init(root, node1, node2, node3, node4, node5);
-
-  auto* root_node = GetRootNode();
-
-  ScopedBstr helpText1;
-  ComPtr<IAccessible> child_node1(
-      IAccessibleFromNode(root_node->children()[0]));
-  EXPECT_EQ(S_OK, child_node1->get_accHelp(SELF, helpText1.Receive()));
-  EXPECT_STREQ(L"placeholder", helpText1);
-
-  ScopedBstr helpText2;
-  ComPtr<IAccessible> child_node2(
-      IAccessibleFromNode(root_node->children()[1]));
-  EXPECT_EQ(S_OK, child_node2->get_accHelp(SELF, helpText2.Receive()));
-  EXPECT_STREQ(L"name-from-title", helpText2);
-
-  ScopedBstr helpText3;
-  ComPtr<IAccessible> child_node3(
-      IAccessibleFromNode(root_node->children()[2]));
-  EXPECT_EQ(S_OK, child_node3->get_accHelp(SELF, helpText3.Receive()));
-  EXPECT_STREQ(L"name-from-placeholder", helpText3);
-
-  ScopedBstr helpText4;
-  ComPtr<IAccessible> child_node4(
-      IAccessibleFromNode(root_node->children()[3]));
-  EXPECT_EQ(S_OK, child_node4->get_accHelp(SELF, helpText4.Receive()));
-  EXPECT_STREQ(L"tooltip", helpText4);
-
-  ScopedBstr helpText5;
-  ComPtr<IAccessible> child_node5(
-      IAccessibleFromNode(root_node->children()[4]));
-  EXPECT_EQ(S_FALSE, child_node5->get_accHelp(SELF, helpText5.Receive()));
-
-  ScopedBstr helpText6;
-  ScopedVariant root_id(0);
-  EXPECT_EQ(S_OK, child_node4->get_accHelp(root_id, helpText6.Receive()));
-  EXPECT_STREQ(L"tooltip", helpText6);
-
-  EXPECT_EQ(E_INVALIDARG, child_node5->get_accHelp(SELF, nullptr));
-  ScopedVariant var_id(5);
-  EXPECT_EQ(E_INVALIDARG,
-            child_node5->get_accHelp(var_id, helpText5.Receive()));
-  ScopedVariant bad_id(999);
-  EXPECT_EQ(E_INVALIDARG,
-            child_node5->get_accHelp(bad_id, helpText5.Receive()));
-}
-
 TEST_F(AXPlatformNodeWinTest,
        TestIAccessibleSelectionListBoxOptionNothingSelected) {
   AXNodeData list;
diff --git a/ui/chromeos/resources/ui_chromeos_resources.grd b/ui/chromeos/resources/ui_chromeos_resources.grd
index 2051b44..b81fb57 100644
--- a/ui/chromeos/resources/ui_chromeos_resources.grd
+++ b/ui/chromeos/resources/ui_chromeos_resources.grd
@@ -99,6 +99,9 @@
       <!-- Kerberos. -->
       <structure type="chrome_scaled_image" name="IDR_KERBEROS_ICON_KEY" file="kerberos/vpn_key_grey600_24dp.png" />
 
+      <!-- Assistant images. -->
+      <structure type="chrome_html" name="IDR_ASSISTANT_VOICE_MATCH_ANIMATION" file="vector/voice_laptop.json" compress="gzip" />
+
     </structures>
   </release>
 </grit>
diff --git a/ui/chromeos/resources/vector/voice_laptop.json b/ui/chromeos/resources/vector/voice_laptop.json
new file mode 100644
index 0000000..74279f2
--- /dev/null
+++ b/ui/chromeos/resources/vector/voice_laptop.json
@@ -0,0 +1 @@
+{"v":"5.3.4","fr":25,"ip":0,"op":101,"w":255,"h":170,"nm":"VOICE LAPTOP 1X","ddd":0,"assets":[{"id":"comp_0","layers":[{"ddd":0,"ind":1,"ty":4,"nm":"EQ 11","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[281.125,206.625,0],"ix":2},"a":{"a":0,"k":[37.75,-11,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":12,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[38.125,-11],[38.125,-11]],"c":false}],"e":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[38.465,-35.562],[38.215,-10.688]],"c":false}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":16,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[38.465,-35.562],[38.215,-10.688]],"c":false}],"e":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[38.25,-19.75],[38.188,-10.625]],"c":false}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":21,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[38.25,-19.75],[38.188,-10.625]],"c":false}],"e":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[38.465,-35.562],[38.215,-10.688]],"c":false}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":24,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[38.465,-35.562],[38.215,-10.688]],"c":false}],"e":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[38.25,-19.75],[38.188,-10.625]],"c":false}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":27,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[38.25,-19.75],[38.188,-10.625]],"c":false}],"e":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[38.465,-35.562],[38.215,-10.688]],"c":false}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":31,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[38.465,-35.562],[38.215,-10.688]],"c":false}],"e":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[38.125,-11],[38.125,-11]],"c":false}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":44,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[38.125,-11],[38.125,-11]],"c":false}],"e":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[38.21,-28.853],[38.082,-10.803]],"c":false}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":47,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[38.21,-28.853],[38.082,-10.803]],"c":false}],"e":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[38.125,-19.793],[38.125,-10.918]],"c":false}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":50,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[38.125,-19.793],[38.125,-10.918]],"c":false}],"e":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[38.304,-28.865],[38.129,-10.94]],"c":false}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":53,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[38.304,-28.865],[38.129,-10.94]],"c":false}],"e":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[38.219,-19.699],[38.109,-11.074]],"c":false}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":56,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[38.219,-19.699],[38.109,-11.074]],"c":false}],"e":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[38.465,-35.562],[38.215,-10.688]],"c":false}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":60,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[38.465,-35.562],[38.215,-10.688]],"c":false}],"e":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[38.125,-11],[38.125,-11]],"c":false}]},{"t":70}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.2588239782,0.521568986481,0.956862984452,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":6,"ix":5},"lc":2,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.2588239782,0.521568986481,0.956862984452,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":103,"st":2,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":"EQ 10","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[270.625,206.625,0],"ix":2},"a":{"a":0,"k":[37.75,-11,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":9,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[38.125,-11],[38.125,-11]],"c":false}],"e":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[38.465,-35.562],[38.215,-10.688]],"c":false}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":13,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[38.465,-35.562],[38.215,-10.688]],"c":false}],"e":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[38.25,-19.75],[38.188,-10.625]],"c":false}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":18,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[38.25,-19.75],[38.188,-10.625]],"c":false}],"e":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[38.465,-35.562],[38.215,-10.688]],"c":false}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":21,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[38.465,-35.562],[38.215,-10.688]],"c":false}],"e":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[38.25,-19.75],[38.188,-10.625]],"c":false}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":24,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[38.25,-19.75],[38.188,-10.625]],"c":false}],"e":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[38.465,-35.562],[38.215,-10.688]],"c":false}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":28,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[38.465,-35.562],[38.215,-10.688]],"c":false}],"e":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[38.125,-11],[38.125,-11]],"c":false}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":41,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[38.125,-11],[38.125,-11]],"c":false}],"e":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[38.21,-28.853],[38.082,-10.803]],"c":false}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":44,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[38.21,-28.853],[38.082,-10.803]],"c":false}],"e":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[38.125,-19.793],[38.125,-10.918]],"c":false}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":47,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[38.125,-19.793],[38.125,-10.918]],"c":false}],"e":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[38.304,-28.865],[38.129,-10.94]],"c":false}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":50,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[38.304,-28.865],[38.129,-10.94]],"c":false}],"e":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[38.219,-19.699],[38.109,-11.074]],"c":false}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":53,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[38.219,-19.699],[38.109,-11.074]],"c":false}],"e":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[38.465,-35.562],[38.215,-10.688]],"c":false}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":57,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[38.465,-35.562],[38.215,-10.688]],"c":false}],"e":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[38.125,-11],[38.125,-11]],"c":false}]},{"t":67}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.2588239782,0.521568986481,0.956862984452,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":6,"ix":5},"lc":2,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.2588239782,0.521568986481,0.956862984452,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-1,"op":101,"st":-1,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":"EQ 9","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[260.25,206.625,0],"ix":2},"a":{"a":0,"k":[37.75,-11,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":11,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[38.125,-11],[38.125,-11]],"c":false}],"e":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[38.465,-35.562],[38.215,-10.688]],"c":false}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":15,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[38.465,-35.562],[38.215,-10.688]],"c":false}],"e":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[38.25,-19.75],[38.188,-10.625]],"c":false}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":20,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[38.25,-19.75],[38.188,-10.625]],"c":false}],"e":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[38.465,-35.562],[38.215,-10.688]],"c":false}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":23,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[38.465,-35.562],[38.215,-10.688]],"c":false}],"e":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[38.25,-19.75],[38.188,-10.625]],"c":false}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":26,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[38.25,-19.75],[38.188,-10.625]],"c":false}],"e":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[38.465,-35.562],[38.215,-10.688]],"c":false}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":30,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[38.465,-35.562],[38.215,-10.688]],"c":false}],"e":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[38.125,-11],[38.125,-11]],"c":false}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":43,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[38.125,-11],[38.125,-11]],"c":false}],"e":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[38.21,-28.853],[38.082,-10.803]],"c":false}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":46,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[38.21,-28.853],[38.082,-10.803]],"c":false}],"e":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[38.125,-19.793],[38.125,-10.918]],"c":false}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":49,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[38.125,-19.793],[38.125,-10.918]],"c":false}],"e":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[38.304,-28.865],[38.129,-10.94]],"c":false}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":52,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[38.304,-28.865],[38.129,-10.94]],"c":false}],"e":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[38.219,-19.699],[38.109,-11.074]],"c":false}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":55,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[38.219,-19.699],[38.109,-11.074]],"c":false}],"e":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[38.465,-35.562],[38.215,-10.688]],"c":false}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":59,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[38.465,-35.562],[38.215,-10.688]],"c":false}],"e":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[38.125,-11],[38.125,-11]],"c":false}]},{"t":69}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.2588239782,0.521568986481,0.956862984452,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":6,"ix":5},"lc":2,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.2588239782,0.521568986481,0.956862984452,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":102,"st":1,"bm":0},{"ddd":0,"ind":4,"ty":4,"nm":"EQ 5","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[249.75,206.625,0],"ix":2},"a":{"a":0,"k":[37.75,-11,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":10,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[38.125,-11],[38.125,-11]],"c":false}],"e":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[38.465,-35.562],[38.215,-10.688]],"c":false}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":14,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[38.465,-35.562],[38.215,-10.688]],"c":false}],"e":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[38.25,-19.75],[38.188,-10.625]],"c":false}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":19,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[38.25,-19.75],[38.188,-10.625]],"c":false}],"e":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[38.465,-35.562],[38.215,-10.688]],"c":false}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":22,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[38.465,-35.562],[38.215,-10.688]],"c":false}],"e":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[38.25,-19.75],[38.188,-10.625]],"c":false}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":25,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[38.25,-19.75],[38.188,-10.625]],"c":false}],"e":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[38.465,-35.562],[38.215,-10.688]],"c":false}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":29,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[38.465,-35.562],[38.215,-10.688]],"c":false}],"e":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[38.125,-11],[38.125,-11]],"c":false}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":42,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[38.125,-11],[38.125,-11]],"c":false}],"e":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[38.21,-28.853],[38.082,-10.803]],"c":false}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":45,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[38.21,-28.853],[38.082,-10.803]],"c":false}],"e":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[38.125,-19.793],[38.125,-10.918]],"c":false}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":48,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[38.125,-19.793],[38.125,-10.918]],"c":false}],"e":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[38.304,-28.865],[38.129,-10.94]],"c":false}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":51,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[38.304,-28.865],[38.129,-10.94]],"c":false}],"e":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[38.219,-19.699],[38.109,-11.074]],"c":false}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":54,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[38.219,-19.699],[38.109,-11.074]],"c":false}],"e":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[38.465,-35.562],[38.215,-10.688]],"c":false}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":58,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[38.465,-35.562],[38.215,-10.688]],"c":false}],"e":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[38.125,-11],[38.125,-11]],"c":false}]},{"t":68}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.2588239782,0.521568986481,0.956862984452,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":6,"ix":5},"lc":2,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.2588239782,0.521568986481,0.956862984452,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":101,"st":0,"bm":0},{"ddd":0,"ind":5,"ty":4,"nm":"laptop","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[206,150,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[2.25,-1.75],[-5,0.125],[-3.333,0],[2.417,1.333],[0,0]],"o":[[0,0],[-2.25,1.75],[3.002,-0.075],[3.333,0],[-2.417,-1.333],[0,0]],"v":[[3.875,82],[-10.125,91.375],[-8.458,94.083],[130.083,94],[129.333,91.417],[114.667,81.333]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.858823529412,0.866666666667,0.874509803922,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":4,"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":true},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 2","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[4.75,0],[0,-4.125],[0,-4.375],[-5.25,0],[-4.25,0],[0,4.75],[0,3.875],[4.125,0]],"o":[[-4.75,0],[0,4.632],[0,4.375],[5.25,0],[4.25,0],[0,-4.75],[0,-3.875],[-4.125,0]],"v":[[7.75,-3.125],[1.875,4.25],[1.875,72],[7.375,82.25],[109,82],[116.375,77.375],[117,4.625],[112.375,-3]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.858823537827,0.866666674614,0.874509811401,0.411764711142],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":4,"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.101961001228,0.619607962814,0.988234994926,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":true},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"ix":2,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":101,"st":0,"bm":0},{"ddd":0,"ind":6,"ty":4,"nm":"mouth","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[206,150,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.167,"y":0},"n":"0p667_1_0p167_0","t":8,"s":[{"i":[[4.5,0.25],[4.125,3.25],[-6.12,-0.556],[-4.5,2.5]],"o":[[-5.753,-0.32],[4.625,3.625],[4.125,0.375],[-4.5,2.625]],"v":[[-76.25,56.75],[-89,51],[-76,56.75],[-64.875,52.5]],"c":true}],"e":[{"i":[[5.75,0.375],[-0.125,-3.875],[-6.132,-0.409],[-1.625,4]],"o":[[-5.75,-0.375],[0.125,3.875],[5.625,0.375],[1.625,-4]],"v":[[-85.375,51.25],[-95.75,57],[-88.375,67],[-76.625,59]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.167,"y":0},"n":"0p667_1_0p167_0","t":14,"s":[{"i":[[5.75,0.375],[-0.125,-3.875],[-6.132,-0.409],[-1.625,4]],"o":[[-5.75,-0.375],[0.125,3.875],[5.625,0.375],[1.625,-4]],"v":[[-85.375,51.25],[-95.75,57],[-88.375,67],[-76.625,59]],"c":true}],"e":[{"i":[[5.75,0.375],[-0.125,-3.875],[-6.132,-0.409],[-1.625,4]],"o":[[-5.75,-0.375],[0.125,3.875],[5.625,0.375],[1.625,-4]],"v":[[-85.875,54.125],[-95.75,57],[-88.375,65],[-76.625,59]],"c":true}]},{"i":{"x":0.833,"y":1},"o":{"x":0.167,"y":0},"n":"0p833_1_0p167_0","t":16,"s":[{"i":[[5.75,0.375],[-0.125,-3.875],[-6.132,-0.409],[-1.625,4]],"o":[[-5.75,-0.375],[0.125,3.875],[5.625,0.375],[1.625,-4]],"v":[[-85.875,54.125],[-95.75,57],[-88.375,65],[-76.625,59]],"c":true}],"e":[{"i":[[5.75,0.375],[-0.125,-1.75],[-3.235,-0.34],[-2.02,3.816]],"o":[[-5.75,-0.375],[0.276,3.867],[4.75,0.5],[1.125,-2.125]],"v":[[-86,57],[-93.625,57.125],[-87.375,63.625],[-76.625,59]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.167,"y":0},"n":"0p667_1_0p167_0","t":19,"s":[{"i":[[5.75,0.375],[-0.125,-1.75],[-3.235,-0.34],[-2.02,3.816]],"o":[[-5.75,-0.375],[0.276,3.867],[4.75,0.5],[1.125,-2.125]],"v":[[-86,57],[-93.625,57.125],[-87.375,63.625],[-76.625,59]],"c":true}],"e":[{"i":[[5.75,0.375],[-0.125,-3.875],[-6.132,-0.409],[-1.625,4]],"o":[[-5.75,-0.375],[0.125,3.875],[5.625,0.375],[1.625,-4]],"v":[[-85.375,51.25],[-95.75,57],[-88.375,67],[-76.625,59]],"c":true}]},{"i":{"x":0.833,"y":1},"o":{"x":0.167,"y":0},"n":"0p833_1_0p167_0","t":22,"s":[{"i":[[5.75,0.375],[-0.125,-3.875],[-6.132,-0.409],[-1.625,4]],"o":[[-5.75,-0.375],[0.125,3.875],[5.625,0.375],[1.625,-4]],"v":[[-85.375,51.25],[-95.75,57],[-88.375,67],[-76.625,59]],"c":true}],"e":[{"i":[[5.75,0.375],[-0.125,-1.75],[-3.235,-0.34],[-2.02,3.816]],"o":[[-5.75,-0.375],[0.276,3.867],[4.75,0.5],[1.125,-2.125]],"v":[[-86,57],[-93.625,57.125],[-87.375,63.625],[-76.625,59]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.167,"y":0},"n":"0p667_1_0p167_0","t":25,"s":[{"i":[[5.75,0.375],[-0.125,-1.75],[-3.235,-0.34],[-2.02,3.816]],"o":[[-5.75,-0.375],[0.276,3.867],[4.75,0.5],[1.125,-2.125]],"v":[[-86,57],[-93.625,57.125],[-87.375,63.625],[-76.625,59]],"c":true}],"e":[{"i":[[5.75,0.375],[-0.125,-3.875],[-6.132,-0.409],[-1.625,4]],"o":[[-5.75,-0.375],[0.125,3.875],[5.625,0.375],[1.625,-4]],"v":[[-85.375,51.25],[-95.75,57],[-88.375,67],[-76.625,59]],"c":true}]},{"i":{"x":0.833,"y":1},"o":{"x":0.167,"y":0},"n":"0p833_1_0p167_0","t":29,"s":[{"i":[[5.75,0.375],[-0.125,-3.875],[-6.132,-0.409],[-1.625,4]],"o":[[-5.75,-0.375],[0.125,3.875],[5.625,0.375],[1.625,-4]],"v":[[-85.375,51.25],[-95.75,57],[-88.375,67],[-76.625,59]],"c":true}],"e":[{"i":[[5.75,0.375],[0.25,-0.375],[-2.111,-0.275],[-0.625,0.875]],"o":[[-5.75,-0.375],[0,1.5],[2.875,0.375],[0.689,-0.965]],"v":[[-87.375,59.75],[-95.75,57],[-87.625,60.5],[-76.625,59]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.167,"y":0},"n":"0p667_1_0p167_0","t":42,"s":[{"i":[[5.75,0.375],[0.25,-0.375],[-2.111,-0.275],[-0.625,0.875]],"o":[[-5.75,-0.375],[0,1.5],[2.875,0.375],[0.689,-0.965]],"v":[[-87.375,59.75],[-95.75,57],[-87.625,60.5],[-76.625,59]],"c":true}],"e":[{"i":[[5.75,0.375],[-0.125,-3.875],[-6.132,-0.409],[-1.625,4]],"o":[[-5.75,-0.375],[0.125,3.875],[5.625,0.375],[1.625,-4]],"v":[[-85.875,54.125],[-95.75,57],[-88.375,65],[-76.625,59]],"c":true}]},{"i":{"x":0.833,"y":1},"o":{"x":0.167,"y":0},"n":"0p833_1_0p167_0","t":45,"s":[{"i":[[5.75,0.375],[-0.125,-3.875],[-6.132,-0.409],[-1.625,4]],"o":[[-5.75,-0.375],[0.125,3.875],[5.625,0.375],[1.625,-4]],"v":[[-85.875,54.125],[-95.75,57],[-88.375,65],[-76.625,59]],"c":true}],"e":[{"i":[[5.75,0.375],[-0.125,-1.75],[-3.235,-0.34],[-2.02,3.816]],"o":[[-5.75,-0.375],[0.276,3.867],[4.75,0.5],[1.125,-2.125]],"v":[[-86,57],[-93.625,57.125],[-87.375,63.625],[-76.625,59]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.167,"y":0},"n":"0p667_1_0p167_0","t":48,"s":[{"i":[[5.75,0.375],[-0.125,-1.75],[-3.235,-0.34],[-2.02,3.816]],"o":[[-5.75,-0.375],[0.276,3.867],[4.75,0.5],[1.125,-2.125]],"v":[[-86,57],[-93.625,57.125],[-87.375,63.625],[-76.625,59]],"c":true}],"e":[{"i":[[4.591,0.299],[-0.1,-3.094],[-4.896,-0.326],[-1.085,4.145]],"o":[[-4.591,-0.299],[0.1,3.094],[4.491,0.299],[0.873,-3.335]],"v":[[-85.405,52.799],[-92.533,58.315],[-87.569,64.451],[-79.574,58.987]],"c":true}]},{"i":{"x":0.833,"y":1},"o":{"x":0.167,"y":0},"n":"0p833_1_0p167_0","t":51,"s":[{"i":[[4.591,0.299],[-0.1,-3.094],[-4.896,-0.326],[-1.085,4.145]],"o":[[-4.591,-0.299],[0.1,3.094],[4.491,0.299],[0.873,-3.335]],"v":[[-85.405,52.799],[-92.533,58.315],[-87.569,64.451],[-79.574,58.987]],"c":true}],"e":[{"i":[[5.75,0.375],[-0.125,-1.75],[-3.235,-0.34],[-2.02,3.816]],"o":[[-5.75,-0.375],[0.276,3.867],[4.75,0.5],[1.125,-2.125]],"v":[[-86,57],[-93.625,57.125],[-87.375,63.625],[-76.625,59]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.167,"y":0},"n":"0p667_1_0p167_0","t":54,"s":[{"i":[[5.75,0.375],[-0.125,-1.75],[-3.235,-0.34],[-2.02,3.816]],"o":[[-5.75,-0.375],[0.276,3.867],[4.75,0.5],[1.125,-2.125]],"v":[[-86,57],[-93.625,57.125],[-87.375,63.625],[-76.625,59]],"c":true}],"e":[{"i":[[5.75,0.375],[-0.125,-3.875],[-6.132,-0.409],[-1.625,4]],"o":[[-5.75,-0.375],[0.125,3.875],[5.625,0.375],[1.625,-4]],"v":[[-85.375,51.25],[-95.75,57],[-88.375,67],[-76.625,59]],"c":true}]},{"i":{"x":0.833,"y":1},"o":{"x":0.167,"y":0},"n":"0p833_1_0p167_0","t":58,"s":[{"i":[[5.75,0.375],[-0.125,-3.875],[-6.132,-0.409],[-1.625,4]],"o":[[-5.75,-0.375],[0.125,3.875],[5.625,0.375],[1.625,-4]],"v":[[-85.375,51.25],[-95.75,57],[-88.375,67],[-76.625,59]],"c":true}],"e":[{"i":[[4.5,0.25],[4.125,3.25],[-6.12,-0.556],[-4.5,2.5]],"o":[[-5.753,-0.32],[4.625,3.625],[4.125,0.375],[-4.5,2.625]],"v":[[-76.25,56.75],[-89,51],[-76,56.75],[-64.875,52.5]],"c":true}]},{"t":68}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.258823529412,0.521568627451,0.956862745098,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":3.8,"ix":5},"lc":1,"lj":2,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.854902020623,0.862744978362,0.878431013519,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":true},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":101,"st":0,"bm":0},{"ddd":0,"ind":7,"ty":4,"nm":"eyes","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[206,150,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.167,"y":0.167},"n":"0p667_1_0p167_0p167","t":11,"s":[{"i":[[2.125,0],[0,-2.812],[-2.125,0],[0,3.125]],"o":[[-2.125,0],[0,2.812],[2.125,0],[0,-3.125]],"v":[[-106.5,7.875],[-110.938,12.312],[-106.562,17.062],[-101.938,12.625]],"c":true}],"e":[{"i":[[2.125,0],[1.312,1.812],[-2.125,0],[0,3.125]],"o":[[-2.125,0],[0,2.812],[2.125,0],[-0.688,2.125]],"v":[[-106.5,14.75],[-110.938,12.312],[-106.562,17.062],[-101.938,12.625]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":13,"s":[{"i":[[2.125,0],[1.312,1.812],[-2.125,0],[0,3.125]],"o":[[-2.125,0],[0,2.812],[2.125,0],[-0.688,2.125]],"v":[[-106.5,14.75],[-110.938,12.312],[-106.562,17.062],[-101.938,12.625]],"c":true}],"e":[{"i":[[2.125,0],[0,-2.812],[-2.125,0],[0,3.125]],"o":[[-2.125,0],[0,2.812],[2.125,0],[0,-3.125]],"v":[[-106.5,7.875],[-110.938,12.312],[-106.562,17.062],[-101.938,12.625]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":18,"s":[{"i":[[2.125,0],[0,-2.812],[-2.125,0],[0,3.125]],"o":[[-2.125,0],[0,2.812],[2.125,0],[0,-3.125]],"v":[[-106.5,7.875],[-110.938,12.312],[-106.562,17.062],[-101.938,12.625]],"c":true}],"e":[{"i":[[2.125,0],[0,-2.812],[-2.125,0],[0,3.125]],"o":[[-2.125,0],[0,2.812],[2.125,0],[0,-3.125]],"v":[[-106.5,7.875],[-110.938,12.312],[-106.562,17.062],[-101.938,12.625]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.167,"y":0.167},"n":"0p667_1_0p167_0p167","t":53,"s":[{"i":[[2.125,0],[0,-2.812],[-2.125,0],[0,3.125]],"o":[[-2.125,0],[0,2.812],[2.125,0],[0,-3.125]],"v":[[-106.5,7.875],[-110.938,12.312],[-106.562,17.062],[-101.938,12.625]],"c":true}],"e":[{"i":[[2.125,0],[1.312,1.812],[-2.125,0],[0,3.125]],"o":[[-2.125,0],[0,2.812],[2.125,0],[-0.688,2.125]],"v":[[-106.5,14.75],[-110.938,12.312],[-106.562,17.062],[-101.938,12.625]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":55,"s":[{"i":[[2.125,0],[1.312,1.812],[-2.125,0],[0,3.125]],"o":[[-2.125,0],[0,2.812],[2.125,0],[-0.688,2.125]],"v":[[-106.5,14.75],[-110.938,12.312],[-106.562,17.062],[-101.938,12.625]],"c":true}],"e":[{"i":[[2.125,0],[0,-2.812],[-2.125,0],[0,3.125]],"o":[[-2.125,0],[0,2.812],[2.125,0],[0,-3.125]],"v":[[-106.5,7.875],[-110.938,12.312],[-106.562,17.062],[-101.938,12.625]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":60,"s":[{"i":[[2.125,0],[0,-2.812],[-2.125,0],[0,3.125]],"o":[[-2.125,0],[0,2.812],[2.125,0],[0,-3.125]],"v":[[-106.5,7.875],[-110.938,12.312],[-106.562,17.062],[-101.938,12.625]],"c":true}],"e":[{"i":[[2.125,0],[0,-2.812],[-2.125,0],[0,3.125]],"o":[[-2.125,0],[0,2.812],[2.125,0],[0,-3.125]],"v":[[-106.5,7.875],[-110.938,12.312],[-106.562,17.062],[-101.938,12.625]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.167,"y":0.167},"n":"0p667_1_0p167_0p167","t":83,"s":[{"i":[[2.125,0],[0,-2.812],[-2.125,0],[0,3.125]],"o":[[-2.125,0],[0,2.812],[2.125,0],[0,-3.125]],"v":[[-106.5,7.875],[-110.938,12.312],[-106.562,17.062],[-101.938,12.625]],"c":true}],"e":[{"i":[[2.125,0],[1.312,1.812],[-2.125,0],[0,3.125]],"o":[[-2.125,0],[0,2.812],[2.125,0],[-0.688,2.125]],"v":[[-106.5,14.75],[-110.938,12.312],[-106.562,17.062],[-101.938,12.625]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":85,"s":[{"i":[[2.125,0],[1.312,1.812],[-2.125,0],[0,3.125]],"o":[[-2.125,0],[0,2.812],[2.125,0],[-0.688,2.125]],"v":[[-106.5,14.75],[-110.938,12.312],[-106.562,17.062],[-101.938,12.625]],"c":true}],"e":[{"i":[[2.125,0],[0,-2.812],[-2.125,0],[0,3.125]],"o":[[-2.125,0],[0,2.812],[2.125,0],[0,-3.125]],"v":[[-106.5,7.875],[-110.938,12.312],[-106.562,17.062],[-101.938,12.625]],"c":true}]},{"t":90}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.167,"y":0.167},"n":"0p667_1_0p167_0p167","t":11,"s":[{"i":[[2.125,0],[0,-2.812],[-2.125,0],[0,3.125]],"o":[[-2.125,0],[0,2.812],[2.125,0],[0,-3.125]],"v":[[-46.25,7.875],[-50.688,12.312],[-46.312,17.062],[-41.688,12.625]],"c":true}],"e":[{"i":[[2.125,0],[1.438,1.938],[-2.125,0],[0,3.125]],"o":[[-2.125,0],[0,2.812],[2.125,0],[-1.438,1.375]],"v":[[-46.25,14.75],[-50.688,12.312],[-46.312,17.062],[-41.688,12.625]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":13,"s":[{"i":[[2.125,0],[1.438,1.938],[-2.125,0],[0,3.125]],"o":[[-2.125,0],[0,2.812],[2.125,0],[-1.438,1.375]],"v":[[-46.25,14.75],[-50.688,12.312],[-46.312,17.062],[-41.688,12.625]],"c":true}],"e":[{"i":[[2.125,0],[0,-2.812],[-2.125,0],[0,3.125]],"o":[[-2.125,0],[0,2.812],[2.125,0],[0,-3.125]],"v":[[-46.25,7.875],[-50.688,12.312],[-46.312,17.062],[-41.688,12.625]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":18,"s":[{"i":[[2.125,0],[0,-2.812],[-2.125,0],[0,3.125]],"o":[[-2.125,0],[0,2.812],[2.125,0],[0,-3.125]],"v":[[-46.25,7.875],[-50.688,12.312],[-46.312,17.062],[-41.688,12.625]],"c":true}],"e":[{"i":[[2.125,0],[0,-2.812],[-2.125,0],[0,3.125]],"o":[[-2.125,0],[0,2.812],[2.125,0],[0,-3.125]],"v":[[-46.25,7.875],[-50.688,12.312],[-46.312,17.062],[-41.688,12.625]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.167,"y":0.167},"n":"0p667_1_0p167_0p167","t":53,"s":[{"i":[[2.125,0],[0,-2.812],[-2.125,0],[0,3.125]],"o":[[-2.125,0],[0,2.812],[2.125,0],[0,-3.125]],"v":[[-46.25,7.875],[-50.688,12.312],[-46.312,17.062],[-41.688,12.625]],"c":true}],"e":[{"i":[[2.125,0],[1.438,1.938],[-2.125,0],[0,3.125]],"o":[[-2.125,0],[0,2.812],[2.125,0],[-1.438,1.375]],"v":[[-46.25,14.75],[-50.688,12.312],[-46.312,17.062],[-41.688,12.625]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":55,"s":[{"i":[[2.125,0],[1.438,1.938],[-2.125,0],[0,3.125]],"o":[[-2.125,0],[0,2.812],[2.125,0],[-1.438,1.375]],"v":[[-46.25,14.75],[-50.688,12.312],[-46.312,17.062],[-41.688,12.625]],"c":true}],"e":[{"i":[[2.125,0],[0,-2.812],[-2.125,0],[0,3.125]],"o":[[-2.125,0],[0,2.812],[2.125,0],[0,-3.125]],"v":[[-46.25,7.875],[-50.688,12.312],[-46.312,17.062],[-41.688,12.625]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":60,"s":[{"i":[[2.125,0],[0,-2.812],[-2.125,0],[0,3.125]],"o":[[-2.125,0],[0,2.812],[2.125,0],[0,-3.125]],"v":[[-46.25,7.875],[-50.688,12.312],[-46.312,17.062],[-41.688,12.625]],"c":true}],"e":[{"i":[[2.125,0],[0,-2.812],[-2.125,0],[0,3.125]],"o":[[-2.125,0],[0,2.812],[2.125,0],[0,-3.125]],"v":[[-46.25,7.875],[-50.688,12.312],[-46.312,17.062],[-41.688,12.625]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.167,"y":0.167},"n":"0p667_1_0p167_0p167","t":83,"s":[{"i":[[2.125,0],[0,-2.812],[-2.125,0],[0,3.125]],"o":[[-2.125,0],[0,2.812],[2.125,0],[0,-3.125]],"v":[[-46.25,7.875],[-50.688,12.312],[-46.312,17.062],[-41.688,12.625]],"c":true}],"e":[{"i":[[2.125,0],[1.438,1.938],[-2.125,0],[0,3.125]],"o":[[-2.125,0],[0,2.812],[2.125,0],[-1.438,1.375]],"v":[[-46.25,14.75],[-50.688,12.312],[-46.312,17.062],[-41.688,12.625]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":85,"s":[{"i":[[2.125,0],[1.438,1.938],[-2.125,0],[0,3.125]],"o":[[-2.125,0],[0,2.812],[2.125,0],[-1.438,1.375]],"v":[[-46.25,14.75],[-50.688,12.312],[-46.312,17.062],[-41.688,12.625]],"c":true}],"e":[{"i":[[2.125,0],[0,-2.812],[-2.125,0],[0,3.125]],"o":[[-2.125,0],[0,2.812],[2.125,0],[0,-3.125]],"v":[[-46.25,7.875],[-50.688,12.312],[-46.312,17.062],[-41.688,12.625]],"c":true}]},{"t":90}],"ix":2},"nm":"Path 2","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.258823529412,0.521568627451,0.956862745098,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.258823529412,0.521568627451,0.956862745098,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":4,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":101,"st":0,"bm":0},{"ddd":0,"ind":8,"ty":4,"nm":"eyebrows","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":15,"s":[127.375,143.5,0],"e":[127.375,141,0],"to":[0,-0.41666665673256,0],"ti":[0,0.33333334326744,0]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":20,"s":[127.375,141,0],"e":[127.375,141.5,0],"to":[0,-0.33333334326744,0],"ti":[0,-0.41666665673256,0]},{"i":{"x":0.833,"y":1},"o":{"x":0.333,"y":0},"n":"0p833_1_0p333_0","t":36,"s":[127.375,141.5,0],"e":[127.375,143.5,0],"to":[0,0.41666665673256,0],"ti":[0,-0.08333333581686,0]},{"i":{"x":0.667,"y":1},"o":{"x":0.167,"y":0},"n":"0p667_1_0p167_0","t":40,"s":[127.375,143.5,0],"e":[127.375,142,0],"to":[0,0.08333333581686,0],"ti":[0,0,0]},{"i":{"x":0.833,"y":1},"o":{"x":0.333,"y":0},"n":"0p833_1_0p333_0","t":44,"s":[127.375,142,0],"e":[127.375,143.5,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.667,"y":1},"o":{"x":0.167,"y":0},"n":"0p667_1_0p167_0","t":49,"s":[127.375,143.5,0],"e":[127.375,142,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":53,"s":[127.375,142,0],"e":[127.375,143.5,0],"to":[0,0,0],"ti":[0,-0.25,0]},{"t":58}],"ix":2},"a":{"a":0,"k":[-78.625,-6.5,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[-6.75,0],[0,0]],"o":[[0,0],[6.75,0],[0,0]],"v":[[-118.812,-4.625],[-107.375,-9.188],[-95.688,-4.25]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[0,0],[-6.75,0],[0,0]],"o":[[0,0],[6.75,0],[0,0]],"v":[[-61.688,-4.625],[-50.25,-9.188],[-38.562,-4.25]],"c":false},"ix":2},"nm":"Path 2","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.258823529412,0.521568627451,0.956862745098,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":3.8,"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":true},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":4,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":101,"st":0,"bm":0},{"ddd":0,"ind":9,"ty":4,"nm":"face","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[206,150,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[-74.875,24.75],[-68,37.75],[-76.625,39.25]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.258823529412,0.521568627451,0.956862745098,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":3.8,"ix":5},"lc":1,"lj":2,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":true},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 2","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,-11.25],[14.75,-13.25],[0,0]],"o":[[0,0],[0,19.25],[-14.504,13.029],[0,0]],"v":[[-28,1],[-28.25,30.5],[-47.25,74.5],[-81,86.5]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.258823529412,0.521568627451,0.956862745098,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":3.8,"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":true},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"ix":2,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":101,"st":0,"bm":0}]}],"layers":[{"ddd":0,"ind":1,"ty":0,"nm":"pre VOICE LAPTOP","refId":"comp_0","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[120.5,53,0],"ix":2},"a":{"a":0,"k":[206,150,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"w":412,"h":300,"ip":0,"op":101,"st":0,"bm":0}],"markers":[]}
diff --git a/ui/views/animation/ink_drop_host_view.cc b/ui/views/animation/ink_drop_host_view.cc
index 5f8a9ac..49620fc 100644
--- a/ui/views/animation/ink_drop_host_view.cc
+++ b/ui/views/animation/ink_drop_host_view.cc
@@ -21,6 +21,9 @@
 
 namespace views {
 
+// static
+constexpr gfx::Size InkDropHostView::kDefaultInkDropSize;
+
 InkDropHostView::InkDropHostViewEventHandlerDelegate::
     InkDropHostViewEventHandlerDelegate(InkDropHostView* host_view)
     : host_view_(host_view) {}
diff --git a/ui/views/animation/ink_drop_host_view.h b/ui/views/animation/ink_drop_host_view.h
index c410d9fb..3b5bc508 100644
--- a/ui/views/animation/ink_drop_host_view.h
+++ b/ui/views/animation/ink_drop_host_view.h
@@ -134,7 +134,7 @@
 
  protected:
   // Size used for the default SquareInkDropRipple.
-  static constexpr int kDefaultInkDropSize = 24;
+  static constexpr gfx::Size kDefaultInkDropSize = gfx::Size(24, 24);
 
   // Called after a new InkDrop instance is created.
   virtual void OnInkDropCreated() {}
@@ -151,8 +151,7 @@
   // directly.
   std::unique_ptr<InkDropRipple> CreateDefaultInkDropRipple(
       const gfx::Point& center_point,
-      const gfx::Size& size = gfx::Size(kDefaultInkDropSize,
-                                        kDefaultInkDropSize)) const;
+      const gfx::Size& size = kDefaultInkDropSize) const;
 
   // Creates a SquareInkDropRipple centered on |center_point|.
   std::unique_ptr<InkDropRipple> CreateSquareInkDropRipple(
@@ -163,8 +162,7 @@
   // directly.
   std::unique_ptr<InkDropHighlight> CreateDefaultInkDropHighlight(
       const gfx::PointF& center_point,
-      const gfx::Size& size = gfx::Size(kDefaultInkDropSize,
-                                        kDefaultInkDropSize)) const;
+      const gfx::Size& size = kDefaultInkDropSize) const;
 
   // Creates a InkDropHighlight centered on |center_point|.
   std::unique_ptr<InkDropHighlight> CreateSquareInkDropHighlight(
diff --git a/ui/views/animation/square_ink_drop_ripple.cc b/ui/views/animation/square_ink_drop_ripple.cc
index 61184b3..1e157b35 100644
--- a/ui/views/animation/square_ink_drop_ripple.cc
+++ b/ui/views/animation/square_ink_drop_ripple.cc
@@ -110,24 +110,6 @@
 // The scale factor used to burst the ACTION_TRIGGERED bubble as it fades out.
 constexpr float kQuickActionBurstScale = 1.3f;
 
-// Duration constants for InkDropStateSubAnimations. See the
-// InkDropStateSubAnimations enum documentation for more info.
-int kAnimationDurationInMs[] = {
-    150,  // HIDDEN_FADE_OUT
-    200,  // HIDDEN_TRANSFORM
-    0,    // ACTION_PENDING_FADE_IN
-    160,  // ACTION_PENDING_TRANSFORM
-    150,  // ACTION_TRIGGERED_FADE_OUT
-    160,  // ACTION_TRIGGERED_TRANSFORM
-    200,  // ALTERNATE_ACTION_PENDING
-    150,  // ALTERNATE_ACTION_TRIGGERED_FADE_OUT
-    200,  // ALTERNATE_ACTION_TRIGGERED_TRANSFORM
-    200,  // ACTIVATED_CIRCLE_TRANSFORM
-    160,  // ACTIVATED_RECT_TRANSFORM
-    150,  // DEACTIVATED_FADE_OUT
-    200,  // DEACTIVATED_TRANSFORM
-};
-
 // Returns the InkDropState sub animation duration for the given |state|.
 base::TimeDelta GetAnimationDuration(InkDropSubAnimations state) {
   if (!PlatformStyle::kUseRipples ||
@@ -135,7 +117,24 @@
     return base::TimeDelta();
   }
 
-  return base::TimeDelta::FromMilliseconds(kAnimationDurationInMs[state]);
+  // Duration constants for InkDropStateSubAnimations. See the
+  // InkDropStateSubAnimations enum documentation for more info.
+  constexpr base::TimeDelta kAnimationDuration[] = {
+      base::TimeDelta::FromMilliseconds(150),  // HIDDEN_FADE_OUT
+      base::TimeDelta::FromMilliseconds(200),  // HIDDEN_TRANSFORM
+      base::TimeDelta(),                       // ACTION_PENDING_FADE_IN
+      base::TimeDelta::FromMilliseconds(160),  // ACTION_PENDING_TRANSFORM
+      base::TimeDelta::FromMilliseconds(150),  // ACTION_TRIGGERED_FADE_OUT
+      base::TimeDelta::FromMilliseconds(160),  // ACTION_TRIGGERED_TRANSFORM
+      base::TimeDelta::FromMilliseconds(200),  // ALTERNATE_ACTION_PENDING
+      base::TimeDelta::FromMilliseconds(150),  // ALTERNAT..._TRIGGERED_FADE_OUT
+      base::TimeDelta::FromMilliseconds(200),  // ALTERNA..._TRIGGERED_TRANSFORM
+      base::TimeDelta::FromMilliseconds(200),  // ACTIVATED_CIRCLE_TRANSFORM
+      base::TimeDelta::FromMilliseconds(160),  // ACTIVATED_RECT_TRANSFORM
+      base::TimeDelta::FromMilliseconds(150),  // DEACTIVATED_FADE_OUT
+      base::TimeDelta::FromMilliseconds(200),  // DEACTIVATED_TRANSFORM
+  };
+  return kAnimationDuration[state];
 }
 
 }  // namespace
diff --git a/ui/views/animation/square_ink_drop_ripple_unittest.cc b/ui/views/animation/square_ink_drop_ripple_unittest.cc
index 8dfd33ea..d6973f8 100644
--- a/ui/views/animation/square_ink_drop_ripple_unittest.cc
+++ b/ui/views/animation/square_ink_drop_ripple_unittest.cc
@@ -40,32 +40,43 @@
 
  protected:
   // Half the width/height of the drawn ink drop.
-  static const int kHalfDrawnSize;
+  static constexpr int kHalfDrawnSize = 5;
 
   // The full width/height of the drawn ink drop.
-  static const int kDrawnSize;
+  static constexpr int kDrawnSize = 2 * kHalfDrawnSize;
 
   // The radius of the rounded rectangle corners.
-  static const int kTransformedRadius;
+  static constexpr int kTransformedRadius = 10;
 
   // Half the width/height of the transformed ink drop.
-  static const int kHalfTransformedSize;
+  static const int kHalfTransformedSize = 100;
 
   // The full width/height of the transformed ink drop.
-  static const int kTransformedSize;
+  static const int kTransformedSize = 2 * kHalfTransformedSize;
 
   // Constant points in the drawn space that will be transformed.
-  static const gfx::Point kDrawnCenterPoint;
-  static const gfx::Point kDrawnMidLeftPoint;
-  static const gfx::Point kDrawnMidRightPoint;
-  static const gfx::Point kDrawnTopMidPoint;
-  static const gfx::Point kDrawnBottomMidPoint;
+  static constexpr gfx::Point kDrawnCenterPoint =
+      gfx::Point(kHalfDrawnSize, kHalfDrawnSize);
+  static constexpr gfx::Point kDrawnMidLeftPoint =
+      gfx::Point(0, kHalfDrawnSize);
+  static constexpr gfx::Point kDrawnMidRightPoint =
+      gfx::Point(kDrawnSize, kHalfDrawnSize);
+  static constexpr gfx::Point kDrawnTopMidPoint = gfx::Point(kHalfDrawnSize, 0);
+  static constexpr gfx::Point kDrawnBottomMidPoint =
+      gfx::Point(kHalfDrawnSize, kDrawnSize);
 
   // The test target.
-  SquareInkDropRipple ink_drop_ripple_;
+  SquareInkDropRipple ink_drop_ripple_{
+      gfx::Size(kDrawnSize, kDrawnSize),
+      2,
+      gfx::Size(kHalfDrawnSize, kHalfDrawnSize),
+      1,
+      gfx::Point(),
+      SK_ColorBLACK,
+      0.175f};
 
   // Provides internal access to the test target.
-  SquareInkDropRippleTestApi test_api_;
+  SquareInkDropRippleTestApi test_api_{&ink_drop_ripple_};
 
   // The gfx::Transforms collection that is populated via the
   // Calculate*Transforms() calls.
@@ -75,48 +86,23 @@
   DISALLOW_COPY_AND_ASSIGN(SquareInkDropRippleCalculateTransformsTest);
 };
 
-const int SquareInkDropRippleCalculateTransformsTest::kHalfDrawnSize = 5;
-const int SquareInkDropRippleCalculateTransformsTest::kDrawnSize =
-    2 * kHalfDrawnSize;
-
-const int SquareInkDropRippleCalculateTransformsTest::kTransformedRadius = 10;
-const int SquareInkDropRippleCalculateTransformsTest::kHalfTransformedSize =
-    100;
-const int SquareInkDropRippleCalculateTransformsTest::kTransformedSize =
-    2 * kHalfTransformedSize;
-
-const gfx::Point SquareInkDropRippleCalculateTransformsTest::kDrawnCenterPoint =
-    gfx::Point(kHalfDrawnSize, kHalfDrawnSize);
-
-const gfx::Point
-    SquareInkDropRippleCalculateTransformsTest::kDrawnMidLeftPoint =
-        gfx::Point(0, kHalfDrawnSize);
-
-const gfx::Point
-    SquareInkDropRippleCalculateTransformsTest::kDrawnMidRightPoint =
-        gfx::Point(kDrawnSize, kHalfDrawnSize);
-
-const gfx::Point SquareInkDropRippleCalculateTransformsTest::kDrawnTopMidPoint =
-    gfx::Point(kHalfDrawnSize, 0);
-
-const gfx::Point
-    SquareInkDropRippleCalculateTransformsTest::kDrawnBottomMidPoint =
-        gfx::Point(kHalfDrawnSize, kDrawnSize);
-
 SquareInkDropRippleCalculateTransformsTest::
-    SquareInkDropRippleCalculateTransformsTest()
-    : ink_drop_ripple_(gfx::Size(kDrawnSize, kDrawnSize),
-                       2,
-                       gfx::Size(kHalfDrawnSize, kHalfDrawnSize),
-                       1,
-                       gfx::Point(),
-                       SK_ColorBLACK,
-                       0.175f),
-      test_api_(&ink_drop_ripple_) {}
+    SquareInkDropRippleCalculateTransformsTest() = default;
 
 SquareInkDropRippleCalculateTransformsTest::
     ~SquareInkDropRippleCalculateTransformsTest() = default;
 
+constexpr gfx::Point
+    SquareInkDropRippleCalculateTransformsTest::kDrawnCenterPoint;
+constexpr gfx::Point
+    SquareInkDropRippleCalculateTransformsTest::kDrawnMidLeftPoint;
+constexpr gfx::Point
+    SquareInkDropRippleCalculateTransformsTest::kDrawnMidRightPoint;
+constexpr gfx::Point
+    SquareInkDropRippleCalculateTransformsTest::kDrawnTopMidPoint;
+constexpr gfx::Point
+    SquareInkDropRippleCalculateTransformsTest::kDrawnBottomMidPoint;
+
 }  // namespace
 
 TEST_F(SquareInkDropRippleCalculateTransformsTest,
@@ -124,7 +110,7 @@
   test_api_.CalculateCircleTransforms(
       gfx::Size(kTransformedSize, kTransformedSize), &transforms_);
 
-  struct {
+  constexpr struct {
     PaintedShape shape;
     gfx::Point center_point;
     gfx::Point mid_left_point;
@@ -183,10 +169,10 @@
       gfx::Size(kTransformedSize, kTransformedSize), kTransformedRadius,
       &transforms_);
 
-  const int x_offset = kHalfTransformedSize - kTransformedRadius;
-  const int y_offset = kHalfTransformedSize - kTransformedRadius;
+  constexpr int x_offset = kHalfTransformedSize - kTransformedRadius;
+  constexpr int y_offset = kHalfTransformedSize - kTransformedRadius;
 
-  struct {
+  constexpr struct {
     PaintedShape shape;
     gfx::Point center_point;
     gfx::Point mid_left_point;
@@ -243,11 +229,11 @@
 TEST_F(SquareInkDropRippleCalculateTransformsTest, RippleIsPixelAligned) {
   // Create a ripple that would not naturally be pixel aligned at a fractional
   // scale factor.
-  const gfx::Point center(14, 14);
-  const gfx::Rect drawn_rect_bounds(0, 0, 10, 10);
-  SquareInkDropRipple ink_drop_ripple(drawn_rect_bounds.size(), 2,
+  constexpr gfx::Point kCenter(14, 14);
+  constexpr gfx::Rect kDrawnRectBounds(0, 0, 10, 10);
+  SquareInkDropRipple ink_drop_ripple(kDrawnRectBounds.size(), 2,
                                       gfx::Size(1, 1),  // unimportant
-                                      1, center, SK_ColorBLACK, 0.175f);
+                                      1, kCenter, SK_ColorBLACK, 0.175f);
   SquareInkDropRippleTestApi test_api(&ink_drop_ripple);
 
   // Add to a widget so we can control the DSF.
@@ -259,8 +245,8 @@
   host_view->layer()->Add(ink_drop_ripple.GetRootLayer());
 
   // Test a variety of scale factors and target transform sizes.
-  std::vector<float> dsfs({1.0f, 1.25f, 1.5f, 2.0f, 3.0f});
-  std::vector<int> target_sizes({5, 7, 11, 13, 31});
+  const std::vector<float> dsfs({1.0f, 1.25f, 1.5f, 2.0f, 3.0f});
+  const std::vector<int> target_sizes({5, 7, 11, 13, 31});
 
   for (float dsf : dsfs) {
     for (int target_size : target_sizes) {
@@ -295,13 +281,13 @@
       // what the target size was you should get an integer aligned bounding
       // box.
       gfx::Transform transform = transforms[PaintedShape::HORIZONTAL_RECT];
-      gfx::RectF horizontal_rect(drawn_rect_bounds);
+      gfx::RectF horizontal_rect(kDrawnRectBounds);
       transform.TransformRect(&horizontal_rect);
       horizontal_rect.Scale(dsf);
       verify_bounds(horizontal_rect);
 
       transform = transforms[PaintedShape::VERTICAL_RECT];
-      gfx::RectF vertical_rect(drawn_rect_bounds);
+      gfx::RectF vertical_rect(kDrawnRectBounds);
       transform.TransformRect(&vertical_rect);
       vertical_rect.Scale(dsf);
       verify_bounds(vertical_rect);
diff --git a/ui/views/bubble/bubble_dialog_delegate_view.cc b/ui/views/bubble/bubble_dialog_delegate_view.cc
index 8ce310e3..8d480044 100644
--- a/ui/views/bubble/bubble_dialog_delegate_view.cc
+++ b/ui/views/bubble/bubble_dialog_delegate_view.cc
@@ -307,8 +307,7 @@
     Widget* widget) const {}
 
 void BubbleDialogDelegateView::UseCompactMargins() {
-  const int kCompactMargin = 6;
-  set_margins(gfx::Insets(kCompactMargin));
+  set_margins(gfx::Insets(6));
 }
 
 void BubbleDialogDelegateView::OnAnchorBoundsChanged() {
diff --git a/ui/views/bubble/bubble_dialog_delegate_view_unittest.cc b/ui/views/bubble/bubble_dialog_delegate_view_unittest.cc
index 144314d..960a65a3 100644
--- a/ui/views/bubble/bubble_dialog_delegate_view_unittest.cc
+++ b/ui/views/bubble/bubble_dialog_delegate_view_unittest.cc
@@ -35,8 +35,7 @@
 
 namespace {
 
-constexpr int kContentHeight = 200;
-constexpr int kContentWidth = 200;
+constexpr gfx::Size kContentSize = gfx::Size(200, 200);
 
 class TestBubbleDialogDelegateView : public BubbleDialogDelegateView {
  public:
@@ -51,9 +50,7 @@
 
   // BubbleDialogDelegateView overrides:
   View* GetInitiallyFocusedView() override { return view_; }
-  gfx::Size CalculatePreferredSize() const override {
-    return gfx::Size(kContentWidth, kContentHeight);
-  }
+  gfx::Size CalculatePreferredSize() const override { return kContentSize; }
   void AddedToWidget() override {
     if (title_view_)
       GetBubbleFrameView()->SetTitleView(std::move(title_view_));
@@ -422,10 +419,10 @@
   // Use GetContentsBounds() to exclude the bubble border, which can change per
   // platform.
   gfx::Rect frame_size = bubble_frame->GetContentsBounds();
-  EXPECT_EQ(content_margins.height() + kContentHeight + title_margins.height() +
-                kTitleHeight,
+  EXPECT_EQ(content_margins.height() + kContentSize.height() +
+                title_margins.height() + kTitleHeight,
             frame_size.height());
-  EXPECT_EQ(content_margins.width() + kContentWidth, frame_size.width());
+  EXPECT_EQ(content_margins.width() + kContentSize.width(), frame_size.width());
 
   // Set the title preferred size to 0. The bubble frame makes fewer assumptions
   // about custom title views, so there should still be margins for it while the
@@ -434,17 +431,19 @@
   bubble_widget->UpdateWindowTitle();
   bubble_delegate->SizeToContents();
   frame_size = bubble_frame->GetContentsBounds();
-  EXPECT_EQ(content_margins.height() + kContentHeight + title_margins.height(),
-            frame_size.height());
-  EXPECT_EQ(content_margins.width() + kContentWidth, frame_size.width());
+  EXPECT_EQ(
+      content_margins.height() + kContentSize.height() + title_margins.height(),
+      frame_size.height());
+  EXPECT_EQ(content_margins.width() + kContentSize.width(), frame_size.width());
 
   // Now hide the title properly. The margins should also disappear.
   bubble_delegate->set_should_show_window_title(false);
   bubble_widget->UpdateWindowTitle();
   bubble_delegate->SizeToContents();
   frame_size = bubble_frame->GetContentsBounds();
-  EXPECT_EQ(content_margins.height() + kContentHeight, frame_size.height());
-  EXPECT_EQ(content_margins.width() + kContentWidth, frame_size.width());
+  EXPECT_EQ(content_margins.height() + kContentSize.height(),
+            frame_size.height());
+  EXPECT_EQ(content_margins.width() + kContentSize.width(), frame_size.width());
 }
 
 // Ensure the BubbleFrameView correctly resizes when the title is provided by a
diff --git a/ui/views/bubble/bubble_frame_view_unittest.cc b/ui/views/bubble/bubble_frame_view_unittest.cc
index fe86a69..cf879870 100644
--- a/ui/views/bubble/bubble_frame_view_unittest.cc
+++ b/ui/views/bubble/bubble_frame_view_unittest.cc
@@ -34,20 +34,19 @@
 
 namespace {
 
-const BubbleBorder::Arrow kArrow = BubbleBorder::TOP_LEFT;
-const SkColor kColor = SK_ColorRED;
-const int kMargin = 6;
-const int kMinimumClientWidth = 100;
-const int kMinimumClientHeight = 200;
-const int kMaximumClientWidth = 300;
-const int kMaximumClientHeight = 300;
-const int kPreferredClientWidth = 150;
-const int kPreferredClientHeight = 250;
+constexpr BubbleBorder::Arrow kArrow = BubbleBorder::TOP_LEFT;
+constexpr SkColor kColor = SK_ColorRED;
+constexpr int kMargin = 6;
+constexpr gfx::Size kMinimumClientSize = gfx::Size(100, 200);
+constexpr gfx::Size kPreferredClientSize = gfx::Size(150, 250);
+constexpr gfx::Size kMaximumClientSize = gfx::Size(300, 300);
 
 // These account for non-client areas like the title bar, footnote etc. However
 // these do not take the bubble border into consideration.
-const int kExpectedAdditionalWidth = 12;
-const int kExpectedAdditionalHeight = 12;
+gfx::Size AddAdditionalSize(gfx::Size size) {
+  size.Enlarge(12, 12);
+  return size;
+}
 
 class TestBubbleFrameViewWidgetDelegate : public WidgetDelegate {
  public:
@@ -62,12 +61,10 @@
 
   View* GetContentsView() override {
     if (!contents_view_) {
-      StaticSizedView* contents_view = new StaticSizedView(
-          gfx::Size(kPreferredClientWidth, kPreferredClientHeight));
-      contents_view->set_minimum_size(
-          gfx::Size(kMinimumClientWidth, kMinimumClientHeight));
-      contents_view->set_maximum_size(
-          gfx::Size(kMaximumClientWidth, kMaximumClientHeight));
+      StaticSizedView* contents_view =
+          new StaticSizedView(kPreferredClientSize);
+      contents_view->set_minimum_size(kMinimumClientSize);
+      contents_view->set_maximum_size(kMaximumClientSize);
       contents_view_ = contents_view;
     }
     return contents_view_;
@@ -795,8 +792,7 @@
   // Expect that a border has been added to the preferred size.
   preferred_rect.Inset(frame.GetBorderInsets());
 
-  gfx::Size expected_size(kPreferredClientWidth + kExpectedAdditionalWidth,
-                          kPreferredClientHeight + kExpectedAdditionalHeight);
+  gfx::Size expected_size = AddAdditionalSize(kPreferredClientSize);
   EXPECT_EQ(expected_size, preferred_rect.size());
 }
 
@@ -831,8 +827,7 @@
   // Expect that a border has been added to the minimum size.
   minimum_rect.Inset(frame.GetBorderInsets());
 
-  gfx::Size expected_size(kMinimumClientWidth + kExpectedAdditionalWidth,
-                          kMinimumClientHeight + kExpectedAdditionalHeight);
+  gfx::Size expected_size = AddAdditionalSize(kMinimumClientSize);
   EXPECT_EQ(expected_size, minimum_rect.size());
 }
 
@@ -847,8 +842,7 @@
   maximum_rect.Inset(frame.GetBorderInsets());
 
   // Should ignore the contents view's maximum size and use the preferred size.
-  gfx::Size expected_size(kPreferredClientWidth + kExpectedAdditionalWidth,
-                          kPreferredClientHeight + kExpectedAdditionalHeight);
+  gfx::Size expected_size = AddAdditionalSize(kPreferredClientSize);
   EXPECT_EQ(expected_size, maximum_rect.size());
 #endif
 }
diff --git a/ui/views/controls/button/menu_button_controller.cc b/ui/views/controls/button/menu_button_controller.cc
index 2995da2..049bf660 100644
--- a/ui/views/controls/button/menu_button_controller.cc
+++ b/ui/views/controls/button/menu_button_controller.cc
@@ -299,8 +299,8 @@
 }
 
 bool MenuButtonController::IsIntentionalMenuTrigger() const {
-  return (TimeTicks::Now() - menu_closed_time_).InMilliseconds() >=
-         kMinimumMsBetweenButtonClicks;
+  return (TimeTicks::Now() - menu_closed_time_) >=
+         kMinimumTimeBetweenButtonClicks;
 }
 
 void MenuButtonController::IncrementPressedLocked(
diff --git a/ui/views/controls/button/toggle_button.cc b/ui/views/controls/button/toggle_button.cc
index 1305b2223..d01b522 100644
--- a/ui/views/controls/button/toggle_button.cc
+++ b/ui/views/controls/button/toggle_button.cc
@@ -26,8 +26,7 @@
 namespace {
 
 // Constants are measured in dip.
-constexpr int kTrackHeight = 12;
-constexpr int kTrackWidth = 28;
+constexpr gfx::Size kTrackSize = gfx::Size(28, 12);
 // Margins from edge of track to edge of view.
 constexpr int kTrackVerticalMargin = 5;
 constexpr int kTrackHorizontalMargin = 6;
@@ -157,7 +156,7 @@
 }
 
 gfx::Size ToggleButton::CalculatePreferredSize() const {
-  gfx::Rect rect(kTrackWidth, kTrackHeight);
+  gfx::Rect rect(kTrackSize);
   rect.Inset(gfx::Insets(-kTrackVerticalMargin, -kTrackHorizontalMargin));
   if (border())
     rect.Inset(-border()->GetInsets());
@@ -166,7 +165,7 @@
 
 gfx::Rect ToggleButton::GetTrackBounds() const {
   gfx::Rect track_bounds(GetContentsBounds());
-  track_bounds.ClampToCenteredSize(gfx::Size(kTrackWidth, kTrackHeight));
+  track_bounds.ClampToCenteredSize(kTrackSize);
   return track_bounds;
 }
 
diff --git a/ui/views/controls/combobox/combobox.cc b/ui/views/controls/combobox/combobox.cc
index d3395ada..e32cbce 100644
--- a/ui/views/controls/combobox/combobox.cc
+++ b/ui/views/controls/combobox/combobox.cc
@@ -506,7 +506,7 @@
   // TODO(hajimehoshi): Fix the problem that the arrow button blinks when
   // cliking this while the dropdown menu is opened.
   const base::TimeDelta delta = base::TimeTicks::Now() - closed_time_;
-  if (delta.InMilliseconds() <= kMinimumMsBetweenButtonClicks)
+  if (delta <= kMinimumTimeBetweenButtonClicks)
     return;
 
   ui::MenuSourceType source_type = ui::MENU_SOURCE_MOUSE;
diff --git a/ui/views/controls/link.cc b/ui/views/controls/link.cc
index 377a412d..b0fe4fc 100644
--- a/ui/views/controls/link.cc
+++ b/ui/views/controls/link.cc
@@ -24,7 +24,8 @@
 
 namespace views {
 
-constexpr int Link::kFocusBorderPadding;
+// static
+constexpr gfx::Insets Link::kFocusBorderPadding;
 
 Link::Link(const base::string16& title, int text_context, int text_style)
     : Label(title, text_context, text_style),
@@ -66,7 +67,7 @@
 void Link::PaintFocusRing(gfx::Canvas* canvas) const {
   if (GetFocusStyle() == FocusStyle::kRing) {
     gfx::Rect focus_ring_bounds = GetTextBounds();
-    focus_ring_bounds.Inset(gfx::Insets(-kFocusBorderPadding));
+    focus_ring_bounds.Inset(-kFocusBorderPadding);
     focus_ring_bounds.Intersect(GetLocalBounds());
     canvas->DrawFocusRect(focus_ring_bounds);
   }
@@ -77,7 +78,7 @@
   if (GetFocusStyle() == FocusStyle::kRing &&
       GetFocusBehavior() != FocusBehavior::NEVER) {
     DCHECK(!GetText().empty());
-    insets += gfx::Insets(kFocusBorderPadding);
+    insets += kFocusBorderPadding;
   }
   return insets;
 }
diff --git a/ui/views/controls/link.h b/ui/views/controls/link.h
index d642330..b913db5 100644
--- a/ui/views/controls/link.h
+++ b/ui/views/controls/link.h
@@ -30,7 +30,7 @@
 
   // The padding for the focus ring border when rendering a focused Link with
   // FocusStyle::kRing.
-  static constexpr int kFocusBorderPadding = 1;
+  static constexpr gfx::Insets kFocusBorderPadding = gfx::Insets(1);
 
   // How the Link is styled when focused.
   enum class FocusStyle {
diff --git a/ui/views/controls/menu/menu_controller.cc b/ui/views/controls/menu/menu_controller.cc
index 3d56b91..cc7418e 100644
--- a/ui/views/controls/menu/menu_controller.cc
+++ b/ui/views/controls/menu/menu_controller.cc
@@ -101,13 +101,12 @@
 }
 #endif
 
-// When showing context menu on mouse down, the user might accidentally select
-// the menu item on the subsequent mouse up. To prevent this, we add the
-// following delay before the user is able to select an item.
-int menu_selection_hold_time_ms = kMinimumMsPressedToActivate;
-
-// Period of the scroll timer (in milliseconds).
-constexpr int kScrollTimerMS = 30;
+// The amount of time the mouse should be down before a mouse release is
+// considered intentional. This is to prevent spurious mouse releases from
+// activating controls, especially when some UI element is revealed under the
+// source of the activation (ex. menus showing underneath menu buttons).
+base::TimeDelta menu_selection_hold_time =
+    base::TimeDelta::FromMilliseconds(200);
 
 // Amount of time from when the drop exits the menu and the menu is hidden.
 constexpr int kCloseOnExitTime = 1200;
@@ -359,8 +358,7 @@
     is_scrolling_up_ = new_is_up;
 
     if (!scrolling_timer_.IsRunning()) {
-      scrolling_timer_.Start(FROM_HERE,
-                             TimeDelta::FromMilliseconds(kScrollTimerMS), this,
+      scrolling_timer_.Start(FROM_HERE, TimeDelta::FromMilliseconds(30), this,
                              &MenuScrollTask::Run);
     }
   }
@@ -772,7 +770,7 @@
     }
     // If a mouse release was received quickly after showing.
     base::TimeDelta time_shown = base::TimeTicks::Now() - menu_start_time_;
-    if (time_shown.InMilliseconds() < menu_selection_hold_time_ms) {
+    if (time_shown < menu_selection_hold_time) {
       // And it wasn't far from the mouse press location.
       gfx::Point screen_loc(event.location());
       View::ConvertPointToScreen(source->GetScrollViewContainer(), &screen_loc);
@@ -793,7 +791,7 @@
         part.menu->GetDelegate()->IsTriggerableEvent(part.menu, event)) {
       base::TimeDelta shown_time = base::TimeTicks::Now() - menu_start_time_;
       if (!state_.context_menu || !View::ShouldShowContextMenuOnMousePress() ||
-          shown_time.InMilliseconds() > menu_selection_hold_time_ms) {
+          shown_time > menu_selection_hold_time) {
         Accept(part.menu, event.flags());
       }
       return;
@@ -1280,7 +1278,7 @@
 
 // static
 void MenuController::TurnOffMenuSelectionHoldForTest() {
-  menu_selection_hold_time_ms = -1;
+  menu_selection_hold_time = base::TimeDelta();
 }
 
 void MenuController::OnMenuItemDestroying(MenuItemView* menu_item) {
diff --git a/ui/views/controls/menu/menu_runner_cocoa_unittest.mm b/ui/views/controls/menu/menu_runner_cocoa_unittest.mm
index a002f7d5..a199536 100644
--- a/ui/views/controls/menu/menu_runner_cocoa_unittest.mm
+++ b/ui/views/controls/menu/menu_runner_cocoa_unittest.mm
@@ -86,10 +86,8 @@
 class MenuRunnerCocoaTest : public ViewsTestBase,
                             public ::testing::WithParamInterface<MenuType> {
  public:
-  enum {
-    kWindowHeight = 200,
-    kWindowOffset = 100,
-  };
+  static constexpr int kWindowHeight = 200;
+  static constexpr int kWindowOffset = 100;
 
   MenuRunnerCocoaTest() = default;
   ~MenuRunnerCocoaTest() override = default;
diff --git a/ui/views/controls/prefix_selector.cc b/ui/views/controls/prefix_selector.cc
index b859d93..ceab3ca 100644
--- a/ui/views/controls/prefix_selector.cc
+++ b/ui/views/controls/prefix_selector.cc
@@ -20,12 +20,6 @@
 
 namespace views {
 
-namespace {
-
-constexpr int64_t kTimeBeforeClearingMS = 1000;
-
-}  // namespace
-
 PrefixSelector::PrefixSelector(PrefixDelegate* delegate, View* host_view)
     : prefix_delegate_(delegate),
       host_view_(host_view),
@@ -39,7 +33,8 @@
 
 bool PrefixSelector::ShouldContinueSelection() const {
   const base::TimeTicks now(tick_clock_->NowTicks());
-  return ((now - time_of_last_key_).InMilliseconds() < kTimeBeforeClearingMS);
+  constexpr auto kTimeBeforeClearing = base::TimeDelta::FromSeconds(1);
+  return (now - time_of_last_key_) < kTimeBeforeClearing;
 }
 
 void PrefixSelector::SetCompositionText(
diff --git a/ui/views/controls/scrollbar/cocoa_scroll_bar.mm b/ui/views/controls/scrollbar/cocoa_scroll_bar.mm
index da1d949..676dc8f 100644
--- a/ui/views/controls/scrollbar/cocoa_scroll_bar.mm
+++ b/ui/views/controls/scrollbar/cocoa_scroll_bar.mm
@@ -20,12 +20,6 @@
 
 namespace {
 
-// The length of the fade animation.
-constexpr int kFadeDurationMs = 240;
-
-// How long we should wait before hiding the scrollbar.
-constexpr int kScrollbarHideTimeoutMs = 500;
-
 // The thickness of the normal and expanded scrollbars.
 constexpr int kScrollbarThickness = 12;
 constexpr int kExpandedScrollbarThickness = 16;
@@ -176,11 +170,10 @@
 
 CocoaScrollBar::CocoaScrollBar(bool horizontal)
     : ScrollBar(horizontal),
-      hide_scrollbar_timer_(
-          FROM_HERE,
-          base::TimeDelta::FromMilliseconds(kScrollbarHideTimeoutMs),
-          base::BindRepeating(&CocoaScrollBar::HideScrollbar,
-                              base::Unretained(this))),
+      hide_scrollbar_timer_(FROM_HERE,
+                            base::TimeDelta::FromMilliseconds(500),
+                            base::BindRepeating(&CocoaScrollBar::HideScrollbar,
+                                                base::Unretained(this))),
       thickness_animation_(this),
       last_contents_scroll_offset_(0),
       is_expanded_(false),
@@ -483,8 +476,7 @@
   did_start_dragging_ = false;
 
   ui::ScopedLayerAnimationSettings animation(layer()->GetAnimator());
-  animation.SetTransitionDuration(
-      base::TimeDelta::FromMilliseconds(kFadeDurationMs));
+  animation.SetTransitionDuration(base::TimeDelta::FromMilliseconds(240));
   animation.AddObserver(this);
   layer()->SetOpacity(0.0f);
 }
diff --git a/ui/views/controls/tabbed_pane/tabbed_pane.cc b/ui/views/controls/tabbed_pane/tabbed_pane.cc
index 905c9144..791e7650 100644
--- a/ui/views/controls/tabbed_pane/tabbed_pane.cc
+++ b/ui/views/controls/tabbed_pane/tabbed_pane.cc
@@ -52,8 +52,6 @@
 constexpr SkColor kTabHighlightBackgroundColor_Focused =
     SkColorSetARGB(0xFF, 0xD2, 0xE3, 0xFC);
 constexpr int kTabHighlightBorderRadius = 32;
-constexpr int kTabHighlightPreferredHeight = 32;
-constexpr int kTabHighlightPreferredWidth = 192;
 
 constexpr gfx::Font::Weight kHoverWeightBorder = gfx::Font::Weight::NORMAL;
 constexpr gfx::Font::Weight kHoverWeightHighlight = gfx::Font::Weight::MEDIUM;
@@ -65,7 +63,6 @@
 constexpr int kLabelFontSizeDeltaHighlight = 1;
 
 constexpr int kHarmonyTabStripTabHeight = 32;
-constexpr int kBorderThickness = 2;
 
 }  // namespace
 
@@ -139,17 +136,11 @@
   if (is_vertical)
     title_label->SetHorizontalAlignment(gfx::HorizontalAlignment::ALIGN_LEFT);
 
-  if (is_highlight_style && is_vertical) {
-    constexpr int kTabVerticalPadding = 8;
-    constexpr int kTabHorizontalPadding = 32;
-    SetBorder(CreateEmptyBorder(gfx::Insets(
-        kTabVerticalPadding, kTabHorizontalPadding, kTabVerticalPadding, 0)));
-  } else {
-    constexpr int kTabVerticalPadding = 5;
-    constexpr int kTabHorizontalPadding = 10;
-    SetBorder(CreateEmptyBorder(
-        gfx::Insets(kTabVerticalPadding, kTabHorizontalPadding)));
-  }
+  constexpr auto kTabPadding = gfx::Insets(5, 10);
+  constexpr auto kTabPaddingVerticalHighlight = gfx::Insets(8, 32, 8, 0);
+  SetBorder(CreateEmptyBorder((is_highlight_style && is_vertical)
+                                  ? kTabPaddingVerticalHighlight
+                                  : kTabPadding));
   SetLayoutManager(std::make_unique<FillLayout>());
   SetState(State::kInactive);
   // Calculate the size while the font list is normal and set the max size.
@@ -264,8 +255,8 @@
   size.Enlarge(GetInsets().width(), GetInsets().height());
   if (tabbed_pane_->GetStyle() == TabbedPane::TabStripStyle::kHighlight &&
       tabbed_pane_->GetOrientation() == TabbedPane::Orientation::kVertical) {
-    size.SetToMax(
-        gfx::Size(kTabHighlightPreferredWidth, kTabHighlightPreferredHeight));
+    constexpr gfx::Size kTabHighlightPreferredSize = gfx::Size(192, 32);
+    size.SetToMax(kTabHighlightPreferredSize);
   }
   return size;
 }
@@ -361,7 +352,8 @@
              View* contents)
     : Tab(tabbed_pane, title, contents) {
   if (tabbed_pane->GetOrientation() == TabbedPane::Orientation::kHorizontal) {
-    SetBorder(CreateEmptyBorder(gfx::Insets(kBorderThickness)));
+    constexpr auto kBorderThickness = gfx::Insets(2);
+    SetBorder(CreateEmptyBorder(kBorderThickness));
   }
   OnStateChanged();
 }
@@ -432,17 +424,15 @@
     : orientation_(orientation), style_(style) {
   std::unique_ptr<BoxLayout> layout;
   if (orientation == TabbedPane::Orientation::kHorizontal) {
-    constexpr int kTabStripLeadingEdgePadding = 9;
-    layout = std::make_unique<BoxLayout>(
-        BoxLayout::Orientation::kHorizontal,
-        gfx::Insets(0, kTabStripLeadingEdgePadding));
+    constexpr auto kEdgePadding = gfx::Insets(0, 9);
+    layout = std::make_unique<BoxLayout>(BoxLayout::Orientation::kHorizontal,
+                                         kEdgePadding);
     layout->set_cross_axis_alignment(BoxLayout::CrossAxisAlignment::kEnd);
   } else {
-    constexpr int kTabStripEdgePadding = 8;
+    constexpr auto kEdgePadding = gfx::Insets(8, 0, 0, 0);
     constexpr int kTabSpacing = 8;
-    layout = std::make_unique<BoxLayout>(
-        BoxLayout::Orientation::kVertical,
-        gfx::Insets(kTabStripEdgePadding, 0, 0, 0), kTabSpacing);
+    layout = std::make_unique<BoxLayout>(BoxLayout::Orientation::kVertical,
+                                         kEdgePadding, kTabSpacing);
     layout->set_cross_axis_alignment(BoxLayout::CrossAxisAlignment::kStart);
   }
   layout->set_main_axis_alignment(BoxLayout::MainAxisAlignment::kStart);
diff --git a/ui/views/controls/throbber.cc b/ui/views/controls/throbber.cc
index 90231f3..eae46f9 100644
--- a/ui/views/controls/throbber.cc
+++ b/ui/views/controls/throbber.cc
@@ -21,10 +21,10 @@
 
 // The default diameter of a Throbber. If you change this, also change
 // kCheckmarkDipSize.
-static constexpr int kDefaultDiameter = 16;
+constexpr int kDefaultDiameter = 16;
 // The size of the checkmark, in DIP. This magic number matches the default
-// diamater plus padding inherent in the checkmark SVG.
-static constexpr int kCheckmarkDipSize = 18;
+// diameter plus padding inherent in the checkmark SVG.
+constexpr int kCheckmarkDipSize = kDefaultDiameter + 2;
 
 Throbber::Throbber() = default;
 
@@ -37,9 +37,8 @@
     return;
 
   start_time_ = base::TimeTicks::Now();
-  constexpr int kFrameTimeMs = 30;
   timer_.Start(
-      FROM_HERE, base::TimeDelta::FromMilliseconds(kFrameTimeMs),
+      FROM_HERE, base::TimeDelta::FromMilliseconds(30),
       base::BindRepeating(&Throbber::SchedulePaint, base::Unretained(this)));
   SchedulePaint();  // paint right away
 }
diff --git a/ui/views/layout/flex_layout_unittest.cc b/ui/views/layout/flex_layout_unittest.cc
index b062f6d..534fec36 100644
--- a/ui/views/layout/flex_layout_unittest.cc
+++ b/ui/views/layout/flex_layout_unittest.cc
@@ -117,12 +117,12 @@
 
  protected:
   // Constants re-used in many tests.
-  static const Insets kSmallInsets;
-  static const Insets kLayoutInsets;
-  static const Insets kLargeInsets;
-  static const Size kChild1Size;
-  static const Size kChild2Size;
-  static const Size kChild3Size;
+  static constexpr Insets kSmallInsets = Insets(1, 2, 3, 4);
+  static constexpr Insets kLayoutInsets = Insets(5, 6, 7, 9);
+  static constexpr Insets kLargeInsets = Insets(10, 11, 12, 13);
+  static constexpr Size kChild1Size = Size(12, 10);
+  static constexpr Size kChild2Size = Size(13, 11);
+  static constexpr Size kChild3Size = Size(17, 13);
 
   // Preferred size or drop out.
   static const FlexSpecification kDropOut;
@@ -149,12 +149,13 @@
   FlexLayout* layout_;
 };
 
-const Insets FlexLayoutTest::kSmallInsets{1, 2, 3, 4};
-const Insets FlexLayoutTest::kLayoutInsets{5, 6, 7, 9};
-const Insets FlexLayoutTest::kLargeInsets{10, 11, 12, 13};
-const Size FlexLayoutTest::kChild1Size{12, 10};
-const Size FlexLayoutTest::kChild2Size{13, 11};
-const Size FlexLayoutTest::kChild3Size{17, 13};
+// static
+constexpr Insets FlexLayoutTest::kSmallInsets;
+constexpr Insets FlexLayoutTest::kLayoutInsets;
+constexpr Insets FlexLayoutTest::kLargeInsets;
+constexpr Size FlexLayoutTest::kChild1Size;
+constexpr Size FlexLayoutTest::kChild2Size;
+constexpr Size FlexLayoutTest::kChild3Size;
 
 const FlexSpecification FlexLayoutTest::kDropOut =
     FlexSpecification::ForSizeRule(MinimumFlexSizeRule::kPreferredSnapToZero,
@@ -2035,22 +2036,21 @@
 
  protected:
   static constexpr size_t kNumChildren = 3;
-  static const gfx::Size kHostSize;
-  static const gfx::Size kChildSizes[kNumChildren];
-  static const gfx::Insets kChildMargins[kNumChildren];
+  static constexpr gfx::Size kHostSize = gfx::Size(200, 20);
+  static constexpr gfx::Size kChildSizes[kNumChildren] = {{10, 10},
+                                                          {10, 10},
+                                                          {10, 30}};
+  static constexpr gfx::Insets kChildMargins[kNumChildren] = {{6, 0, 2, 0},
+                                                              {10, 0, 5, 0},
+                                                              {6, 0, 2, 0}};
 
   std::vector<View*> child_views_;
 };
 
-const gfx::Size FlexLayoutCrossAxisFitTest::kHostSize{200, 20};
-
-const gfx::Size FlexLayoutCrossAxisFitTest::kChildSizes[]{{10, 10},
-                                                          {10, 10},
-                                                          {10, 30}};
-
-const gfx::Insets FlexLayoutCrossAxisFitTest::kChildMargins[]{{6, 0, 2, 0},
-                                                              {10, 0, 5, 0},
-                                                              {6, 0, 2, 0}};
+// static
+constexpr gfx::Size FlexLayoutCrossAxisFitTest::kHostSize;
+constexpr gfx::Size FlexLayoutCrossAxisFitTest::kChildSizes[kNumChildren];
+constexpr gfx::Insets FlexLayoutCrossAxisFitTest::kChildMargins[kNumChildren];
 
 TEST_F(FlexLayoutCrossAxisFitTest, Layout_CrossStretch) {
   layout_->SetCrossAxisAlignment(LayoutAlignment::kStretch);
diff --git a/ui/views/mouse_constants.h b/ui/views/mouse_constants.h
index 957eee3..ce8e6de 100644
--- a/ui/views/mouse_constants.h
+++ b/ui/views/mouse_constants.h
@@ -5,18 +5,14 @@
 #ifndef UI_VIEWS_MOUSE_CONSTANTS_H_
 #define UI_VIEWS_MOUSE_CONSTANTS_H_
 
+#include "base/time/time.h"
 
 namespace views {
 
-// The amount of time the mouse should be down before a mouse release is
-// considered intentional. This is to prevent spurious mouse releases from
-// activating controls, especially when some UI element is revealed under the
-// source of the activation (ex. menus showing underneath menu buttons).
-constexpr int kMinimumMsPressedToActivate = 200;
-
 // The amount of time, in milliseconds, between clicks until they're
 // considered intentionally different.
-constexpr int kMinimumMsBetweenButtonClicks = 100;
+constexpr auto kMinimumTimeBetweenButtonClicks =
+    base::TimeDelta::FromMilliseconds(100);
 
 }  // namespace views
 
diff --git a/ui/views/mouse_watcher.cc b/ui/views/mouse_watcher.cc
index c13daf4..ff3ba92 100644
--- a/ui/views/mouse_watcher.cc
+++ b/ui/views/mouse_watcher.cc
@@ -22,7 +22,7 @@
 
 // Amount of time between when the mouse moves outside the Host's zone and when
 // the listener is notified.
-constexpr int kNotifyListenerTimeMs = 300;
+constexpr auto kNotifyListenerTime = base::TimeDelta::FromMilliseconds(300);
 
 class MouseWatcher::Observer : public ui::EventObserver {
  public:
@@ -72,7 +72,7 @@
             base::BindOnce(&Observer::NotifyListener,
                            notify_listener_factory_.GetWeakPtr()),
             event_type == EventType::kMove
-                ? base::TimeDelta::FromMilliseconds(kNotifyListenerTimeMs)
+                ? kNotifyListenerTime
                 : mouse_watcher_->notify_on_exit_time_);
       }
     } else {
@@ -105,8 +105,7 @@
                            MouseWatcherListener* listener)
     : host_(std::move(host)),
       listener_(listener),
-      notify_on_exit_time_(
-          base::TimeDelta::FromMilliseconds(kNotifyListenerTimeMs)) {}
+      notify_on_exit_time_(kNotifyListenerTime) {}
 
 MouseWatcher::~MouseWatcher() = default;
 
diff --git a/ui/views/repeat_controller.cc b/ui/views/repeat_controller.cc
index fcd75ad..5cabeac2 100644
--- a/ui/views/repeat_controller.cc
+++ b/ui/views/repeat_controller.cc
@@ -10,11 +10,6 @@
 
 namespace views {
 
-// The delay before the first and then subsequent repeats. Values taken from
-// XUL code: http://mxr.mozilla.org/seamonkey/source/layout/xul/base/src/nsRepeatService.cpp#52
-constexpr int kInitialRepeatDelay = 250;
-constexpr int kRepeatDelay = 50;
-
 ///////////////////////////////////////////////////////////////////////////////
 // RepeatController, public:
 
@@ -25,8 +20,8 @@
 
 void RepeatController::Start() {
   // The first timer is slightly longer than subsequent repeats.
-  timer_.Start(FROM_HERE, TimeDelta::FromMilliseconds(kInitialRepeatDelay),
-               this, &RepeatController::Run);
+  timer_.Start(FROM_HERE, TimeDelta::FromMilliseconds(250), this,
+               &RepeatController::Run);
 }
 
 void RepeatController::Stop() {
@@ -37,7 +32,7 @@
 // RepeatController, private:
 
 void RepeatController::Run() {
-  timer_.Start(FROM_HERE, TimeDelta::FromMilliseconds(kRepeatDelay), this,
+  timer_.Start(FROM_HERE, TimeDelta::FromMilliseconds(50), this,
                &RepeatController::Run);
   callback_.Run();
 }
diff --git a/ui/views/touchui/touch_selection_controller_impl.cc b/ui/views/touchui/touch_selection_controller_impl.cc
index 77727f2..f77cfc7 100644
--- a/ui/views/touchui/touch_selection_controller_impl.cc
+++ b/ui/views/touchui/touch_selection_controller_impl.cc
@@ -62,10 +62,6 @@
 constexpr int kSelectionHandleHorizPadding = 10;
 constexpr int kSelectionHandleVertPadding = 20;
 
-constexpr int kQuickMenuTimoutMs = 200;
-
-constexpr int kSelectionHandleQuickFadeDurationMs = 50;
-
 // Minimum height for selection handle bar. If the bar height is going to be
 // less than this value, handle will not be shown.
 constexpr int kSelectionHandleBarMinHeight = 5;
@@ -305,8 +301,7 @@
     if (widget_->IsVisible() == visible)
       return;
     widget_->SetVisibilityAnimationDuration(
-        base::TimeDelta::FromMilliseconds(
-            quick ? kSelectionHandleQuickFadeDurationMs : 0));
+        quick ? base::TimeDelta::FromMilliseconds(50) : base::TimeDelta());
     if (visible)
       widget_->Show();
     else
@@ -664,11 +659,9 @@
 void TouchSelectionControllerImpl::StartQuickMenuTimer() {
   if (quick_menu_timer_.IsRunning())
     return;
-  quick_menu_timer_.Start(
-      FROM_HERE,
-      base::TimeDelta::FromMilliseconds(kQuickMenuTimoutMs),
-      this,
-      &TouchSelectionControllerImpl::QuickMenuTimerFired);
+  quick_menu_timer_.Start(FROM_HERE, base::TimeDelta::FromMilliseconds(200),
+                          this,
+                          &TouchSelectionControllerImpl::QuickMenuTimerFired);
 }
 
 void TouchSelectionControllerImpl::UpdateQuickMenu() {
diff --git a/ui/views/touchui/touch_selection_menu_views.cc b/ui/views/touchui/touch_selection_menu_views.cc
index 1081c83..3ec8e90e 100644
--- a/ui/views/touchui/touch_selection_menu_views.cc
+++ b/ui/views/touchui/touch_selection_menu_views.cc
@@ -27,12 +27,6 @@
 
 constexpr int kMenuCommands[] = {IDS_APP_CUT, IDS_APP_COPY, IDS_APP_PASTE};
 constexpr int kSpacingBetweenButtons = 2;
-constexpr int kButtonSeparatorColor = SkColorSetARGB(13, 0, 0, 0);
-constexpr int kMenuButtonMinHeight = 38;
-constexpr int kMenuButtonMinWidth = 63;
-constexpr int kMenuMargin = 1;
-
-constexpr char kEllipsesButtonText[] = "...";
 constexpr int kEllipsesButtonTag = -1;
 
 }  // namespace
@@ -49,7 +43,8 @@
 
   set_shadow(BubbleBorder::SMALL_SHADOW);
   set_parent_window(context);
-  set_margins(gfx::Insets(kMenuMargin, kMenuMargin, kMenuMargin, kMenuMargin));
+  constexpr gfx::Insets kMenuMargins = gfx::Insets(1);
+  set_margins(kMenuMargins);
   SetCanActivate(false);
   set_adjust_if_offscreen(true);
   EnableCanvasFlippingForRTLUI(true);
@@ -127,8 +122,7 @@
   }
 
   // Finally, add ellipses button.
-  AddChildView(
-      CreateButton(base::UTF8ToUTF16(kEllipsesButtonText), kEllipsesButtonTag));
+  AddChildView(CreateButton(base::ASCIIToUTF16("..."), kEllipsesButtonTag));
   InvalidateLayout();
 }
 
@@ -137,7 +131,8 @@
   base::string16 label =
       gfx::RemoveAcceleratorChar(title, '&', nullptr, nullptr);
   LabelButton* button = new LabelButton(this, label, style::CONTEXT_TOUCH_MENU);
-  button->SetMinSize(gfx::Size(kMenuButtonMinWidth, kMenuButtonMinHeight));
+  constexpr gfx::Size kMenuButtonMinSize = gfx::Size(63, 38);
+  button->SetMinSize(kMenuButtonMinSize);
   button->SetFocusForPlatform();
   button->SetHorizontalAlignment(gfx::ALIGN_CENTER);
   button->set_tag(tag);
@@ -159,6 +154,7 @@
   for (auto i = children().cbegin(); i != std::prev(children().cend()); ++i) {
     const View* child = *i;
     int x = child->bounds().right() + kSpacingBetweenButtons / 2;
+    constexpr SkColor kButtonSeparatorColor = SkColorSetA(SK_ColorBLACK, 13);
     canvas->FillRect(gfx::Rect(x, 0, 1, child->height()),
                      kButtonSeparatorColor);
   }
diff --git a/ui/views/widget/desktop_aura/desktop_drag_drop_client_aurax11.cc b/ui/views/widget/desktop_aura/desktop_drag_drop_client_aurax11.cc
index 8deeff4618..be91014 100644
--- a/ui/views/widget/desktop_aura/desktop_drag_drop_client_aurax11.cc
+++ b/ui/views/widget/desktop_aura/desktop_drag_drop_client_aurax11.cc
@@ -180,21 +180,12 @@
   return modifiers;
 }
 
-// The time to wait for the target to respond after the user has released the
-// mouse button before ending the move loop.
-const int kEndMoveLoopTimeoutMs = 1000;
-
-// The time to wait since sending the last XdndPosition message before
-// reprocessing the most recent mouse move event in case that the window
-// stacking order has changed and |source_current_window_| needs to be updated.
-const int kRepeatMouseMoveTimeoutMs = 350;
-
 // The minimum alpha before we declare a pixel transparent when searching in
 // our source image.
-const uint32_t kMinAlpha = 32;
+constexpr uint32_t kMinAlpha = 32;
 
 // |drag_widget_|'s opacity.
-const float kDragWidgetOpacity = .75f;
+constexpr float kDragWidgetOpacity = .75f;
 
 static base::LazyInstance<
     std::map<::Window, views::DesktopDragDropClientAuraX11*> >::Leaky
@@ -1021,11 +1012,8 @@
 }
 
 void DesktopDragDropClientAuraX11::StartEndMoveLoopTimer() {
-  end_move_loop_timer_.Start(FROM_HERE,
-                             base::TimeDelta::FromMilliseconds(
-                                 kEndMoveLoopTimeoutMs),
-                             this,
-                             &DesktopDragDropClientAuraX11::EndMoveLoop);
+  end_move_loop_timer_.Start(FROM_HERE, base::TimeDelta::FromMilliseconds(1000),
+                             this, &DesktopDragDropClientAuraX11::EndMoveLoop);
 }
 
 void DesktopDragDropClientAuraX11::EndMoveLoop() {
@@ -1239,7 +1227,7 @@
   // the Xdnd protocol both recommend that drag events should be sent
   // periodically.
   repeat_mouse_move_timer_.Start(
-      FROM_HERE, base::TimeDelta::FromMilliseconds(kRepeatMouseMoveTimeoutMs),
+      FROM_HERE, base::TimeDelta::FromMilliseconds(350),
       base::BindOnce(&DesktopDragDropClientAuraX11::ProcessMouseMove,
                      base::Unretained(this), screen_point, event_time));
 }
diff --git a/ui/views/widget/desktop_aura/desktop_drag_drop_client_aurax11_unittest.cc b/ui/views/widget/desktop_aura/desktop_drag_drop_client_aurax11_unittest.cc
index 98cf507..e81a78ca5 100644
--- a/ui/views/widget/desktop_aura/desktop_drag_drop_client_aurax11_unittest.cc
+++ b/ui/views/widget/desktop_aura/desktop_drag_drop_client_aurax11_unittest.cc
@@ -132,8 +132,8 @@
  public:
   // The location in screen coordinates used for the synthetic mouse moves
   // generated in SetTopmostXWindowAndMoveMouse().
-  static const int kMouseMoveX;
-  static const int kMouseMoveY;
+  static constexpr int kMouseMoveX = 100;
+  static constexpr int kMouseMoveY = 200;
 
   TestDragDropClient(aura::Window* window,
                      DesktopNativeCursorManager* cursor_manager);
@@ -279,12 +279,6 @@
 ///////////////////////////////////////////////////////////////////////////////
 // TestDragDropClient
 
-// static
-const int TestDragDropClient::kMouseMoveX = 100;
-
-// static
-const int TestDragDropClient::kMouseMoveY = 200;
-
 TestDragDropClient::TestDragDropClient(
     aura::Window* window,
     DesktopNativeCursorManager* cursor_manager)
diff --git a/ui/views/win/hwnd_message_handler.cc b/ui/views/win/hwnd_message_handler.cc
index dd4b2c6..0fa5dab 100644
--- a/ui/views/win/hwnd_message_handler.cc
+++ b/ui/views/win/hwnd_message_handler.cc
@@ -320,7 +320,8 @@
   }
 }
 
-constexpr int kTouchDownContextResetTimeout = 500;
+constexpr auto kTouchDownContextResetTimeout =
+    base::TimeDelta::FromMilliseconds(500);
 
 // Windows does not flag synthesized mouse messages from touch or pen in all
 // cases. This causes us grief as we don't want to process touch and mouse
@@ -2624,7 +2625,7 @@
             FROM_HERE,
             base::BindOnce(&HWNDMessageHandler::ResetTouchDownContext,
                            msg_handler_weak_factory_.GetWeakPtr()),
-            base::TimeDelta::FromMilliseconds(kTouchDownContextResetTimeout));
+            kTouchDownContextResetTimeout);
       } else {
         if (input[i].dwFlags & TOUCHEVENTF_MOVE) {
           GenerateTouchEvent(ui::ET_TOUCH_MOVED, touch_point, touch_id,
@@ -3034,7 +3035,7 @@
         FROM_HERE,
         base::BindOnce(&HWNDMessageHandler::ResetTouchDownContext,
                        msg_handler_weak_factory_.GetWeakPtr()),
-        base::TimeDelta::FromMilliseconds(kTouchDownContextResetTimeout));
+        kTouchDownContextResetTimeout);
   }
 
   POINTER_INFO pointer_info = pointer_touch_info.pointerInfo;
diff --git a/ui/webui/resources/cr_components/chromeos/quick_unlock/pin_keyboard.js b/ui/webui/resources/cr_components/chromeos/quick_unlock/pin_keyboard.js
index 803cef7..7f9ad440 100644
--- a/ui/webui/resources/cr_components/chromeos/quick_unlock/pin_keyboard.js
+++ b/ui/webui/resources/cr_components/chromeos/quick_unlock/pin_keyboard.js
@@ -64,9 +64,15 @@
   154,  // LaunchControlPanel, aka system tray menu
 ]);
 
-/** @return {boolean} */
-function receivedFocusFromKeyboard() {
-  return !!document.querySelector('html.focus-outline-visible');
+/**
+ * @param {!Event} event
+ * @return {boolean}
+ */
+function receivedEventFromKeyboard(event) {
+  if (!event.detail || !event.detail.sourceEvent) {
+    return false;
+  }
+  return event.detail.sourceEvent.detail === 0;
 }
 
 Polymer({
@@ -250,7 +256,7 @@
 
   /**
    * Called when a keypad number has been tapped.
-   * @param {Event} event The event object.
+   * @param {!Event} event The event object.
    * @private
    */
   onNumberTap_: function(event) {
@@ -266,7 +272,7 @@
     // button, therefore we transfer focus back to the input, but if a number
     // button is tabbed into, it should keep focus, so users can use tab and
     // spacebar/return to enter their PIN.
-    if (!receivedFocusFromKeyboard()) {
+    if (!receivedEventFromKeyboard(event)) {
       this.focusInput(selectionStart + 1, selectionStart + 1);
     }
     event.stopImmediatePropagation();
@@ -319,11 +325,11 @@
    * onBackspacePointerUp_ will handle the events if they come from mouse or
    * touch. Note: This does not support repeatedly backspacing by holding down
    * the space or enter key like touch or mouse does.
-   * @param {Event} event The event object.
+   * @param {!Event} event The event object.
    * @private
    */
   onBackspaceTap_: function(event) {
-    if (!receivedFocusFromKeyboard()) {
+    if (!receivedEventFromKeyboard(event)) {
       return;
     }
 
@@ -336,7 +342,7 @@
    * Called when the user presses or touches the backspace button. Starts a
    * timer which starts an interval to repeatedly backspace the pin value until
    * the interval is cleared.
-   * @param {Event} event The event object.
+   * @param {!Event} event The event object.
    * @private
    */
   onBackspacePointerDown_: function(event) {
@@ -345,7 +351,7 @@
           setInterval(this.onPinClear_.bind(this), REPEAT_BACKSPACE_DELAY_MS);
     }.bind(this), INITIAL_BACKSPACE_DELAY_MS);
 
-    if (!receivedFocusFromKeyboard()) {
+    if (!receivedEventFromKeyboard(event)) {
       this.focusInput(this.selectionStart_, this.selectionEnd_);
     }
     event.stopImmediatePropagation();
@@ -366,7 +372,7 @@
    * Called when the user unpresses or untouches the backspace button. Stops the
    * interval callback and fires a backspace event if there is no interval
    * running.
-   * @param {Event} event The event object.
+   * @param {!Event} event The event object.
    * @private
    */
   onBackspacePointerUp_: function(event) {
@@ -381,7 +387,7 @@
     // virtual keyboard, even if focusInput() is wrapped in a setTimeout. Blur
     // the input element first to workaround this.
     this.blur();
-    if (!receivedFocusFromKeyboard()) {
+    if (!receivedEventFromKeyboard(event)) {
       this.focusInput(this.selectionStart_, this.selectionEnd_);
     }
     event.stopImmediatePropagation();
diff --git a/ui/webui/resources/cr_elements/chromeos/cr_lottie/cr_lottie.js b/ui/webui/resources/cr_elements/chromeos/cr_lottie/cr_lottie.js
index e57edee77..e0c38b3 100644
--- a/ui/webui/resources/cr_elements/chromeos/cr_lottie/cr_lottie.js
+++ b/ui/webui/resources/cr_elements/chromeos/cr_lottie/cr_lottie.js
@@ -8,6 +8,7 @@
  * Fires a 'cr-lottie-initialized' event when the animation was successfully
  * initialized.
  * Fires a 'cr-lottie-playing' event when the animation starts playing.
+ * Fires a 'cr-lottie-paused' event when the animation has paused.
  * Fires a 'cr-lottie-resized' event when the canvas the animation is being
  * drawn on is resized.
  */
@@ -26,6 +27,10 @@
       type: String,
       value: '',
     },
+    autoplay: {
+      type: Boolean,
+      value: false,
+    },
   },
 
   /** @private {?HTMLCanvasElement} */
@@ -69,6 +74,16 @@
   },
 
   /**
+   * Controls the animation based on the value of |shouldPlay|.
+   * @param {boolean} shouldPlay Will play the animation if true else pauses it.
+   */
+  setPlay: function(shouldPlay) {
+    if (this.isAnimationLoaded_) {
+      this.worker_.postMessage({control: {play: shouldPlay}});
+    }
+  },
+
+  /**
    * Initializes all the members of this polymer element.
    * @private
    */
@@ -88,7 +103,7 @@
 
     // Open animation file and start playing the animation.
     this.sendXmlHttpRequest_(
-        this.animationUrl, 'json', this.startAnimation_.bind(this));
+        this.animationUrl, 'json', this.initAnimation_.bind(this));
   },
 
   /**
@@ -157,18 +172,18 @@
   },
 
   /**
-   * Starts playing the animation on the canvas.
+   * Initializes the the animation on the web worker with the data provided.
    * @param {Object|null|string} animationData The animation that will be
    * played.
    * @private
    */
-  startAnimation_: function(animationData) {
+  initAnimation_: function(animationData) {
     this.worker_.postMessage(
         {
           canvas: this.offscreenCanvas_,
           animationData: animationData,
           drawSize: this.getCanvasDrawBufferSize_(),
-          params: {loop: true, autoplay: true}
+          params: {loop: true, autoplay: this.autoplay}
         },
         [this.offscreenCanvas_]);
   },
@@ -184,6 +199,8 @@
       this.fire('cr-lottie-initialized');
     } else if (event.data.name == 'playing') {
       this.fire('cr-lottie-playing');
+    } else if (event.data.name == 'paused') {
+      this.fire('cr-lottie-paused');
     } else if (event.data.name == 'resized') {
       this.fire('cr-lottie-resized', event.data.size);
     }
diff --git a/ui/webui/resources/cr_elements/cr_slider/cr_slider.html b/ui/webui/resources/cr_elements/cr_slider/cr_slider.html
index 256a0af..586cbaa 100644
--- a/ui/webui/resources/cr_elements/cr_slider/cr_slider.html
+++ b/ui/webui/resources/cr_elements/cr_slider/cr_slider.html
@@ -35,7 +35,7 @@
         :host {
           --cr-slider-active-color: var(--google-blue-refresh-300);
           --cr-slider-container-color:
-              rgba(var(--google-blue-refresh-500-rgb, .48));
+              rgba(var(--google-blue-refresh-500-rgb), .48);
           --cr-slider-container-disabled-color:
               rgba(var(--google-grey-600-rgb), .48);
           /* --cr-slider-disabled-color is the same in dark mode (GG600). */
diff --git a/weblayer/README.md b/weblayer/README.md
index 7f0df24..d8b2b36 100644
--- a/weblayer/README.md
+++ b/weblayer/README.md
@@ -28,3 +28,12 @@
 `common` internal code which runs in the browser and child processes
 
 `renderer` internal code which runs in the renderer process
+
+## Testing
+
+To run instrumentation tests:
+
+$ autoninja -C out/Default weblayer_instrumentation_test_apk
+$ out/Default/bin/run_weblayer_instrumentation_test_apk
+
+The test script will build and install all necessary APKs.
diff --git a/weblayer/shell/android/BUILD.gn b/weblayer/shell/android/BUILD.gn
index 3aea576..9549b9b4f 100644
--- a/weblayer/shell/android/BUILD.gn
+++ b/weblayer/shell/android/BUILD.gn
@@ -133,3 +133,21 @@
     ":weblayer_support_apk",
   ]
 }
+
+instrumentation_test_apk("weblayer_instrumentation_test_apk") {
+  apk_name = "WebLayerInstrumentationTest"
+  apk_under_test = "//weblayer/shell/android:weblayer_shell_apk"
+  android_manifest = "javatests/AndroidManifest.xml"
+  min_sdk_version = 21
+  deps = [
+    "//base:base_java_test_support",
+    "//content/public/test/android:content_java_test_support",
+    "//third_party/android_support_test_runner:runner_java",
+  ]
+  java_files = [
+    "javatests/src/org/chromium/weblayer/test/NavigationTest.java",
+    "javatests/src/org/chromium/weblayer/test/WebLayerShellActivityTestRule.java",
+    "shell_apk/src/org/chromium/weblayer/shell/WebLayerShellActivity.java",
+  ]
+  additional_apks = [ "//weblayer/shell/android:weblayer_support_apk" ]
+}
diff --git a/weblayer/shell/android/javatests/AndroidManifest.xml b/weblayer/shell/android/javatests/AndroidManifest.xml
new file mode 100644
index 0000000..b53d494c
--- /dev/null
+++ b/weblayer/shell/android/javatests/AndroidManifest.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<!-- Copyright 2019 The Chromium Authors. All rights reserved.
+
+     Use of this source code is governed by a BSD-style license that can be
+     found in the LICENSE file.
+ -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="org.chromium.weblayer.tests">
+  <uses-permission android:name="android.permission.RUN_INSTRUMENTATION" />
+  <!-- We add an application tag here just so that we can indicate that this
+       package needs to link against the android.test library, which is
+       needed when building test cases. -->
+  <application>
+      <uses-library android:name="android.test.runner" />
+      <activity android:name="org.chromium.test.broker.OnDeviceInstrumentationBroker"
+          android:exported="true"/>
+  </application>
+
+  <instrumentation android:name="org.chromium.base.test.BaseChromiumAndroidJUnitRunner"
+      android:targetPackage="org.chromium.weblayer.shell"
+      android:label="JUnit4-based tests for org.chromium.weblayer.shell" />
+</manifest>
diff --git a/weblayer/shell/android/javatests/DEPS b/weblayer/shell/android/javatests/DEPS
new file mode 100644
index 0000000..b969a40
--- /dev/null
+++ b/weblayer/shell/android/javatests/DEPS
@@ -0,0 +1,3 @@
+include_rules = [
+  "+content/public/test",
+]
diff --git a/weblayer/shell/android/javatests/src/org/chromium/weblayer/test/NavigationTest.java b/weblayer/shell/android/javatests/src/org/chromium/weblayer/test/NavigationTest.java
new file mode 100644
index 0000000..07b3dfa
--- /dev/null
+++ b/weblayer/shell/android/javatests/src/org/chromium/weblayer/test/NavigationTest.java
@@ -0,0 +1,103 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package org.chromium.weblayer.test;
+
+import android.net.Uri;
+import android.support.test.filters.SmallTest;
+
+import org.junit.Assert;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import org.chromium.base.test.BaseJUnit4ClassRunner;
+import org.chromium.base.test.util.CallbackHelper;
+import org.chromium.content_public.browser.test.util.TestThreadUtils;
+import org.chromium.weblayer.Navigation;
+import org.chromium.weblayer.NavigationObserver;
+import org.chromium.weblayer.shell.WebLayerShellActivity;
+
+import java.util.concurrent.TimeoutException;
+
+/**
+ * Example test that just starts the weblayer shell.
+ */
+@RunWith(BaseJUnit4ClassRunner.class)
+public class NavigationTest {
+    @Rule
+    public WebLayerShellActivityTestRule mActivityTestRule = new WebLayerShellActivityTestRule();
+
+    // URL used for base tests.
+    private static final String URL = "data:text";
+
+    private static class Observer extends NavigationObserver {
+        public static class NavigationCallbackHelper extends CallbackHelper {
+            private Uri mUri;
+
+            public void notifyCalled(Uri uri) {
+                mUri = uri;
+                notifyCalled();
+            }
+
+            public void assertCalledWith(int currentCallCount, String uri)
+                    throws TimeoutException, InterruptedException {
+                waitForCallback(currentCallCount);
+                Assert.assertEquals(mUri.toString(), uri);
+            }
+        }
+
+        public NavigationCallbackHelper onStartedCallback = new NavigationCallbackHelper();
+        public NavigationCallbackHelper onCommittedCallback = new NavigationCallbackHelper();
+        public NavigationCallbackHelper onCompletedCallback = new NavigationCallbackHelper();
+
+        @Override
+        public void navigationStarted(Navigation navigation) {
+            onStartedCallback.notifyCalled(navigation.getUri());
+        }
+
+        @Override
+        public void navigationCommitted(Navigation navigation) {
+            onCommittedCallback.notifyCalled(navigation.getUri());
+        }
+
+        @Override
+        public void navigationCompleted(Navigation navigation) {
+            onCompletedCallback.notifyCalled(navigation.getUri());
+        }
+    }
+
+    @Test
+    @SmallTest
+    public void testBaseStartup() throws Exception {
+        WebLayerShellActivity activity = mActivityTestRule.launchShellWithUrl(URL);
+
+        Assert.assertNotNull(activity);
+
+        mActivityTestRule.waitForNavigation(URL);
+    }
+
+    @Test
+    @SmallTest
+    public void testNavigationEvents() throws Exception {
+        WebLayerShellActivity activity = mActivityTestRule.launchShellWithUrl(URL);
+        mActivityTestRule.waitForNavigation(URL);
+
+        Observer observer = new Observer();
+        TestThreadUtils.runOnUiThreadBlocking(() -> {
+            activity.getBrowserController().getNavigationController().addObserver(observer);
+        });
+        int curStartedCount = observer.onStartedCallback.getCallCount();
+        int curCommittedCount = observer.onCommittedCallback.getCallCount();
+        int curCompletedCount = observer.onCompletedCallback.getCallCount();
+
+        String url = "data:text,foo";
+        mActivityTestRule.loadUrl(url);
+        mActivityTestRule.waitForNavigation(url);
+
+        observer.onStartedCallback.assertCalledWith(curStartedCount, url);
+        observer.onCommittedCallback.assertCalledWith(curCommittedCount, url);
+        observer.onCompletedCallback.assertCalledWith(curCompletedCount, url);
+    }
+}
diff --git a/weblayer/shell/android/javatests/src/org/chromium/weblayer/test/WebLayerShellActivityTestRule.java b/weblayer/shell/android/javatests/src/org/chromium/weblayer/test/WebLayerShellActivityTestRule.java
new file mode 100644
index 0000000..919310bb
--- /dev/null
+++ b/weblayer/shell/android/javatests/src/org/chromium/weblayer/test/WebLayerShellActivityTestRule.java
@@ -0,0 +1,67 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package org.chromium.weblayer.test;
+
+import android.content.ComponentName;
+import android.content.Intent;
+import android.net.Uri;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.rule.ActivityTestRule;
+
+import org.chromium.content_public.browser.test.util.Criteria;
+import org.chromium.content_public.browser.test.util.CriteriaHelper;
+import org.chromium.content_public.browser.test.util.TestThreadUtils;
+import org.chromium.weblayer.NavigationController;
+import org.chromium.weblayer.shell.WebLayerShellActivity;
+
+/**
+ * ActivityTestRule for WebLayerShellActivity.
+ *
+ * Test can use this ActivityTestRule to launch or get WebLayerShellActivity.
+ */
+public class WebLayerShellActivityTestRule extends ActivityTestRule<WebLayerShellActivity> {
+    private static final long WAIT_FOR_NAVIGATION_TIMEOUT = 10000L;
+
+    public WebLayerShellActivityTestRule() {
+        super(WebLayerShellActivity.class, false, false);
+    }
+
+    /**
+     * Starts the WebLayer activity and loads the given URL.
+     */
+    public WebLayerShellActivity launchShellWithUrl(String url) {
+        Intent intent = new Intent(Intent.ACTION_MAIN);
+        intent.addCategory(Intent.CATEGORY_LAUNCHER);
+        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+        if (url != null) intent.setData(Uri.parse(url));
+        intent.setComponent(
+                new ComponentName(InstrumentationRegistry.getInstrumentation().getTargetContext(),
+                        WebLayerShellActivity.class));
+        return launchActivity(intent);
+    }
+
+    /**
+     * Waits for the shell to navigate to the given URI.
+     */
+    public void waitForNavigation(String uri) {
+        CriteriaHelper.pollUiThread(new Criteria() {
+            @Override
+            public boolean isSatisfied() {
+                NavigationController navigationController =
+                        getActivity().getBrowserController().getNavigationController();
+                Uri currentUri = navigationController.getNavigationEntryDisplayUri(
+                        navigationController.getNavigationListCurrentIndex());
+                return currentUri.toString().equals(uri);
+            }
+        }, WAIT_FOR_NAVIGATION_TIMEOUT, CriteriaHelper.DEFAULT_POLLING_INTERVAL);
+    }
+
+    /**
+     * Loads the given URL in the shell.
+     */
+    public void loadUrl(String url) {
+        TestThreadUtils.runOnUiThreadBlocking(() -> { getActivity().loadUrl(url); });
+    }
+}
diff --git a/weblayer/shell/android/shell_apk/src/org/chromium/weblayer/shell/WebLayerShellActivity.java b/weblayer/shell/android/shell_apk/src/org/chromium/weblayer/shell/WebLayerShellActivity.java
index 8608844..10ffcab3 100644
--- a/weblayer/shell/android/shell_apk/src/org/chromium/weblayer/shell/WebLayerShellActivity.java
+++ b/weblayer/shell/android/shell_apk/src/org/chromium/weblayer/shell/WebLayerShellActivity.java
@@ -4,12 +4,14 @@
 
 package org.chromium.weblayer.shell;
 
+import android.content.Intent;
 import android.net.Uri;
 import android.os.Bundle;
 import android.support.v4.app.Fragment;
 import android.support.v4.app.FragmentActivity;
 import android.support.v4.app.FragmentTransaction;
 import android.text.InputType;
+import android.text.TextUtils;
 import android.view.KeyEvent;
 import android.view.LayoutInflater;
 import android.view.View;
@@ -52,6 +54,10 @@
         }
     }
 
+    public BrowserController getBrowserController() {
+        return mBrowserController;
+    }
+
     @Override
     protected void onCreate(final Bundle savedInstanceState) {
         // Only call init for main process.
@@ -94,7 +100,12 @@
         transaction.commit();
 
         mBrowserFragment.setTopView(mUrlView);
-        loadUrl("http://google.com");
+
+        String startupUrl = getUrlFromIntent(getIntent());
+        if (TextUtils.isEmpty(startupUrl)) {
+            startupUrl = "http://google.com";
+        }
+        loadUrl(startupUrl);
         mBrowserController.addObserver(new BrowserObserver() {
             @Override
             public void displayURLChanged(Uri uri) {
@@ -115,11 +126,15 @@
         super.onStart();
     }
 
-    private void loadUrl(String url) {
+    public void loadUrl(String url) {
         mBrowserController.getNavigationController().navigate(Uri.parse(sanitizeUrl(url)));
         mUrlView.clearFocus();
     }
 
+    private static String getUrlFromIntent(Intent intent) {
+        return intent != null ? intent.getDataString() : null;
+    }
+
     /**
      * Given an URL, this performs minimal sanitizing to ensure it will be valid.
      * @param url The url to be sanitized.