diff --git a/BUILD.gn b/BUILD.gn
index 4bec44b..5edf3f6 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -261,14 +261,9 @@
     deps += [
       "//extensions:extensions_browsertests",
       "//extensions:extensions_unittests",
+      "//extensions/browser/api/declarative_net_request/filter_list_converter",
       "//extensions/shell:app_shell_unittests",
     ]
-
-    # TODO(crbug.com/981112): This target is failing to compile consistently in
-    # coverage build, remove this condition when the bug is fixed.
-    if (!use_clang_coverage) {
-      deps += [ "//extensions/browser/api/declarative_net_request/filter_list_converter" ]
-    }
   }
 
   if (enable_remoting) {
diff --git a/DEPS b/DEPS
index 16ebd02..919ae05 100644
--- a/DEPS
+++ b/DEPS
@@ -200,11 +200,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': '888c5d3e57eb197c4d9abcc35966d9bc97f38d1d',
+  'skia_revision': '51b74afb84d4150f67668e36e95563b39cb26b5b',
   # 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': 'c38503fc1652232c4e2f897daf4501b9d98db210',
+  'v8_revision': '12af0f034a649a235be640e47205ef94d9916d4a',
   # 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.
@@ -212,7 +212,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling ANGLE
   # and whatever else without interference from each other.
-  'angle_revision': 'bb4f496d2a32aa2c872f1d998c6d12e738e72a65',
+  'angle_revision': 'bc82325e3445f76a09f720ddbc835b0d404af2b9',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling SwiftShader
   # and whatever else without interference from each other.
@@ -275,7 +275,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling devtools-frontend
   # and whatever else without interference from each other.
-  'devtools_frontend_revision': '16534e267df0a1783928b6658a0d128cfc8e3393',
+  'devtools_frontend_revision': '81585eced14ba3c79ffee8e9fb5019ccd5cd3c5c',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling libprotobuf-mutator
   # and whatever else without interference from each other.
@@ -327,7 +327,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling feed
   # and whatever else without interference from each other.
-  'dawn_revision': 'a66263753a9f31ae9fa05af4f5ef0b18924d0b8e',
+  'dawn_revision': '2b606e9297e0ef91677b280560fdeb281ca80bc1',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling feed
   # and whatever else without interference from each other.
@@ -899,7 +899,7 @@
   # Tools used when building Chrome for Chrome OS. This affects both the Simple
   # Chrome workflow, as well as the chromeos-chrome ebuild.
   'src/third_party/chromite': {
-      'url': Var('chromium_git') + '/chromiumos/chromite.git' + '@' + '740b9c2b4984ed562905324dd9f3d1fbb78688c8',
+      'url': Var('chromium_git') + '/chromiumos/chromite.git' + '@' + '9ed30bc3ed292b02d85fde89c64207484b7a3aa4',
       'condition': 'checkout_chromeos',
   },
 
@@ -1551,7 +1551,7 @@
   },
 
   'src/third_party/webrtc':
-    Var('webrtc_git') + '/src.git' + '@' + '9db3ab201ec73d5bbc547ebe2701b4695d1e281f',
+    Var('webrtc_git') + '/src.git' + '@' + '0db3396646aa4383b990678e09f8519a1d793d65',
 
   'src/third_party/libgifcodec':
      Var('skia_git') + '/libgifcodec' + '@'+  Var('libgifcodec_revision'),
@@ -1623,7 +1623,7 @@
     Var('chromium_git') + '/v8/v8.git' + '@' +  Var('v8_revision'),
 
   'src-internal': {
-    'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@1bb4e5eef6d35a46aeb7b2ed24e60aafc912af1d',
+    'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@04353ebb20053f8f5231ad769312e7c296f61178',
     'condition': 'checkout_src_internal',
   },
 
@@ -1642,7 +1642,7 @@
     'packages': [
       {
         'package': 'chromeos_internal/apps/media_app/app',
-        'version': '0KTan3JjAK3TKZLqwQfdI9v6kFtn1w-lwzUN2LIDnHQC',
+        'version': 'UEDryZf_VuC_LfcEXlTJ_7tEzVfL6qKZIy8qC-wjmbIC',
       },
     ],
     'condition': 'checkout_chromeos and checkout_src_internal',
diff --git a/PRESUBMIT.py b/PRESUBMIT.py
index 1e3fa54..6119384 100644
--- a/PRESUBMIT.py
+++ b/PRESUBMIT.py
@@ -319,6 +319,7 @@
 # checks for them and prevent regressions.
 _NOT_CONVERTED_TO_MODERN_BIND_AND_CALLBACK = '|'.join((
   '^base/callback.h',  # Intentional.
+  '^base/cancelable_callback.h',  # Intentional.
   '^chrome/browser/android/webapps/add_to_homescreen_data_fetcher_unittest.cc',
   '^chrome/browser/apps/guest_view/',
   '^chrome/browser/browsing_data/',
@@ -831,6 +832,24 @@
       (_NOT_CONVERTED_TO_MODERN_BIND_AND_CALLBACK,),
     ),
     (
+      r'/\bbase::CancelableCallback[<:]',
+      (
+          'Please use base::Cancelable{Once,Repeating}Callback instead',
+          'of base::CancelableCallback. (crbug.com/714018)',
+      ),
+      False,
+      (_NOT_CONVERTED_TO_MODERN_BIND_AND_CALLBACK,),
+    ),
+    (
+      r'/\bbase::CancelableClosure\b',
+      (
+          'Please use base::Cancelable{Once,Repeating}Closure instead',
+          'of base::CancelableClosure. (crbug.com/714018)',
+      ),
+      False,
+      (_NOT_CONVERTED_TO_MODERN_BIND_AND_CALLBACK,),
+    ),
+    (
       r'/\bRunMessageLoop\b',
       (
           'RunMessageLoop is deprecated, use RunLoop instead.',
diff --git a/ash/accessibility/DIR_METADATA b/ash/accessibility/DIR_METADATA
index 9b0c277b..85a969c 100644
--- a/ash/accessibility/DIR_METADATA
+++ b/ash/accessibility/DIR_METADATA
@@ -7,6 +7,6 @@
 #   https://source.chromium.org/chromium/infra/infra/+/HEAD:go/src/infra/tools/dirmd/proto/dir_metadata.proto
 
 monorail {
-  component: "UI>Accessibility"
+  component: "OS>Accessibility"
 }
-team_email: "chromium-accessibility@chromium.org"
\ No newline at end of file
+team_email: "chromium-accessibility@chromium.org"
diff --git a/ash/app_list/views/app_list_item_view.cc b/ash/app_list/views/app_list_item_view.cc
index 0476922..613663a 100644
--- a/ash/app_list/views/app_list_item_view.cc
+++ b/ash/app_list/views/app_list_item_view.cc
@@ -171,11 +171,11 @@
     DCHECK_EQ(width(), height());
     const float dsf = canvas->UndoDeviceScaleFactor();
 
-    int radius = width() * kNotificationIndicatorWidthRatio / 2.0f;
-    int padding = width() * kNotificationIndicatorPaddingRatio;
+    float radius = width() * kNotificationIndicatorWidthRatio / 2.0f;
+    float padding = width() * kNotificationIndicatorPaddingRatio;
 
-    int center_x = width() - radius - padding;
-    int center_y = padding + radius;
+    float center_x = width() - radius - padding;
+    float center_y = padding + radius;
     gfx::PointF center = gfx::PointF(center_x, center_y);
     center.Scale(dsf);
 
diff --git a/ash/autoclick/DIR_METADATA b/ash/autoclick/DIR_METADATA
index 9b0c277b..85a969c 100644
--- a/ash/autoclick/DIR_METADATA
+++ b/ash/autoclick/DIR_METADATA
@@ -7,6 +7,6 @@
 #   https://source.chromium.org/chromium/infra/infra/+/HEAD:go/src/infra/tools/dirmd/proto/dir_metadata.proto
 
 monorail {
-  component: "UI>Accessibility"
+  component: "OS>Accessibility"
 }
-team_email: "chromium-accessibility@chromium.org"
\ No newline at end of file
+team_email: "chromium-accessibility@chromium.org"
diff --git a/ash/high_contrast/DIR_METADATA b/ash/high_contrast/DIR_METADATA
index 9b0c277b..85a969c 100644
--- a/ash/high_contrast/DIR_METADATA
+++ b/ash/high_contrast/DIR_METADATA
@@ -7,6 +7,6 @@
 #   https://source.chromium.org/chromium/infra/infra/+/HEAD:go/src/infra/tools/dirmd/proto/dir_metadata.proto
 
 monorail {
-  component: "UI>Accessibility"
+  component: "OS>Accessibility"
 }
-team_email: "chromium-accessibility@chromium.org"
\ No newline at end of file
+team_email: "chromium-accessibility@chromium.org"
diff --git a/ash/magnifier/DIR_METADATA b/ash/magnifier/DIR_METADATA
index 9b0c277b..c00e4c80 100644
--- a/ash/magnifier/DIR_METADATA
+++ b/ash/magnifier/DIR_METADATA
@@ -7,6 +7,6 @@
 #   https://source.chromium.org/chromium/infra/infra/+/HEAD:go/src/infra/tools/dirmd/proto/dir_metadata.proto
 
 monorail {
-  component: "UI>Accessibility"
+  component: "OS>Accessibility>Magnifier"
 }
-team_email: "chromium-accessibility@chromium.org"
\ No newline at end of file
+team_email: "chromium-accessibility@chromium.org"
diff --git a/ash/sticky_keys/DIR_METADATA b/ash/sticky_keys/DIR_METADATA
index 9b0c277b..85a969c 100644
--- a/ash/sticky_keys/DIR_METADATA
+++ b/ash/sticky_keys/DIR_METADATA
@@ -7,6 +7,6 @@
 #   https://source.chromium.org/chromium/infra/infra/+/HEAD:go/src/infra/tools/dirmd/proto/dir_metadata.proto
 
 monorail {
-  component: "UI>Accessibility"
+  component: "OS>Accessibility"
 }
-team_email: "chromium-accessibility@chromium.org"
\ No newline at end of file
+team_email: "chromium-accessibility@chromium.org"
diff --git a/ash/system/accessibility/DIR_METADATA b/ash/system/accessibility/DIR_METADATA
index 9b0c277b..85a969c 100644
--- a/ash/system/accessibility/DIR_METADATA
+++ b/ash/system/accessibility/DIR_METADATA
@@ -7,6 +7,6 @@
 #   https://source.chromium.org/chromium/infra/infra/+/HEAD:go/src/infra/tools/dirmd/proto/dir_metadata.proto
 
 monorail {
-  component: "UI>Accessibility"
+  component: "OS>Accessibility"
 }
-team_email: "chromium-accessibility@chromium.org"
\ No newline at end of file
+team_email: "chromium-accessibility@chromium.org"
diff --git a/ash/system/accessibility/OWNERS b/ash/system/accessibility/OWNERS
new file mode 100644
index 0000000..976b955
--- /dev/null
+++ b/ash/system/accessibility/OWNERS
@@ -0,0 +1 @@
+file://ui/accessibility/OWNERS
diff --git a/base/allocator/partition_allocator/partition_alloc.cc b/base/allocator/partition_allocator/partition_alloc.cc
index de7eeaf1..78fa246 100644
--- a/base/allocator/partition_allocator/partition_alloc.cc
+++ b/base/allocator/partition_allocator/partition_alloc.cc
@@ -20,6 +20,7 @@
 #include "base/allocator/partition_allocator/partition_page.h"
 #include "base/allocator/partition_allocator/partition_root.h"
 #include "base/allocator/partition_allocator/partition_stats.h"
+#include "base/allocator/partition_allocator/pcscan.h"
 
 namespace base {
 
@@ -75,6 +76,8 @@
 #endif  // defined(PA_HAS_64_BITS_POINTERS)
   }
 #endif  // !BUILDFLAG(USE_PARTITION_ALLOC_AS_MALLOC)
+  internal::PCScan<internal::ThreadSafe>::Instance()
+      .ClearRootsForTesting();  // IN-TEST
   internal::g_oom_handling_function = nullptr;
 }
 
diff --git a/base/allocator/partition_allocator/partition_bucket.cc b/base/allocator/partition_allocator/partition_bucket.cc
index 08c045e..7b6afde7 100644
--- a/base/allocator/partition_allocator/partition_bucket.cc
+++ b/base/allocator/partition_allocator/partition_bucket.cc
@@ -265,7 +265,7 @@
   char* quarantine_bitmaps = super_page + PartitionPageSize();
   size_t quarantine_bitmaps_reserved_size = 0;
   size_t quarantine_bitmaps_size_to_commit = 0;
-  if (root->scannable) {
+  if (root->IsScannable()) {
     quarantine_bitmaps_reserved_size = ReservedQuarantineBitmapsSize();
     quarantine_bitmaps_size_to_commit = CommittedQuarantineBitmapsSize();
   }
@@ -276,7 +276,7 @@
   char* ret = quarantine_bitmaps + quarantine_bitmaps_reserved_size;
   root->next_partition_page = ret + slot_span_reserved_size;
   root->next_partition_page_end = root->next_super_page - PartitionPageSize();
-  PA_DCHECK(ret == SuperPagePayloadBegin(super_page, root->scannable));
+  PA_DCHECK(ret == SuperPagePayloadBegin(super_page, root->IsScannable()));
   PA_DCHECK(root->next_partition_page_end == SuperPagePayloadEnd(super_page));
 
   // The first slot span is accessible. The given slot_span_committed_size is
@@ -306,8 +306,8 @@
   // unused part of partition page, if any. If PCScan isn't used, release the
   // entire reserved region (PartitionRoot::EnablePCScan will be responsible
   // for committing it when enabling PCScan).
-  if (root->pcscan.has_value()) {
-    PA_DCHECK(root->scannable);
+  if (root->IsScanEnabled()) {
+    PA_DCHECK(root->IsScannable());
     if (quarantine_bitmaps_reserved_size > quarantine_bitmaps_size_to_commit) {
       SetSystemPagesAccess(
           quarantine_bitmaps + quarantine_bitmaps_size_to_commit,
@@ -317,7 +317,7 @@
   } else {
     // If partition isn't scannable, no quarantine bitmaps were reserved, hence
     // nothing to decommit.
-    if (root->scannable) {
+    if (root->IsScannable()) {
       PA_DCHECK(quarantine_bitmaps_reserved_size > 0);
       SetSystemPagesAccess(quarantine_bitmaps, quarantine_bitmaps_reserved_size,
                            PageInaccessible);
diff --git a/base/allocator/partition_allocator/partition_page.h b/base/allocator/partition_allocator/partition_page.h
index 8231285..9f6f5d4 100644
--- a/base/allocator/partition_allocator/partition_page.h
+++ b/base/allocator/partition_allocator/partition_page.h
@@ -291,8 +291,8 @@
       reinterpret_cast<uintptr_t>(maybe_inner_ptr) & kSuperPageBaseMask);
   auto* extent = reinterpret_cast<PartitionSuperPageExtentEntry<thread_safe>*>(
       PartitionSuperPageToMetadataArea(super_page_ptr));
-  PA_DCHECK(IsWithinSuperPagePayload(maybe_inner_ptr,
-                                     extent->root->pcscan.has_value()));
+  PA_DCHECK(
+      IsWithinSuperPagePayload(maybe_inner_ptr, extent->root->IsScanEnabled()));
   auto* slot_span = SlotSpanMetadata<thread_safe>::FromPointerNoAlignmentCheck(
       maybe_inner_ptr);
   // Check if the slot span is actually used and valid.
diff --git a/base/allocator/partition_allocator/partition_root.cc b/base/allocator/partition_allocator/partition_root.cc
index f0a6b91..ae8cae6 100644
--- a/base/allocator/partition_allocator/partition_root.cc
+++ b/base/allocator/partition_allocator/partition_root.cc
@@ -14,6 +14,22 @@
 
 namespace base {
 
+namespace {
+template <bool thread_safe>
+typename PartitionRoot<thread_safe>::PCScanMode PartitionOptionsToPCScanMode(
+    PartitionOptions::PCScan opt) {
+  using Root = PartitionRoot<thread_safe>;
+  switch (opt) {
+    case PartitionOptions::PCScan::kAlwaysDisabled:
+      return Root::PCScanMode::kNonScannable;
+    case PartitionOptions::PCScan::kDisabledByDefault:
+      return Root::PCScanMode::kDisabled;
+    case PartitionOptions::PCScan::kForcedEnabledForTesting:
+      return Root::PCScanMode::kEnabled;
+  }
+}
+}  // namespace
+
 namespace internal {
 
 template <bool thread_safe>
@@ -381,12 +397,13 @@
   extras_size = static_cast<uint32_t>(size);
   extras_offset = static_cast<uint32_t>(offset);
 
-  scannable = (opts.pcscan != PartitionOptions::PCScan::kAlwaysDisabled);
-  // Concurrent freeing in PCScan can only safely work on thread-safe
-  // partitions.
-  if (thread_safe &&
-      opts.pcscan == PartitionOptions::PCScan::kForcedEnabledForTesting)
-    pcscan.emplace(this);
+  pcscan_mode = PartitionOptionsToPCScanMode<thread_safe>(opts.pcscan);
+  if (pcscan_mode == PCScanMode::kEnabled) {
+    // Concurrent freeing in PCScan can only safely work on thread-safe
+    // partitions.
+    PA_CHECK(thread_safe);
+    PCScan::Instance().RegisterRoot(this);
+  }
 
   // We mark the sentinel slot span as free to make sure it is skipped by our
   // logic to find a new active slot span.
@@ -618,9 +635,8 @@
 template <bool thread_safe>
 void PartitionRoot<thread_safe>::PurgeMemory(int flags) {
   // TODO(chromium:1129751): Change to LIKELY once PCScan is enabled by default.
-  if (UNLIKELY(pcscan) && (flags & PartitionPurgeForceAllFreed)) {
-    pcscan->PerformScanIfNeeded(
-        internal::PCScan<thread_safe>::InvocationMode::kBlocking);
+  if (UNLIKELY(IsScanEnabled()) && (flags & PartitionPurgeForceAllFreed)) {
+    PCScan::Instance().PerformScanIfNeeded(PCScan::InvocationMode::kBlocking);
   }
 
   {
@@ -702,7 +718,7 @@
     stats.total_resident_bytes += direct_mapped_allocations_total_size;
     stats.total_active_bytes += direct_mapped_allocations_total_size;
 
-    stats.has_thread_cache = !is_light_dump && with_thread_cache;
+    stats.has_thread_cache = with_thread_cache;
     if (stats.has_thread_cache) {
       internal::ThreadCacheRegistry::Instance().DumpStats(
           true, &stats.current_thread_cache_stats);
diff --git a/base/allocator/partition_allocator/partition_root.h b/base/allocator/partition_allocator/partition_root.h
index a924775f..38d5493 100644
--- a/base/allocator/partition_allocator/partition_root.h
+++ b/base/allocator/partition_allocator/partition_root.h
@@ -129,14 +129,19 @@
       internal::PartitionSuperPageExtentEntry<thread_safe>;
   using DirectMapExtent = internal::PartitionDirectMapExtent<thread_safe>;
   using ScopedGuard = internal::ScopedGuard<thread_safe>;
-  using PCScan = base::Optional<internal::PCScan<thread_safe>>;
+  using PCScan = internal::PCScan<thread_safe>;
 
   internal::MaybeSpinLock<thread_safe> lock_;
 
+  enum class PCScanMode : uint8_t {
+    kNonScannable,
+    kDisabled,
+    kEnabled,
+  } pcscan_mode = PCScanMode::kNonScannable;
+
   // Flags accessed on fast paths.
   bool with_thread_cache = false;
   const bool is_thread_safe = thread_safe;
-  bool scannable = false;
   bool initialized = false;
 
   bool allow_extras;
@@ -171,7 +176,6 @@
 
   // Integrity check = ~reinterpret_cast<uintptr_t>(this).
   uintptr_t inverted_self = 0;
-  PCScan pcscan;
 
   // The bucket lookup table lets us map a size_t to a bucket quickly.
   // The trailing +1 caters for the overflow case for very large allocation
@@ -203,6 +207,8 @@
 
   ALWAYS_INLINE static bool IsValidSlotSpan(SlotSpan* slot_span);
   ALWAYS_INLINE static PartitionRoot* FromSlotSpan(SlotSpan* slot_span);
+  ALWAYS_INLINE static PartitionRoot* FromSuperPage(char* super_page);
+  ALWAYS_INLINE static PartitionRoot* FromPointerInNormalBucketPool(char* ptr);
 
   ALWAYS_INLINE void IncreaseCommittedPages(size_t len);
   ALWAYS_INLINE void DecreaseCommittedPages(size_t len);
@@ -284,14 +290,21 @@
     return features::IsPartitionAllocGigaCageEnabled() && allow_extras;
   }
 
+  ALWAYS_INLINE bool IsScannable() const {
+    return pcscan_mode != PCScanMode::kNonScannable;
+  }
+
+  ALWAYS_INLINE bool IsScanEnabled() const {
+    return pcscan_mode == PCScanMode::kEnabled;
+  }
+
+  // Enables PCScan for this root.
   void EnablePCScan() {
     PA_CHECK(thread_safe);
-    PA_CHECK(scannable && !pcscan.has_value());
-    // Setting |pcscan| and committing bitmaps has to be done under the lock to
-    // avoid racing with PartitionBucket::AllocNewSlotSpan and avoid racing on
-    // |pcscan| ifself during free calls.
-    internal::ScopedGuard<thread_safe> guard{lock_};
-    pcscan.emplace(this);
+    PA_CHECK(IsScannable() && !IsScanEnabled());
+    ScopedGuard guard{lock_};
+    PCScan::Instance().RegisterRoot(this);
+    pcscan_mode = PCScanMode::kEnabled;
   }
 
   static PAGE_ALLOCATOR_CONSTANTS_DECLARE_CONSTEXPR ALWAYS_INLINE size_t
@@ -576,9 +589,9 @@
 
   // TODO(bikineev): Change the first condition to LIKELY once PCScan is enabled
   // by default.
-  if (UNLIKELY(root->pcscan) &&
+  if (UNLIKELY(root->IsScanEnabled()) &&
       LIKELY(!slot_span->bucket->is_direct_mapped())) {
-    root->pcscan->MoveToQuarantine(ptr, slot_span);
+    PCScan::Instance().MoveToQuarantine(ptr, slot_span);
     return;
   }
 
@@ -724,6 +737,25 @@
 }
 
 template <bool thread_safe>
+ALWAYS_INLINE PartitionRoot<thread_safe>*
+PartitionRoot<thread_safe>::FromSuperPage(char* super_page) {
+  auto* extent_entry = reinterpret_cast<SuperPageExtentEntry*>(
+      internal::PartitionSuperPageToMetadataArea(super_page));
+  PartitionRoot* root = extent_entry->root;
+  PA_DCHECK(root->inverted_self == ~reinterpret_cast<uintptr_t>(root));
+  return root;
+}
+
+template <bool thread_safe>
+ALWAYS_INLINE PartitionRoot<thread_safe>*
+PartitionRoot<thread_safe>::FromPointerInNormalBucketPool(char* ptr) {
+  PA_DCHECK(!IsManagedByPartitionAllocDirectMap(ptr));
+  char* super_page = reinterpret_cast<char*>(reinterpret_cast<uintptr_t>(ptr) &
+                                             kSuperPageBaseMask);
+  return FromSuperPage(super_page);
+}
+
+template <bool thread_safe>
 ALWAYS_INLINE void PartitionRoot<thread_safe>::IncreaseCommittedPages(
     size_t len) {
   total_size_of_committed_pages.fetch_add(len, std::memory_order_relaxed);
diff --git a/base/allocator/partition_allocator/pcscan.cc b/base/allocator/partition_allocator/pcscan.cc
index 7ea6592..e729df57 100644
--- a/base/allocator/partition_allocator/pcscan.cc
+++ b/base/allocator/partition_allocator/pcscan.cc
@@ -7,6 +7,8 @@
 #include <map>
 #include <set>
 // TODO(bikineev): Change to base's thread.
+#include <algorithm>
+#include <numeric>
 #include <thread>
 #include <vector>
 
@@ -94,8 +96,8 @@
 template <bool thread_safe>
 class PCScan<thread_safe>::PCScanTask final {
  public:
-  // Creates and initializes a PCScan state from PartitionRoot.
-  PCScanTask(PCScan& pcscan, Root& root);
+  // Creates and initializes a PCScan state.
+  explicit PCScanTask(PCScan& pcscan);
 
   // Only allow moving to make sure that the state is not redundantly copied.
   PCScanTask(PCScanTask&&) noexcept = default;
@@ -141,21 +143,21 @@
   // Clear quarantined objects inside the PCScan task.
   void ClearQuarantinedObjects() const;
 
-  // Scans the partition and marks reachable quarantined objects. Returns the
-  // size of marked objects.
-  size_t ScanPartition();
+  // Scans all registeres partitions and marks reachable quarantined objects.
+  // Returns the size of marked objects.
+  size_t ScanPartitions();
 
   // Scans a range of addresses and marks reachable quarantined objects. Returns
   // the size of marked objects. The function race-fully reads the heap and
   // therefore TSAN is disabled for it.
-  size_t ScanRange(uintptr_t* begin, uintptr_t* end) NO_SANITIZE("thread");
+  size_t ScanRange(Root* root, uintptr_t* begin, uintptr_t* end)
+      NO_SANITIZE("thread");
 
   // Sweeps (frees) unreachable quarantined entries. Returns the size of swept
   // objects.
   size_t SweepQuarantine();
 
   PCScan<thread_safe>& pcscan_;
-  PartitionRoot<thread_safe>& root_;
 
   ScanAreas scan_areas_;
   LargeScanAreas large_scan_areas_;
@@ -202,9 +204,12 @@
   if (!bitmap)
     return 0;
 
+  auto* root =
+      Root::FromPointerInNormalBucketPool(reinterpret_cast<char*>(maybe_ptr));
+
   // Check if pointer was in the quarantine bitmap.
   const uintptr_t base =
-      GetObjectStartInSuperPage<thread_safe>(maybe_ptr, root_);
+      GetObjectStartInSuperPage<thread_safe>(maybe_ptr, *root);
   if (!base || !bitmap->CheckBit(base))
     return 0;
 
@@ -212,10 +217,9 @@
 
   auto target_slot_span =
       SlotSpan::FromPointerNoAlignmentCheck(reinterpret_cast<void*>(base));
-  PA_DCHECK(&root_ ==
-            PartitionRoot<thread_safe>::FromSlotSpan(target_slot_span));
+  PA_DCHECK(root == PartitionRoot<thread_safe>::FromSlotSpan(target_slot_span));
 
-  const size_t usable_size = root_.AdjustSizeForExtrasSubtract(
+  const size_t usable_size = root->AdjustSizeForExtrasSubtract(
       target_slot_span->GetUtilizedSlotSize());
   // Range check for inner pointers.
   if (maybe_ptr >= base + usable_size)
@@ -237,26 +241,28 @@
     auto* bitmap = QuarantineBitmapFromPointer(
         QuarantineBitmapType::kScanner, pcscan_.quarantine_data_.epoch(),
         reinterpret_cast<char*>(super_page));
-    bitmap->Iterate([&](uintptr_t ptr) {
+    auto* root = Root::FromSuperPage(reinterpret_cast<char*>(super_page));
+    bitmap->Iterate([root](uintptr_t ptr) {
       auto* object = reinterpret_cast<void*>(ptr);
       auto* slot_span = SlotSpan::FromPointerNoAlignmentCheck(object);
       // Use zero as a zapping value to speed up the fast bailout check in
-      // ScanPartition.
+      // ScanPartitions.
       memset(
           object, 0,
-          root_.AdjustSizeForExtrasSubtract(slot_span->GetUtilizedSlotSize()));
+          root->AdjustSizeForExtrasSubtract(slot_span->GetUtilizedSlotSize()));
     });
   }
 }
 
 template <bool thread_safe>
 size_t NO_SANITIZE("thread") PCScan<thread_safe>::PCScanTask::ScanRange(
+    Root* root,
     uintptr_t* begin,
     uintptr_t* end) {
   static_assert(alignof(uintptr_t) % alignof(void*) == 0,
                 "Alignment of uintptr_t must be at least as strict as "
                 "alignment of a pointer type.");
-  const bool uses_giga_cage = root_.UsesGigaCage();
+  const bool uses_giga_cage = root->UsesGigaCage();
   (void)uses_giga_cage;
   size_t new_quarantine_size = 0;
 
@@ -293,7 +299,7 @@
 }
 
 template <bool thread_safe>
-size_t PCScan<thread_safe>::PCScanTask::ScanPartition() {
+size_t PCScan<thread_safe>::PCScanTask::ScanPartitions() {
   size_t new_quarantine_size = 0;
 
   // For scanning large areas, it's worthwhile checking whether the range that
@@ -303,6 +309,8 @@
     // objects in a given slot span.
     // TODO(chromium:1129751): Check mutator bitmap as well if performance
     // allows.
+    auto* root = Root::FromPointerInNormalBucketPool(
+        reinterpret_cast<char*>(scan_area.begin));
     auto* bitmap = QuarantineBitmapFromPointer(
         QuarantineBitmapType::kScanner, pcscan_.quarantine_data_.epoch(),
         reinterpret_cast<char*>(scan_area.begin));
@@ -317,12 +325,14 @@
       uintptr_t* payload_end =
           reinterpret_cast<uintptr_t*>(current_slot + scan_area.slot_size);
       PA_DCHECK(payload_end <= scan_area.end);
-      new_quarantine_size +=
-          ScanRange(reinterpret_cast<uintptr_t*>(current_slot), payload_end);
+      new_quarantine_size += ScanRange(
+          root, reinterpret_cast<uintptr_t*>(current_slot), payload_end);
     }
   }
   for (auto scan_area : scan_areas_) {
-    new_quarantine_size += ScanRange(scan_area.begin, scan_area.end);
+    auto* root = Root::FromPointerInNormalBucketPool(
+        reinterpret_cast<char*>(scan_area.begin));
+    new_quarantine_size += ScanRange(root, scan_area.begin, scan_area.end);
   }
   return new_quarantine_size;
 }
@@ -335,11 +345,12 @@
     auto* bitmap = QuarantineBitmapFromPointer(
         QuarantineBitmapType::kScanner, pcscan_.quarantine_data_.epoch(),
         reinterpret_cast<char*>(super_page));
-    bitmap->Iterate([this, &swept_bytes](uintptr_t ptr) {
+    auto* root = Root::FromSuperPage(reinterpret_cast<char*>(super_page));
+    bitmap->Iterate([root, &swept_bytes](uintptr_t ptr) {
       auto* object = reinterpret_cast<void*>(ptr);
       auto* slot_span = SlotSpan::FromPointerNoAlignmentCheck(object);
       swept_bytes += slot_span->bucket->slot_size;
-      root_.FreeNoHooksImmediate(object, slot_span);
+      root->FreeNoHooksImmediate(object, slot_span);
     });
     bitmap->Clear();
   }
@@ -348,43 +359,46 @@
 }
 
 template <bool thread_safe>
-PCScan<thread_safe>::PCScanTask::PCScanTask(PCScan& pcscan, Root& root)
-    : pcscan_(pcscan), root_(root) {
+PCScan<thread_safe>::PCScanTask::PCScanTask(PCScan& pcscan) : pcscan_(pcscan) {
   // Threshold for which bucket size it is worthwhile in checking whether the
   // object is a quarantined object and can be skipped.
   static constexpr size_t kLargeScanAreaThreshold = 8192;
   // Take a snapshot of all allocated non-empty slot spans.
-  static constexpr size_t kScanAreasReservationSlack = 10;
-  const size_t kScanAreasReservationSize =
-      root_.get_total_size_of_committed_pages() / PartitionPageSize() /
-      kScanAreasReservationSlack;
+  static constexpr size_t kScanAreasReservationSize = 128;
   scan_areas_.reserve(kScanAreasReservationSize);
 
-  typename Root::ScopedGuard guard(root.lock_);
-  // Take a snapshot of all super pages and scannable slot spans.
-  // TODO(bikineev): Consider making current_extent lock-free and moving it to
-  // the concurrent thread.
-  for (auto* super_page_extent = root_.first_extent; super_page_extent;
-       super_page_extent = super_page_extent->next) {
-    for (char* super_page = super_page_extent->super_page_base;
-         super_page != super_page_extent->super_pages_end;
-         super_page += kSuperPageSize) {
-      // TODO(bikineev): Consider following freelists instead of slot spans.
-      IterateActiveAndFullSlotSpans<thread_safe>(
-          super_page, true /*with pcscan*/, [this](SlotSpan* slot_span) {
-            auto* payload_begin =
-                static_cast<uintptr_t*>(SlotSpan::ToPointer(slot_span));
-            auto* payload_end =
-                payload_begin +
-                (slot_span->bucket->get_bytes_per_span() / sizeof(uintptr_t));
-            if (slot_span->bucket->slot_size >= kLargeScanAreaThreshold) {
-              large_scan_areas_.push_back(
-                  {payload_begin, payload_end, slot_span->bucket->slot_size});
-            } else {
-              scan_areas_.push_back({payload_begin, payload_end});
-            }
-          });
-      super_pages_.insert(reinterpret_cast<uintptr_t>(super_page));
+  for (Root* root : pcscan.roots_) {
+    typename Root::ScopedGuard guard(root->lock_);
+
+    // TODO: We should probably skip some roots if they are not highly
+    // allocating/freeing. For that we would need to introduce and record some
+    // LocalQuarantineData per partition.
+
+    // Take a snapshot of all super pages and scannable slot spans.
+    // TODO(bikineev): Consider making current_extent lock-free and moving it to
+    // the concurrent thread.
+    for (auto* super_page_extent = root->first_extent; super_page_extent;
+         super_page_extent = super_page_extent->next) {
+      for (char* super_page = super_page_extent->super_page_base;
+           super_page != super_page_extent->super_pages_end;
+           super_page += kSuperPageSize) {
+        // TODO(bikineev): Consider following freelists instead of slot spans.
+        IterateActiveAndFullSlotSpans<thread_safe>(
+            super_page, true /*with pcscan*/, [this](SlotSpan* slot_span) {
+              auto* payload_begin =
+                  static_cast<uintptr_t*>(SlotSpan::ToPointer(slot_span));
+              auto* payload_end =
+                  payload_begin +
+                  (slot_span->bucket->get_bytes_per_span() / sizeof(uintptr_t));
+              if (slot_span->bucket->slot_size >= kLargeScanAreaThreshold) {
+                large_scan_areas_.push_back(
+                    {payload_begin, payload_end, slot_span->bucket->slot_size});
+              } else {
+                scan_areas_.push_back({payload_begin, payload_end});
+              }
+            });
+        super_pages_.insert(reinterpret_cast<uintptr_t>(super_page));
+      }
     }
   }
 }
@@ -397,15 +411,20 @@
   ClearQuarantinedObjects();
 
   // Mark and sweep the quarantine list.
-  const auto new_quarantine_size = ScanPartition();
+  const auto new_quarantine_size = ScanPartitions();
   const auto swept_bytes = SweepQuarantine();
 
   ReportStats(swept_bytes, pcscan_.quarantine_data_.last_size(),
               new_quarantine_size);
 
+  const size_t total_pa_heap_size =
+      std::accumulate(pcscan_.roots_.begin(), pcscan_.roots_.end(), 0u,
+                      [](size_t size, Root* root) {
+                        return size + root->get_total_size_of_committed_pages();
+                      });
+
   pcscan_.quarantine_data_.Account(new_quarantine_size);
-  pcscan_.quarantine_data_.GrowLimitIfNeeded(
-      root_.get_total_size_of_committed_pages());
+  pcscan_.quarantine_data_.GrowLimitIfNeeded(total_pa_heap_size);
 
   // Check that concurrent task can't be scheduled twice.
   PA_CHECK(pcscan_.in_progress_.exchange(false));
@@ -431,31 +450,26 @@
       std::memory_order_relaxed);
 }
 
-// TODO(bikineev): Synchronize task execution with destruction of
-// PartitionRoot/PCScan.
 template <bool thread_safe>
-PCScan<thread_safe>::~PCScan() = default;
+void PCScan<thread_safe>::Roots::Add(Root* root) {
+  PA_CHECK(std::find(begin(), end(), root) == end());
+  (*this)[current_] = root;
+  ++current_;
+  PA_CHECK(current_ != kMaxNumberOfPartitions)
+      << "Exceeded number of allowed partitions";
+}
 
 template <bool thread_safe>
-PCScan<thread_safe>::PCScan(Root* root) : root_(root) {
-  root->lock_.AssertAcquired();
-  // Commit quarantine bitmaps.
-  size_t quarantine_bitmaps_size_to_commit = CommittedQuarantineBitmapsSize();
-  for (auto* super_page_extent = root->first_extent; super_page_extent;
-       super_page_extent = super_page_extent->next) {
-    for (char* super_page = super_page_extent->super_page_base;
-         super_page != super_page_extent->super_pages_end;
-         super_page += kSuperPageSize) {
-      SetSystemPagesAccess(internal::SuperPageQuarantineBitmaps(super_page),
-                           quarantine_bitmaps_size_to_commit, PageReadWrite);
-    }
-  }
+void PCScan<thread_safe>::Roots::ClearForTesting() {
+  std::fill(begin(), end(), nullptr);
+  current_ = 0;
 }
 
 template <bool thread_safe>
 void PCScan<thread_safe>::PerformScan(InvocationMode invocation_mode) {
-  PA_DCHECK(root_);
-  PA_DCHECK(root_->pcscan);
+  PA_DCHECK(roots_.size() > 0);
+  PA_DCHECK(std::all_of(roots_.begin(), roots_.end(),
+                        [](Root* root) { return root->IsScanEnabled(); }));
 
   if (in_progress_.exchange(true)) {
     // Bail out if PCScan is already in progress.
@@ -465,7 +479,7 @@
   quarantine_data_.ResetAndAdvanceEpoch();
 
   // Initialize PCScan task.
-  PCScanTask task(*this, *root_);
+  PCScanTask task(*this);
 
   // Post PCScan task.
   const auto callback = [](PCScanTask task) { std::move(task).RunOnce(); };
@@ -490,6 +504,30 @@
     PerformScan(invocation_mode);
 }
 
+template <bool thread_safe>
+void PCScan<thread_safe>::RegisterRoot(Root* root) {
+  // Commit quarantine bitmaps.
+  size_t quarantine_bitmaps_size_to_commit = CommittedQuarantineBitmapsSize();
+  for (auto* super_page_extent = root->first_extent; super_page_extent;
+       super_page_extent = super_page_extent->next) {
+    for (char* super_page = super_page_extent->super_page_base;
+         super_page != super_page_extent->super_pages_end;
+         super_page += kSuperPageSize) {
+      SetSystemPagesAccess(internal::SuperPageQuarantineBitmaps(super_page),
+                           quarantine_bitmaps_size_to_commit, PageReadWrite);
+    }
+  }
+  roots_.Add(root);
+}
+
+template <bool thread_safe>
+void PCScan<thread_safe>::ClearRootsForTesting() {
+  roots_.ClearForTesting();  // IN-TEST
+}
+
+template <bool thread_safe>
+PCScan<thread_safe> PCScan<thread_safe>::instance_ PA_CONSTINIT;
+
 template class PCScan<ThreadSafe>;
 template class PCScan<NotThreadSafe>;
 
diff --git a/base/allocator/partition_allocator/pcscan.h b/base/allocator/partition_allocator/pcscan.h
index 7d47a4d4..e6af5be 100644
--- a/base/allocator/partition_allocator/pcscan.h
+++ b/base/allocator/partition_allocator/pcscan.h
@@ -14,6 +14,14 @@
 #include "base/allocator/partition_allocator/partition_page.h"
 #include "base/base_export.h"
 
+#if defined(__has_attribute)
+#if __has_attribute(require_constant_initialization)
+#define PA_CONSTINIT __attribute__((require_constant_initialization))
+#else
+#define PA_CONSTINIT
+#endif
+#endif
+
 namespace base {
 namespace internal {
 
@@ -30,9 +38,6 @@
 // The driver class encapsulates the entire PCScan infrastructure. It provides
 // a single function MoveToQuarantine() that posts a concurrent task if the
 // limit is reached.
-//
-// TODO: PCScan should work for all partitions in the PartitionAlloc heap, not
-// on a per-PartitionRoot basis.
 template <bool thread_safe>
 class BASE_EXPORT PCScan final {
  public:
@@ -44,17 +49,27 @@
     kNonBlocking,
   };
 
-  explicit PCScan(Root* root);
+  static PCScan& Instance() {
+    // The instance is declared as a static member, not static local. The reason
+    // is that we want to use the require_constant_initialization attribute to
+    // avoid double-checked-locking which would otherwise have been introduced
+    // by the compiler for thread-safe dynamic initialization (see constinit
+    // from C++20).
+    return instance_;
+  }
 
   PCScan(const PCScan&) = delete;
   PCScan& operator=(const PCScan&) = delete;
 
-  ~PCScan();
+  // Registers a root for scanning.
+  void RegisterRoot(Root* root);
 
   ALWAYS_INLINE void MoveToQuarantine(void* ptr, SlotSpan* slot_span);
 
   void PerformScanIfNeeded(InvocationMode invocation_mode);
 
+  void ClearRootsForTesting();
+
  private:
   class PCScanTask;
   friend class PCScanTest;
@@ -86,10 +101,45 @@
     size_t last_size_ = 0;
   };
 
+  static constexpr size_t kMaxNumberOfPartitions = 8u;
+
+  // A custom constexpr container class that avoids dynamic initialization.
+  // Constexprness is required to const-initialize the global PCScan.
+  class Roots final : private std::array<Root*, kMaxNumberOfPartitions> {
+    using Base = std::array<Root*, kMaxNumberOfPartitions>;
+
+   public:
+    using typename Base::const_iterator;
+    using typename Base::iterator;
+
+    // Explicitly value-initialize Base{} as otherwise the default
+    // (aggregate) initialization won't be considered as constexpr.
+    constexpr Roots() : Base{} {}
+
+    iterator begin() { return Base::begin(); }
+    const_iterator begin() const { return Base::begin(); }
+
+    iterator end() { return begin() + current_; }
+    const_iterator end() const { return begin() + current_; }
+
+    void Add(Root* root);
+
+    size_t size() const { return current_; }
+
+    void ClearForTesting();
+
+   private:
+    size_t current_ = 0u;
+  };
+
+  constexpr PCScan() = default;
+
   void PerformScan(InvocationMode invocation_mode);
 
-  Root* root_;
-  QuarantineData quarantine_data_;
+  static PCScan instance_ PA_CONSTINIT;
+
+  Roots roots_{};
+  QuarantineData quarantine_data_{};
   std::atomic<bool> in_progress_{false};
 };
 
diff --git a/base/allocator/partition_allocator/pcscan_unittest.cc b/base/allocator/partition_allocator/pcscan_unittest.cc
index b48d55ef..7cf9e0f 100644
--- a/base/allocator/partition_allocator/pcscan_unittest.cc
+++ b/base/allocator/partition_allocator/pcscan_unittest.cc
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#include "base/allocator/partition_allocator/partition_root.h"
 #if !defined(MEMORY_TOOL_REPLACES_ALLOCATOR)
 
 #include "base/allocator/partition_allocator/pcscan.h"
@@ -27,13 +28,14 @@
   }
 
   void RunPCScan() {
-    root().pcscan->PerformScan(PCScan<ThreadSafe>::InvocationMode::kBlocking);
+    PCScan<true>::Instance().PerformScan(
+        PCScan<ThreadSafe>::InvocationMode::kBlocking);
   }
 
   bool IsInQuarantine(void* ptr) const {
-    return QuarantineBitmapFromPointer(QuarantineBitmapType::kMutator,
-                                       root().pcscan->quarantine_data_.epoch(),
-                                       ptr)
+    return QuarantineBitmapFromPointer(
+               QuarantineBitmapType::kMutator,
+               PCScan<true>::Instance().quarantine_data_.epoch(), ptr)
         ->CheckBit(reinterpret_cast<uintptr_t>(ptr));
   }
 
@@ -162,10 +164,13 @@
 void TestDanglingReference(PCScanTest& test,
                            SourceList* source,
                            ValueList* value) {
-  auto& root = test.root();
+  auto* source_root = ThreadSafePartitionRoot::FromPointerInNormalBucketPool(
+      reinterpret_cast<char*>(source));
+  auto* value_root = ThreadSafePartitionRoot::FromPointerInNormalBucketPool(
+      reinterpret_cast<char*>(value));
   {
     // Free |value| and leave the dangling reference in |source|.
-    ValueList::Destroy(root, value);
+    ValueList::Destroy(*source_root, value);
     // Check that |value| is in the quarantine now.
     EXPECT_TRUE(test.IsInQuarantine(value));
     // Run PCScan.
@@ -182,7 +187,8 @@
     // Check that the object is no longer in the quarantine.
     EXPECT_FALSE(test.IsInQuarantine(value));
     // Check that the object is in the freelist now.
-    EXPECT_TRUE(IsInFreeList(root.AdjustPointerForExtrasSubtract(value)));
+    EXPECT_TRUE(
+        IsInFreeList(value_root->AdjustPointerForExtrasSubtract(value)));
   }
 }
 
@@ -300,6 +306,26 @@
   TestDanglingReference(*this, source, value);
 }
 
+TEST_F(PCScanTest, DanglingInterPartitionReference) {
+  using SourceList = List<64>;
+  using ValueList = SourceList;
+
+  ThreadSafePartitionRoot source_root(
+      {PartitionOptions::Alignment::kRegular,
+       PartitionOptions::ThreadCache::kDisabled,
+       PartitionOptions::PCScan::kForcedEnabledForTesting});
+  ThreadSafePartitionRoot value_root(
+      {PartitionOptions::Alignment::kRegular,
+       PartitionOptions::ThreadCache::kDisabled,
+       PartitionOptions::PCScan::kForcedEnabledForTesting});
+
+  auto* source = SourceList::Create(source_root);
+  auto* value = ValueList::Create(value_root);
+  source->next = value;
+
+  TestDanglingReference(*this, source, value);
+}
+
 }  // namespace internal
 }  // namespace base
 
diff --git a/base/feature_list.h b/base/feature_list.h
index c3f1c9cb..2551e1aa 100644
--- a/base/feature_list.h
+++ b/base/feature_list.h
@@ -13,6 +13,7 @@
 #include <vector>
 
 #include "base/base_export.h"
+#include "base/containers/flat_map.h"
 #include "base/gtest_prod_util.h"
 #include "base/metrics/field_trial_params.h"
 #include "base/metrics/persistent_memory_allocator.h"
@@ -285,7 +286,7 @@
 
   struct OverrideEntry {
     // The overridden enable (on/off) state of the feature.
-    const OverrideState overridden_state;
+    OverrideState overridden_state;
 
     // An optional associated field trial, which will be activated when the
     // state of the feature is queried for the first time. Weak pointer to the
@@ -296,7 +297,7 @@
     // If it's not, and |field_trial| is not null, it means it is simply an
     // associated field trial for reporting purposes (and |overridden_state|
     // came from the command-line).
-    const bool overridden_by_field_trial;
+    bool overridden_by_field_trial;
 
     // TODO(asvitkine): Expand this as more support is added.
 
@@ -356,7 +357,7 @@
 
   // Map from feature name to an OverrideEntry struct for the feature, if it
   // exists.
-  std::map<std::string, OverrideEntry, std::less<>> overrides_;
+  base::flat_map<std::string, OverrideEntry> overrides_;
 
   // Locked map that keeps track of seen features, to ensure a single feature is
   // only defined once. This verification is only done in builds with DCHECKs
diff --git a/base/pending_task.h b/base/pending_task.h
index fa534ab..a09aa86 100644
--- a/base/pending_task.h
+++ b/base/pending_task.h
@@ -47,11 +47,13 @@
   base::TimeTicks delayed_run_time;
 
   // The time at which the task was queued. For SequenceManager tasks and
-  // ThreadPool non-delayed tasks, this happens at post time. For
-  // ThreadPool delayed tasks, this happens some time after the task's delay
-  // has expired. This is not set for SequenceManager tasks if
-  // SetAddQueueTimeToTasks(true) wasn't call. This defaults to a null TimeTicks
-  // if the task hasn't been inserted in a sequence yet.
+  // ThreadPool non-delayed tasks, this happens at post time. For ThreadPool
+  // delayed tasks, this happens some time after the task's delay has expired.
+  // For deferred non-nestable tasks, this is reset when the nested loop exits
+  // and the deferred tasks are pushed back at the front of the queue. This is
+  // not set for SequenceManager tasks if SetAddQueueTimeToTasks(true) wasn't
+  // called. This defaults to a null TimeTicks if the task hasn't been inserted
+  // in a sequence yet.
   TimeTicks queue_time;
 
   // Chain of symbols of the parent tasks which led to this one being posted.
diff --git a/base/task/sequence_manager/sequence_manager_impl.cc b/base/task/sequence_manager/sequence_manager_impl.cc
index 71bb0cf..a77e4ae 100644
--- a/base/task/sequence_manager/sequence_manager_impl.cc
+++ b/base/task/sequence_manager/sequence_manager_impl.cc
@@ -460,9 +460,18 @@
     // While we were nested some non-nestable tasks may have been deferred.
     // We push them back onto the *front* of their original work queues,
     // that's why we iterate |non_nestable_task_queue| in FIFO order.
+    LazyNow exited_nested_now(controller_->GetClock());
     while (!main_thread_only().non_nestable_task_queue.empty()) {
       internal::TaskQueueImpl::DeferredNonNestableTask& non_nestable_task =
           main_thread_only().non_nestable_task_queue.back();
+      if (!non_nestable_task.task.queue_time.is_null()) {
+        // Adjust the deferred tasks' queue time to now so that intentionally
+        // deferred tasks are not unfairly considered as having been stuck in
+        // the queue for a while. Note: this does not affect task ordering as
+        // |enqueue_order| is untouched and deferred tasks will still be pushed
+        // back to the front of the queue.
+        non_nestable_task.task.queue_time = exited_nested_now.Now();
+      }
       auto* const task_queue = non_nestable_task.task_queue;
       task_queue->RequeueDeferredNonNestableTask(std::move(non_nestable_task));
       main_thread_only().non_nestable_task_queue.pop_back();
diff --git a/base/task/sequence_manager/sequence_manager_impl_unittest.cc b/base/task/sequence_manager/sequence_manager_impl_unittest.cc
index 873d1df..12986dc 100644
--- a/base/task/sequence_manager/sequence_manager_impl_unittest.cc
+++ b/base/task/sequence_manager/sequence_manager_impl_unittest.cc
@@ -77,8 +77,8 @@
 namespace base {
 namespace sequence_manager {
 namespace internal {
-// To avoid symbol collisions in jumbo builds.
-namespace sequence_manager_impl_unittest {
+
+namespace {
 
 enum class TestType {
   kMockTaskRunner,
@@ -431,6 +431,21 @@
   mutable int now_calls_count_ = 0;
 };
 
+class QueueTimeTaskObserver : public TaskObserver {
+ public:
+  void WillProcessTask(const PendingTask& pending_task,
+                       bool was_blocked_or_low_priority) override {
+    queue_times_.push_back(pending_task.queue_time);
+  }
+  void DidProcessTask(const PendingTask& pending_task) override {}
+  std::vector<TimeTicks> queue_times() const { return queue_times_; }
+
+ private:
+  std::vector<TimeTicks> queue_times_;
+};
+
+}  // namespace
+
 TEST_P(SequenceManagerTest, GetCorrectTaskRunnerForCurrentTask) {
   auto queue = CreateTaskQueue();
 
@@ -579,6 +594,7 @@
 }
 
 TEST_P(SequenceManagerTest, NonNestableTasksDoesntExecuteInNestedLoop) {
+  // TestMockTimeTaskRunner doesn't support nested loops.
   if (GetUnderlyingRunnerType() == TestType::kMockTaskRunner)
     return;
   auto queue = CreateTaskQueue();
@@ -606,6 +622,77 @@
   EXPECT_THAT(run_order, ElementsAre(1u, 2u, 5u, 6u, 3u, 4u));
 }
 
+TEST_P(SequenceManagerTest, NonNestableTaskQueueTimeShiftsToEndOfNestedLoop) {
+  // TestMockTimeTaskRunner doesn't support nested loops.
+  if (GetUnderlyingRunnerType() == TestType::kMockTaskRunner)
+    return;
+
+  auto queue = CreateTaskQueue();
+
+  QueueTimeTaskObserver observer;
+  sequence_manager()->AddTaskObserver(&observer);
+  sequence_manager()->SetAddQueueTimeToTasks(true);
+
+  RunLoop nested_run_loop(RunLoop::Type::kNestableTasksAllowed);
+
+  const TimeTicks start_time = mock_tick_clock()->NowTicks();
+
+  constexpr auto kTimeSpentInNestedLoop = TimeDelta::FromSeconds(1);
+  constexpr auto kTimeInTaskAfterNestedLoop = TimeDelta::FromSeconds(3);
+
+  // 1) Run task 1
+  // 2) Enter a nested loop
+  // 3) Run task 3
+  // 4) Advance time by 1 second
+  // 5) Run task 5
+  // 6) Exit nested loop
+  // 7) Run task 7 (non-nestable)
+  // 8) Advance time by 3 seconds (non-nestable)
+  // 9) Run task 9 (non-nestable)
+  // Steps 7-9 are expected to run last and have had their queue time adjusted
+  // to 6 (task 8 shouldn't affect task 9's queue time).
+  std::vector<EnqueueOrder> run_order;
+  queue->task_runner()->PostTask(FROM_HERE, BindOnce(&TestTask, 1, &run_order));
+  queue->task_runner()->PostTask(FROM_HERE, BindLambdaForTesting([&]() {
+                                   TestTask(2, &run_order);
+                                   nested_run_loop.Run();
+                                 }));
+  queue->task_runner()->PostTask(FROM_HERE, BindOnce(&TestTask, 3, &run_order));
+  queue->task_runner()->PostNonNestableTask(FROM_HERE,
+                                            BindOnce(&TestTask, 7, &run_order));
+  queue->task_runner()->PostTask(FROM_HERE, BindLambdaForTesting([&]() {
+                                   TestTask(4, &run_order);
+                                   AdvanceMockTickClock(kTimeSpentInNestedLoop);
+                                 }));
+  queue->task_runner()->PostNonNestableTask(
+      FROM_HERE, BindLambdaForTesting([&]() {
+        TestTask(8, &run_order);
+        AdvanceMockTickClock(kTimeInTaskAfterNestedLoop);
+      }));
+  queue->task_runner()->PostTask(FROM_HERE, BindOnce(&TestTask, 5, &run_order));
+  queue->task_runner()->PostNonNestableTask(FROM_HERE,
+                                            BindOnce(&TestTask, 9, &run_order));
+  queue->task_runner()->PostTask(FROM_HERE, BindLambdaForTesting([&]() {
+                                   TestTask(6, &run_order);
+                                   nested_run_loop.Quit();
+                                 }));
+
+  RunLoop().RunUntilIdle();
+
+  EXPECT_THAT(run_order, ElementsAre(1u, 2u, 3u, 4u, 5u, 6u, 7u, 8u, 9u));
+
+  const TimeTicks expected_adjusted_queueing_time =
+      start_time + kTimeSpentInNestedLoop;
+  EXPECT_THAT(
+      observer.queue_times(),
+      ElementsAre(start_time, start_time, start_time, start_time, start_time,
+                  start_time, expected_adjusted_queueing_time,
+                  expected_adjusted_queueing_time,
+                  expected_adjusted_queueing_time));
+
+  sequence_manager()->RemoveTaskObserver(&observer);
+}
+
 namespace {
 
 void InsertFenceAndPostTestTask(int id,
@@ -869,6 +956,8 @@
   EXPECT_EQ(1u, fixture.test_task_runner()->GetPendingTaskCount());
 }
 
+namespace {
+
 class TestObject {
  public:
   ~TestObject() { destructor_count__++; }
@@ -880,6 +969,8 @@
 
 int TestObject::destructor_count__ = 0;
 
+}  // namespace
+
 TEST_P(SequenceManagerTest, PendingDelayedTasksRemovedOnShutdown) {
   auto queue = CreateTaskQueue();
 
@@ -1343,6 +1434,7 @@
 }
 
 namespace {
+
 class RefCountedCallbackFactory {
  public:
   OnceCallback<void()> WrapCallback(OnceCallback<void()> cb) {
@@ -1357,6 +1449,7 @@
   bool dummy_;
   WeakPtrFactory<bool> task_references_{&dummy_};
 };
+
 }  // namespace
 
 TEST_P(SequenceManagerTest, NoTasksAfterShutdown) {
@@ -1453,6 +1546,8 @@
   EXPECT_THAT(run_order, ElementsAre(0u, 1u, 2u, 3u));
 }
 
+namespace {
+
 class MockTaskObserver : public TaskObserver {
  public:
   MOCK_METHOD1(DidProcessTask, void(const PendingTask& task));
@@ -1460,6 +1555,8 @@
                void(const PendingTask& task, bool was_blocked_or_low_priority));
 };
 
+}  // namespace
+
 TEST_P(SequenceManagerTest, TaskObserverAdding) {
   auto queue = CreateTaskQueue();
   MockTaskObserver observer;
@@ -1817,6 +1914,8 @@
   EXPECT_THAT(run_order, ElementsAre(2u, 1u));
 }
 
+namespace {
+
 void CheckIsNested(bool* is_nested) {
   *is_nested = RunLoop::IsNestedOnCurrentThread();
 }
@@ -1830,6 +1929,8 @@
   run_loop->Run();
 }
 
+}  // namespace
+
 TEST_P(SequenceManagerTest, QuitWhileNested) {
   if (GetUnderlyingRunnerType() == TestType::kMockTaskRunner)
     return;
@@ -1848,6 +1949,8 @@
   EXPECT_FALSE(was_nested);
 }
 
+namespace {
+
 class SequenceNumberCapturingTaskObserver : public TaskObserver {
  public:
   // TaskObserver overrides.
@@ -1863,6 +1966,8 @@
   std::vector<int> sequence_numbers_;
 };
 
+}  // namespace
+
 TEST_P(SequenceManagerTest, SequenceNumSetWhenTaskIsPosted) {
   auto queue = CreateTaskQueue();
 
@@ -2392,6 +2497,8 @@
   queue->ShutdownTaskQueue();
 }
 
+namespace {
+
 class CancelableTask {
  public:
   explicit CancelableTask(const TickClock* clock) : clock_(clock) {}
@@ -2404,6 +2511,8 @@
   WeakPtrFactory<CancelableTask> weak_factory_{this};
 };
 
+}  // namespace
+
 TEST_P(SequenceManagerTest, TaskQueueObserver_SweepCanceledDelayedTasks) {
   auto queue = CreateTaskQueue();
 
@@ -2438,11 +2547,13 @@
 }
 
 namespace {
+
 void ChromiumRunloopInspectionTask(
     scoped_refptr<TestMockTimeTaskRunner> test_task_runner) {
   // We don't expect more than 1 pending task at any time.
   EXPECT_GE(1u, test_task_runner->GetPendingTaskCount());
 }
+
 }  // namespace
 
 TEST(SequenceManagerTestWithMockTaskRunner,
@@ -4262,19 +4373,6 @@
 // TODO(altimin): Add a test that posts an infinite number of other tasks
 // from its destructor.
 
-class QueueTimeTaskObserver : public TaskObserver {
- public:
-  void WillProcessTask(const PendingTask& pending_task,
-                       bool was_blocked_or_low_priority) override {
-    queue_time_ = pending_task.queue_time;
-  }
-  void DidProcessTask(const PendingTask& pending_task) override {}
-  TimeTicks queue_time() { return queue_time_; }
-
- private:
-  TimeTicks queue_time_;
-};
-
 TEST_P(SequenceManagerTest, DoesNotRecordQueueTimeIfSettingFalse) {
   auto queue = CreateTaskQueue();
 
@@ -4286,7 +4384,7 @@
   AdvanceMockTickClock(TimeDelta::FromMilliseconds(99));
   queue->task_runner()->PostTask(FROM_HERE, BindOnce(&NopTask));
   RunLoop().RunUntilIdle();
-  EXPECT_TRUE(observer.queue_time().is_null());
+  EXPECT_THAT(observer.queue_times(), ElementsAre(TimeTicks()));
 
   sequence_manager()->RemoveTaskObserver(&observer);
 }
@@ -4303,13 +4401,14 @@
   AdvanceMockTickClock(TimeDelta::FromMilliseconds(99));
   queue->task_runner()->PostTask(FROM_HERE, BindOnce(&NopTask));
   RunLoop().RunUntilIdle();
-  EXPECT_EQ(observer.queue_time(),
-            kStartTime + TimeDelta::FromMilliseconds(99));
+  EXPECT_THAT(observer.queue_times(),
+              ElementsAre(kStartTime + TimeDelta::FromMilliseconds(99)));
 
   sequence_manager()->RemoveTaskObserver(&observer);
 }
 
 namespace {
+
 // Inject a test point for recording the destructor calls for OnceClosure
 // objects sent to PostTask(). It is awkward usage since we are trying to hook
 // the actual destruction, which is not a common operation.
@@ -4531,6 +4630,8 @@
   thread.Stop();
 }
 
+namespace {
+
 void PostTaskA(scoped_refptr<TaskRunner> task_runner) {
   task_runner->PostTask(FROM_HERE, BindOnce(&NopTask));
   task_runner->PostDelayedTask(FROM_HERE, BindOnce(&NopTask),
@@ -4549,6 +4650,8 @@
                                base::TimeDelta::FromMilliseconds(30));
 }
 
+}  // namespace
+
 TEST_P(SequenceManagerTest, DescribeAllPendingTasks) {
   auto queues = CreateTaskQueues(3u);
 
@@ -4596,6 +4699,8 @@
             "666666666666666666666666666666666666666666666666666666666666");
 }
 
+namespace {
+
 class CancelableTaskWithDestructionObserver {
  public:
   CancelableTaskWithDestructionObserver() {}
@@ -4608,6 +4713,8 @@
   WeakPtrFactory<CancelableTaskWithDestructionObserver> weak_factory_{this};
 };
 
+}  // namespace
+
 TEST_P(SequenceManagerTest, PeriodicHousekeeping) {
   auto queue = CreateTaskQueue();
 
@@ -4667,6 +4774,8 @@
   FastForwardUntilNoTasksRemain();
 }
 
+namespace {
+
 class MockCrashKeyImplementation : public debug::CrashKeyImplementation {
  public:
   MOCK_METHOD2(Allocate,
@@ -4675,6 +4784,8 @@
   MOCK_METHOD1(Clear, void(debug::CrashKeyString*));
 };
 
+}  // namespace
+
 TEST_P(SequenceManagerTest, CrashKeys) {
   testing::InSequence sequence;
   auto queue = CreateTaskQueue();
@@ -5063,7 +5174,6 @@
   sequence_manager()->RemoveTaskObserver(&observer);
 }
 
-}  // namespace sequence_manager_impl_unittest
 }  // namespace internal
 }  // namespace sequence_manager
 }  // namespace base
diff --git a/base/test/task_environment.cc b/base/test/task_environment.cc
index 2c744cc7..b40d32f 100644
--- a/base/test/task_environment.cc
+++ b/base/test/task_environment.cc
@@ -309,7 +309,7 @@
         // Thread B : Complete enqueue of task U.
         // Thread A : FastForwardToNextTaskOrCap() => must stay at 300ms and run
         //            U, not go back to 120ms.
-        // Hence we need std::max() to protect again this because construction
+        // Hence we need std::max() to protect against this because construction
         // and enqueuing isn't atomic in time (LazyNow support in
         // base/task/thread_pool could help).
         now_ticks_ = std::max(now_ticks_, *next_task_time);
diff --git a/base/trace_event/malloc_dump_provider.cc b/base/trace_event/malloc_dump_provider.cc
index 33994731..00fca84 100644
--- a/base/trace_event/malloc_dump_provider.cc
+++ b/base/trace_event/malloc_dump_provider.cc
@@ -65,10 +65,10 @@
 #endif  // defined(OS_WIN)
 
 #if BUILDFLAG(USE_PARTITION_ALLOC_AS_MALLOC)
-void ReportDetailedPartitionAllocStats(ProcessMemoryDump* pmd) {
+void ReportPartitionAllocStats(ProcessMemoryDump* pmd, bool detailed) {
   SimplePartitionStatsDumper allocator_dumper;
-  internal::PartitionAllocMalloc::Allocator()->DumpStats("malloc", false,
-                                                         &allocator_dumper);
+  internal::PartitionAllocMalloc::Allocator()->DumpStats(
+      "malloc", !detailed /* is_light_dump */, &allocator_dumper);
 
   if (allocator_dumper.stats().has_thread_cache) {
     const auto& stats = allocator_dumper.stats().all_thread_caches_stats;
@@ -113,9 +113,8 @@
   size_t allocated_objects_size = 0;
   size_t allocated_objects_count = 0;
 #if BUILDFLAG(USE_PARTITION_ALLOC_AS_MALLOC)
-  if (args.level_of_detail == MemoryDumpLevelOfDetail::DETAILED) {
-    ReportDetailedPartitionAllocStats(pmd);
-  }
+  ReportPartitionAllocStats(
+      pmd, args.level_of_detail == MemoryDumpLevelOfDetail::DETAILED);
 #endif  // BUILDFLAG(USE_PARTITION_ALLOC_AS_MALLOC)
 
 #if BUILDFLAG(USE_TCMALLOC)
diff --git a/base/trace_event/memory_infra_background_allowlist.cc b/base/trace_event/memory_infra_background_allowlist.cc
index f7c23af..67f40d4 100644
--- a/base/trace_event/memory_infra_background_allowlist.cc
+++ b/base/trace_event/memory_infra_background_allowlist.cc
@@ -9,6 +9,7 @@
 
 #include <string>
 
+#include "base/allocator/buildflags.h"
 #include "base/strings/string_util.h"
 
 namespace base {
@@ -136,6 +137,10 @@
     "malloc",
     "malloc/allocated_objects",
     "malloc/metadata_fragmentation_caches",
+#if BUILDFLAG(USE_PARTITION_ALLOC_AS_MALLOC)
+    "malloc/thread_cache",
+    "malloc/thread_cache/main_thread",
+#endif
     "media/webmediaplayer/audio/player_0x?",
     "media/webmediaplayer/data_source/player_0x?",
     "media/webmediaplayer/demuxer/player_0x?",
@@ -285,6 +290,10 @@
     "partition_alloc/partitions/array_buffer",
     "partition_alloc/partitions/buffer",
     "partition_alloc/partitions/fast_malloc",
+#if !BUILDFLAG(USE_PARTITION_ALLOC_AS_MALLOC)
+    "partition_alloc/partitions/fast_malloc/thread_cache",
+    "partition_alloc/partitions/fast_malloc/thread_cache/main_thread",
+#endif
     "partition_alloc/partitions/layout",
     "skia/gpu_resources/context_0x?",
     "skia/sk_glyph_cache",
diff --git a/build/config/compiler/compiler.gni b/build/config/compiler/compiler.gni
index 9e472bef..12ca7df 100644
--- a/build/config/compiler/compiler.gni
+++ b/build/config/compiler/compiler.gni
@@ -19,7 +19,7 @@
   import("//build/config/arm.gni")
 }
 
-if (is_apple) {
+if (is_mac) {
   import("//build/config/mac/symbols.gni")
 }
 
@@ -216,7 +216,7 @@
 # official builders.
 strip_absolute_paths_from_debug_symbols_default =
     is_android || is_fuchsia || is_nacl || (is_win && use_lld) || is_linux ||
-    is_chromeos || (is_apple && !enable_dsyms)
+    is_chromeos || (is_mac && !enable_dsyms) || ios_use_goma_rbe
 
 # If the platform uses stripped absolute paths by default, then we don't expose
 # it as a configuration option. If this is causing problems, please file a bug.
diff --git a/build/config/ios/BUILD.gn b/build/config/ios/BUILD.gn
index e2acca73..c80f98a 100644
--- a/build/config/ios/BUILD.gn
+++ b/build/config/ios/BUILD.gn
@@ -87,11 +87,14 @@
 # that is iOS-only. Please see that target for advice on what should go in
 # :runtime_library vs. :compiler.
 config("runtime_library") {
-  # The variable ios_sdk_path is relative to root_out_dir for goma RBE. As it
-  # is passed to the compiler via cflags, ldflags which do not rebase the
-  # values (since they are compiler flags, not paths), it has to rebased. Use
-  # a local variable to avoid repeating the rebase invocation.
-  _sdk_root = rebase_path(ios_sdk_path, root_build_dir)
+  # The variable ios_sdk_path may be relative to root_out_dir on the bots. As
+  # it is passed to the compiler via cflags, ldflags which do not rebase the
+  # values (since they are compiler flags, not paths), it may be required to
+  # rebase it. Use a local variable to avoid repeating the rebase invocation.
+  _sdk_root = ios_sdk_path
+  if (ios_enable_relative_sdk_path) {
+    _sdk_root = rebase_path(ios_sdk_path, root_build_dir)
+  }
 
   common_flags = [
     "-isysroot",
@@ -219,14 +222,16 @@
 #
 # To workaround this, add a target that pretends to create those files
 # (but does nothing). See https://crbug.com/1061487 for why this is needed.
-action("copy_xctrunner_app") {
-  testonly = true
-  script = "//build/noop.py"
-  outputs = [
-    "$_xctrunner_path/Info.plist",
-    "$_xctrunner_path/PkgInfo",
-    "$_xctrunner_path/XCTRunner",
-  ]
+if (ios_use_goma_rbe) {
+  action("copy_xctrunner_app") {
+    testonly = true
+    script = "//build/noop.py"
+    outputs = [
+      "$_xctrunner_path/Info.plist",
+      "$_xctrunner_path/PkgInfo",
+      "$_xctrunner_path/XCTRunner",
+    ]
+  }
 }
 
 # When creating the test runner for an XCUITest, the arm64e slice of the binary
@@ -246,5 +251,7 @@
     xcode_version,
   ]
 
-  deps = [ ":copy_xctrunner_app" ]
+  if (ios_use_goma_rbe) {
+    deps = [ ":copy_xctrunner_app" ]
+  }
 }
diff --git a/build/config/ios/ios_sdk.gni b/build/config/ios/ios_sdk.gni
index 5b878db..0f63b48e7 100644
--- a/build/config/ios/ios_sdk.gni
+++ b/build/config/ios/ios_sdk.gni
@@ -58,6 +58,9 @@
   # You can also pass the value via "--args" parameter for "gn gen" command by
   # using the syntax --args='additional_target_cpus=["arm"] target_cpu="arm64"'.
   additional_target_cpus = []
+
+  # TODO(crbug.com/1015730): remove this flag because ios_use_goma_rbe covers.
+  ios_enable_relative_sdk_path = ios_use_goma_rbe
 }
 
 declare_args() {
@@ -127,8 +130,6 @@
   ios_sdk_info_args = [
     "--get_sdk_info",
     "--get_machine_info",
-    "--create_symlink_at",
-    "sdk/xcode_links",
   ]
   ios_sdk_info_args += [ ios_sdk_name ]
   if (ios_sdk_developer_dir != "") {
@@ -137,6 +138,12 @@
       ios_sdk_developer_dir,
     ]
   }
+  if (ios_use_goma_rbe) {
+    ios_sdk_info_args += [
+      "--create_symlink_at",
+      "sdk/xcode_links",
+    ]
+  }
   script_name = "//build/config/mac/sdk_info.py"
   _ios_sdk_result = exec_script(script_name, ios_sdk_info_args, "scope")
   ios_sdk_path = _ios_sdk_result.sdk_path
diff --git a/build/config/ios/rules.gni b/build/config/ios/rules.gni
index 021f2d5..5dd023e1 100644
--- a/build/config/ios/rules.gni
+++ b/build/config/ios/rules.gni
@@ -433,8 +433,15 @@
       code_signing_args += [ "--disable-code-signature" ]
     }
     if (defined(invoker.extra_system_frameworks)) {
+      # All framework in extra_system_frameworks are expected to be system
+      # framework and the path to be already system absolute so do not use
+      # rebase_path here unless ios_enable_relative_sdk_path is trued.
       foreach(_framework, invoker.extra_system_frameworks) {
-        _framework_path = rebase_path(_framework, root_build_dir)
+        if (ios_enable_relative_sdk_path) {
+          _framework_path = rebase_path(_framework, root_build_dir)
+        } else {
+          _framework_path = _framework
+        }
         code_signing_args += [ "-F=$_framework_path" ]
       }
     }
@@ -1967,7 +1974,9 @@
              "-o=" + rebase_path(_output_name, root_build_dir),
            ] + rebase_path(sources, root_build_dir)
 
-    deps = [ "//build/config/ios:copy_xctrunner_app" ]
+    if (ios_use_goma_rbe) {
+      deps = [ "//build/config/ios:copy_xctrunner_app" ]
+    }
   }
 
   ios_info_plist(_info_plist_target) {
@@ -1997,7 +2006,9 @@
 
     outputs = [ "{{bundle_contents_dir}}/PkgInfo" ]
 
-    public_deps = [ "//build/config/ios:copy_xctrunner_app" ]
+    if (ios_use_goma_rbe) {
+      public_deps = [ "//build/config/ios:copy_xctrunner_app" ]
+    }
   }
 
   _xctest_bundle = invoker.xctest_bundle
diff --git a/build/config/mac/mac_sdk.gni b/build/config/mac/mac_sdk.gni
index a9d84b2..d26ec47 100644
--- a/build/config/mac/mac_sdk.gni
+++ b/build/config/mac/mac_sdk.gni
@@ -77,7 +77,7 @@
 }
 
 # put system xcode under src to avoid absolute path.
-if (use_system_xcode) {
+if (use_system_xcode && ios_use_goma_rbe) {
   sdk_info_args += [
     "--get_sdk_info",
     "--create_symlink_at",
@@ -89,7 +89,7 @@
 _mac_sdk_result = exec_script(script_name, sdk_info_args, "scope")
 xcode_version = _mac_sdk_result.xcode_version
 xcode_build = _mac_sdk_result.xcode_build
-if (mac_sdk_path == "" && use_system_xcode) {
+if (mac_sdk_path == "" && use_system_xcode && ios_use_goma_rbe) {
   mac_sdk_path = _mac_sdk_result.sdk_path
 }
 
diff --git a/build/toolchain/clang_code_coverage_wrapper.py b/build/toolchain/clang_code_coverage_wrapper.py
index 5b5550d..f4e00bda 100755
--- a/build/toolchain/clang_code_coverage_wrapper.py
+++ b/build/toolchain/clang_code_coverage_wrapper.py
@@ -130,6 +130,13 @@
     # be linked in. Therefore we force coverage for this file to ensure that
     # any target that includes it will also get the profiling runtime.
     'win': [r'..\..\base\test\clang_profiling.cc'],
+    # TODO(crbug.com/1141727) We're seeing runtime LLVM errors in mac-rel when
+    # no files are changed, so we suspect that this is similar to the other
+    # problem with clang_profiling.cc on Windows. The TODO here is to force
+    # coverage for this specific file on ALL platforms, if it turns out to fix
+    # this issue on Mac as well. It's the only file that directly calls
+    # `__llvm_profile_dump` so it warrants some special treatment.
+    'mac': ['../../base/test/clang_profiling.cc'],
 }
 
 
@@ -157,7 +164,6 @@
 
 
 def main():
-  # TODO(crbug.com/898695): Make this wrapper work on Windows platform.
   arg_parser = argparse.ArgumentParser()
   arg_parser.usage = __doc__
   arg_parser.add_argument(
diff --git a/build/toolchain/goma.gni b/build/toolchain/goma.gni
index bad826ab..be14c8b 100644
--- a/build/toolchain/goma.gni
+++ b/build/toolchain/goma.gni
@@ -25,10 +25,13 @@
   # TODO(crbug.com/726475): true if use_goma = true in the future.
   use_java_goma = false
 
-  # Deprecated and ignored as Goma RBE is now the default. Still exists
-  # to avoid breaking the build on the bots. Will be removed when all
-  # bots have been configured to not set this variable.
-  ios_use_goma_rbe = false
+  # Auto-configure for Goma RBE backend.
+  # TODO(crbug.com/1015730): true if use_goma = true in the future.
+  ios_use_goma_rbe = -1
+}
+
+if (ios_use_goma_rbe == -1) {
+  ios_use_goma_rbe = is_ios && use_goma
 }
 
 assert(!is_win || !use_goma || is_clang,
diff --git a/cc/animation/animation.cc b/cc/animation/animation.cc
index 718e1f7f..e47af5cd 100644
--- a/cc/animation/animation.cc
+++ b/cc/animation/animation.cc
@@ -6,6 +6,8 @@
 
 #include <inttypes.h>
 #include <algorithm>
+#include <string>
+#include <utility>
 
 #include "base/stl_util.h"
 #include "base/strings/stringprintf.h"
diff --git a/cc/animation/animation_host.cc b/cc/animation/animation_host.cc
index 137ee986..301f09c 100644
--- a/cc/animation/animation_host.cc
+++ b/cc/animation/animation_host.cc
@@ -146,7 +146,7 @@
 
 void AnimationHost::UpdateRegisteredElementIds(ElementListType changed_list) {
   for (auto map_entry : element_to_animations_map_) {
-    // kReservedElementId is reserved for an paint worklet element that animates
+    // kReservedElementId is reserved for a paint worklet element that animates
     // a custom property. This element is assumed to always be present as no
     // element is needed to tick this animation.
     if (mutator_host_client()->IsElementInPropertyTrees(map_entry.first,
diff --git a/cc/animation/element_animations.cc b/cc/animation/element_animations.cc
index 03996f2..2ccca3d3f 100644
--- a/cc/animation/element_animations.cc
+++ b/cc/animation/element_animations.cc
@@ -7,6 +7,7 @@
 #include <stddef.h>
 
 #include <algorithm>
+#include <utility>
 
 #include "base/numerics/ranges.h"
 #include "cc/animation/animation_delegate.h"
@@ -35,6 +36,12 @@
   return element_animations->element_id();
 }
 
+bool UsingPaintWorklet(int property_index) {
+  // The set of properties where its animation uses paint worklet infra.
+  return property_index == TargetProperty::BACKGROUND_COLOR ||
+         property_index == TargetProperty::CSS_CUSTOM_PROPERTY;
+}
+
 }  // namespace
 
 scoped_refptr<ElementAnimations> ElementAnimations::Create(
@@ -534,6 +541,18 @@
   for (int property_index = TargetProperty::FIRST_TARGET_PROPERTY;
        property_index <= TargetProperty::LAST_TARGET_PROPERTY;
        ++property_index) {
+    // We skip the set of properties that uses paint worklet, because the
+    // animation is not directly associated with the element its compositing
+    // layer targets and we use reserved element id when we attach a layer for
+    // the animation. In that case, the DCHECK here is no longer applicable.
+    // For example, when we have two paint worklet elements with two different
+    // custom property animations, then these two KeyframeModels would have
+    // different element_id and thus fail the first DCHECK here.
+    // It is not valid to include these properties in the PropertyToElementIdMap
+    // as they do not map to a single element id. Therefore, these properties
+    // should not be included in the map.
+    if (UsingPaintWorklet(property_index))
+      continue;
     TargetProperty::Type property =
         static_cast<TargetProperty::Type>(property_index);
     ElementId element_id_for_property;
diff --git a/cc/animation/keyframe_effect.cc b/cc/animation/keyframe_effect.cc
index a6d70065b1..e6979e5 100644
--- a/cc/animation/keyframe_effect.cc
+++ b/cc/animation/keyframe_effect.cc
@@ -4,7 +4,10 @@
 
 #include "cc/animation/keyframe_effect.h"
 
+#include <algorithm>
 #include <memory>
+#include <string>
+#include <utility>
 
 #include "base/stl_util.h"
 #include "base/time/time.h"
diff --git a/chrome/android/BUILD.gn b/chrome/android/BUILD.gn
index 64ddc9f0..23137891 100644
--- a/chrome/android/BUILD.gn
+++ b/chrome/android/BUILD.gn
@@ -331,8 +331,8 @@
     "//chrome/browser/settings:java",
     "//chrome/browser/share:java",
     "//chrome/browser/share/android:java_resources",
-    "//chrome/browser/signin/android:java",
     "//chrome/browser/signin/services/android:java",
+    "//chrome/browser/signin/ui/android:java",
     "//chrome/browser/tab:java",
     "//chrome/browser/tabmodel:factory_java",
     "//chrome/browser/tabmodel:java",
@@ -881,6 +881,7 @@
     "//components/omnibox/browser:browser_java",
     "//components/page_info/android:java",
     "//components/payments/content/android:java",
+    "//components/payments/content/android:service_java",
     "//components/payments/mojom:mojom_java",
     "//components/policy/android:policy_java",
     "//components/prefs/android:java",
diff --git a/chrome/android/DEPS b/chrome/android/DEPS
index 9596fe69..e28d6ab 100644
--- a/chrome/android/DEPS
+++ b/chrome/android/DEPS
@@ -21,6 +21,7 @@
   "+chrome/browser/safe_browsing/android",
   "+chrome/browser/safety_check/android",
   "+chrome/browser/signin/services/android/java",
+  "+chrome/browser/signin/ui/android/java",
   "+chrome/browser/settings/android",
   "+chrome/browser/ui/android/favicon/java",
   "+chrome/browser/ui/android/native_page",
diff --git a/chrome/android/chrome_java_sources.gni b/chrome/android/chrome_java_sources.gni
index c15d4a0..bd65735 100644
--- a/chrome/android/chrome_java_sources.gni
+++ b/chrome/android/chrome_java_sources.gni
@@ -1274,7 +1274,6 @@
   "java/src/org/chromium/chrome/browser/signin/SigninFragmentBase.java",
   "java/src/org/chromium/chrome/browser/signin/SigninHelper.java",
   "java/src/org/chromium/chrome/browser/signin/SigninInvestigator.java",
-  "java/src/org/chromium/chrome/browser/signin/SigninManager.java",
   "java/src/org/chromium/chrome/browser/signin/SigninManagerImpl.java",
   "java/src/org/chromium/chrome/browser/signin/SigninPromoController.java",
   "java/src/org/chromium/chrome/browser/signin/SigninPromoUtil.java",
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/FeedSurfaceMediator.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/FeedSurfaceMediator.java
index f13c812..01c6498d 100644
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/FeedSurfaceMediator.java
+++ b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/FeedSurfaceMediator.java
@@ -37,9 +37,9 @@
 import org.chromium.chrome.browser.search_engines.TemplateUrlServiceFactory;
 import org.chromium.chrome.browser.signin.IdentityServicesProvider;
 import org.chromium.chrome.browser.signin.PersonalizedSigninPromoView;
-import org.chromium.chrome.browser.signin.SigninManager;
 import org.chromium.chrome.browser.signin.SigninPromoController;
 import org.chromium.chrome.browser.signin.SigninPromoUtil;
+import org.chromium.chrome.browser.signin.services.SigninManager;
 import org.chromium.chrome.browser.suggestions.SuggestionsMetrics;
 import org.chromium.chrome.features.start_surface.StartSurfaceConfiguration;
 import org.chromium.components.browser_ui.widget.listmenu.ListMenu;
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/shared/ui/MaterialSpinnerView.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/shared/ui/MaterialSpinnerView.java
index 08d3e67..05450e73 100644
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/shared/ui/MaterialSpinnerView.java
+++ b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/shared/ui/MaterialSpinnerView.java
@@ -14,15 +14,11 @@
 import androidx.appcompat.widget.AppCompatImageView;
 import androidx.swiperefreshlayout.widget.CircularProgressDrawable;
 
-import org.chromium.base.FeatureList;
-import org.chromium.base.TraceEvent;
 import org.chromium.chrome.R;
-import org.chromium.chrome.browser.flags.ChromeFeatureList;
 
 /** View that shows a Material themed spinner. */
 public class MaterialSpinnerView extends AppCompatImageView {
     private final CircularProgressDrawable mSpinner;
-    private final boolean mAlwaysAnimate;
 
     public MaterialSpinnerView(Context context) {
         this(context, null);
@@ -37,7 +33,6 @@
     @SuppressWarnings({"nullness:argument.type.incompatible", "nullness:method.invocation.invalid"})
     public MaterialSpinnerView(Context context, @Nullable AttributeSet attrs, int defStyle) {
         super(context, attrs, defStyle);
-        TraceEvent.begin("MaterialSpinnerView");
         mSpinner = new CircularProgressDrawable(context);
         mSpinner.setStyle(CircularProgressDrawable.DEFAULT);
         setImageDrawable(mSpinner);
@@ -45,45 +40,19 @@
         Theme theme = context.getTheme();
         theme.resolveAttribute(R.attr.feedSpinnerColor, typedValue, true);
         mSpinner.setColorSchemeColors(typedValue.data);
-        mAlwaysAnimate = FeatureList.isInitialized() ? ChromeFeatureList.isEnabled(
-                                 ChromeFeatureList.INTEREST_FEED_SPINNER_ALWAYS_ANIMATE)
-                                                     : false;
-        updateAnimationState(isAttachedToWindow());
-        TraceEvent.end("MaterialSpinnerView");
-    }
 
-    @Override
-    protected void onVisibilityChanged(View changedView, int visibility) {
-        super.onVisibilityChanged(changedView, visibility);
-        updateAnimationState(isAttachedToWindow());
-    }
-
-    @Override
-    protected void onAttachedToWindow() {
-        super.onAttachedToWindow();
-        updateAnimationState(/*isAttached=*/true);
-    }
-
-    @Override
-    protected void onDetachedFromWindow() {
-        // isAttachedToWindow() doesn't turn false during onDetachedFromWindow(), so we pass the new
-        // attachment state into updateAnimationState() here explicitly.
-        updateAnimationState(/*isAttached=*/false);
-        super.onDetachedFromWindow();
-    }
-
-    private void updateAnimationState(boolean isAttached) {
-        // TODO(crbug.com/1151391): This feature is used for A:B testing to determine the impact of
-        // a bug fix. Remove after experiment is complete.
-        if (mAlwaysAnimate) {
-            if (!mSpinner.isRunning()) mSpinner.start();
-            return;
+        if (getVisibility() == View.VISIBLE) {
+            mSpinner.start();
         }
+    }
 
-        boolean visible = isShown() && isAttached;
-        if (mSpinner.isRunning() && !visible) {
+    @Override
+    public void setVisibility(int visibility) {
+        super.setVisibility(visibility);
+
+        if (mSpinner.isRunning() && getVisibility() != View.VISIBLE) {
             mSpinner.stop();
-        } else if (!mSpinner.isRunning() && visible) {
+        } else if (!mSpinner.isRunning() && getVisibility() == View.VISIBLE) {
             mSpinner.start();
         }
     }
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/v1/FeedAppLifecycle.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/v1/FeedAppLifecycle.java
index 46dc3e1..11ad26c 100644
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/v1/FeedAppLifecycle.java
+++ b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/v1/FeedAppLifecycle.java
@@ -17,7 +17,7 @@
 import org.chromium.chrome.browser.flags.ChromeFeatureList;
 import org.chromium.chrome.browser.profiles.Profile;
 import org.chromium.chrome.browser.signin.IdentityServicesProvider;
-import org.chromium.chrome.browser.signin.SigninManager;
+import org.chromium.chrome.browser.signin.services.SigninManager;
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
diff --git a/chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/shared/ui/MaterialSpinnerViewTest.java b/chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/shared/ui/MaterialSpinnerViewTest.java
index 5996ca5..22924a4 100644
--- a/chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/shared/ui/MaterialSpinnerViewTest.java
+++ b/chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/shared/ui/MaterialSpinnerViewTest.java
@@ -8,7 +8,6 @@
 
 import android.app.Activity;
 import android.view.View;
-import android.widget.FrameLayout;
 
 import androidx.swiperefreshlayout.widget.CircularProgressDrawable;
 
@@ -17,7 +16,6 @@
 import org.junit.runner.RunWith;
 import org.robolectric.Robolectric;
 import org.robolectric.annotation.Config;
-import org.robolectric.annotation.LooperMode;
 
 import org.chromium.chrome.R;
 import org.chromium.testing.local.LocalRobolectricTestRunner;
@@ -25,52 +23,38 @@
 /** Tests for {@link MaterialSpinnerView}. */
 @RunWith(LocalRobolectricTestRunner.class)
 @Config(manifest = Config.NONE)
-@LooperMode(LooperMode.Mode.PAUSED)
 public class MaterialSpinnerViewTest {
-    private FrameLayout mLayout;
     private MaterialSpinnerView mMaterialSpinnerView;
-    private CircularProgressDrawable mAnimationDrawable;
 
     @Before
     public void setUp() {
-        Activity activity = Robolectric.setupActivity(Activity.class);
-        activity.setTheme(R.style.Light);
-
-        // Attach the spinner inside a layout, so we can hide either the spinner
-        // or the parent view (ie. the layout) in the tests. Note that we
-        // require the looper to stay paused (LooperMode.Mode.PAUSED) for the
-        // duration of the tests. Otherwise, Robolectric will run through the
-        // animation and stop it before the tests get run. Because
-        // Robolectric.setupActivity() will run the looper until idle, we call
-        // setContentView() only after launching the activity above.
-        mMaterialSpinnerView = new MaterialSpinnerView(activity);
-        mAnimationDrawable = (CircularProgressDrawable) mMaterialSpinnerView.getDrawable();
-
-        mLayout = new FrameLayout(activity);
-        mLayout.addView(mMaterialSpinnerView);
-        activity.setContentView(mLayout);
+        Activity context = Robolectric.buildActivity(Activity.class).get();
+        context.setTheme(R.style.Light);
+        mMaterialSpinnerView = new MaterialSpinnerView(context);
     }
 
     @Test
     public void testInit_isVisible_spinnerStarted() {
         assertThat(mMaterialSpinnerView.getVisibility()).isEqualTo(View.VISIBLE);
-        assertThat(mMaterialSpinnerView.isShown()).isTrue();
 
-        assertThat(mAnimationDrawable.isRunning()).isTrue();
+        assertThat(((CircularProgressDrawable) mMaterialSpinnerView.getDrawable()).isRunning())
+                .isTrue();
     }
 
     @Test
     public void testSetVisibility_gone_stopsSpinner() {
         mMaterialSpinnerView.setVisibility(View.GONE);
 
-        assertThat(mAnimationDrawable.isRunning()).isFalse();
+        assertThat(((CircularProgressDrawable) mMaterialSpinnerView.getDrawable()).isRunning())
+                .isFalse();
     }
 
     @Test
     public void testSetVisibility_invisible_stopsSpinner() {
         mMaterialSpinnerView.setVisibility(View.INVISIBLE);
 
-        assertThat(mAnimationDrawable.isRunning()).isFalse();
+        assertThat(((CircularProgressDrawable) mMaterialSpinnerView.getDrawable()).isRunning())
+                .isFalse();
     }
 
     @Test
@@ -78,43 +62,7 @@
         mMaterialSpinnerView.setVisibility(View.GONE);
         mMaterialSpinnerView.setVisibility(View.VISIBLE);
 
-        assertThat(mAnimationDrawable.isRunning()).isTrue();
-    }
-
-    @Test
-    public void testContainerSetVisibility_gone_stopsSpinner() {
-        mLayout.setVisibility(View.GONE);
-
-        assertThat(mAnimationDrawable.isRunning()).isFalse();
-    }
-
-    @Test
-    public void testContainerSetVisibility_invisible_stopsSpinner() {
-        mLayout.setVisibility(View.INVISIBLE);
-
-        assertThat(mAnimationDrawable.isRunning()).isFalse();
-    }
-
-    @Test
-    public void testContainerSetVisibility_toTrue_startsSpinner() {
-        mLayout.setVisibility(View.GONE);
-        mLayout.setVisibility(View.VISIBLE);
-
-        assertThat(mAnimationDrawable.isRunning()).isTrue();
-    }
-
-    @Test
-    public void testDetachFromWindow_stopsSpinner() {
-        mLayout.removeView(mMaterialSpinnerView);
-
-        assertThat(mAnimationDrawable.isRunning()).isFalse();
-    }
-
-    @Test
-    public void testAttachToWindow_startsSpinner() {
-        mLayout.removeView(mMaterialSpinnerView);
-        mLayout.addView(mMaterialSpinnerView);
-
-        assertThat(mAnimationDrawable.isRunning()).isTrue();
+        assertThat(((CircularProgressDrawable) mMaterialSpinnerView.getDrawable()).isRunning())
+                .isTrue();
     }
 }
diff --git a/chrome/android/java/res/layout/infobar_footer.xml b/chrome/android/java/res/layout/infobar_footer.xml
index f9760674..d37b8fb 100644
--- a/chrome/android/java/res/layout/infobar_footer.xml
+++ b/chrome/android/java/res/layout/infobar_footer.xml
@@ -33,8 +33,9 @@
             android:ellipsize="middle"
             android:layout_height="wrap_content"
             android:layout_width="match_parent"
-            android:paddingStart="@dimen/infobar_padding"
-            android:singleLine="true"/>
+            android:paddingStart="@dimen/infobar_small_icon_margin"
+            android:singleLine="true"
+            android:textAppearance="@style/TextAppearance.TextMedium.Secondary"/>
     </LinearLayout>
 
 </LinearLayout>
\ No newline at end of file
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkPromoHeader.java b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkPromoHeader.java
index d08773b8..7d31c91 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkPromoHeader.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkPromoHeader.java
@@ -23,11 +23,11 @@
 import org.chromium.chrome.browser.signin.IdentityServicesProvider;
 import org.chromium.chrome.browser.signin.PersonalizedSigninPromoView;
 import org.chromium.chrome.browser.signin.ProfileDataCache;
-import org.chromium.chrome.browser.signin.SigninManager;
-import org.chromium.chrome.browser.signin.SigninManager.SignInStateObserver;
 import org.chromium.chrome.browser.signin.SigninPromoController;
 import org.chromium.chrome.browser.signin.SigninPromoUtil;
 import org.chromium.chrome.browser.signin.SyncPromoView;
+import org.chromium.chrome.browser.signin.services.SigninManager;
+import org.chromium.chrome.browser.signin.services.SigninManager.SignInStateObserver;
 import org.chromium.chrome.browser.sync.AndroidSyncSettings;
 import org.chromium.chrome.browser.sync.AndroidSyncSettings.AndroidSyncSettingsObserver;
 import org.chromium.components.signin.AccountManagerFacade;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/firstrun/FirstRunFlowSequencer.java b/chrome/android/java/src/org/chromium/chrome/browser/firstrun/FirstRunFlowSequencer.java
index 849e704..18d7f82 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/firstrun/FirstRunFlowSequencer.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/firstrun/FirstRunFlowSequencer.java
@@ -29,7 +29,7 @@
 import org.chromium.chrome.browser.profiles.Profile;
 import org.chromium.chrome.browser.services.AndroidChildAccountHelper;
 import org.chromium.chrome.browser.signin.IdentityServicesProvider;
-import org.chromium.chrome.browser.signin.SigninManager;
+import org.chromium.chrome.browser.signin.services.SigninManager;
 import org.chromium.chrome.browser.vr.VrModuleProvider;
 import org.chromium.components.embedder_support.util.UrlConstants;
 import org.chromium.components.signin.AccountManagerFacadeProvider;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/firstrun/FirstRunSignInProcessor.java b/chrome/android/java/src/org/chromium/chrome/browser/firstrun/FirstRunSignInProcessor.java
index 9323159..afbc204 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/firstrun/FirstRunSignInProcessor.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/firstrun/FirstRunSignInProcessor.java
@@ -18,9 +18,9 @@
 import org.chromium.chrome.browser.settings.SettingsLauncher;
 import org.chromium.chrome.browser.settings.SettingsLauncherImpl;
 import org.chromium.chrome.browser.signin.IdentityServicesProvider;
-import org.chromium.chrome.browser.signin.SigninManager;
-import org.chromium.chrome.browser.signin.SigninManager.SignInCallback;
 import org.chromium.chrome.browser.signin.UnifiedConsentServiceBridge;
+import org.chromium.chrome.browser.signin.services.SigninManager;
+import org.chromium.chrome.browser.signin.services.SigninManager.SignInCallback;
 import org.chromium.chrome.browser.sync.ProfileSyncService;
 import org.chromium.chrome.browser.sync.settings.ManageSyncSettings;
 import org.chromium.chrome.browser.sync.settings.SyncAndServicesSettings;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/firstrun/ForcedSigninProcessor.java b/chrome/android/java/src/org/chromium/chrome/browser/firstrun/ForcedSigninProcessor.java
index 8a1ccd5..35ede39 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/firstrun/ForcedSigninProcessor.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/firstrun/ForcedSigninProcessor.java
@@ -14,7 +14,7 @@
 import org.chromium.chrome.browser.profiles.Profile;
 import org.chromium.chrome.browser.services.AndroidChildAccountHelper;
 import org.chromium.chrome.browser.signin.IdentityServicesProvider;
-import org.chromium.chrome.browser.signin.SigninManager;
+import org.chromium.chrome.browser.signin.services.SigninManager;
 import org.chromium.chrome.browser.sync.ProfileSyncService;
 import org.chromium.chrome.browser.sync.settings.AccountManagementFragment;
 import org.chromium.components.signin.AccountManagerFacadeProvider;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/firstrun/SigninFirstRunFragment.java b/chrome/android/java/src/org/chromium/chrome/browser/firstrun/SigninFirstRunFragment.java
index f9aacce..bf1b170 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/firstrun/SigninFirstRunFragment.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/firstrun/SigninFirstRunFragment.java
@@ -16,7 +16,7 @@
 import org.chromium.chrome.R;
 import org.chromium.chrome.browser.ntp.cards.SignInPromo;
 import org.chromium.chrome.browser.signin.SigninFragmentBase;
-import org.chromium.chrome.browser.signin.SigninManager;
+import org.chromium.chrome.browser.signin.services.SigninManager;
 import org.chromium.components.signin.AccountManagerFacadeProvider;
 import org.chromium.components.signin.ChildAccountStatus;
 import org.chromium.components.signin.metrics.SigninAccessPoint;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/history/HistoryManager.java b/chrome/android/java/src/org/chromium/chrome/browser/history/HistoryManager.java
index d07b33b0..b1369ee 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/history/HistoryManager.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/history/HistoryManager.java
@@ -41,7 +41,7 @@
 import org.chromium.chrome.browser.settings.SettingsLauncher;
 import org.chromium.chrome.browser.settings.SettingsLauncherImpl;
 import org.chromium.chrome.browser.signin.IdentityServicesProvider;
-import org.chromium.chrome.browser.signin.SigninManager.SignInStateObserver;
+import org.chromium.chrome.browser.signin.services.SigninManager.SignInStateObserver;
 import org.chromium.chrome.browser.tab.TabLaunchType;
 import org.chromium.chrome.browser.tabmodel.TabCreator;
 import org.chromium.chrome.browser.ui.messages.snackbar.Snackbar;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ntp/RecentTabsManager.java b/chrome/android/java/src/org/chromium/chrome/browser/ntp/RecentTabsManager.java
index a9e2f4eff..ec0f260 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/ntp/RecentTabsManager.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/ntp/RecentTabsManager.java
@@ -19,10 +19,10 @@
 import org.chromium.chrome.browser.signin.IdentityServicesProvider;
 import org.chromium.chrome.browser.signin.PersonalizedSigninPromoView;
 import org.chromium.chrome.browser.signin.ProfileDataCache;
-import org.chromium.chrome.browser.signin.SigninManager;
-import org.chromium.chrome.browser.signin.SigninManager.SignInStateObserver;
 import org.chromium.chrome.browser.signin.SigninPromoController;
 import org.chromium.chrome.browser.signin.SigninPromoUtil;
+import org.chromium.chrome.browser.signin.services.SigninManager;
+import org.chromium.chrome.browser.signin.services.SigninManager.SignInStateObserver;
 import org.chromium.chrome.browser.sync.AndroidSyncSettings;
 import org.chromium.chrome.browser.sync.AndroidSyncSettings.AndroidSyncSettingsObserver;
 import org.chromium.chrome.browser.tab.Tab;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/SignInPromo.java b/chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/SignInPromo.java
index 097dac1..c7e1310 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/SignInPromo.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/SignInPromo.java
@@ -18,10 +18,10 @@
 import org.chromium.chrome.browser.profiles.Profile;
 import org.chromium.chrome.browser.signin.IdentityServicesProvider;
 import org.chromium.chrome.browser.signin.ProfileDataCache;
-import org.chromium.chrome.browser.signin.SigninManager;
-import org.chromium.chrome.browser.signin.SigninManager.SignInAllowedObserver;
-import org.chromium.chrome.browser.signin.SigninManager.SignInStateObserver;
 import org.chromium.chrome.browser.signin.SigninPromoController;
+import org.chromium.chrome.browser.signin.services.SigninManager;
+import org.chromium.chrome.browser.signin.services.SigninManager.SignInAllowedObserver;
+import org.chromium.chrome.browser.signin.services.SigninManager.SignInStateObserver;
 import org.chromium.chrome.browser.signin.services.SigninPreferencesManager;
 import org.chromium.components.signin.AccountManagerFacade;
 import org.chromium.components.signin.AccountManagerFacadeProvider;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/settings/MainSettings.java b/chrome/android/java/src/org/chromium/chrome/browser/settings/MainSettings.java
index f61eebfe..69bbf85 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/settings/MainSettings.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/settings/MainSettings.java
@@ -34,7 +34,7 @@
 import org.chromium.chrome.browser.search_engines.TemplateUrlServiceFactory;
 import org.chromium.chrome.browser.signin.IdentityServicesProvider;
 import org.chromium.chrome.browser.signin.SigninActivityLauncherImpl;
-import org.chromium.chrome.browser.signin.SigninManager;
+import org.chromium.chrome.browser.signin.services.SigninManager;
 import org.chromium.chrome.browser.sync.ProfileSyncService;
 import org.chromium.chrome.browser.sync.settings.ManageSyncSettings;
 import org.chromium.chrome.browser.sync.settings.SignInPreference;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/signin/IdentityServicesProvider.java b/chrome/android/java/src/org/chromium/chrome/browser/signin/IdentityServicesProvider.java
index 0338b1f..cf9aac2 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/signin/IdentityServicesProvider.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/signin/IdentityServicesProvider.java
@@ -9,6 +9,7 @@
 import org.chromium.base.ThreadUtils;
 import org.chromium.base.annotations.NativeMethods;
 import org.chromium.chrome.browser.profiles.Profile;
+import org.chromium.chrome.browser.signin.services.SigninManager;
 import org.chromium.components.signin.AccountTrackerService;
 import org.chromium.components.signin.identitymanager.IdentityManager;
 
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/signin/SignOutDialogFragment.java b/chrome/android/java/src/org/chromium/chrome/browser/signin/SignOutDialogFragment.java
index 1cded3e..97113e0 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/signin/SignOutDialogFragment.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/signin/SignOutDialogFragment.java
@@ -19,6 +19,7 @@
 import org.chromium.chrome.R;
 import org.chromium.chrome.browser.profiles.Profile;
 import org.chromium.chrome.browser.profiles.ProfileAccountManagementMetrics;
+import org.chromium.chrome.browser.signin.services.SigninManager;
 import org.chromium.components.signin.GAIAServiceType;
 
 /**
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninActivityLauncherImpl.java b/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninActivityLauncherImpl.java
index 538dd81..7def9b9 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninActivityLauncherImpl.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninActivityLauncherImpl.java
@@ -10,6 +10,7 @@
 import androidx.annotation.Nullable;
 import androidx.annotation.VisibleForTesting;
 
+import org.chromium.chrome.browser.signin.ui.SigninActivityLauncher;
 import org.chromium.components.signin.metrics.SigninAccessPoint;
 
 /**
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninFragment.java b/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninFragment.java
index 96270d2..d1844ad 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninFragment.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninFragment.java
@@ -19,6 +19,7 @@
 import org.chromium.chrome.browser.profiles.Profile;
 import org.chromium.chrome.browser.settings.SettingsLauncher;
 import org.chromium.chrome.browser.settings.SettingsLauncherImpl;
+import org.chromium.chrome.browser.signin.services.SigninManager;
 import org.chromium.chrome.browser.sync.ProfileSyncService;
 import org.chromium.chrome.browser.sync.settings.ManageSyncSettings;
 import org.chromium.chrome.browser.sync.settings.SyncAndServicesSettings;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninHelper.java b/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninHelper.java
index 6d9a2a4a..637c7de 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninHelper.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninHelper.java
@@ -21,7 +21,8 @@
 import org.chromium.base.TraceEvent;
 import org.chromium.base.task.AsyncTask;
 import org.chromium.chrome.browser.profiles.Profile;
-import org.chromium.chrome.browser.signin.SigninManager.SignInCallback;
+import org.chromium.chrome.browser.signin.services.SigninManager;
+import org.chromium.chrome.browser.signin.services.SigninManager.SignInCallback;
 import org.chromium.chrome.browser.signin.services.SigninPreferencesManager;
 import org.chromium.chrome.browser.sync.SyncController;
 import org.chromium.components.signin.AccountManagerFacadeProvider;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninManagerImpl.java b/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninManagerImpl.java
index 4a4ca3d..5f6af5a 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninManagerImpl.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninManagerImpl.java
@@ -24,6 +24,7 @@
 import org.chromium.chrome.browser.AppHooks;
 import org.chromium.chrome.browser.externalauth.ExternalAuthUtils;
 import org.chromium.chrome.browser.flags.ChromeFeatureList;
+import org.chromium.chrome.browser.signin.services.SigninManager;
 import org.chromium.chrome.browser.signin.services.SigninPreferencesManager;
 import org.chromium.chrome.browser.sync.AndroidSyncSettings;
 import org.chromium.chrome.browser.sync.ProfileSyncService;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninUtils.java b/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninUtils.java
index ea5d1da..7d426bc 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninUtils.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninUtils.java
@@ -25,6 +25,7 @@
 import org.chromium.chrome.browser.signin.account_picker.AccountPickerBottomSheetCoordinator;
 import org.chromium.chrome.browser.signin.account_picker.AccountPickerDelegate;
 import org.chromium.chrome.browser.signin.account_picker.AccountPickerDelegateImpl;
+import org.chromium.chrome.browser.signin.services.SigninManager;
 import org.chromium.chrome.browser.signin.services.WebSigninBridge;
 import org.chromium.chrome.browser.sync.settings.AccountManagementFragment;
 import org.chromium.chrome.browser.tabmodel.TabCreator;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/signin/account_picker/AccountPickerDelegateImpl.java b/chrome/android/java/src/org/chromium/chrome/browser/signin/account_picker/AccountPickerDelegateImpl.java
index 38024b30..459d932a 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/signin/account_picker/AccountPickerDelegateImpl.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/signin/account_picker/AccountPickerDelegateImpl.java
@@ -16,8 +16,8 @@
 import org.chromium.chrome.browser.incognito.IncognitoUtils;
 import org.chromium.chrome.browser.profiles.Profile;
 import org.chromium.chrome.browser.signin.IdentityServicesProvider;
-import org.chromium.chrome.browser.signin.SigninManager;
 import org.chromium.chrome.browser.signin.SigninUtils;
+import org.chromium.chrome.browser.signin.services.SigninManager;
 import org.chromium.chrome.browser.signin.services.WebSigninBridge;
 import org.chromium.chrome.browser.tab.Tab;
 import org.chromium.components.signin.AccountManagerFacadeProvider;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/sync/settings/AccountManagementFragment.java b/chrome/android/java/src/org/chromium/chrome/browser/sync/settings/AccountManagementFragment.java
index ea34073..2541fb8 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/sync/settings/AccountManagementFragment.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/sync/settings/AccountManagementFragment.java
@@ -36,9 +36,9 @@
 import org.chromium.chrome.browser.signin.ProfileDataCache;
 import org.chromium.chrome.browser.signin.SignOutDialogFragment;
 import org.chromium.chrome.browser.signin.SignOutDialogFragment.SignOutDialogListener;
-import org.chromium.chrome.browser.signin.SigninManager;
-import org.chromium.chrome.browser.signin.SigninManager.SignInStateObserver;
 import org.chromium.chrome.browser.signin.SigninUtils;
+import org.chromium.chrome.browser.signin.services.SigninManager;
+import org.chromium.chrome.browser.signin.services.SigninManager.SignInStateObserver;
 import org.chromium.chrome.browser.superviseduser.FilteringBehavior;
 import org.chromium.chrome.browser.sync.ProfileSyncService;
 import org.chromium.components.browser_ui.settings.ChromeBasePreference;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/sync/settings/GoogleServicesSettings.java b/chrome/android/java/src/org/chromium/chrome/browser/sync/settings/GoogleServicesSettings.java
index f9d56cd..3e116a9 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/sync/settings/GoogleServicesSettings.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/sync/settings/GoogleServicesSettings.java
@@ -33,8 +33,8 @@
 import org.chromium.chrome.browser.settings.ChromeManagedPreferenceDelegate;
 import org.chromium.chrome.browser.signin.IdentityServicesProvider;
 import org.chromium.chrome.browser.signin.SignOutDialogFragment;
-import org.chromium.chrome.browser.signin.SigninManager;
 import org.chromium.chrome.browser.signin.UnifiedConsentServiceBridge;
+import org.chromium.chrome.browser.signin.services.SigninManager;
 import org.chromium.components.browser_ui.settings.ChromeSwitchPreference;
 import org.chromium.components.browser_ui.settings.ManagedPreferenceDelegate;
 import org.chromium.components.browser_ui.settings.SettingsUtils;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/sync/settings/ManageSyncSettings.java b/chrome/android/java/src/org/chromium/chrome/browser/sync/settings/ManageSyncSettings.java
index c437801..8d879e0 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/sync/settings/ManageSyncSettings.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/sync/settings/ManageSyncSettings.java
@@ -48,9 +48,9 @@
 import org.chromium.chrome.browser.settings.SettingsActivity;
 import org.chromium.chrome.browser.signin.IdentityServicesProvider;
 import org.chromium.chrome.browser.signin.SignOutDialogFragment;
-import org.chromium.chrome.browser.signin.SigninManager;
 import org.chromium.chrome.browser.signin.SigninUtils;
 import org.chromium.chrome.browser.signin.UnifiedConsentServiceBridge;
+import org.chromium.chrome.browser.signin.services.SigninManager;
 import org.chromium.chrome.browser.sync.ProfileSyncService;
 import org.chromium.chrome.browser.sync.TrustedVaultClient;
 import org.chromium.chrome.browser.sync.settings.SyncSettingsUtils.SyncError;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/sync/settings/SignInPreference.java b/chrome/android/java/src/org/chromium/chrome/browser/sync/settings/SignInPreference.java
index caf5e33..5786a8b 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/sync/settings/SignInPreference.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/sync/settings/SignInPreference.java
@@ -21,8 +21,8 @@
 import org.chromium.chrome.browser.signin.DisplayableProfileData;
 import org.chromium.chrome.browser.signin.IdentityServicesProvider;
 import org.chromium.chrome.browser.signin.ProfileDataCache;
-import org.chromium.chrome.browser.signin.SigninManager.SignInAllowedObserver;
 import org.chromium.chrome.browser.signin.SigninUtils;
+import org.chromium.chrome.browser.signin.services.SigninManager.SignInAllowedObserver;
 import org.chromium.chrome.browser.sync.AndroidSyncSettings;
 import org.chromium.chrome.browser.sync.ProfileSyncService;
 import org.chromium.chrome.browser.sync.ProfileSyncService.SyncStateChangedListener;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/sync/settings/SyncPromoPreference.java b/chrome/android/java/src/org/chromium/chrome/browser/sync/settings/SyncPromoPreference.java
index 4a1951f..f0d6efb 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/sync/settings/SyncPromoPreference.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/sync/settings/SyncPromoPreference.java
@@ -20,13 +20,12 @@
 import org.chromium.chrome.browser.signin.IdentityServicesProvider;
 import org.chromium.chrome.browser.signin.PersonalizedSigninPromoView;
 import org.chromium.chrome.browser.signin.ProfileDataCache;
-import org.chromium.chrome.browser.signin.SigninManager.SignInAllowedObserver;
 import org.chromium.chrome.browser.signin.SigninPromoController;
 import org.chromium.chrome.browser.signin.SigninPromoUtil;
+import org.chromium.chrome.browser.signin.services.SigninManager.SignInAllowedObserver;
 import org.chromium.chrome.browser.sync.AndroidSyncSettings;
 import org.chromium.chrome.browser.sync.ProfileSyncService;
 import org.chromium.chrome.browser.sync.ProfileSyncService.SyncStateChangedListener;
-import org.chromium.chrome.browser.sync.settings.SignInPreference.State;
 import org.chromium.components.signin.AccountManagerFacade;
 import org.chromium.components.signin.AccountManagerFacadeProvider;
 import org.chromium.components.signin.AccountsChangeObserver;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tab/TabImpl.java b/chrome/android/java/src/org/chromium/chrome/browser/tab/TabImpl.java
index 335aecde..6bf3dc7 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/tab/TabImpl.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/tab/TabImpl.java
@@ -24,6 +24,7 @@
 import org.chromium.base.UserDataHost;
 import org.chromium.base.annotations.CalledByNative;
 import org.chromium.base.annotations.NativeMethods;
+import org.chromium.base.supplier.ObservableSupplierImpl;
 import org.chromium.chrome.R;
 import org.chromium.chrome.browser.WarmupManager;
 import org.chromium.chrome.browser.WebContentsFactory;
@@ -189,6 +190,8 @@
     private final UserDataHost mUserDataHost = new UserDataHost();
 
     private boolean mIsDestroyed;
+    private ObservableSupplierImpl<Boolean> mIsTabSaveEnabledSupplier =
+            new ObservableSupplierImpl<>();
 
     /**
      * Creates an instance of a {@link TabImpl}.
@@ -205,6 +208,7 @@
      */
     @SuppressLint("HandlerLeak")
     TabImpl(int id, Tab parent, boolean incognito, @Nullable @TabLaunchType Integer launchType) {
+        mIsTabSaveEnabledSupplier.set(false);
         mId = TabIdManager.getInstance().generateValidId(id);
         mIncognito = incognito;
         if (parent == null) {
@@ -757,6 +761,11 @@
                 && TabImplJni.get().getHideFutureNavigations(mNativeTabAndroid);
     }
 
+    @Override
+    public void setIsTabSaveEnabled(boolean isTabSaveEnabled) {
+        mIsTabSaveEnabledSupplier.set(isTabSaveEnabled);
+    }
+
     // TabObscuringHandler.Observer
 
     @Override
@@ -851,6 +860,7 @@
             if (CriticalPersistedTabData.from(this).getTimestampMillis() == INVALID_TIMESTAMP) {
                 CriticalPersistedTabData.from(this).setTimestampMillis(System.currentTimeMillis());
             }
+            registerTabSaving();
             String appId;
             Boolean hasThemeColor;
             int themeColor;
@@ -871,6 +881,12 @@
         }
     }
 
+    @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
+    public void registerTabSaving() {
+        CriticalPersistedTabData.from(this).registerIsTabSaveEnabledSupplier(
+                mIsTabSaveEnabledSupplier);
+    }
+
     private boolean useCriticalPersistedTabData() {
         return CachedFeatureFlags.isEnabled(ChromeFeatureList.CRITICAL_PERSISTED_TAB_DATA);
     }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabModelImpl.java b/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabModelImpl.java
index 3129697..254614e 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabModelImpl.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabModelImpl.java
@@ -662,6 +662,7 @@
     private void finalizeTabClosure(Tab tab, boolean notifyTabClosureCommitted) {
         if (mTabContentManager != null) mTabContentManager.removeTabThumbnail(tab.getId());
         mTabSaver.removeTabFromQueues(tab);
+        tab.setIsTabSaveEnabled(false);
 
         if (!isIncognito()) HistoricalTabSaver.createHistoricalTab(tab);
 
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabPersistentStore.java b/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabPersistentStore.java
index 4f64de8..c970ba3 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabPersistentStore.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabPersistentStore.java
@@ -756,6 +756,7 @@
             return;
         }
         mTabsToSave.addLast(tab);
+        tab.setIsTabSaveEnabled(isCriticalPersistedTabDataEnabled());
     }
 
     public void removeTabFromQueues(Tab tab) {
@@ -773,8 +774,6 @@
             mSaveTabTask = null;
             saveNextTab();
         }
-        // TODO(crbug.com/1119454) hook delete() into Tab#destroy()
-        CriticalPersistedTabData.from(tab).delete();
         cleanupPersistentData(tab.getId(), tab.isIncognito());
     }
 
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/signin/ConfirmSyncDataIntegrationTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/signin/ConfirmSyncDataIntegrationTest.java
index 8d9ec78..7fcf737d 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/signin/ConfirmSyncDataIntegrationTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/signin/ConfirmSyncDataIntegrationTest.java
@@ -37,6 +37,7 @@
 import org.chromium.chrome.R;
 import org.chromium.chrome.browser.flags.ChromeSwitches;
 import org.chromium.chrome.browser.profiles.Profile;
+import org.chromium.chrome.browser.signin.services.SigninManager;
 import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
 import org.chromium.content_public.browser.test.util.TestThreadUtils;
 import org.chromium.ui.test.util.DummyUiActivityTestCase;
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/signin/SignOutDialogRenderTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/signin/SignOutDialogRenderTest.java
index 05bc9c9..badcdac 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/signin/SignOutDialogRenderTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/signin/SignOutDialogRenderTest.java
@@ -30,6 +30,7 @@
 import org.chromium.base.test.util.JniMocker;
 import org.chromium.chrome.browser.flags.ChromeSwitches;
 import org.chromium.chrome.browser.profiles.Profile;
+import org.chromium.chrome.browser.signin.services.SigninManager;
 import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
 import org.chromium.chrome.test.util.ChromeRenderTestRule;
 import org.chromium.components.signin.GAIAServiceType;
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/signin/SigninSignoutIntegrationTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/signin/SigninSignoutIntegrationTest.java
index 3a252820..d029a8d0 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/signin/SigninSignoutIntegrationTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/signin/SigninSignoutIntegrationTest.java
@@ -38,6 +38,7 @@
 import org.chromium.chrome.browser.profiles.Profile;
 import org.chromium.chrome.browser.profiles.ProfileAccountManagementMetrics;
 import org.chromium.chrome.browser.settings.SettingsActivityTestRule;
+import org.chromium.chrome.browser.signin.services.SigninManager;
 import org.chromium.chrome.browser.sync.settings.AccountManagementFragment;
 import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
 import org.chromium.chrome.test.ChromeTabbedActivityTestRule;
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/tab/state/CriticalPersistedTabDataTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/tab/state/CriticalPersistedTabDataTest.java
index f0f14b0..29b8cb0 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/tab/state/CriticalPersistedTabDataTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/tab/state/CriticalPersistedTabDataTest.java
@@ -4,6 +4,10 @@
 
 package org.chromium.chrome.browser.tab.state;
 
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+
 import androidx.test.filters.SmallTest;
 
 import org.junit.Assert;
@@ -15,9 +19,12 @@
 
 import org.chromium.base.Callback;
 import org.chromium.base.ThreadUtils;
+import org.chromium.base.supplier.ObservableSupplierImpl;
 import org.chromium.base.test.BaseJUnit4ClassRunner;
+import org.chromium.base.test.UiThreadTest;
 import org.chromium.chrome.browser.tab.MockTab;
 import org.chromium.chrome.browser.tab.Tab;
+import org.chromium.chrome.browser.tab.TabImpl;
 import org.chromium.chrome.browser.tab.WebContentsState;
 import org.chromium.chrome.test.ChromeBrowserTestRule;
 
@@ -50,11 +57,12 @@
     }
 
     private CriticalPersistedTabData mCriticalPersistedTabData;
-
     private MockPersistedTabDataStorage mStorage;
 
     private static Tab mockTab(int id, boolean isEncrypted) {
-        return new MockTab(id, isEncrypted);
+        Tab tab = MockTab.createAndInitialize(id, isEncrypted);
+        tab.setIsTabSaveEnabled(true);
+        return tab;
     }
 
     @Before
@@ -96,6 +104,9 @@
                             ROOT_ID, TIMESTAMP, WEB_CONTENTS_STATE, CONTENT_STATE_VERSION,
                             OPENER_APP_ID, THEME_COLOR, LAUNCH_TYPE_AT_CREATION);
             mStorage.setSemaphore(saveSemaphore);
+            ObservableSupplierImpl<Boolean> supplier = new ObservableSupplierImpl<>();
+            supplier.set(true);
+            criticalPersistedTabData.registerIsTabSaveEnabledSupplier(supplier);
             criticalPersistedTabData.saveForTesting();
             acquireSemaphore(saveSemaphore);
             CriticalPersistedTabData.from(mockTab(TAB_ID, isEncrypted), callback);
@@ -140,4 +151,27 @@
             throw new RuntimeException(e);
         }
     }
+
+    @Test
+    @SmallTest
+    @UiThreadTest
+    public void testTabSaving() throws Throwable {
+        TabImpl tab = new MockTab(1, false);
+        CriticalPersistedTabData spyCriticalPersistedTabData =
+                spy(CriticalPersistedTabData.from(tab));
+        tab = MockTab.initializeWithCriticalPersistedTabData(tab, spyCriticalPersistedTabData);
+        tab.registerTabSaving();
+
+        tab.setIsTabSaveEnabled(true);
+        verify(spyCriticalPersistedTabData, times(1)).save();
+        verify(spyCriticalPersistedTabData, times(0)).delete();
+
+        tab.setIsTabSaveEnabled(false);
+        verify(spyCriticalPersistedTabData, times(1)).save();
+        verify(spyCriticalPersistedTabData, times(1)).delete();
+
+        tab.setIsTabSaveEnabled(true);
+        verify(spyCriticalPersistedTabData, times(2)).save();
+        verify(spyCriticalPersistedTabData, times(1)).delete();
+    }
 }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/tab/state/PersistedTabDataTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/tab/state/PersistedTabDataTest.java
index 1601154..09a03d0 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/tab/state/PersistedTabDataTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/tab/state/PersistedTabDataTest.java
@@ -12,6 +12,7 @@
 import org.junit.runner.RunWith;
 import org.mockito.MockitoAnnotations;
 
+import org.chromium.base.supplier.ObservableSupplierImpl;
 import org.chromium.base.test.BaseJUnit4ClassRunner;
 import org.chromium.base.test.UiThreadTest;
 import org.chromium.chrome.browser.tab.MockTab;
@@ -34,12 +35,15 @@
     @UiThreadTest
     @Test
     public void testCacheCallbacks() throws InterruptedException {
-        Tab tab = new MockTab(1, false);
+        Tab tab = MockTab.createAndInitialize(1, false);
+        tab.setIsTabSaveEnabled(true);
         MockPersistedTabData mockPersistedTabData = new MockPersistedTabData(tab, INITIAL_VALUE);
+        registerObserverSupplier(mockPersistedTabData);
         mockPersistedTabData.save();
         // 1
         MockPersistedTabData.from(tab, (res) -> {
             Assert.assertEquals(INITIAL_VALUE, res.getField());
+            registerObserverSupplier(tab.getUserDataHost().getUserData(MockPersistedTabData.class));
             tab.getUserDataHost().getUserData(MockPersistedTabData.class).setField(CHANGED_VALUE);
             // Caching callbacks means 2) shouldn't overwrite CHANGED_VALUE
             // back to INITIAL_VALUE in the callback.
@@ -52,4 +56,10 @@
             mockPersistedTabData.delete();
         });
     }
+
+    private static void registerObserverSupplier(MockPersistedTabData mockPersistedTabData) {
+        ObservableSupplierImpl<Boolean> supplier = new ObservableSupplierImpl<>();
+        supplier.set(true);
+        mockPersistedTabData.registerIsTabSaveEnabledSupplier(supplier);
+    }
 }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/tab/state/ShoppingPersistedTabDataTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/tab/state/ShoppingPersistedTabDataTest.java
index 86a24c6..f54387d 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/tab/state/ShoppingPersistedTabDataTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/tab/state/ShoppingPersistedTabDataTest.java
@@ -24,6 +24,7 @@
 import org.mockito.stubbing.Answer;
 
 import org.chromium.base.Callback;
+import org.chromium.base.supplier.ObservableSupplierImpl;
 import org.chromium.base.test.BaseJUnit4ClassRunner;
 import org.chromium.base.test.UiThreadTest;
 import org.chromium.base.test.util.JniMocker;
@@ -66,6 +67,9 @@
     private static final long LOW_PRICE_MICROS = 100000000L;
     private static final String HIGH_PRICE_FORMATTED = "$141";
     private static final String LOW_PRICE_FORMATTED = "$100";
+    private static final String UNITED_STATES_CURRENCY_CODE = "USD";
+    private static final String GREAT_BRITAIN_CURRENCY_CODE = "GBP";
+    private static final String JAPAN_CURRENCY_CODE = "JPY";
 
     private static final String EMPTY_PRICE = "";
     private static final String ENDPOINT_RESPONSE_INITIAL =
@@ -95,6 +99,9 @@
     public void testShoppingProto() {
         Tab tab = new MockTab(TAB_ID, IS_INCOGNITO);
         ShoppingPersistedTabData shoppingPersistedTabData = new ShoppingPersistedTabData(tab);
+        ObservableSupplierImpl<Boolean> supplier = new ObservableSupplierImpl<>();
+        supplier.set(true);
+        shoppingPersistedTabData.registerIsTabSaveEnabledSupplier(supplier);
         shoppingPersistedTabData.setPriceMicros(PRICE_MICROS, null);
         byte[] serialized = shoppingPersistedTabData.serialize();
         ShoppingPersistedTabData deserialized = new ShoppingPersistedTabData(tab);
@@ -132,6 +139,8 @@
                         PRICE_MICROS, shoppingPersistedTabData.getPreviousPriceMicros());
                 Assert.assertEquals(mLastPriceChangeTimeMs,
                         shoppingPersistedTabData.getLastPriceChangeTimeMs());
+                Assert.assertEquals(
+                        UNITED_STATES_CURRENCY_CODE, shoppingPersistedTabData.getCurrencyCode());
                 semaphore.release();
             });
         });
@@ -146,6 +155,8 @@
             ShoppingPersistedTabData.from(tab, (shoppingPersistedTabData) -> {
                 verifyEndpointFetcherCalled(1);
                 Assert.assertEquals(PRICE_MICROS, shoppingPersistedTabData.getPriceMicros());
+                Assert.assertEquals(
+                        UNITED_STATES_CURRENCY_CODE, shoppingPersistedTabData.getCurrencyCode());
                 Assert.assertEquals(ShoppingPersistedTabData.NO_PRICE_KNOWN,
                         shoppingPersistedTabData.getPreviousPriceMicros());
                 Assert.assertEquals(ShoppingPersistedTabData.NO_TRANSITIONS_OCCURRED,
@@ -186,6 +197,8 @@
                 Assert.assertEquals(PRICE_MICROS, shoppingPersistedTabData.getPriceMicros());
                 Assert.assertEquals(ShoppingPersistedTabData.NO_PRICE_KNOWN,
                         shoppingPersistedTabData.getPreviousPriceMicros());
+                Assert.assertEquals(
+                        UNITED_STATES_CURRENCY_CODE, shoppingPersistedTabData.getCurrencyCode());
                 // By setting time to live to be a negative number, an update
                 // will be forced in the subsequent call
                 initialSemaphore.release();
@@ -214,8 +227,8 @@
     @SmallTest
     @Test
     public void testPriceDrop() {
-        Tab tab = createTabOnUiThread(TAB_ID, IS_INCOGNITO);
-        ShoppingPersistedTabData shoppingPersistedTabData = new ShoppingPersistedTabData(tab);
+        ShoppingPersistedTabData shoppingPersistedTabData =
+                createShoppingPersistedTabDataWithDefaults();
         // Prices unknown is not a price drop
         Assert.assertNull(shoppingPersistedTabData.getPriceDrop());
 
@@ -242,7 +255,7 @@
     @Test
     public void testPriceDropFilterSamePrice() {
         ShoppingPersistedTabData shoppingPersistedTabData =
-                new ShoppingPersistedTabData(createTabOnUiThread(TAB_ID, IS_INCOGNITO));
+                createShoppingPersistedTabDataWithDefaults();
 
         // $10 -> $10 is not a price drop (same price)
         shoppingPersistedTabData.setPreviousPriceMicrosForTesting(10_000_000L);
@@ -255,7 +268,7 @@
     @Test
     public void testPriceDropFilterNoFormattedPriceDifference() {
         ShoppingPersistedTabData shoppingPersistedTabData =
-                new ShoppingPersistedTabData(createTabOnUiThread(TAB_ID, IS_INCOGNITO));
+                createShoppingPersistedTabDataWithDefaults();
 
         // $10.40 -> $10 (which would be displayed $10 -> $10 is not a price drop)
         shoppingPersistedTabData.setPreviousPriceMicrosForTesting(10_400_000L);
@@ -268,7 +281,7 @@
     @Test
     public void testPriceDropFilterAbsoluteDifferenceTooSmall() {
         ShoppingPersistedTabData shoppingPersistedTabData =
-                new ShoppingPersistedTabData(createTabOnUiThread(TAB_ID, IS_INCOGNITO));
+                createShoppingPersistedTabDataWithDefaults();
 
         // $2 -> $1 ($1 price drop - less than $2. Not big enough)
         shoppingPersistedTabData.setPreviousPriceMicrosForTesting(1_000_000L);
@@ -281,7 +294,7 @@
     @Test
     public void testPriceDropFilterPriceIncrease() {
         ShoppingPersistedTabData shoppingPersistedTabData =
-                new ShoppingPersistedTabData(createTabOnUiThread(TAB_ID, IS_INCOGNITO));
+                createShoppingPersistedTabDataWithDefaults();
 
         // $9.33 -> $9.66 price increase is not a price drop
         shoppingPersistedTabData.setPreviousPriceMicrosForTesting(9_330_000L);
@@ -294,7 +307,7 @@
     @Test
     public void testPriceDropFilterPercentageDropNotEnough() {
         ShoppingPersistedTabData shoppingPersistedTabData =
-                new ShoppingPersistedTabData(createTabOnUiThread(TAB_ID, IS_INCOGNITO));
+                createShoppingPersistedTabDataWithDefaults();
 
         // $50 -> $46 (8% price drop (less than 10%) not big enough)
         shoppingPersistedTabData.setPreviousPriceMicrosForTesting(50_000_000L);
@@ -302,12 +315,27 @@
         Assert.assertNull(shoppingPersistedTabData.getPriceDrop());
     }
 
+    private ShoppingPersistedTabData createShoppingPersistedTabDataWithDefaults() {
+        ShoppingPersistedTabData shoppingPersistedTabData =
+                new ShoppingPersistedTabData(createTabOnUiThread(TAB_ID, IS_INCOGNITO));
+        shoppingPersistedTabData.setCurrencyCode(UNITED_STATES_CURRENCY_CODE);
+        return shoppingPersistedTabData;
+    }
+
+    private ShoppingPersistedTabData createShoppingPersistedTabDataWithCurrencyCode(
+            int tabId, boolean isIncognito, String currencyCode) {
+        ShoppingPersistedTabData shoppingPersistedTabData =
+                new ShoppingPersistedTabData(createTabOnUiThread(tabId, isIncognito));
+        shoppingPersistedTabData.setCurrencyCode(currencyCode);
+        return shoppingPersistedTabData;
+    }
+
     @UiThreadTest
     @SmallTest
     @Test
     public void testPriceDropFilterAllowedPriceDrop1() {
         ShoppingPersistedTabData shoppingPersistedTabData =
-                new ShoppingPersistedTabData(createTabOnUiThread(TAB_ID, IS_INCOGNITO));
+                createShoppingPersistedTabDataWithDefaults();
 
         // $10 -> $7 (30% and $3 price drop is big enough)
         shoppingPersistedTabData.setPreviousPriceMicrosForTesting(10_000_000L);
@@ -322,7 +350,7 @@
     @Test
     public void testPriceDropFilterAllowedPriceDrop2() {
         ShoppingPersistedTabData shoppingPersistedTabData =
-                new ShoppingPersistedTabData(createTabOnUiThread(TAB_ID, IS_INCOGNITO));
+                createShoppingPersistedTabDataWithDefaults();
 
         // $15.72 -> $4.80 (70% and $10.92 price drop is big enough)
         shoppingPersistedTabData.setPreviousPriceMicrosForTesting(15_720_000L);
@@ -337,7 +365,7 @@
     @Test
     public void testPriceDropFilterAllowedPriceDrop3() {
         ShoppingPersistedTabData shoppingPersistedTabData =
-                new ShoppingPersistedTabData(createTabOnUiThread(TAB_ID, IS_INCOGNITO));
+                createShoppingPersistedTabDataWithDefaults();
 
         // $20 -> $10 (50% and $10 price drop is big enough)
         shoppingPersistedTabData.setPreviousPriceMicrosForTesting(20_000_000L);
@@ -352,7 +380,7 @@
     @Test
     public void testPriceDropFilterAllowedPriceDrop4() {
         ShoppingPersistedTabData shoppingPersistedTabData =
-                new ShoppingPersistedTabData(createTabOnUiThread(TAB_ID, IS_INCOGNITO));
+                createShoppingPersistedTabDataWithDefaults();
 
         // $30 -> $27 (10% and $3 price drop is big enough)
         shoppingPersistedTabData.setPreviousPriceMicrosForTesting(30_000_000L);
@@ -367,7 +395,7 @@
     @Test
     public void testPriceDropFilterAllowedPriceDrop5() {
         ShoppingPersistedTabData shoppingPersistedTabData =
-                new ShoppingPersistedTabData(createTabOnUiThread(TAB_ID, IS_INCOGNITO));
+                createShoppingPersistedTabDataWithDefaults();
 
         // $30.65 -> $25.50 (17% and $5.15 price drop is big enough)
         shoppingPersistedTabData.setPreviousPriceMicrosForTesting(30_650_000L);
@@ -382,7 +410,7 @@
     @Test
     public void testPriceDropFilterAllowedPriceDrop6() {
         ShoppingPersistedTabData shoppingPersistedTabData =
-                new ShoppingPersistedTabData(createTabOnUiThread(TAB_ID, IS_INCOGNITO));
+                createShoppingPersistedTabDataWithDefaults();
 
         // $9.65 -> $3.80 (40% and $5.85 price drop is big enough)
         shoppingPersistedTabData.setPreviousPriceMicrosForTesting(9_650_000L);
@@ -397,7 +425,7 @@
     @Test
     public void testPriceDropFilterAllowedPriceDrop7() {
         ShoppingPersistedTabData shoppingPersistedTabData =
-                new ShoppingPersistedTabData(createTabOnUiThread(TAB_ID, IS_INCOGNITO));
+                createShoppingPersistedTabDataWithDefaults();
 
         // $9.33 -> $0.90 (96% price drop and $8.43 price drop is big enough)
         shoppingPersistedTabData.setPreviousPriceMicrosForTesting(9_330_000L);
@@ -412,7 +440,7 @@
     @Test
     public void testPriceDropFilterAllowedPriceDrop8() {
         ShoppingPersistedTabData shoppingPersistedTabData =
-                new ShoppingPersistedTabData(createTabOnUiThread(TAB_ID, IS_INCOGNITO));
+                createShoppingPersistedTabDataWithDefaults();
 
         // $20 -> $18 (10% price drop and $2 price drop is big enough)
         shoppingPersistedTabData.setPreviousPriceMicrosForTesting(20_000_000L);
@@ -427,7 +455,7 @@
     @Test
     public void testPriceDropFilterAllowedPriceDrop9() {
         ShoppingPersistedTabData shoppingPersistedTabData =
-                new ShoppingPersistedTabData(createTabOnUiThread(TAB_ID, IS_INCOGNITO));
+                createShoppingPersistedTabDataWithDefaults();
 
         // $2 -> $0 ($2 price drop is big enough)
         shoppingPersistedTabData.setPreviousPriceMicrosForTesting(2_000_000L);
@@ -440,9 +468,40 @@
     @UiThreadTest
     @SmallTest
     @Test
-    public void testStalePriceDrop() {
-        Tab tab = createTabOnUiThread(TAB_ID, IS_INCOGNITO);
-        ShoppingPersistedTabData shoppingPersistedTabData = new ShoppingPersistedTabData(tab);
+    public void testPriceDropGBP() {
+        ShoppingPersistedTabData shoppingPersistedTabData =
+                createShoppingPersistedTabDataWithCurrencyCode(
+                        TAB_ID, IS_INCOGNITO, GREAT_BRITAIN_CURRENCY_CODE);
+
+        shoppingPersistedTabData.setPreviousPriceMicrosForTesting(15_000_000L);
+        shoppingPersistedTabData.setPriceMicrosForTesting(9_560_000L);
+        Assert.assertNotNull(shoppingPersistedTabData.getPriceDrop());
+        Assert.assertEquals("£15", shoppingPersistedTabData.getPriceDrop().previousPrice);
+        Assert.assertEquals("£9.56", shoppingPersistedTabData.getPriceDrop().price);
+    }
+
+    @UiThreadTest
+    @SmallTest
+    @Test
+    public void testPriceDropJPY() {
+        ShoppingPersistedTabData shoppingPersistedTabData =
+                createShoppingPersistedTabDataWithCurrencyCode(
+                        TAB_ID, IS_INCOGNITO, JAPAN_CURRENCY_CODE);
+
+        shoppingPersistedTabData.setPreviousPriceMicrosForTesting(3_140_000_000_000L);
+        shoppingPersistedTabData.setPriceMicrosForTesting(287_000_000_000L);
+        Assert.assertNotNull(shoppingPersistedTabData.getPriceDrop());
+        Assert.assertEquals("¥3,140,000", shoppingPersistedTabData.getPriceDrop().previousPrice);
+        Assert.assertEquals("¥287,000", shoppingPersistedTabData.getPriceDrop().price);
+    }
+
+    @UiThreadTest
+    @SmallTest
+    @Test
+    public void testStalePriceDropUSD() {
+        ShoppingPersistedTabData shoppingPersistedTabData =
+                createShoppingPersistedTabDataWithCurrencyCode(
+                        TAB_ID, IS_INCOGNITO, UNITED_STATES_CURRENCY_CODE);
         // $10 -> $5 (50% and $5 price drop is big enough)
         shoppingPersistedTabData.setPreviousPriceMicrosForTesting(10000000L);
         shoppingPersistedTabData.setPriceMicrosForTesting(5000000L);
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/signin/ConfirmImportSyncDataDialogTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/signin/ConfirmImportSyncDataDialogTest.java
index 408ab04..d7ba03f 100644
--- a/chrome/android/junit/src/org/chromium/chrome/browser/signin/ConfirmImportSyncDataDialogTest.java
+++ b/chrome/android/junit/src/org/chromium/chrome/browser/signin/ConfirmImportSyncDataDialogTest.java
@@ -26,6 +26,7 @@
 import org.chromium.base.test.BaseRobolectricTestRunner;
 import org.chromium.chrome.R;
 import org.chromium.chrome.browser.profiles.Profile;
+import org.chromium.chrome.browser.signin.services.SigninManager;
 
 /** Tests for {@link ConfirmImportSyncDataDialog}. */
 @RunWith(BaseRobolectricTestRunner.class)
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/signin/ConfirmSyncDataStateMachineTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/signin/ConfirmSyncDataStateMachineTest.java
index 38af0af..a60634b 100644
--- a/chrome/android/junit/src/org/chromium/chrome/browser/signin/ConfirmSyncDataStateMachineTest.java
+++ b/chrome/android/junit/src/org/chromium/chrome/browser/signin/ConfirmSyncDataStateMachineTest.java
@@ -24,6 +24,7 @@
 import org.chromium.base.Callback;
 import org.chromium.base.test.BaseRobolectricTestRunner;
 import org.chromium.chrome.browser.profiles.Profile;
+import org.chromium.chrome.browser.signin.services.SigninManager;
 
 /** Tests for {@link ConfirmSyncDataStateMachine}. */
 @RunWith(BaseRobolectricTestRunner.class)
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/signin/SignOutDialogFragmentTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/signin/SignOutDialogFragmentTest.java
index 7939716..c15ae9e 100644
--- a/chrome/android/junit/src/org/chromium/chrome/browser/signin/SignOutDialogFragmentTest.java
+++ b/chrome/android/junit/src/org/chromium/chrome/browser/signin/SignOutDialogFragmentTest.java
@@ -34,6 +34,7 @@
 import org.chromium.chrome.R;
 import org.chromium.chrome.browser.profiles.Profile;
 import org.chromium.chrome.browser.profiles.ProfileAccountManagementMetrics;
+import org.chromium.chrome.browser.signin.services.SigninManager;
 import org.chromium.components.signin.GAIAServiceType;
 
 /** Tests for {@link SignOutDialogFragment}. */
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/signin/SigninManagerTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/signin/SigninManagerTest.java
index 16839f20..8ec9149 100644
--- a/chrome/android/junit/src/org/chromium/chrome/browser/signin/SigninManagerTest.java
+++ b/chrome/android/junit/src/org/chromium/chrome/browser/signin/SigninManagerTest.java
@@ -31,6 +31,7 @@
 import org.chromium.base.test.util.JniMocker;
 import org.chromium.chrome.browser.externalauth.ExternalAuthUtils;
 import org.chromium.chrome.browser.flags.ChromeFeatureList;
+import org.chromium.chrome.browser.signin.services.SigninManager;
 import org.chromium.chrome.browser.sync.AndroidSyncSettings;
 import org.chromium.chrome.browser.sync.ProfileSyncService;
 import org.chromium.chrome.test.util.browser.Features;
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/signin/SigninUtilsAccountPickerTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/signin/SigninUtilsAccountPickerTest.java
index a84c0a0..ee51dbdc 100644
--- a/chrome/android/junit/src/org/chromium/chrome/browser/signin/SigninUtilsAccountPickerTest.java
+++ b/chrome/android/junit/src/org/chromium/chrome/browser/signin/SigninUtilsAccountPickerTest.java
@@ -21,6 +21,7 @@
 import org.chromium.base.test.BaseRobolectricTestRunner;
 import org.chromium.chrome.browser.profiles.Profile;
 import org.chromium.chrome.browser.signin.account_picker.AccountConsistencyPromoAction;
+import org.chromium.chrome.browser.signin.services.SigninManager;
 import org.chromium.chrome.test.util.browser.signin.AccountManagerTestRule;
 import org.chromium.ui.base.WindowAndroid;
 
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/signin/SigninUtilsStartActivityTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/signin/SigninUtilsStartActivityTest.java
index 124290a..4e1fdc1 100644
--- a/chrome/android/junit/src/org/chromium/chrome/browser/signin/SigninUtilsStartActivityTest.java
+++ b/chrome/android/junit/src/org/chromium/chrome/browser/signin/SigninUtilsStartActivityTest.java
@@ -25,6 +25,7 @@
 import org.chromium.base.test.BaseRobolectricTestRunner;
 import org.chromium.chrome.R;
 import org.chromium.chrome.browser.profiles.Profile;
+import org.chromium.chrome.browser.signin.services.SigninManager;
 import org.chromium.components.signin.metrics.SigninAccessPoint;
 
 /** Tests for the method startSigninActivityIfAllowed {@link SigninUtils}. */
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/signin/account_picker/AccountPickerDelegateTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/signin/account_picker/AccountPickerDelegateTest.java
index e0fe8f0..e951cc3 100644
--- a/chrome/android/junit/src/org/chromium/chrome/browser/signin/account_picker/AccountPickerDelegateTest.java
+++ b/chrome/android/junit/src/org/chromium/chrome/browser/signin/account_picker/AccountPickerDelegateTest.java
@@ -35,7 +35,7 @@
 import org.chromium.chrome.browser.incognito.IncognitoUtils;
 import org.chromium.chrome.browser.profiles.Profile;
 import org.chromium.chrome.browser.signin.IdentityServicesProvider;
-import org.chromium.chrome.browser.signin.SigninManager;
+import org.chromium.chrome.browser.signin.services.SigninManager;
 import org.chromium.chrome.browser.signin.services.WebSigninBridge;
 import org.chromium.chrome.browser.tab.Tab;
 import org.chromium.chrome.test.util.browser.signin.AccountManagerTestRule;
diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn
index 3b8931f..9d53dc5 100644
--- a/chrome/browser/BUILD.gn
+++ b/chrome/browser/BUILD.gn
@@ -6758,6 +6758,8 @@
       "chromeos/login/ui/mock_login_display.h",
       "chromeos/login/ui/mock_login_display_host.cc",
       "chromeos/login/ui/mock_login_display_host.h",
+      "chromeos/login/ui/mock_signin_ui.cc",
+      "chromeos/login/ui/mock_signin_ui.h",
       "chromeos/login/users/avatar/mock_user_image_manager.cc",
       "chromeos/login/users/avatar/mock_user_image_manager.h",
       "chromeos/login/users/fake_supervised_user_manager.cc",
diff --git a/chrome/browser/apps/guest_view/web_view_browsertest.cc b/chrome/browser/apps/guest_view/web_view_browsertest.cc
index e28f921f..378e16e 100644
--- a/chrome/browser/apps/guest_view/web_view_browsertest.cc
+++ b/chrome/browser/apps/guest_view/web_view_browsertest.cc
@@ -21,6 +21,7 @@
 #include "base/strings/stringprintf.h"
 #include "base/strings/utf_string_conversions.h"
 #include "base/test/test_mock_time_task_runner.h"
+#include "base/test/test_timeouts.h"
 #include "base/threading/thread_restrictions.h"
 #include "base/threading/thread_task_runner_handle.h"
 #include "build/build_config.h"
@@ -62,6 +63,7 @@
 #include "content/public/browser/ax_event_notification_details.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/browser/gpu_data_manager.h"
+#include "content/public/browser/navigation_handle.h"
 #include "content/public/browser/notification_service.h"
 #include "content/public/browser/render_frame_host.h"
 #include "content/public/browser/render_process_host.h"
@@ -3231,6 +3233,51 @@
   TestHelper("testLoadDataAPI", "web_view/shim", NEEDS_TEST_SERVER);
 }
 
+IN_PROC_BROWSER_TEST_F(WebViewTest, Shim_TestLoadDataAPIAccessibleResources) {
+  TestHelper("testLoadDataAPIAccessibleResources", "web_view/shim",
+             NEEDS_TEST_SERVER);
+}
+
+namespace {
+// Fails the test if a navigation is started in the given WebContents.
+class FailOnNavigation : public content::WebContentsObserver {
+ public:
+  explicit FailOnNavigation(content::WebContents* contents)
+      : content::WebContentsObserver(contents) {}
+
+  // content::WebContentsObserver:
+  void DidStartNavigation(
+      content::NavigationHandle* navigation_handle) override {
+    ADD_FAILURE() << "Unexpected navigation: " << navigation_handle->GetURL();
+  }
+};
+}  // namespace
+
+IN_PROC_BROWSER_TEST_F(WebViewTest, LoadDataAPINotRelativeToAnotherExtension) {
+  ASSERT_TRUE(StartEmbeddedTestServer());
+  const extensions::Extension* other_extension =
+      LoadExtension(test_data_dir_.AppendASCII("simple_with_file"));
+  LoadAppWithGuest("web_view/simple");
+  content::WebContents* embedder = GetEmbedderWebContents();
+  content::WebContents* guest = GetGuestWebContents();
+
+  FailOnNavigation fail_if_webview_navigates(guest);
+  ASSERT_TRUE(content::ExecuteScript(
+      embedder, content::JsReplace(
+                    "var webview = document.querySelector('webview'); "
+                    "webview.loadDataWithBaseUrl('data:text/html,hello', $1);",
+                    other_extension->url())));
+
+  // We expect the call to loadDataWithBaseUrl to fail and not cause a
+  // navigation. Since loadDataWithBaseUrl doesn't notify when it fails, we
+  // resort to a timeout here. If |fail_if_webview_navigates| doesn't see a
+  // navigation in that time, we consider the test to have passed.
+  base::RunLoop run_loop;
+  base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
+      FROM_HERE, run_loop.QuitClosure(), TestTimeouts::tiny_timeout());
+  run_loop.Run();
+}
+
 // This test verifies that the resize and contentResize events work correctly.
 IN_PROC_BROWSER_TEST_F(WebViewSizeTest, Shim_TestResizeEvents) {
   TestHelper("testResizeEvents", "web_view/shim", NO_TEST_SERVER);
diff --git a/chrome/browser/browser_resources.grd b/chrome/browser/browser_resources.grd
index 0ed8d45..849f39d4 100644
--- a/chrome/browser/browser_resources.grd
+++ b/chrome/browser/browser_resources.grd
@@ -93,7 +93,7 @@
       </if>
       <if expr="not disable_nacl">
         <include name="IDR_ABOUT_NACL_HTML" file="resources\about_nacl\about_nacl.html" flattenhtml="true" allowexternalscript="true" type="BINDATA" />
-        <include name="IDR_ABOUT_NACL_CSS" file="resources\about_nacl\about_nacl.css" flattenhtml="true" type="chrome_html" />
+        <include name="IDR_ABOUT_NACL_CSS" file="resources\about_nacl\about_nacl.css" type="chrome_html" />
         <include name="IDR_ABOUT_NACL_JS" file="resources\about_nacl\about_nacl.js" type="BINDATA" />
       </if>
       <if expr="not is_android">
@@ -151,7 +151,7 @@
       <if expr="not is_android">
         <!-- Page not available for guest. -->
         <include name="IDR_PAGE_NOT_AVAILABLE_FOR_GUEST_APP_HTML" file="resources\page_not_available_for_guest\app.html" type="BINDATA" />
-        <include name="IDR_INLINE_LOGIN_HTML" file="resources\inline_login\inline_login.html" flattenhtml="true" allowexternalscript="true" type="BINDATA" />
+        <include name="IDR_INLINE_LOGIN_HTML" file="resources\inline_login\inline_login.html" type="BINDATA" />
         <include name="IDR_INLINE_LOGIN_APP_JS" file="${root_gen_dir}\chrome\browser\resources\inline_login\inline_login_app.js" use_base_dir="false" type ="BINDATA" preprocess="true" />
         <include name="IDR_INLINE_LOGIN_BROWSER_PROXY_JS" file="resources\inline_login\inline_login_browser_proxy.js" type ="BINDATA"/>
       </if>
@@ -164,7 +164,7 @@
 
       <include name="IDR_INSPECT_CSS" file="resources\inspect\inspect.css" flattenhtml="true" type="BINDATA" />
       <include name="IDR_INSPECT_HTML" file="resources\inspect\inspect.html" flattenhtml="true" allowexternalscript="true" type="BINDATA" />
-      <include name="IDR_INSPECT_JS" file="resources\inspect\inspect.js" flattenhtml="true" type="BINDATA" />
+      <include name="IDR_INSPECT_JS" file="resources\inspect\inspect.js" type="BINDATA" />
 
       <include name="IDR_NETWORK_SPEECH_SYNTHESIS_MANIFEST" file="resources\network_speech_synthesis\manifest.json" type="BINDATA" />
 
@@ -186,7 +186,7 @@
         <include name="IDR_PLUGIN_DB_JSON" file="resources\plugin_metadata\plugins_linux.json" type="BINDATA" />
       </if>
       <if expr="not is_android">
-        <include name="IDR_MANAGEMENT_HTML" file="resources\management\management.html" flattenhtml="true" allowexternalscript="true" type="BINDATA" />
+        <include name="IDR_MANAGEMENT_HTML" file="resources\management\management.html" type="BINDATA" />
         <include name="IDR_MANAGEMENT_UI_JS" file="${root_gen_dir}/chrome/browser/resources/management/management_ui.js" use_base_dir="false" type="BINDATA" preprocess="true" />
         <include name="IDR_MANAGEMENT_BROWSER_PROXY_JS" file="resources\management\management_browser_proxy.js" type="BINDATA" preprocess="true" />
         <include name="IDR_MANAGEMENT_ICONS_JS" file="${root_gen_dir}/chrome/browser/resources/management/icons.js" use_base_dir="false" type="BINDATA" preprocess="true" />
@@ -195,7 +195,7 @@
       <if expr="is_win or is_macosx or desktop_linux or chromeos">
         <include name="IDR_SYNC_DISABLED_CONFIRMATION_HTML" file="resources\signin\sync_confirmation\sync_disabled_confirmation.html" type="BINDATA" />
         <include name="IDR_SYNC_DISABLED_CONFIRMATION_APP_JS" file="${root_gen_dir}\chrome\browser\resources\signin\sync_confirmation\sync_disabled_confirmation_app.js" use_base_dir="false" preprocess="true" type="BINDATA" />
-        <include name="IDR_SYNC_CONFIRMATION_HTML" file="resources\signin\sync_confirmation\sync_confirmation.html" flattenhtml="true" allowexternalscript="true" type="BINDATA" />
+        <include name="IDR_SYNC_CONFIRMATION_HTML" file="resources\signin\sync_confirmation\sync_confirmation.html" type="BINDATA" />
         <include name="IDR_SYNC_CONFIRMATION_JS" file="resources\signin\sync_confirmation\sync_confirmation.js" type="BINDATA" />
         <include name="IDR_SYNC_CONFIRMATION_BROWSER_PROXY_JS" file="resources\signin\sync_confirmation\sync_confirmation_browser_proxy.js" type="BINDATA" />
         <include name="IDR_SYNC_CONFIRMATION_APP_JS" file="${root_gen_dir}\chrome\browser\resources\signin\sync_confirmation\sync_confirmation_app.js" use_base_dir="false" preprocess="true" type="BINDATA" />
@@ -206,7 +206,7 @@
         <include name="IDR_SIGNIN_DICE_WEB_INTERCEPT_HTML" file="resources\signin\dice_web_signin_intercept\dice_web_signin_intercept.html" type="BINDATA" />
         <include name="IDR_SIGNIN_DICE_WEB_INTERCEPT_APP_JS" file="${root_gen_dir}\chrome\browser\resources\signin\dice_web_signin_intercept\dice_web_signin_intercept_app.js" use_base_dir="false" type="BINDATA" />
         <include name="IDR_SIGNIN_DICE_WEB_INTERCEPT_BROWSER_PROXY_JS" file="resources/signin/dice_web_signin_intercept/dice_web_signin_intercept_browser_proxy.js" type="BINDATA" />
-        <include name="IDR_SIGNIN_EMAIL_CONFIRMATION_HTML" file="resources\signin\signin_email_confirmation\signin_email_confirmation.html" flattenhtml="true" allowexternalscript="true" type="BINDATA" />
+        <include name="IDR_SIGNIN_EMAIL_CONFIRMATION_HTML" file="resources\signin\signin_email_confirmation\signin_email_confirmation.html" type="BINDATA" />
         <include name="IDR_SIGNIN_EMAIL_CONFIRMATION_APP_JS" file="${root_gen_dir}\chrome\browser\resources\signin\signin_email_confirmation\signin_email_confirmation_app.js" use_base_dir="false" preprocess="true" type="BINDATA" />
         <include name="IDR_SIGNIN_ERROR_HTML" file="resources\signin\signin_error\signin_error.html" type="BINDATA" />
         <include name="IDR_SIGNIN_ERROR_JS" file="resources\signin\signin_error\signin_error.js" type="BINDATA" />
@@ -217,11 +217,11 @@
         <include name="IDR_SIGNIN_REAUTH_IMAGES_ACCOUNT_PASSWORDS_REAUTH_ILLUSTRATION_SVG" file="resources\signin\signin_reauth\images\account_passwords_reauth_illustration.svg" type="BINDATA" />
         <include name="IDR_SIGNIN_REAUTH_IMAGES_ACCOUNT_PASSWORDS_REAUTH_ILLUSTRATION_DARK_SVG" file="resources\signin\signin_reauth\images\account_passwords_reauth_illustration_dark.svg" type="BINDATA" />
       </if>
-      <include name="IDR_USB_ENUMERATION_OPTIONS_MOJOM_WEBUI_JS" file="${root_gen_dir}\mojom-webui\services\device\public\mojom\usb_enumeration_options.mojom-webui.js" use_base_dir="false" flattenhtml="true" allowexternalscript="true" type="BINDATA" />
-      <include name="IDR_USB_DEVICE_MANAGER_CLIENT_MOJOM_WEBUI_JS" file="${root_gen_dir}\mojom-webui\services\device\public\mojom\usb_manager_client.mojom-webui.js" use_base_dir="false" flattenhtml="true" allowexternalscript="true" type="BINDATA" />
+      <include name="IDR_USB_ENUMERATION_OPTIONS_MOJOM_WEBUI_JS" file="${root_gen_dir}\mojom-webui\services\device\public\mojom\usb_enumeration_options.mojom-webui.js" use_base_dir="false" type="BINDATA" />
+      <include name="IDR_USB_DEVICE_MANAGER_CLIENT_MOJOM_WEBUI_JS" file="${root_gen_dir}\mojom-webui\services\device\public\mojom\usb_manager_client.mojom-webui.js" use_base_dir="false" type="BINDATA" />
       <include name="IDR_USB_DEVICE_MANAGER_MOJOM_WEBUI_JS" file="${root_gen_dir}\mojom-webui\services\device\public\mojom\usb_manager.mojom-webui.js" use_base_dir="false" type="BINDATA" />
-      <include name="IDR_USB_DEVICE_MANAGER_TEST_MOJOM_WEBUI_JS" file="${root_gen_dir}\mojom-webui\services\device\public\mojom\usb_manager_test.mojom-webui.js" use_base_dir="false" flattenhtml="true" allowexternalscript="true" type="BINDATA" />
-      <include name="IDR_USB_DEVICE_MOJOM_WEBUI_JS" file="${root_gen_dir}\mojom-webui\services\device\public\mojom\usb_device.mojom-webui.js" use_base_dir="false" flattenhtml="true" allowexternalscript="true" type="BINDATA" />
+      <include name="IDR_USB_DEVICE_MANAGER_TEST_MOJOM_WEBUI_JS" file="${root_gen_dir}\mojom-webui\services\device\public\mojom\usb_manager_test.mojom-webui.js" use_base_dir="false" type="BINDATA" />
+      <include name="IDR_USB_DEVICE_MOJOM_WEBUI_JS" file="${root_gen_dir}\mojom-webui\services\device\public\mojom\usb_device.mojom-webui.js" use_base_dir="false" type="BINDATA" />
       <include name="IDR_WEB_FOOTER_EXPERIMENT_HTML" file="resources\web_footer_experiment\index.html" type="BINDATA" />
       <include name="IDR_WEBSTORE_MANIFEST" file="resources\webstore_app\manifest.json" type="BINDATA" />
       <include name="IDR_CRYPTOTOKEN_MANIFEST" file="resources\cryptotoken\manifest.json" type="BINDATA" />
diff --git a/chrome/browser/chrome_browser_main.cc b/chrome/browser/chrome_browser_main.cc
index 83d1172..9f4be27 100644
--- a/chrome/browser/chrome_browser_main.cc
+++ b/chrome/browser/chrome_browser_main.cc
@@ -343,10 +343,9 @@
                               const base::FilePath& user_data_dir,
                               const base::CommandLine& parsed_command_line) {
   TRACE_EVENT0("startup", "ChromeBrowserMainParts::CreateProfile")
-
   base::Time start = base::Time::Now();
 
-  bool set_last_used_profile = false;
+  bool last_used_profile_set = false;
 
 // If the browser is launched due to activation on Windows native
 // notification, the profile id encoded in the notification launch id should
@@ -356,22 +355,24 @@
       NotificationLaunchId::GetNotificationLaunchProfileId(parsed_command_line);
   if (!last_used_profile_id.empty()) {
     profiles::SetLastUsedProfile(last_used_profile_id);
-    set_last_used_profile = true;
+    last_used_profile_set = true;
   }
 #endif  // defined(OS_WIN)
 
   bool profile_dir_specified =
       profiles::IsMultipleProfilesEnabled() &&
       parsed_command_line.HasSwitch(switches::kProfileDirectory);
-  if (!set_last_used_profile && profile_dir_specified) {
+  if (!last_used_profile_set && profile_dir_specified) {
     profiles::SetLastUsedProfile(
         parsed_command_line.GetSwitchValueASCII(switches::kProfileDirectory));
-    set_last_used_profile = true;
+    last_used_profile_set = true;
   }
 
-  if (set_last_used_profile) {
+  if (last_used_profile_set &&
+      !parsed_command_line.HasSwitch(switches::kAppId)) {
     // Clear kProfilesLastActive since the user only wants to launch a specific
-    // profile.
+    // profile. Don't clear it if the user launched a web app, in order to not
+    // break any subsequent multi-profile session restore.
     ListPrefUpdate update(g_browser_process->local_state(),
                           prefs::kProfilesLastActive);
     base::ListValue* profile_list = update.Get();
@@ -395,7 +396,7 @@
 #else
   profile = GetStartupProfile(user_data_dir, parsed_command_line);
 
-  if (!profile && !set_last_used_profile)
+  if (!profile && !last_used_profile_set)
     profile = GetFallbackStartupProfile();
 
   if (!profile) {
@@ -1612,9 +1613,12 @@
 #if !defined(OS_CHROMEOS)
   // On ChromeOS multiple profiles doesn't apply, and will break if we load
   // them this early as the cryptohome hasn't yet been mounted (which happens
-  // only once we log in).
-  last_opened_profiles =
-      g_browser_process->profile_manager()->GetLastOpenedProfiles();
+  // only once we log in). And if we're launching a web app, we don't want to
+  // restore the last opened profiles.
+  if (!parsed_command_line().HasSwitch(switches::kAppId)) {
+    last_opened_profiles =
+        g_browser_process->profile_manager()->GetLastOpenedProfiles();
+  }
 #endif  // defined(OS_CHROMEOS)
 
   // This step is costly and is already measured in
diff --git a/chrome/browser/chrome_browser_main_win.cc b/chrome/browser/chrome_browser_main_win.cc
index 4dd3612..851e675 100644
--- a/chrome/browser/chrome_browser_main_win.cc
+++ b/chrome/browser/chrome_browser_main_win.cc
@@ -681,7 +681,8 @@
   // complete run of the Chrome Cleanup tool. If post-cleanup settings reset is
   // enabled, we delay checks for settings reset prompt until the scheduled
   // reset is finished.
-  if (safe_browsing::PostCleanupSettingsResetter::IsEnabled()) {
+  if (safe_browsing::PostCleanupSettingsResetter::IsEnabled() &&
+      !parsed_command_line().HasSwitch(switches::kAppId)) {
     // Using last opened profiles, because we want to find reset the profile
     // that was open in the last Chrome run, which may not be open yet in
     // the current run.
diff --git a/chrome/browser/chromeos/BUILD.gn b/chrome/browser/chromeos/BUILD.gn
index 3e4c78fe..92f77af 100644
--- a/chrome/browser/chromeos/BUILD.gn
+++ b/chrome/browser/chromeos/BUILD.gn
@@ -1902,6 +1902,7 @@
     "login/ui/oobe_dialog_size_utils.h",
     "login/ui/oobe_ui_dialog_delegate.cc",
     "login/ui/oobe_ui_dialog_delegate.h",
+    "login/ui/signin_ui.h",
     "login/ui/simple_web_view_dialog.cc",
     "login/ui/simple_web_view_dialog.h",
     "login/ui/user_adding_screen.cc",
diff --git a/chrome/browser/chromeos/arc/tracing/arc_app_performance_tracing.cc b/chrome/browser/chromeos/arc/tracing/arc_app_performance_tracing.cc
index d665ac68..ac2df7c 100644
--- a/chrome/browser/chromeos/arc/tracing/arc_app_performance_tracing.cc
+++ b/chrome/browser/chromeos/arc/tracing/arc_app_performance_tracing.cc
@@ -165,8 +165,10 @@
 
 void ArcAppPerformanceTracing::StopCustomTracing(
     ResultCallback result_callback) {
-  if (!session_ || !session_->AsCustomSession())
+  if (!session_ || !session_->AsCustomSession()) {
     std::move(result_callback).Run(false /* success */, 0, 0, 0);
+    return;
+  }
 
   session_->AsCustomSession()->StopAndAnalyze(std::move(result_callback));
 }
diff --git a/chrome/browser/chromeos/login/existing_user_controller.cc b/chrome/browser/chromeos/login/existing_user_controller.cc
index 76b94d238..d274825 100644
--- a/chrome/browser/chromeos/login/existing_user_controller.cc
+++ b/chrome/browser/chromeos/login/existing_user_controller.cc
@@ -44,7 +44,6 @@
 #include "chrome/browser/chromeos/login/quick_unlock/pin_storage_cryptohome.h"
 #include "chrome/browser/chromeos/login/reauth_stats.h"
 #include "chrome/browser/chromeos/login/screens/encryption_migration_mode.h"
-#include "chrome/browser/chromeos/login/screens/encryption_migration_screen.h"
 #include "chrome/browser/chromeos/login/session/user_session_manager.h"
 #include "chrome/browser/chromeos/login/signin/oauth2_token_initializer.h"
 #include "chrome/browser/chromeos/login/signin_specifics.h"
@@ -760,12 +759,6 @@
   ContinuePerformLogin(auth_mode, user_context_ecryptfs);
 }
 
-void ExistingUserController::RestartLogin(const UserContext& user_context) {
-  is_login_in_progress_ = false;
-  login_performer_.reset();
-  GetLoginDisplayHost()->ShowGaiaDialog(user_context.GetAccountId());
-}
-
 void ExistingUserController::OnSigninScreenReady() {
   // Used to debug crbug.com/902315. Feel free to remove after that is fixed.
   VLOG(1) << "OnSigninScreenReady";
@@ -873,21 +866,11 @@
 void ExistingUserController::ShowEncryptionMigrationScreen(
     const UserContext& user_context,
     EncryptionMigrationMode migration_mode) {
-  GetLoginDisplayHost()->StartWizard(EncryptionMigrationScreenView::kScreenId);
-
-  EncryptionMigrationScreen* migration_screen =
-      static_cast<EncryptionMigrationScreen*>(
-          WizardController::default_controller()->GetScreen(
-              EncryptionMigrationScreenView::kScreenId));
-  DCHECK(migration_screen);
-  migration_screen->SetUserContext(user_context);
-  migration_screen->SetMode(migration_mode);
-  migration_screen->SetOperationCallbacks(
+  GetLoginDisplayHost()->GetSigninUI()->StartEncryptionMigration(
+      user_context, migration_mode,
       base::BindOnce(&ExistingUserController::ContinuePerformLogin,
-                     weak_factory_.GetWeakPtr(), login_performer_->auth_mode()),
-      base::BindOnce(&ExistingUserController::RestartLogin,
-                     weak_factory_.GetWeakPtr()));
-  migration_screen->SetupInitialView();
+                     weak_factory_.GetWeakPtr(),
+                     login_performer_->auth_mode()));
 }
 
 void ExistingUserController::ShowTPMError() {
@@ -906,13 +889,8 @@
   bool show_invalid_old_password_error =
       login_performer_->password_changed_callback_count() > 1;
 
-  // Note: We allow owner using "full sync" mode which will recreate
-  // cryptohome and deal with owner private key being lost. This also allows
-  // us to recover from a lost owner password/homedir.
-  // TODO(gspencer): We shouldn't have to erase stateful data when
-  // doing this.  See http://crosbug.com/9115 http://crosbug.com/7792
-  GetLoginDisplay()->ShowPasswordChangedDialog(show_invalid_old_password_error,
-                                               user_context.GetAccountId());
+  GetLoginDisplayHost()->GetSigninUI()->ShowPasswordChangedDialog(
+      user_context.GetAccountId(), show_invalid_old_password_error);
 }
 
 ////////////////////////////////////////////////////////////////////////////////
diff --git a/chrome/browser/chromeos/login/existing_user_controller_browsertest.cc b/chrome/browser/chromeos/login/existing_user_controller_browsertest.cc
index b1b20b5a..977ac21 100644
--- a/chrome/browser/chromeos/login/existing_user_controller_browsertest.cc
+++ b/chrome/browser/chromeos/login/existing_user_controller_browsertest.cc
@@ -41,6 +41,7 @@
 #include "chrome/browser/chromeos/login/test/user_policy_mixin.h"
 #include "chrome/browser/chromeos/login/ui/mock_login_display.h"
 #include "chrome/browser/chromeos/login/ui/mock_login_display_host.h"
+#include "chrome/browser/chromeos/login/ui/mock_signin_ui.h"
 #include "chrome/browser/chromeos/login/users/chrome_user_manager.h"
 #include "chrome/browser/chromeos/login/wizard_controller.h"
 #include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h"
@@ -197,6 +198,7 @@
 
     mock_login_display_host_ = std::make_unique<MockLoginDisplayHost>();
     mock_login_display_ = std::make_unique<MockLoginDisplay>();
+    mock_signin_ui_ = std::make_unique<MockSigninUI>();
     SetUpLoginDisplay();
   }
 
@@ -204,6 +206,9 @@
     EXPECT_CALL(*mock_login_display_host_, GetLoginDisplay())
         .Times(AnyNumber())
         .WillRepeatedly(Return(mock_login_display_.get()));
+    EXPECT_CALL(*mock_login_display_host_, GetSigninUI())
+        .Times(AnyNumber())
+        .WillRepeatedly(Return(mock_signin_ui_.get()));
     EXPECT_CALL(*mock_login_display_host_, OnPreferencesChanged()).Times(1);
     EXPECT_CALL(*mock_login_display_, Init(_, true, true, true)).Times(1);
   }
@@ -273,6 +278,7 @@
 
   std::unique_ptr<ExistingUserController> existing_user_controller_;
 
+  std::unique_ptr<MockSigninUI> mock_signin_ui_;
   std::unique_ptr<MockLoginDisplay> mock_login_display_;
   std::unique_ptr<MockLoginDisplayHost> mock_login_display_host_;
 
@@ -430,6 +436,9 @@
     EXPECT_CALL(*mock_login_display_host_, GetLoginDisplay())
         .Times(AnyNumber())
         .WillRepeatedly(Return(mock_login_display_.get()));
+    EXPECT_CALL(*mock_login_display_host_, GetSigninUI())
+        .Times(AnyNumber())
+        .WillRepeatedly(Return(mock_signin_ui_.get()));
     EXPECT_CALL(*mock_login_display_host_.get(), OnPreferencesChanged())
         .Times(AnyNumber());
     EXPECT_CALL(*mock_login_display_, Init(_, _, _, _)).Times(AnyNumber());
@@ -1001,6 +1010,9 @@
     EXPECT_CALL(*mock_login_display_host_, GetLoginDisplay())
         .Times(AnyNumber())
         .WillRepeatedly(Return(mock_login_display_.get()));
+    EXPECT_CALL(*mock_login_display_host_, GetSigninUI())
+        .Times(AnyNumber())
+        .WillRepeatedly(Return(mock_signin_ui_.get()));
     EXPECT_CALL(*mock_login_display_host_, OnPreferencesChanged()).Times(1);
     EXPECT_CALL(*mock_login_display_, Init(_, true, true, false)).Times(1);
   }
diff --git a/chrome/browser/chromeos/login/screens/encryption_migration_screen.cc b/chrome/browser/chromeos/login/screens/encryption_migration_screen.cc
index d2d0b088..daa96488 100644
--- a/chrome/browser/chromeos/login/screens/encryption_migration_screen.cc
+++ b/chrome/browser/chromeos/login/screens/encryption_migration_screen.cc
@@ -285,12 +285,10 @@
   view_->SetIsResuming(IsStartImmediately());
 }
 
-void EncryptionMigrationScreen::SetOperationCallbacks(
-    ContinueLoginCallback continue_login_callback,
-    RestartLoginCallback restart_login_callback) {
+void EncryptionMigrationScreen::SetSkipMigrationCallback(
+    SkipMigrationCallback skip_migration_callback) {
   DCHECK(view_);
-  continue_login_callback_ = std::move(continue_login_callback);
-  restart_login_callback_ = std::move(restart_login_callback);
+  skip_migration_callback_ = std::move(skip_migration_callback);
 }
 
 void EncryptionMigrationScreen::SetupInitialView() {
@@ -375,9 +373,9 @@
   // previous attempt and dropping |is_forcing_dircrypto| flag in UserContext.
   // In this case, the user can not launch ARC apps in the session, and will be
   // asked to do the migration again in the next log-in attempt.
-  if (!continue_login_callback_.is_null()) {
+  if (!skip_migration_callback_.is_null()) {
     user_context_.SetIsForcingDircrypto(false);
-    std::move(continue_login_callback_).Run(user_context_);
+    std::move(skip_migration_callback_).Run(user_context_);
   }
 }
 
diff --git a/chrome/browser/chromeos/login/screens/encryption_migration_screen.h b/chrome/browser/chromeos/login/screens/encryption_migration_screen.h
index abf6b2c..1321603 100644
--- a/chrome/browser/chromeos/login/screens/encryption_migration_screen.h
+++ b/chrome/browser/chromeos/login/screens/encryption_migration_screen.h
@@ -36,8 +36,7 @@
  public:
   using TView = EncryptionMigrationScreenView;
 
-  using ContinueLoginCallback = base::OnceCallback<void(const UserContext&)>;
-  using RestartLoginCallback = base::OnceCallback<void(const UserContext&)>;
+  using SkipMigrationCallback = base::OnceCallback<void(const UserContext&)>;
 
   // Callback that can be used to check free disk space.
   using FreeDiskSpaceFetcher = base::RepeatingCallback<int64_t()>;
@@ -58,8 +57,7 @@
   // Sets continue login callback and restart log in callback, which should be
   // called when the user want to log in to the session from the migration UI
   // and when the user should re-enter their password.
-  void SetOperationCallbacks(ContinueLoginCallback continue_login_callback,
-                             RestartLoginCallback restart_login_callback);
+  void SetSkipMigrationCallback(SkipMigrationCallback skip_migration_callback);
 
   // Setup the initial view in the migration UI.
   // This should be called after other state like UserContext, etc... are set.
@@ -139,10 +137,7 @@
   UserContext user_context_;
 
   // The callback which is used to log in to the session from the migration UI.
-  ContinueLoginCallback continue_login_callback_;
-
-  // The callback which is used to require the user to re-enter their password.
-  RestartLoginCallback restart_login_callback_;
+  SkipMigrationCallback skip_migration_callback_;
 
   // The migration mode (ask user / start migration automatically / resume
   // incomplete migratoin).
diff --git a/chrome/browser/chromeos/login/screens/encryption_migration_screen_unittest.cc b/chrome/browser/chromeos/login/screens/encryption_migration_screen_unittest.cc
index dba2321..ba17385 100644
--- a/chrome/browser/chromeos/login/screens/encryption_migration_screen_unittest.cc
+++ b/chrome/browser/chromeos/login/screens/encryption_migration_screen_unittest.cc
@@ -147,10 +147,8 @@
 
     encryption_migration_screen_ =
         std::make_unique<TestEncryptionMigrationScreen>(&mock_view_);
-    encryption_migration_screen_->SetOperationCallbacks(
+    encryption_migration_screen_->SetSkipMigrationCallback(
         base::BindOnce(&EncryptionMigrationScreenTest::OnContinueLogin,
-                       base::Unretained(this)),
-        base::BindOnce(&EncryptionMigrationScreenTest::OnRestartLogin,
                        base::Unretained(this)));
     encryption_migration_screen_->set_free_disk_space(
         arc::kMigrationMinimumAvailableStorage);
@@ -181,9 +179,7 @@
   cryptohome::MockAsyncMethodCaller* mock_async_method_caller_ = nullptr;
 
   // Will be set to true in ContinueLogin.
-  bool continue_login_callback_called_ = false;
-  // Will be set to true in RestartLogin.
-  bool restart_login_callback_called_ = false;
+  bool skip_migration_callback_called_ = false;
 
   const AccountId account_id_ =
       AccountId::FromUserEmail(user_manager::kStubUserEmail);
@@ -193,23 +189,10 @@
   // This will be called by EncryptionMigrationScreen upon finished
   // minimal migration when sign-in should continue.
   void OnContinueLogin(const UserContext& user_context) {
-    EXPECT_FALSE(continue_login_callback_called_)
-        << "ContinueLogin/RestartLogin may only be called once.";
-    EXPECT_FALSE(restart_login_callback_called_)
+    EXPECT_FALSE(skip_migration_callback_called_)
         << "ContinueLogin/RestartLogin may only be called once.";
 
-    continue_login_callback_called_ = true;
-  }
-
-  // This will be called by EncryptionMigrationScreen upon finished
-  // minimal migration when the user should re-enter their password.
-  void OnRestartLogin(const UserContext& user_context) {
-    EXPECT_FALSE(continue_login_callback_called_)
-        << "ContinueLogin/RestartLogin may only be called once.";
-    EXPECT_FALSE(restart_login_callback_called_)
-        << "ContinueLogin/RestartLogin may only be called once.";
-
-    restart_login_callback_called_ = true;
+    skip_migration_callback_called_ = true;
   }
 };
 
diff --git a/chrome/browser/chromeos/login/session/user_session_manager.cc b/chrome/browser/chromeos/login/session/user_session_manager.cc
index 884ac97..380f861 100644
--- a/chrome/browser/chromeos/login/session/user_session_manager.cc
+++ b/chrome/browser/chromeos/login/session/user_session_manager.cc
@@ -60,7 +60,6 @@
 #include "chrome/browser/chromeos/login/saml/saml_offline_signin_limiter.h"
 #include "chrome/browser/chromeos/login/saml/saml_offline_signin_limiter_factory.h"
 #include "chrome/browser/chromeos/login/screens/arc_terms_of_service_screen.h"
-#include "chrome/browser/chromeos/login/screens/pin_setup_screen.h"
 #include "chrome/browser/chromeos/login/screens/sync_consent_screen.h"
 #include "chrome/browser/chromeos/login/session/user_session_initializer.h"
 #include "chrome/browser/chromeos/login/signin/oauth2_login_manager_factory.h"
@@ -99,10 +98,6 @@
 #include "chrome/browser/ui/browser_navigator_params.h"
 #include "chrome/browser/ui/startup/launch_mode_recorder.h"
 #include "chrome/browser/ui/startup/startup_browser_creator.h"
-#include "chrome/browser/ui/webui/chromeos/login/discover/discover_manager.h"
-#include "chrome/browser/ui/webui/chromeos/login/discover/modules/discover_module_pin_setup.h"
-#include "chrome/browser/ui/webui/chromeos/login/supervision_transition_screen_handler.h"
-#include "chrome/browser/ui/webui/chromeos/login/terms_of_service_screen_handler.h"
 #include "chrome/common/channel_info.h"
 #include "chrome/common/chrome_constants.h"
 #include "chrome/common/chrome_features.h"
@@ -1258,11 +1253,10 @@
                        user_context.GetPublicSessionInputMethod());
 
     if (user_manager->GetPrimaryUser() == user &&
-        !PinSetupScreen::ShouldSkip() &&
         !user_manager->IsUserNonCryptohomeDataEphemeral(user->GetAccountId())) {
-      chromeos::DiscoverManager::Get()
-          ->GetModule<chromeos::DiscoverModulePinSetup>()
-          ->SetPrimaryUserPassword(user_context.GetPasswordKey()->GetSecret());
+      LoginDisplayHost::default_host()
+          ->GetSigninUI()
+          ->SetAuthSessionForOnboarding(user_context);
     }
   }
 
@@ -1737,12 +1731,14 @@
       if (!StartupUtils::IsDeviceRegistered())
         StartupUtils::MarkDeviceRegistered(base::OnceClosure());
 
-      ActivateWizard(TermsOfServiceScreenView::kScreenId);
+      LoginDisplayHost::default_host()->GetSigninUI()->StartUserOnboarding();
       return false;
     } else if (!user_manager->IsCurrentUserNew() &&
                arc::GetSupervisionTransition(profile) !=
                    arc::ArcSupervisionTransition::NO_TRANSITION) {
-      ActivateWizard(SupervisionTransitionScreenView::kScreenId);
+      LoginDisplayHost::default_host()
+          ->GetSigninUI()
+          ->StartSupervisionTransition();
       return false;
     }
   }
diff --git a/chrome/browser/chromeos/login/ui/fake_login_display_host.cc b/chrome/browser/chromeos/login/ui/fake_login_display_host.cc
index a0fa65f..61e7fed 100644
--- a/chrome/browser/chromeos/login/ui/fake_login_display_host.cc
+++ b/chrome/browser/chromeos/login/ui/fake_login_display_host.cc
@@ -146,4 +146,8 @@
 void FakeLoginDisplayHost::RemoveObserver(
     LoginDisplayHost::Observer* observer) {}
 
+SigninUI* FakeLoginDisplayHost::GetSigninUI() {
+  return nullptr;
+}
+
 }  // namespace chromeos
diff --git a/chrome/browser/chromeos/login/ui/fake_login_display_host.h b/chrome/browser/chromeos/login/ui/fake_login_display_host.h
index ab9ad46e..da3df5b 100644
--- a/chrome/browser/chromeos/login/ui/fake_login_display_host.h
+++ b/chrome/browser/chromeos/login/ui/fake_login_display_host.h
@@ -69,6 +69,7 @@
   void VerifyOwnerForKiosk(base::OnceClosure on_success) override;
   void AddObserver(LoginDisplayHost::Observer* observer) override;
   void RemoveObserver(LoginDisplayHost::Observer* observer) override;
+  SigninUI* GetSigninUI() override;
 
  private:
   class FakeBaseScreen;
diff --git a/chrome/browser/chromeos/login/ui/login_display.h b/chrome/browser/chromeos/login/ui/login_display.h
index 3dbfff81..a369c1a6 100644
--- a/chrome/browser/chromeos/login/ui/login_display.h
+++ b/chrome/browser/chromeos/login/ui/login_display.h
@@ -86,11 +86,6 @@
                          int login_attempts,
                          HelpAppLauncher::HelpTopic help_topic_id) = 0;
 
-  // Show password changed dialog. If `show_password_error` is not null
-  // user already tried to enter old password but it turned out to be incorrect.
-  virtual void ShowPasswordChangedDialog(bool show_password_error,
-                                         const AccountId& account_id) = 0;
-
   // Show allowlist check failed error. Happens after user completes online
   // signin but allowlist check fails.
   virtual void ShowAllowlistCheckFailedError() = 0;
diff --git a/chrome/browser/chromeos/login/ui/login_display_host.h b/chrome/browser/chromeos/login/ui/login_display_host.h
index 413f6d63..a79e0b9 100644
--- a/chrome/browser/chromeos/login/ui/login_display_host.h
+++ b/chrome/browser/chromeos/login/ui/login_display_host.h
@@ -17,6 +17,7 @@
 #include "chrome/browser/chromeos/login/auth/auth_prewarmer.h"
 #include "chrome/browser/chromeos/login/oobe_screen.h"
 #include "chrome/browser/chromeos/login/ui/login_display.h"
+#include "chrome/browser/chromeos/login/ui/signin_ui.h"
 #include "components/user_manager/user_type.h"
 
 #include "ui/gfx/native_widget_types.h"
@@ -219,6 +220,10 @@
   virtual void AddObserver(Observer* observer) = 0;
   virtual void RemoveObserver(Observer* observer) = 0;
 
+  // Return sign-in UI instance, guaranteed to be non-null
+  // during sign-in process. Result should not be stored.
+  virtual SigninUI* GetSigninUI() = 0;
+
  protected:
   LoginDisplayHost();
   virtual ~LoginDisplayHost();
diff --git a/chrome/browser/chromeos/login/ui/login_display_host_common.cc b/chrome/browser/chromeos/login/ui/login_display_host_common.cc
index 77220e45..31aa656c 100644
--- a/chrome/browser/chromeos/login/ui/login_display_host_common.cc
+++ b/chrome/browser/chromeos/login/ui/login_display_host_common.cc
@@ -15,7 +15,9 @@
 #include "chrome/browser/chromeos/login/demo_mode/demo_app_launcher.h"
 #include "chrome/browser/chromeos/login/existing_user_controller.h"
 #include "chrome/browser/chromeos/login/lock_screen_utils.h"
+#include "chrome/browser/chromeos/login/screens/encryption_migration_screen.h"
 #include "chrome/browser/chromeos/login/screens/gaia_screen.h"
+#include "chrome/browser/chromeos/login/screens/pin_setup_screen.h"
 #include "chrome/browser/chromeos/login/startup_utils.h"
 #include "chrome/browser/chromeos/login/ui/webui_accelerator_mapping.h"
 #include "chrome/browser/chromeos/login/wizard_controller.h"
@@ -25,7 +27,11 @@
 #include "chrome/browser/ui/ash/wallpaper_controller_client.h"
 #include "chrome/browser/ui/browser_list.h"
 #include "chrome/browser/ui/webui/chromeos/internet_detail_dialog.h"
+#include "chrome/browser/ui/webui/chromeos/login/discover/discover_manager.h"
+#include "chrome/browser/ui/webui/chromeos/login/discover/modules/discover_module_pin_setup.h"
 #include "chrome/browser/ui/webui/chromeos/login/gaia_screen_handler.h"
+#include "chrome/browser/ui/webui/chromeos/login/supervision_transition_screen_handler.h"
+#include "chrome/browser/ui/webui/chromeos/login/terms_of_service_screen_handler.h"
 #include "chrome/browser/ui/webui/chromeos/login/user_creation_screen_handler.h"
 #include "chromeos/constants/chromeos_features.h"
 #include "components/keep_alive_registry/keep_alive_types.h"
@@ -327,6 +333,44 @@
   return true;
 }
 
+SigninUI* LoginDisplayHostCommon::GetSigninUI() {
+  return this;
+}
+
+void LoginDisplayHostCommon::StartUserOnboarding() {
+  StartWizard(TermsOfServiceScreenView::kScreenId);
+}
+
+void LoginDisplayHostCommon::StartSupervisionTransition() {
+  StartWizard(SupervisionTransitionScreenView::kScreenId);
+}
+
+void LoginDisplayHostCommon::SetAuthSessionForOnboarding(
+    const UserContext& user_context) {
+  if (PinSetupScreen::ShouldSkip())
+    return;
+  chromeos::DiscoverManager::Get()
+      ->GetModule<chromeos::DiscoverModulePinSetup>()
+      ->SetPrimaryUserPassword(user_context.GetPasswordKey()->GetSecret());
+}
+
+void LoginDisplayHostCommon::StartEncryptionMigration(
+    const UserContext& user_context,
+    EncryptionMigrationMode migration_mode,
+    base::OnceCallback<void(const UserContext&)> on_skip_migration) {
+  StartWizard(EncryptionMigrationScreenView::kScreenId);
+
+  EncryptionMigrationScreen* migration_screen =
+      WizardController::default_controller()
+          ->GetScreen<EncryptionMigrationScreen>();
+
+  DCHECK(migration_screen);
+  migration_screen->SetUserContext(user_context);
+  migration_screen->SetMode(migration_mode);
+  migration_screen->SetSkipMigrationCallback(std::move(on_skip_migration));
+  migration_screen->SetupInitialView();
+}
+
 void LoginDisplayHostCommon::OnBrowserAdded(Browser* browser) {
   // Browsers created before session start (windows opened by extensions, for
   // example) are ignored.
diff --git a/chrome/browser/chromeos/login/ui/login_display_host_common.h b/chrome/browser/chromeos/login/ui/login_display_host_common.h
index 7bdd68da..ea3d4a2 100644
--- a/chrome/browser/chromeos/login/ui/login_display_host_common.h
+++ b/chrome/browser/chromeos/login/ui/login_display_host_common.h
@@ -13,6 +13,7 @@
 #include "base/optional.h"
 #include "chrome/browser/chromeos/login/ui/kiosk_app_menu_controller.h"
 #include "chrome/browser/chromeos/login/ui/login_display_host.h"
+#include "chrome/browser/chromeos/login/ui/signin_ui.h"
 #include "chrome/browser/ui/browser_list_observer.h"
 #include "components/keep_alive_registry/scoped_keep_alive.h"
 #include "components/user_manager/user_type.h"
@@ -30,7 +31,8 @@
 // LoginDisplayHostMojo and LoginDisplayHostWebUI.
 class LoginDisplayHostCommon : public LoginDisplayHost,
                                public BrowserListObserver,
-                               public content::NotificationObserver {
+                               public content::NotificationObserver,
+                               public SigninUI {
  public:
   LoginDisplayHostCommon();
   ~LoginDisplayHostCommon() override;
@@ -59,6 +61,16 @@
   void MigrateUserData(const std::string& old_password) final;
   void ResyncUserData() final;
   bool HandleAccelerator(ash::LoginAcceleratorAction action) final;
+  SigninUI* GetSigninUI() final;
+
+  // SigninUI:
+  void SetAuthSessionForOnboarding(const UserContext& user_context) final;
+  void StartUserOnboarding() final;
+  void StartSupervisionTransition() final;
+  void StartEncryptionMigration(
+      const UserContext& user_context,
+      EncryptionMigrationMode migration_mode,
+      base::OnceCallback<void(const UserContext&)> on_skip_migration) final;
 
   // BrowserListObserver:
   void OnBrowserAdded(Browser* browser) override;
diff --git a/chrome/browser/chromeos/login/ui/login_display_host_mojo.cc b/chrome/browser/chromeos/login/ui/login_display_host_mojo.cc
index c8696408..73be1c0 100644
--- a/chrome/browser/chromeos/login/ui/login_display_host_mojo.cc
+++ b/chrome/browser/chromeos/login/ui/login_display_host_mojo.cc
@@ -129,8 +129,8 @@
 }
 
 void LoginDisplayHostMojo::ShowPasswordChangedDialog(
-    bool show_password_error,
-    const AccountId& account_id) {
+    const AccountId& account_id,
+    bool show_password_error) {
   DCHECK(GetOobeUI());
   wizard_controller_->ShowGaiaPasswordChangedScreen(account_id,
                                                     show_password_error);
diff --git a/chrome/browser/chromeos/login/ui/login_display_host_mojo.h b/chrome/browser/chromeos/login/ui/login_display_host_mojo.h
index 439f0383..b780a1dc 100644
--- a/chrome/browser/chromeos/login/ui/login_display_host_mojo.h
+++ b/chrome/browser/chromeos/login/ui/login_display_host_mojo.h
@@ -56,11 +56,6 @@
 
   void SetUserCount(int user_count);
 
-  // Show password changed dialog. If `show_password_error` is true, user
-  // already tried to enter old password but it turned out to be incorrect.
-  void ShowPasswordChangedDialog(bool show_password_error,
-                                 const AccountId& account_id);
-
   // Show allowlist check failed error. Happens after user completes online
   // signin but allowlist check fails.
   void ShowAllowlistCheckFailedError();
@@ -95,6 +90,8 @@
   void RequestSystemInfoUpdate() override;
   bool HasUserPods() override;
   void VerifyOwnerForKiosk(base::OnceClosure on_success) override;
+  void ShowPasswordChangedDialog(const AccountId& account_id,
+                                 bool show_password_error) override;
   void AddObserver(LoginDisplayHost::Observer* observer) override;
   void RemoveObserver(LoginDisplayHost::Observer* observer) override;
 
diff --git a/chrome/browser/chromeos/login/ui/login_display_host_webui.cc b/chrome/browser/chromeos/login/ui/login_display_host_webui.cc
index a29bbc3..305b838 100644
--- a/chrome/browser/chromeos/login/ui/login_display_host_webui.cc
+++ b/chrome/browser/chromeos/login/ui/login_display_host_webui.cc
@@ -1035,6 +1035,12 @@
   NOTREACHED();
 }
 
+void LoginDisplayHostWebUI::ShowPasswordChangedDialog(
+    const AccountId& account_id,
+    bool show_password_error) {
+  NOTREACHED();
+}
+
 void LoginDisplayHostWebUI::AddObserver(LoginDisplayHost::Observer* observer) {
   observers_.AddObserver(observer);
 }
diff --git a/chrome/browser/chromeos/login/ui/login_display_host_webui.h b/chrome/browser/chromeos/login/ui/login_display_host_webui.h
index eb8aef5..fd0e3375 100644
--- a/chrome/browser/chromeos/login/ui/login_display_host_webui.h
+++ b/chrome/browser/chromeos/login/ui/login_display_host_webui.h
@@ -90,6 +90,8 @@
   void OnCancelPasswordChangedFlow() override;
   bool HasUserPods() override;
   void VerifyOwnerForKiosk(base::OnceClosure) override;
+  void ShowPasswordChangedDialog(const AccountId& account_id,
+                                 bool show_password_error) override;
   void AddObserver(LoginDisplayHost::Observer* observer) override;
   void RemoveObserver(LoginDisplayHost::Observer* observer) override;
 
diff --git a/chrome/browser/chromeos/login/ui/login_display_mojo.cc b/chrome/browser/chromeos/login/ui/login_display_mojo.cc
index 23523e92..126f597 100644
--- a/chrome/browser/chromeos/login/ui/login_display_mojo.cc
+++ b/chrome/browser/chromeos/login/ui/login_display_mojo.cc
@@ -196,11 +196,6 @@
                             help_topic_id);
 }
 
-void LoginDisplayMojo::ShowPasswordChangedDialog(bool show_password_error,
-                                                 const AccountId& account_id) {
-  host_->ShowPasswordChangedDialog(show_password_error, account_id);
-}
-
 void LoginDisplayMojo::ShowAllowlistCheckFailedError() {
   host_->ShowAllowlistCheckFailedError();
 }
diff --git a/chrome/browser/chromeos/login/ui/login_display_mojo.h b/chrome/browser/chromeos/login/ui/login_display_mojo.h
index fee8e9c..112b73e6 100644
--- a/chrome/browser/chromeos/login/ui/login_display_mojo.h
+++ b/chrome/browser/chromeos/login/ui/login_display_mojo.h
@@ -42,8 +42,6 @@
   void ShowError(int error_msg_id,
                  int login_attempts,
                  HelpAppLauncher::HelpTopic help_topic_id) override;
-  void ShowPasswordChangedDialog(bool show_password_error,
-                                 const AccountId& account_id) override;
   void ShowAllowlistCheckFailedError() override;
 
   // SigninScreenHandlerDelegate:
diff --git a/chrome/browser/chromeos/login/ui/login_display_webui.cc b/chrome/browser/chromeos/login/ui/login_display_webui.cc
index e0a7cd1..f3912bb5 100644
--- a/chrome/browser/chromeos/login/ui/login_display_webui.cc
+++ b/chrome/browser/chromeos/login/ui/login_display_webui.cc
@@ -168,11 +168,6 @@
                             help_topic_id);
 }
 
-void LoginDisplayWebUI::ShowPasswordChangedDialog(bool show_password_error,
-                                                  const AccountId& account_id) {
-  NOTIMPLEMENTED();
-}
-
 void LoginDisplayWebUI::ShowAllowlistCheckFailedError() {
   if (webui_handler_)
     webui_handler_->ShowAllowlistCheckFailedError();
diff --git a/chrome/browser/chromeos/login/ui/login_display_webui.h b/chrome/browser/chromeos/login/ui/login_display_webui.h
index c13136c..9d55f16 100644
--- a/chrome/browser/chromeos/login/ui/login_display_webui.h
+++ b/chrome/browser/chromeos/login/ui/login_display_webui.h
@@ -42,8 +42,6 @@
   void ShowError(int error_msg_id,
                  int login_attempts,
                  HelpAppLauncher::HelpTopic help_topic_id) override;
-  void ShowPasswordChangedDialog(bool show_password_error,
-                                 const AccountId& account_id) override;
   void ShowAllowlistCheckFailedError() override;
 
   // SigninScreenHandlerDelegate implementation:
diff --git a/chrome/browser/chromeos/login/ui/mock_login_display.h b/chrome/browser/chromeos/login/ui/mock_login_display.h
index c3110eae..95c2b71 100644
--- a/chrome/browser/chromeos/login/ui/mock_login_display.h
+++ b/chrome/browser/chromeos/login/ui/mock_login_display.h
@@ -22,7 +22,6 @@
   MOCK_METHOD1(OnUserImageChanged, void(const user_manager::User&));
   MOCK_METHOD1(SetUIEnabled, void(bool));
   MOCK_METHOD3(ShowError, void(int, int, HelpAppLauncher::HelpTopic));
-  MOCK_METHOD2(ShowPasswordChangedDialog, void(bool, const AccountId&));
   MOCK_METHOD1(ShowSigninUI, void(const std::string&));
   MOCK_METHOD0(ShowAllowlistCheckFailedError, void(void));
 
diff --git a/chrome/browser/chromeos/login/ui/mock_login_display_host.h b/chrome/browser/chromeos/login/ui/mock_login_display_host.h
index 8b6d191..804a0f9 100644
--- a/chrome/browser/chromeos/login/ui/mock_login_display_host.h
+++ b/chrome/browser/chromeos/login/ui/mock_login_display_host.h
@@ -92,6 +92,7 @@
   MOCK_METHOD(void, VerifyOwnerForKiosk, (base::OnceClosure), (override));
   MOCK_METHOD(void, AddObserver, (LoginDisplayHost::Observer*), (override));
   MOCK_METHOD(void, RemoveObserver, (LoginDisplayHost::Observer*), (override));
+  MOCK_METHOD(SigninUI*, GetSigninUI, (), (override));
 
  private:
   DISALLOW_COPY_AND_ASSIGN(MockLoginDisplayHost);
diff --git a/chrome/browser/chromeos/login/ui/mock_signin_ui.cc b/chrome/browser/chromeos/login/ui/mock_signin_ui.cc
new file mode 100644
index 0000000..87323438
--- /dev/null
+++ b/chrome/browser/chromeos/login/ui/mock_signin_ui.cc
@@ -0,0 +1,13 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/chromeos/login/ui/mock_signin_ui.h"
+
+namespace chromeos {
+
+MockSigninUI::MockSigninUI() {}
+
+MockSigninUI::~MockSigninUI() {}
+
+}  // namespace chromeos
diff --git a/chrome/browser/chromeos/login/ui/mock_signin_ui.h b/chrome/browser/chromeos/login/ui/mock_signin_ui.h
new file mode 100644
index 0000000..608af33
--- /dev/null
+++ b/chrome/browser/chromeos/login/ui/mock_signin_ui.h
@@ -0,0 +1,41 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_CHROMEOS_LOGIN_UI_MOCK_SIGNIN_UI_H_
+#define CHROME_BROWSER_CHROMEOS_LOGIN_UI_MOCK_SIGNIN_UI_H_
+
+#include "base/macros.h"
+#include "chrome/browser/chromeos/login/ui/signin_ui.h"
+#include "testing/gmock/include/gmock/gmock.h"
+
+namespace chromeos {
+
+class MockSigninUI : public SigninUI {
+ public:
+  MockSigninUI();
+  virtual ~MockSigninUI();
+  MockSigninUI(const MockSigninUI&) = delete;
+  MockSigninUI& operator=(const SigninUI&) = delete;
+
+  MOCK_METHOD(void, StartUserOnboarding, (), (override));
+  MOCK_METHOD(void, StartSupervisionTransition, (), (override));
+  MOCK_METHOD(void,
+              StartEncryptionMigration,
+              (const UserContext&,
+               EncryptionMigrationMode,
+               base::OnceCallback<void(const UserContext&)>),
+              (override));
+  MOCK_METHOD(void,
+              SetAuthSessionForOnboarding,
+              (const UserContext&),
+              (override));
+  MOCK_METHOD(void,
+              ShowPasswordChangedDialog,
+              (const AccountId&, bool),
+              (override));
+};
+
+}  // namespace chromeos
+
+#endif  // CHROME_BROWSER_CHROMEOS_LOGIN_UI_MOCK_SIGNIN_UI_H_
diff --git a/chrome/browser/chromeos/login/ui/signin_ui.h b/chrome/browser/chromeos/login/ui/signin_ui.h
new file mode 100644
index 0000000..34b65708
--- /dev/null
+++ b/chrome/browser/chromeos/login/ui/signin_ui.h
@@ -0,0 +1,46 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+#ifndef CHROME_BROWSER_CHROMEOS_LOGIN_UI_SIGNIN_UI_H_
+#define CHROME_BROWSER_CHROMEOS_LOGIN_UI_SIGNIN_UI_H_
+
+#include "base/callback.h"
+#include "chrome/browser/chromeos/login/screens/encryption_migration_mode.h"
+#include "chromeos/login/auth/user_context.h"
+#include "components/account_id/account_id.h"
+
+namespace chromeos {
+
+// This class represents an interface between code that performs sign-in
+// operations and code that handles sign-in UI. It is used to encapsulate UI
+// implementation details and declare the required set of parameters that need
+// to be set for particular UI.
+class SigninUI {
+ public:
+  SigninUI() = default;
+  virtual ~SigninUI() = default;
+  SigninUI(const SigninUI&) = delete;
+  SigninUI& operator=(const SigninUI&) = delete;
+
+  // Starts user onboarding after successful sign-in for new users.
+  virtual void StartUserOnboarding() = 0;
+  // Show UI for supervision transition flow.
+  virtual void StartSupervisionTransition() = 0;
+
+  virtual void StartEncryptionMigration(
+      const UserContext& user_context,
+      EncryptionMigrationMode migration_mode,
+      base::OnceCallback<void(const UserContext&)> skip_migration_callback) = 0;
+
+  // Might store authentication data so that additional auth factors can be
+  // added during user onboarding.
+  virtual void SetAuthSessionForOnboarding(const UserContext& user_context) = 0;
+
+  // Show password changed dialog. If `show_password_error` is true, user
+  // already tried to enter old password but it turned out to be incorrect.
+  virtual void ShowPasswordChangedDialog(const AccountId& account_id,
+                                         bool password_incorrect) = 0;
+};
+
+}  // namespace chromeos
+#endif  // CHROME_BROWSER_CHROMEOS_LOGIN_UI_SIGNIN_UI_H_
diff --git a/chrome/browser/component_updater/third_party_module_list_component_installer_win.cc b/chrome/browser/component_updater/third_party_module_list_component_installer_win.cc
index 64089ce..bec583f0 100644
--- a/chrome/browser/component_updater/third_party_module_list_component_installer_win.cc
+++ b/chrome/browser/component_updater/third_party_module_list_component_installer_win.cc
@@ -14,7 +14,7 @@
 #include "base/memory/ref_counted.h"
 #include "base/values.h"
 #include "base/version.h"
-#include "chrome/browser/win/conflicts/module_blacklist_cache_util.h"
+#include "chrome/browser/win/conflicts/module_blocklist_cache_util.h"
 #include "chrome/browser/win/conflicts/module_database.h"
 #include "chrome/browser/win/conflicts/third_party_conflicts_manager.h"
 
diff --git a/chrome/browser/dev_ui_browser_resources.grd b/chrome/browser/dev_ui_browser_resources.grd
index 2ea1fb1..e7c2e52b 100644
--- a/chrome/browser/dev_ui_browser_resources.grd
+++ b/chrome/browser/dev_ui_browser_resources.grd
@@ -20,7 +20,7 @@
     <includes>
       <include name="IDR_ACCESSIBILITY_HTML" file="resources\accessibility\accessibility.html" flattenhtml="true" allowexternalscript="true" type="BINDATA" />
       <include name="IDR_ACCESSIBILITY_CSS" file="resources\accessibility\accessibility.css" type="BINDATA" />
-      <include name="IDR_ACCESSIBILITY_JS" file="resources\accessibility\accessibility.js" flattenhtml="true" type="BINDATA" />
+      <include name="IDR_ACCESSIBILITY_JS" file="resources\accessibility\accessibility.js" type="BINDATA" />
       <include name="IDR_COMPONENTS_COMPONENTS_HTML" file="resources\components\components.html" flattenhtml="true" allowexternalscript="true" type="BINDATA" />
       <include name="IDR_COMPONENTS_COMPONENTS_JS" file="resources\components\components.js" type="BINDATA" />
       <include name="IDR_DEVICE_LOG_UI_HTML" file="resources\device_log_ui\device_log_ui.html" type="BINDATA" />
@@ -38,17 +38,17 @@
       <include name="IDR_INTERVENTIONS_INTERNALS_INDEX_JS" file="resources\interventions_internals\index.js" type="BINDATA" />
       <include name="IDR_INTERVENTIONS_INTERNALS_MOJOM_LITE_JS" file="${root_gen_dir}\chrome\browser\ui\webui\interventions_internals\interventions_internals.mojom-lite.js" use_base_dir="false" type="BINDATA" />
       <include name="IDR_INTERVENTIONS_INTERNALS_UNSUPPORTED_PAGE_HTML" file="resources\interventions_internals\unsupported_page.html" flattenhtml="true" allowexternalscript="true" type="BINDATA" />
-      <include name="IDR_LOCAL_STATE_HTML" file="resources\local_state\local_state.html" flattenhtml="true" allowexternalscript="true" type="BINDATA" />
-      <include name="IDR_LOCAL_STATE_JS" file="resources\local_state\local_state.js" flattenhtml="true" allowexternalscript="true" type="BINDATA" />
-      <include name="IDR_MEDIA_DATA_TABLE_JS" file="resources\media\media_data_table.js" flattenhtml="true" type="BINDATA" />
-      <include name="IDR_MEDIA_ENGAGEMENT_HTML" file="resources\media\media_engagement.html" flattenhtml="true" type="BINDATA" allowexternalscript="true" />
-      <include name="IDR_MEDIA_ENGAGEMENT_JS" file="resources\media\media_engagement.js" flattenhtml="true" type="BINDATA" />
+      <include name="IDR_LOCAL_STATE_HTML" file="resources\local_state\local_state.html" type="BINDATA" />
+      <include name="IDR_LOCAL_STATE_JS" file="resources\local_state\local_state.js" type="BINDATA" />
+      <include name="IDR_MEDIA_DATA_TABLE_JS" file="resources\media\media_data_table.js" type="BINDATA" />
+      <include name="IDR_MEDIA_ENGAGEMENT_HTML" file="resources\media\media_engagement.html" type="BINDATA" />
+      <include name="IDR_MEDIA_ENGAGEMENT_JS" file="resources\media\media_engagement.js" type="BINDATA" />
       <include name="IDR_MEDIA_ENGAGEMENT_SCORE_DETAILS_MOJOM_LITE_JS" file="${root_gen_dir}\chrome\browser\media\media_engagement_score_details.mojom-lite.js" use_base_dir="false" type="BINDATA" />
-      <include name="IDR_MEDIA_FEEDS_HTML" file="resources\media\media_feeds.html" flattenhtml="true" type="BINDATA" allowexternalscript="true" />
-      <include name="IDR_MEDIA_FEEDS_JS" file="resources\media\media_feeds.js" flattenhtml="true" type="BINDATA" />
+      <include name="IDR_MEDIA_FEEDS_HTML" file="resources\media\media_feeds.html" type="BINDATA" />
+      <include name="IDR_MEDIA_FEEDS_JS" file="resources\media\media_feeds.js" type="BINDATA" />
       <include name="IDR_MEDIA_FEEDS_STORE_MOJOM_LITE_JS" file="${root_gen_dir}\chrome\browser\media\feeds\media_feeds_store.mojom-lite.js" use_base_dir="false" type="BINDATA" />
-      <include name="IDR_MEDIA_HISTORY_HTML" file="resources\media\media_history.html" flattenhtml="true" type="BINDATA" allowexternalscript="true" />
-      <include name="IDR_MEDIA_HISTORY_JS" file="resources\media\media_history.js" flattenhtml="true" type="BINDATA" />
+      <include name="IDR_MEDIA_HISTORY_HTML" file="resources\media\media_history.html" type="BINDATA" allowexternalscript="true" />
+      <include name="IDR_MEDIA_HISTORY_JS" file="resources\media\media_history.js" type="BINDATA" />
       <include name="IDR_MEDIA_HISTORY_STORE_MOJOM_LITE_JS" file="${root_gen_dir}\chrome\browser\media\history\media_history_store.mojom-lite.js" use_base_dir="false" type="BINDATA" />
       <include name="IDR_MEMORY_INTERNALS_HTML" file="resources\memory_internals\memory_internals.html" type="BINDATA" />
       <include name="IDR_MEMORY_INTERNALS_JS" file="resources\memory_internals\memory_internals.js" type="BINDATA" />
@@ -66,8 +66,8 @@
         <include name="IDR_SANDBOX_INTERNALS_JS" file="resources\sandbox_internals\sandbox_internals_win.js" type="BINDATA" />
       </if>
 
-      <include name="IDR_SITE_ENGAGEMENT_HTML" file="resources\engagement\site_engagement.html" flattenhtml="true" allowexternalscript="true" type="BINDATA" />
-      <include name="IDR_SITE_ENGAGEMENT_JS" file="resources\engagement\site_engagement.js" flattenhtml="true" type="BINDATA" />
+      <include name="IDR_SITE_ENGAGEMENT_HTML" file="resources\engagement\site_engagement.html" type="BINDATA" />
+      <include name="IDR_SITE_ENGAGEMENT_JS" file="resources\engagement\site_engagement.js" type="BINDATA" />
       <include name="IDR_SITE_ENGAGEMENT_DETAILS_MOJOM_WEBUI_JS" file="${root_gen_dir}\mojom-webui\components\site_engagement\core\mojom\site_engagement_details.mojom-webui.js" use_base_dir="false" type="BINDATA" />
 
       <if expr="is_android">
@@ -89,13 +89,13 @@
         <include name="IDR_SUPERVISED_USER_INTERNALS_JS" file="resources\supervised_user_internals\supervised_user_internals.js" type="BINDATA" />
       </if>
       <include name="IDR_TRANSLATE_INTERNALS_HTML" file="../../components/translate/translate_internals/translate_internals.html" flattenhtml="true" allowexternalscript="true" type="BINDATA" />
-      <include name="IDR_TRANSLATE_INTERNALS_JS" file="../../components/translate/translate_internals/translate_internals.js" flattenhtml="true" type="BINDATA" />
+      <include name="IDR_TRANSLATE_INTERNALS_JS" file="../../components/translate/translate_internals/translate_internals.js" type="BINDATA" />
       <include name="IDR_WEB_APP_INTERNALS_HTML" file="resources/web_app_internals/index.html" type="BINDATA" />
       <include name="IDR_WEB_APP_INTERNALS_JS" file="${root_gen_dir}/chrome/browser/resources/web_app_internals/web_app_internals.js" use_base_dir="false" type="BINDATA" />
       <include name="IDR_WEB_APP_INTERNALS_MOJOM_LITE_JS" file="${root_gen_dir}/chrome/browser/ui/webui/internals/web_app/web_app_internals.mojom-lite.js" use_base_dir="false" type="BINDATA" />
       <include name="IDR_UKM_INTERNALS_HTML" file="../../components/ukm/debug/ukm_internals.html" flattenhtml="true" allowexternalscript="true" type="BINDATA" />
-      <include name="IDR_UKM_INTERNALS_JS" file="../../components/ukm/debug/ukm_internals.js" flattenhtml="true" type="BINDATA" />
-      <include name="IDR_UKM_INTERNALS_CSS" file="../../components/ukm/debug/ukm_internals.css" flattenhtml="true" type="BINDATA" />
+      <include name="IDR_UKM_INTERNALS_JS" file="../../components/ukm/debug/ukm_internals.js" type="BINDATA" />
+      <include name="IDR_UKM_INTERNALS_CSS" file="../../components/ukm/debug/ukm_internals.css" type="BINDATA" />
     </includes>
   </release>
 </grit>
diff --git a/chrome/browser/enterprise/browser_management/browser_management_status_provider.cc b/chrome/browser/enterprise/browser_management/browser_management_status_provider.cc
index 5f31f56..90703dad 100644
--- a/chrome/browser/enterprise/browser_management/browser_management_status_provider.cc
+++ b/chrome/browser/enterprise/browser_management/browser_management_status_provider.cc
@@ -22,8 +22,13 @@
     default;
 
 bool BrowserCloudManagementStatusProvider::IsManaged() {
-#if !defined(OS_ANDROID)
+#if defined(OS_CHROMEOS)
   return policy::BrowserDMTokenStorage::Get()->RetrieveDMToken().is_valid();
+#elif !defined(OS_ANDROID)
+  // A machine level user cloud policy manager is only created if the browser is
+  // managed by CBCM.
+  return g_browser_process->browser_policy_connector()
+             ->machine_level_user_cloud_policy_manager() != nullptr;
 #else
   return false;
 #endif
diff --git a/chrome/browser/extensions/BUILD.gn b/chrome/browser/extensions/BUILD.gn
index e09c4da5..09fba5b 100644
--- a/chrome/browser/extensions/BUILD.gn
+++ b/chrome/browser/extensions/BUILD.gn
@@ -1002,7 +1002,6 @@
       "api/terminal/terminal_private_api.h",
       "api/virtual_keyboard_private/chrome_virtual_keyboard_delegate.cc",
       "api/virtual_keyboard_private/chrome_virtual_keyboard_delegate.h",
-      "api/vpn_provider/vpn_service_factory.cc",
       "chrome_kiosk_delegate_chromeos.cc",
       "clipboard_extension_helper_chromeos.cc",
       "clipboard_extension_helper_chromeos.h",
diff --git a/chrome/browser/extensions/api/declarative_net_request/declarative_net_request_unittest.cc b/chrome/browser/extensions/api/declarative_net_request/declarative_net_request_unittest.cc
index 2dfd013..7adc343 100644
--- a/chrome/browser/extensions/api/declarative_net_request/declarative_net_request_unittest.cc
+++ b/chrome/browser/extensions/api/declarative_net_request/declarative_net_request_unittest.cc
@@ -194,6 +194,8 @@
     tester.ExpectTotalCount(kManifestRulesCountHistogram, 0u);
   }
 
+  // void Update
+
   enum class RulesetScope { kDynamic, kSession };
 
   // Runs the updateDynamicRules/updateSessionRules extension function based on
@@ -2184,6 +2186,48 @@
   CheckExtensionAllocationInPrefs(second_extension_id, ext_2_allocation);
 }
 
+using MultipleRulesetsGlobalRulesTest_Unpacked =
+    MultipleRulesetsGlobalRulesTest;
+
+// Test that reloading an unpacked extension is functionally identical to
+// uninstalling then reinstalling it for the purpose of global rule allocation,
+// and the allocation should reflect changes made to the extension.
+TEST_P(MultipleRulesetsGlobalRulesTest_Unpacked, UpdateAllocationOnReload) {
+  AddRuleset(CreateRuleset(kId1, 250, 0, true));
+
+  RulesetManagerObserver ruleset_waiter(manager());
+  LoadAndExpectSuccess(250);
+  ruleset_waiter.WaitForExtensionsWithRulesetsCount(1);
+  ExtensionId extension_id = extension()->id();
+
+  // The 150 rules that contribute to the global pool should be
+  // tracked.
+  GlobalRulesTracker& global_rules_tracker =
+      RulesMonitorService::Get(browser_context())->global_rules_tracker();
+  EXPECT_EQ(150u, global_rules_tracker.GetAllocatedGlobalRuleCountForTesting());
+
+  // An entry for these 150 rules should be persisted for the extension in
+  // prefs.
+  CheckExtensionAllocationInPrefs(extension_id, 150);
+
+  // Replace ruleset |kId1| with a smaller ruleset |kId2| and persist the
+  // ruleset to the extension's directory via WriteExtensionData().
+  ClearRulesets();
+  AddRuleset(CreateRuleset(kId2, 150, 0, true));
+  WriteExtensionData();
+
+  // Reload the extension. For unpacked extensions this is functionally
+  // equivalent to uninstalling the extension then installing it again based on
+  // the contents of the extension's directory.
+  service()->ReloadExtension(extension_id);
+  ruleset_waiter.WaitForExtensionsWithRulesetsCount(1);
+
+  // File changes to the extension's ruleset should take effect after it is
+  // reloaded.
+  EXPECT_EQ(50u, global_rules_tracker.GetAllocatedGlobalRuleCountForTesting());
+  CheckExtensionAllocationInPrefs(extension_id, 50);
+}
+
 INSTANTIATE_TEST_SUITE_P(All,
                          SingleRulesetTest,
                          ::testing::Values(ExtensionLoadType::PACKED,
@@ -2204,6 +2248,10 @@
                          ::testing::Values(ExtensionLoadType::PACKED,
                                            ExtensionLoadType::UNPACKED));
 
+INSTANTIATE_TEST_SUITE_P(All,
+                         MultipleRulesetsGlobalRulesTest_Unpacked,
+                         ::testing::Values(ExtensionLoadType::UNPACKED));
+
 }  // namespace
 }  // namespace declarative_net_request
 }  // namespace extensions
diff --git a/chrome/browser/flags/android/chrome_feature_list.cc b/chrome/browser/flags/android/chrome_feature_list.cc
index ac90b99..c1d6933 100644
--- a/chrome/browser/flags/android/chrome_feature_list.cc
+++ b/chrome/browser/flags/android/chrome_feature_list.cc
@@ -106,7 +106,6 @@
     &feature_engagement::kIPHTabSwitcherButtonFeature,
     &feed::kInterestFeedContentSuggestions,
     &feed::kInterestFeedNoticeCardAutoDismiss,
-    &feed::kInterestFeedSpinnerAlwaysAnimate,
     &feed::kInterestFeedV1ClicksAndViewsConditionalUpload,
     &feed::kInterestFeedV2,
     &feed::kReportFeedUserActions,
diff --git a/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/ChromeFeatureList.java b/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/ChromeFeatureList.java
index 5f2907a..38193b67 100644
--- a/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/ChromeFeatureList.java
+++ b/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/ChromeFeatureList.java
@@ -322,8 +322,6 @@
     public static final String INTEREST_FEED_CONTENT_SUGGESTIONS = "InterestFeedContentSuggestions";
     public static final String INTEREST_FEED_NOTICE_CARD_AUTO_DISMISS =
             "InterestFeedNoticeCardAutoDismiss";
-    public static final String INTEREST_FEED_SPINNER_ALWAYS_ANIMATE =
-            "InterestFeedSpinnerAlwaysAnimate";
     public static final String INTEREST_FEED_V2 = "InterestFeedV2";
     public static final String KITKAT_SUPPORTED = "KitKatSupported";
     public static final String LOOKALIKE_NAVIGATION_URL_SUGGESTIONS_UI =
diff --git a/chrome/browser/long_screenshots/long_screenshots_tab_service.cc b/chrome/browser/long_screenshots/long_screenshots_tab_service.cc
index 26b84f57..32ff1dfd 100644
--- a/chrome/browser/long_screenshots/long_screenshots_tab_service.cc
+++ b/chrome/browser/long_screenshots/long_screenshots_tab_service.cc
@@ -4,6 +4,8 @@
 
 #include "chrome/browser/long_screenshots/long_screenshots_tab_service.h"
 
+#include <utility>
+
 #include "base/callback.h"
 #include "base/memory/memory_pressure_listener.h"
 #include "base/memory/memory_pressure_monitor.h"
@@ -20,12 +22,10 @@
 }  // namespace
 
 LongScreenshotsTabService::LongScreenshotsTabService(
-    const base::FilePath& profile_dir,
-    base::StringPiece ascii_feature_name,
+    std::unique_ptr<paint_preview::PaintPreviewFileMixin> file_mixin,
     std::unique_ptr<paint_preview::PaintPreviewPolicy> policy,
     bool is_off_the_record)
-    : PaintPreviewBaseService(profile_dir,
-                              ascii_feature_name,
+    : PaintPreviewBaseService(std::move(file_mixin),
                               std::move(policy),
                               is_off_the_record) {
   // TODO(tgupta): Populate this.
@@ -52,12 +52,12 @@
   // to ensure the renderer doesn't go away while that happens.
   contents->IncrementCapturerCount(gfx::Size(), true);
 
-  auto file_manager = GetFileManager();
+  auto file_manager = GetFileMixin()->GetFileManager();
   auto key = file_manager->CreateKey(tab_id);
-  GetTaskRunner()->PostTaskAndReplyWithResult(
+  GetFileMixin()->GetTaskRunner()->PostTaskAndReplyWithResult(
       FROM_HERE,
       base::BindOnce(&paint_preview::FileManager::CreateOrGetDirectory,
-                     GetFileManager(), key, true),
+                     GetFileMixin()->GetFileManager(), key, true),
       // TODO(tgupta): Check for AMP pages here and get the right node id.
       base::BindOnce(&LongScreenshotsTabService::CaptureTabInternal,
                      weak_ptr_factory_.GetWeakPtr(), tab_id, key,
@@ -93,8 +93,15 @@
   }
   // TODO(tgupta): Modify this call to specify the size of the capture rather
   // than the whole area.
+  CaptureParams capture_params;
+  capture_params.web_contents = contents;
+  capture_params.root_dir = &file_path.value();
+  capture_params.persistence = paint_preview::RecordingPersistence::kFileSystem;
+  capture_params.clip_rect = gfx::Rect();
+  capture_params.capture_links = true;
+  capture_params.max_per_capture_size = kMaxPerCaptureSizeBytes;
   CapturePaintPreview(
-      contents, file_path.value(), gfx::Rect(), true, kMaxPerCaptureSizeBytes,
+      capture_params,
       base::BindOnce(&LongScreenshotsTabService::OnCaptured,
                      weak_ptr_factory_.GetWeakPtr(), tab_id, key,
                      frame_tree_node_id, std::move(callback)));
@@ -118,11 +125,12 @@
     return;
   }
 
-  auto file_manager = GetFileManager();
-  GetTaskRunner()->PostTaskAndReplyWithResult(
+  auto file_manager = GetFileMixin()->GetFileManager();
+  GetFileMixin()->GetTaskRunner()->PostTaskAndReplyWithResult(
       FROM_HERE,
-      base::BindOnce(&FileManager::SerializePaintPreviewProto, GetFileManager(),
-                     key, result->proto, true),
+      base::BindOnce(&FileManager::SerializePaintPreviewProto,
+                     GetFileMixin()->GetFileManager(), key, result->proto,
+                     true),
       base::BindOnce(&LongScreenshotsTabService::OnFinished,
                      weak_ptr_factory_.GetWeakPtr(), tab_id,
                      std::move(callback)));
@@ -136,8 +144,9 @@
 }
 
 void LongScreenshotsTabService::DeleteAllLongScreenshotFiles() {
-  GetTaskRunner()->PostTask(
-      FROM_HERE, base::BindOnce(&FileManager::DeleteAll, GetFileManager()));
+  GetFileMixin()->GetTaskRunner()->PostTask(
+      FROM_HERE, base::BindOnce(&FileManager::DeleteAll,
+                                GetFileMixin()->GetFileManager()));
 }
 
 }  // namespace long_screenshots
diff --git a/chrome/browser/long_screenshots/long_screenshots_tab_service.h b/chrome/browser/long_screenshots/long_screenshots_tab_service.h
index 66c88e6..bfe4131 100644
--- a/chrome/browser/long_screenshots/long_screenshots_tab_service.h
+++ b/chrome/browser/long_screenshots/long_screenshots_tab_service.h
@@ -33,8 +33,7 @@
     : public paint_preview::PaintPreviewBaseService {
  public:
   LongScreenshotsTabService(
-      const base::FilePath& profile_dir,
-      base::StringPiece ascii_feature_name,
+      std::unique_ptr<paint_preview::PaintPreviewFileMixin> file_mixin,
       std::unique_ptr<paint_preview::PaintPreviewPolicy> policy,
       bool is_off_the_record);
   ~LongScreenshotsTabService() override;
diff --git a/chrome/browser/long_screenshots/long_screenshots_tab_service_factory.cc b/chrome/browser/long_screenshots/long_screenshots_tab_service_factory.cc
index 477bb285..d4a7b22 100644
--- a/chrome/browser/long_screenshots/long_screenshots_tab_service_factory.cc
+++ b/chrome/browser/long_screenshots/long_screenshots_tab_service_factory.cc
@@ -4,6 +4,8 @@
 
 #include "chrome/browser/long_screenshots/long_screenshots_tab_service_factory.h"
 
+#include <utility>
+
 #include "build/build_config.h"
 #include "chrome/browser/long_screenshots/long_screenshots_tab_service.h"
 #include "components/keyed_service/core/simple_dependency_manager.h"
@@ -44,7 +46,9 @@
     return nullptr;
 
   return std::make_unique<LongScreenshotsTabService>(
-      key->GetPath(), kFeatureDirname, nullptr, key->IsOffTheRecord());
+      std::make_unique<paint_preview::PaintPreviewFileMixin>(key->GetPath(),
+                                                             kFeatureDirname),
+      nullptr, key->IsOffTheRecord());
 }
 
 SimpleFactoryKey* LongScreenshotsTabServiceFactory::GetKeyToUse(
diff --git a/chrome/browser/long_screenshots/long_screenshots_tab_service_unittest.cc b/chrome/browser/long_screenshots/long_screenshots_tab_service_unittest.cc
index 1f644de..0f33aed 100644
--- a/chrome/browser/long_screenshots/long_screenshots_tab_service_unittest.cc
+++ b/chrome/browser/long_screenshots/long_screenshots_tab_service_unittest.cc
@@ -86,7 +86,9 @@
     task_environment()->RunUntilIdle();
     EXPECT_TRUE(temp_dir_.CreateUniqueTempDir());
     service_ = std::make_unique<LongScreenshotsTabService>(
-        temp_dir_.GetPath(), kFeatureName, nullptr, false);
+        std::make_unique<paint_preview::PaintPreviewFileMixin>(
+            temp_dir_.GetPath(), kFeatureName),
+        nullptr, false);
     task_environment()->RunUntilIdle();
   }
 
@@ -126,9 +128,9 @@
       }));
   task_environment()->RunUntilIdle();
 
-  auto file_manager = service->GetFileManager();
+  auto file_manager = service->GetFileMixin()->GetFileManager();
   auto key = file_manager->CreateKey(kTabId);
-  service->GetTaskRunner()->PostTaskAndReplyWithResult(
+  service->GetFileMixin()->GetTaskRunner()->PostTaskAndReplyWithResult(
       FROM_HERE,
       base::BindOnce(&paint_preview::FileManager::DirectoryExists, file_manager,
                      key),
@@ -137,7 +139,7 @@
 
   service->DeleteAllLongScreenshotFiles();
   task_environment()->RunUntilIdle();
-  service->GetTaskRunner()->PostTaskAndReplyWithResult(
+  service->GetFileMixin()->GetTaskRunner()->PostTaskAndReplyWithResult(
       FROM_HERE,
       base::BindOnce(&FileManager::DirectoryExists, file_manager, key),
       base::BindOnce([](bool exists) { EXPECT_FALSE(exists); }));
@@ -160,9 +162,9 @@
       }));
   task_environment()->RunUntilIdle();
 
-  auto file_manager = service->GetFileManager();
+  auto file_manager = service->GetFileMixin()->GetFileManager();
   auto key = file_manager->CreateKey(kTabId);
-  service->GetTaskRunner()->PostTaskAndReplyWithResult(
+  service->GetFileMixin()->GetTaskRunner()->PostTaskAndReplyWithResult(
       FROM_HERE,
       base::BindOnce(&FileManager::DirectoryExists, file_manager, key),
       base::BindOnce([](bool exists) { EXPECT_TRUE(exists); }));
@@ -170,7 +172,7 @@
 
   service->DeleteAllLongScreenshotFiles();
   task_environment()->RunUntilIdle();
-  service->GetTaskRunner()->PostTaskAndReplyWithResult(
+  service->GetFileMixin()->GetTaskRunner()->PostTaskAndReplyWithResult(
       FROM_HERE,
       base::BindOnce(&FileManager::DirectoryExists, file_manager, key),
       base::BindOnce([](bool exists) { EXPECT_FALSE(exists); }));
diff --git a/chrome/browser/media/kaleidoscope/kaleidoscope_data_provider_impl.cc b/chrome/browser/media/kaleidoscope/kaleidoscope_data_provider_impl.cc
index 5fda797..63a5a13b 100644
--- a/chrome/browser/media/kaleidoscope/kaleidoscope_data_provider_impl.cc
+++ b/chrome/browser/media/kaleidoscope/kaleidoscope_data_provider_impl.cc
@@ -261,6 +261,11 @@
                                 time);
 }
 
+void KaleidoscopeDataProviderImpl::RecordDialogClosedHistogram(bool value) {
+  // If |value| is true then the user opened a watch action from this dialog.
+  base::UmaHistogramBoolean("Media.Kaleidoscope.DialogClosed", value);
+}
+
 media_history::MediaHistoryKeyedService*
 KaleidoscopeDataProviderImpl::GetMediaHistoryService() {
   return media_history::MediaHistoryKeyedServiceFactory::GetForProfile(
diff --git a/chrome/browser/media/kaleidoscope/kaleidoscope_data_provider_impl.h b/chrome/browser/media/kaleidoscope/kaleidoscope_data_provider_impl.h
index d6ee48d..275c0b9 100644
--- a/chrome/browser/media/kaleidoscope/kaleidoscope_data_provider_impl.h
+++ b/chrome/browser/media/kaleidoscope/kaleidoscope_data_provider_impl.h
@@ -68,6 +68,7 @@
   void SetSignedOutProviders(
       const std::vector<std::string>& providers) override;
   void RecordTimeTakenToStartWatchHistogram(base::TimeDelta time) override;
+  void RecordDialogClosedHistogram(bool value) override;
 
  private:
   media_history::MediaHistoryKeyedService* GetMediaHistoryService();
diff --git a/chrome/browser/media/kaleidoscope/mojom/kaleidoscope.mojom b/chrome/browser/media/kaleidoscope/mojom/kaleidoscope.mojom
index 3937f7b0..50acaf91 100644
--- a/chrome/browser/media/kaleidoscope/mojom/kaleidoscope.mojom
+++ b/chrome/browser/media/kaleidoscope/mojom/kaleidoscope.mojom
@@ -107,6 +107,10 @@
 
   // Records a histogram of the time taken to start a watch action.
   RecordTimeTakenToStartWatchHistogram(mojo_base.mojom.TimeDelta time);
+
+  // Records a histogram when the dialog was closed of whether the user selected
+  // a link from the dialog.
+  RecordDialogClosedHistogram(bool value);
 };
 
 // Handles identity related tasks.
diff --git a/chrome/browser/paint_preview/BUILD.gn b/chrome/browser/paint_preview/BUILD.gn
index ef93b54..acd2db8 100644
--- a/chrome/browser/paint_preview/BUILD.gn
+++ b/chrome/browser/paint_preview/BUILD.gn
@@ -8,6 +8,8 @@
     "services/paint_preview_tab_service.h",
     "services/paint_preview_tab_service_factory.cc",
     "services/paint_preview_tab_service_factory.h",
+    "services/paint_preview_tab_service_file_mixin.cc",
+    "services/paint_preview_tab_service_file_mixin.h",
   ]
 
   deps = [
diff --git a/chrome/browser/paint_preview/services/paint_preview_tab_service.cc b/chrome/browser/paint_preview/services/paint_preview_tab_service.cc
index b413c7f..4b4371c 100644
--- a/chrome/browser/paint_preview/services/paint_preview_tab_service.cc
+++ b/chrome/browser/paint_preview/services/paint_preview_tab_service.cc
@@ -14,6 +14,7 @@
 #include "base/strings/string_number_conversions.h"
 #include "base/task/post_task.h"
 #include "base/task/task_traits.h"
+#include "chrome/browser/paint_preview/services/paint_preview_tab_service_file_mixin.h"
 #include "components/paint_preview/browser/file_manager.h"
 #include "components/paint_preview/browser/warm_compositor.h"
 #include "content/public/browser/render_process_host.h"
@@ -34,8 +35,6 @@
 
 constexpr size_t kMaxPerCaptureSizeBytes = 5 * 1000L * 1000L;    // 5 MB.
 constexpr size_t kMaximumTotalCaptureSize = 25 * 1000L * 1000L;  // 25 MB.
-// The time horizon after which unused paint previews will be deleted.
-constexpr int kExpiryHorizonHrs = 72;
 
 #if defined(OS_ANDROID)
 void JavaBooleanCallbackAdapter(base::OnceCallback<void(bool)> callback,
@@ -56,22 +55,23 @@
 }  // namespace
 
 PaintPreviewTabService::PaintPreviewTabService(
-    const base::FilePath& profile_dir,
-    base::StringPiece ascii_feature_name,
+    std::unique_ptr<PaintPreviewFileMixin> file_mixin,
     std::unique_ptr<PaintPreviewPolicy> policy,
     bool is_off_the_record)
-    : PaintPreviewBaseService(profile_dir,
-                              ascii_feature_name,
+    : PaintPreviewBaseService(std::move(file_mixin),
                               std::move(policy),
                               is_off_the_record),
       cache_ready_(false) {
-  GetTaskRunner()->PostTaskAndReplyWithResult(
-      FROM_HERE, base::BindOnce(&FileManager::ListUsedKeys, GetFileManager()),
+  GetFileMixin()->GetTaskRunner()->PostTaskAndReplyWithResult(
+      FROM_HERE,
+      base::BindOnce(&FileManager::ListUsedKeys,
+                     GetFileMixin()->GetFileManager()),
       base::BindOnce(&PaintPreviewTabService::InitializeCache,
                      weak_ptr_factory_.GetWeakPtr()));
-  GetTaskRunner()->PostTaskAndReplyWithResult(
+  GetFileMixin()->GetTaskRunner()->PostTaskAndReplyWithResult(
       FROM_HERE,
-      base::BindOnce(&FileManager::GetTotalDiskUsage, GetFileManager()),
+      base::BindOnce(&FileManager::GetTotalDiskUsage,
+                     GetFileMixin()->GetFileManager()),
       base::BindOnce([](size_t size_bytes) {
         base::UmaHistogramMemoryKB(
             "Browser.PaintPreview.TabService.DiskUsageAtStartup",
@@ -111,12 +111,12 @@
   // to ensure the renderer doesn't go away while that happens.
   contents->IncrementCapturerCount(gfx::Size(), true);
 
-  auto file_manager = GetFileManager();
+  auto file_manager = GetFileMixin()->GetFileManager();
   auto key = file_manager->CreateKey(tab_id);
-  GetTaskRunner()->PostTaskAndReplyWithResult(
+  GetFileMixin()->GetTaskRunner()->PostTaskAndReplyWithResult(
       FROM_HERE,
-      base::BindOnce(&FileManager::CreateOrGetDirectory, GetFileManager(), key,
-                     true),
+      base::BindOnce(&FileManager::CreateOrGetDirectory,
+                     GetFileMixin()->GetFileManager(), key, true),
       base::BindOnce(&PaintPreviewTabService::CaptureTabInternal,
                      weak_ptr_factory_.GetWeakPtr(), tab_id, key,
                      contents->GetMainFrame()->GetFrameTreeNodeId(),
@@ -136,9 +136,9 @@
     return;
   }
 
-  auto file_manager = GetFileManager();
+  auto file_manager = GetFileMixin()->GetFileManager();
   captured_tab_ids_.erase(tab_id);
-  GetTaskRunner()->PostTask(
+  GetFileMixin()->GetTaskRunner()->PostTask(
       FROM_HERE, base::BindOnce(&FileManager::DeleteArtifactSet, file_manager,
                                 file_manager->CreateKey(tab_id)));
 }
@@ -162,24 +162,14 @@
     return;
   }
 
-  GetTaskRunner()->PostTaskAndReplyWithResult(
-      FROM_HERE, base::BindOnce(&FileManager::ListUsedKeys, GetFileManager()),
+  GetFileMixin()->GetTaskRunner()->PostTaskAndReplyWithResult(
+      FROM_HERE,
+      base::BindOnce(&FileManager::ListUsedKeys,
+                     GetFileMixin()->GetFileManager()),
       base::BindOnce(&PaintPreviewTabService::RunAudit,
                      weak_ptr_factory_.GetWeakPtr(), active_tab_ids));
 }
 
-void PaintPreviewTabService::GetCapturedPaintPreviewProto(
-    const DirectoryKey& key,
-    base::Optional<base::TimeDelta> expiry_horizon,
-    PaintPreviewBaseService::OnReadProtoCallback on_read_proto_callback) {
-  PaintPreviewBaseService::GetCapturedPaintPreviewProto(
-      key,
-      expiry_horizon.has_value()
-          ? expiry_horizon.value()
-          : base::TimeDelta::FromHours(kExpiryHorizonHrs),
-      std::move(on_read_proto_callback));
-}
-
 #if defined(OS_ANDROID)
 void PaintPreviewTabService::CaptureTabAndroid(
     JNIEnv* env,
@@ -220,7 +210,7 @@
 base::android::ScopedJavaLocalRef<jstring>
 PaintPreviewTabService::GetPathAndroid(JNIEnv* env) {
   return base::android::ConvertUTF8ToJavaString(
-      env, GetFileManager()->GetPath().AsUTF8Unsafe());
+      env, GetFileMixin()->GetFileManager()->GetPath().AsUTF8Unsafe());
 }
 #endif  // defined(OS_ANDROID)
 
@@ -257,9 +247,16 @@
     std::move(callback).Run(Status::kWebContentsGone);
     return;
   }
+  CaptureParams capture_params;
+  capture_params.web_contents = contents;
+  capture_params.render_frame_host = rfh;
+  capture_params.root_dir = &file_path.value();
+  capture_params.persistence = RecordingPersistence::kFileSystem;
+  capture_params.clip_rect = gfx::Rect();
+  capture_params.capture_links = true;
+  capture_params.max_per_capture_size = kMaxPerCaptureSizeBytes;
   CapturePaintPreview(
-      contents, rfh, file_path.value(), gfx::Rect(), true,
-      kMaxPerCaptureSizeBytes,
+      capture_params,
       base::BindOnce(&PaintPreviewTabService::OnCaptured,
                      weak_ptr_factory_.GetWeakPtr(), tab_id, key,
                      frame_tree_node_id, std::move(callback)));
@@ -283,11 +280,12 @@
     std::move(callback).Run(Status::kCaptureFailed);
     return;
   }
-  auto file_manager = GetFileManager();
-  GetTaskRunner()->PostTaskAndReplyWithResult(
+  auto file_manager = GetFileMixin()->GetFileManager();
+  GetFileMixin()->GetTaskRunner()->PostTaskAndReplyWithResult(
       FROM_HERE,
-      base::BindOnce(&FileManager::SerializePaintPreviewProto, GetFileManager(),
-                     key, result->proto, true),
+      base::BindOnce(&FileManager::SerializePaintPreviewProto,
+                     GetFileMixin()->GetFileManager(), key, result->proto,
+                     true),
       base::BindOnce(&PaintPreviewTabService::OnFinished,
                      weak_ptr_factory_.GetWeakPtr(), tab_id,
                      std::move(callback)));
@@ -301,12 +299,13 @@
     captured_tab_ids_.insert(tab_id);
   std::move(callback).Run(success ? Status::kOk
                                   : Status::kProtoSerializationFailed);
-  auto file_manager = GetFileManager();
-  GetTaskRunner()->PostTaskAndReplyWithResult(
+  auto file_manager = GetFileMixin()->GetFileManager();
+  GetFileMixin()->GetTaskRunner()->PostTaskAndReplyWithResult(
       FROM_HERE,
       base::BindOnce(&FileManager::GetOldestArtifactsForCleanup, file_manager,
                      kMaximumTotalCaptureSize,
-                     base::TimeDelta::FromHours(kExpiryHorizonHrs)),
+                     base::TimeDelta::FromHours(
+                         PaintPreviewTabServiceFileMixin::kExpiryHorizonHrs)),
       base::BindOnce(&PaintPreviewTabService::CleanupOldestFiles,
                      weak_ptr_factory_.GetWeakPtr(), tab_id));
 }
@@ -326,16 +325,17 @@
     keys_to_delete.push_back(key);
   }
 
-  GetTaskRunner()->PostTask(FROM_HERE,
-                            base::BindOnce(&FileManager::DeleteArtifactSets,
-                                           GetFileManager(), keys_to_delete));
+  GetFileMixin()->GetTaskRunner()->PostTask(
+      FROM_HERE,
+      base::BindOnce(&FileManager::DeleteArtifactSets,
+                     GetFileMixin()->GetFileManager(), keys_to_delete));
 }
 
 void PaintPreviewTabService::RunAudit(
     const std::vector<int>& active_tab_ids,
     const base::flat_set<DirectoryKey>& in_use_keys) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  auto file_manager = GetFileManager();
+  auto file_manager = GetFileMixin()->GetFileManager();
   std::vector<DirectoryKey> keys;
   keys.reserve(active_tab_ids.size());
   for (const auto& tab_id : active_tab_ids)
@@ -355,9 +355,10 @@
   for (const auto& key : keys_to_delete)
     captured_tab_ids_.erase(TabIdFromDirectoryKey(key));
 
-  GetTaskRunner()->PostTask(FROM_HERE,
-                            base::BindOnce(&FileManager::DeleteArtifactSets,
-                                           GetFileManager(), keys_to_delete));
+  GetFileMixin()->GetTaskRunner()->PostTask(
+      FROM_HERE,
+      base::BindOnce(&FileManager::DeleteArtifactSets,
+                     GetFileMixin()->GetFileManager(), keys_to_delete));
 }
 
 }  // namespace paint_preview
diff --git a/chrome/browser/paint_preview/services/paint_preview_tab_service.h b/chrome/browser/paint_preview/services/paint_preview_tab_service.h
index 4aa0b27..ffffd65 100644
--- a/chrome/browser/paint_preview/services/paint_preview_tab_service.h
+++ b/chrome/browser/paint_preview/services/paint_preview_tab_service.h
@@ -38,8 +38,7 @@
 // browser is restarted.
 class PaintPreviewTabService : public PaintPreviewBaseService {
  public:
-  PaintPreviewTabService(const base::FilePath& profile_dir,
-                         base::StringPiece ascii_feature_name,
+  PaintPreviewTabService(std::unique_ptr<PaintPreviewFileMixin> file_mixin,
                          std::unique_ptr<PaintPreviewPolicy> policy,
                          bool is_off_the_record);
   ~PaintPreviewTabService() override;
@@ -78,14 +77,6 @@
   // occurred.
   void AuditArtifacts(const std::vector<int>& active_tab_ids);
 
-  // Override for GetCapturedPaintPreviewProto. Defaults expiry horizon to 72
-  // hrs if not specified.
-  void GetCapturedPaintPreviewProto(
-      const DirectoryKey& key,
-      base::Optional<base::TimeDelta> expiry_horizon,
-      PaintPreviewBaseService::OnReadProtoCallback on_read_proto_callback)
-      override;
-
 #if defined(OS_ANDROID)
   // JNI wrapped versions of the above methods
   void CaptureTabAndroid(
diff --git a/chrome/browser/paint_preview/services/paint_preview_tab_service_factory.cc b/chrome/browser/paint_preview/services/paint_preview_tab_service_factory.cc
index bc087ed..a4cabd7f7e 100644
--- a/chrome/browser/paint_preview/services/paint_preview_tab_service_factory.cc
+++ b/chrome/browser/paint_preview/services/paint_preview_tab_service_factory.cc
@@ -4,8 +4,11 @@
 
 #include "chrome/browser/paint_preview/services/paint_preview_tab_service_factory.h"
 
+#include <utility>
+
 #include "build/build_config.h"
 #include "chrome/browser/paint_preview/services/paint_preview_tab_service.h"
+#include "chrome/browser/paint_preview/services/paint_preview_tab_service_file_mixin.h"
 #include "components/keyed_service/core/simple_dependency_manager.h"
 #include "components/keyed_service/core/simple_factory_key.h"
 
@@ -52,7 +55,9 @@
 
   // TODO(crbug/1060556): Inject a useful policy.
   return std::make_unique<paint_preview::PaintPreviewTabService>(
-      key->GetPath(), kFeatureDirname, nullptr, key->IsOffTheRecord());
+      std::make_unique<PaintPreviewTabServiceFileMixin>(key->GetPath(),
+                                                        kFeatureDirname),
+      nullptr, key->IsOffTheRecord());
 }
 
 SimpleFactoryKey* PaintPreviewTabServiceFactory::GetKeyToUse(
diff --git a/chrome/browser/paint_preview/services/paint_preview_tab_service_file_mixin.cc b/chrome/browser/paint_preview/services/paint_preview_tab_service_file_mixin.cc
new file mode 100644
index 0000000..b138729
--- /dev/null
+++ b/chrome/browser/paint_preview/services/paint_preview_tab_service_file_mixin.cc
@@ -0,0 +1,29 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/paint_preview/services/paint_preview_tab_service_file_mixin.h"
+#include "components/paint_preview/browser/paint_preview_file_mixin.h"
+
+namespace paint_preview {
+
+PaintPreviewTabServiceFileMixin::PaintPreviewTabServiceFileMixin(
+    const base::FilePath& path,
+    base::StringPiece ascii_feature_name)
+    : PaintPreviewFileMixin(path, ascii_feature_name) {}
+
+PaintPreviewTabServiceFileMixin::~PaintPreviewTabServiceFileMixin() = default;
+
+void PaintPreviewTabServiceFileMixin::GetCapturedPaintPreviewProto(
+    const DirectoryKey& key,
+    base::Optional<base::TimeDelta> expiry_horizon,
+    OnReadProtoCallback on_read_proto_callback) {
+  PaintPreviewFileMixin::GetCapturedPaintPreviewProto(
+      key,
+      expiry_horizon.has_value()
+          ? expiry_horizon.value()
+          : base::TimeDelta::FromHours(kExpiryHorizonHrs),
+      std::move(on_read_proto_callback));
+}
+
+}  // namespace paint_preview
diff --git a/chrome/browser/paint_preview/services/paint_preview_tab_service_file_mixin.h b/chrome/browser/paint_preview/services/paint_preview_tab_service_file_mixin.h
new file mode 100644
index 0000000..9099f11
--- /dev/null
+++ b/chrome/browser/paint_preview/services/paint_preview_tab_service_file_mixin.h
@@ -0,0 +1,35 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_PAINT_PREVIEW_SERVICES_PAINT_PREVIEW_TAB_SERVICE_FILE_MIXIN_H_
+#define CHROME_BROWSER_PAINT_PREVIEW_SERVICES_PAINT_PREVIEW_TAB_SERVICE_FILE_MIXIN_H_
+
+#include "components/paint_preview/browser/paint_preview_file_mixin.h"
+
+namespace paint_preview {
+
+class PaintPreviewTabServiceFileMixin : public PaintPreviewFileMixin {
+ public:
+  PaintPreviewTabServiceFileMixin(const base::FilePath& profile_dir,
+                                  base::StringPiece ascii_feature_name);
+  PaintPreviewTabServiceFileMixin(const PaintPreviewTabServiceFileMixin&) =
+      delete;
+  PaintPreviewTabServiceFileMixin& operator=(
+      const PaintPreviewTabServiceFileMixin&) = delete;
+  ~PaintPreviewTabServiceFileMixin() override;
+
+  // Override for GetCapturedPaintPreviewProto. Defaults expiry horizon to 72
+  // hrs if not specified.
+  void GetCapturedPaintPreviewProto(
+      const DirectoryKey& key,
+      base::Optional<base::TimeDelta> expiry_horizon,
+      OnReadProtoCallback on_read_proto_callback) override;
+
+  // The time horizon after which unused paint previews will be deleted.
+  static constexpr int kExpiryHorizonHrs = 72;
+};
+
+}  // namespace paint_preview
+
+#endif  // CHROME_BROWSER_PAINT_PREVIEW_SERVICES_PAINT_PREVIEW_TAB_SERVICE_FILE_MIXIN_H_
diff --git a/chrome/browser/paint_preview/services/paint_preview_tab_service_unittest.cc b/chrome/browser/paint_preview/services/paint_preview_tab_service_unittest.cc
index 899c383..86f4683 100644
--- a/chrome/browser/paint_preview/services/paint_preview_tab_service_unittest.cc
+++ b/chrome/browser/paint_preview/services/paint_preview_tab_service_unittest.cc
@@ -12,6 +12,7 @@
 #include "base/files/file_util.h"
 #include "base/files/scoped_temp_dir.h"
 #include "base/test/task_environment.h"
+#include "chrome/browser/paint_preview/services/paint_preview_tab_service_file_mixin.h"
 #include "chrome/test/base/chrome_render_view_host_test_harness.h"
 #include "components/paint_preview/common/mojom/paint_preview_recorder.mojom.h"
 #include "content/public/browser/render_process_host.h"
@@ -89,7 +90,9 @@
     task_environment()->RunUntilIdle();
     EXPECT_TRUE(temp_dir_.CreateUniqueTempDir());
     service_ = std::make_unique<PaintPreviewTabService>(
-        temp_dir_.GetPath(), kFeatureName, nullptr, false);
+        std::make_unique<PaintPreviewTabServiceFileMixin>(temp_dir_.GetPath(),
+                                                          kFeatureName),
+        nullptr, false);
     task_environment()->RunUntilIdle();
     EXPECT_TRUE(service_->CacheInitialized());
   }
@@ -124,8 +127,10 @@
                 fake_content.size());
     }
 
-    return std::make_unique<PaintPreviewTabService>(GetPath(), kFeatureName,
-                                                    nullptr, false);
+    return std::make_unique<PaintPreviewTabService>(
+        std::make_unique<PaintPreviewTabServiceFileMixin>(GetPath(),
+                                                          kFeatureName),
+        nullptr, false);
   }
 
  private:
@@ -148,9 +153,9 @@
   task_environment()->RunUntilIdle();
   EXPECT_TRUE(service->HasCaptureForTab(kTabId));
 
-  auto file_manager = service->GetFileManager();
+  auto file_manager = service->GetFileMixin()->GetFileManager();
   auto key = file_manager->CreateKey(kTabId);
-  service->GetTaskRunner()->PostTaskAndReplyWithResult(
+  service->GetFileMixin()->GetTaskRunner()->PostTaskAndReplyWithResult(
       FROM_HERE,
       base::BindOnce(&FileManager::DirectoryExists, file_manager, key),
       base::BindOnce([](bool exists) { EXPECT_TRUE(exists); }));
@@ -159,7 +164,7 @@
   service->TabClosed(kTabId);
   EXPECT_FALSE(service->HasCaptureForTab(kTabId));
   task_environment()->RunUntilIdle();
-  service->GetTaskRunner()->PostTaskAndReplyWithResult(
+  service->GetFileMixin()->GetTaskRunner()->PostTaskAndReplyWithResult(
       FROM_HERE,
       base::BindOnce(&FileManager::DirectoryExists, file_manager, key),
       base::BindOnce([](bool exists) { EXPECT_FALSE(exists); }));
@@ -181,9 +186,9 @@
       }));
   task_environment()->RunUntilIdle();
 
-  auto file_manager = service->GetFileManager();
+  auto file_manager = service->GetFileMixin()->GetFileManager();
   auto key = file_manager->CreateKey(kTabId);
-  service->GetTaskRunner()->PostTaskAndReplyWithResult(
+  service->GetFileMixin()->GetTaskRunner()->PostTaskAndReplyWithResult(
       FROM_HERE,
       base::BindOnce(&FileManager::DirectoryExists, file_manager, key),
       base::BindOnce([](bool exists) { EXPECT_TRUE(exists); }));
@@ -192,7 +197,7 @@
 
   service->TabClosed(kTabId);
   task_environment()->RunUntilIdle();
-  service->GetTaskRunner()->PostTaskAndReplyWithResult(
+  service->GetFileMixin()->GetTaskRunner()->PostTaskAndReplyWithResult(
       FROM_HERE,
       base::BindOnce(&FileManager::DirectoryExists, file_manager, key),
       base::BindOnce([](bool exists) { EXPECT_FALSE(exists); }));
@@ -213,15 +218,15 @@
                         EXPECT_EQ(status, PaintPreviewTabService::Status::kOk);
                       }));
   task_environment()->RunUntilIdle();
-  auto file_manager = service->GetFileManager();
+  auto file_manager = service->GetFileMixin()->GetFileManager();
   auto key = file_manager->CreateKey(kTabId);
-  service->GetTaskRunner()->PostTaskAndReplyWithResult(
+  service->GetFileMixin()->GetTaskRunner()->PostTaskAndReplyWithResult(
       FROM_HERE,
       base::BindOnce(&FileManager::DirectoryExists, file_manager, key),
       base::BindOnce([](bool exists) { EXPECT_TRUE(exists); }));
   task_environment()->RunUntilIdle();
   base::FilePath path_1;
-  service->GetTaskRunner()->PostTaskAndReplyWithResult(
+  service->GetFileMixin()->GetTaskRunner()->PostTaskAndReplyWithResult(
       FROM_HERE,
       base::BindOnce(&FileManager::CreateOrGetDirectory, file_manager, key,
                      false),
@@ -241,12 +246,12 @@
                       }));
   task_environment()->RunUntilIdle();
 
-  service->GetTaskRunner()->PostTaskAndReplyWithResult(
+  service->GetFileMixin()->GetTaskRunner()->PostTaskAndReplyWithResult(
       FROM_HERE,
       base::BindOnce(&FileManager::DirectoryExists, file_manager, key),
       base::BindOnce([](bool exists) { EXPECT_TRUE(exists); }));
   base::FilePath path_2;
-  service->GetTaskRunner()->PostTaskAndReplyWithResult(
+  service->GetFileMixin()->GetTaskRunner()->PostTaskAndReplyWithResult(
       FROM_HERE,
       base::BindOnce(&FileManager::CreateOrGetDirectory, file_manager, key,
                      false),
@@ -267,7 +272,7 @@
   EXPECT_TRUE(service->HasCaptureForTab(kTabId));
 
   service->TabClosed(kTabId);
-  service->GetTaskRunner()->PostTaskAndReplyWithResult(
+  service->GetFileMixin()->GetTaskRunner()->PostTaskAndReplyWithResult(
       FROM_HERE,
       base::BindOnce(&FileManager::DirectoryExists, file_manager, key),
       base::BindOnce([](bool exists) { EXPECT_FALSE(exists); }));
@@ -278,7 +283,7 @@
 TEST_F(PaintPreviewTabServiceTest, TestUnityAudit) {
   std::vector<int> tab_ids = {1, 2, 3};
   auto service = BuildServiceWithCache(tab_ids);
-  auto file_manager = service->GetFileManager();
+  auto file_manager = service->GetFileMixin()->GetFileManager();
   task_environment()->RunUntilIdle();
 
   service->AuditArtifacts(tab_ids);
@@ -287,7 +292,7 @@
   for (const auto& id : tab_ids) {
     EXPECT_TRUE(service->HasCaptureForTab(id));
     auto key = file_manager->CreateKey(id);
-    service->GetTaskRunner()->PostTaskAndReplyWithResult(
+    service->GetFileMixin()->GetTaskRunner()->PostTaskAndReplyWithResult(
         FROM_HERE,
         base::BindOnce(&FileManager::DirectoryExists, file_manager, key),
         base::BindOnce([](bool exists) { EXPECT_TRUE(exists); }));
@@ -298,7 +303,7 @@
 TEST_F(PaintPreviewTabServiceTest, TestDisjointAudit) {
   std::vector<int> tab_ids = {1, 2, 3};
   auto service = BuildServiceWithCache(tab_ids);
-  auto file_manager = service->GetFileManager();
+  auto file_manager = service->GetFileMixin()->GetFileManager();
   task_environment()->RunUntilIdle();
 
   service->AuditArtifacts({4});
@@ -307,7 +312,7 @@
   for (const auto& id : tab_ids) {
     EXPECT_FALSE(service->HasCaptureForTab(id));
     auto key = file_manager->CreateKey(id);
-    service->GetTaskRunner()->PostTaskAndReplyWithResult(
+    service->GetFileMixin()->GetTaskRunner()->PostTaskAndReplyWithResult(
         FROM_HERE,
         base::BindOnce(&FileManager::DirectoryExists, file_manager, key),
         base::BindOnce([](bool exists) { EXPECT_FALSE(exists); }));
@@ -317,7 +322,7 @@
 
 TEST_F(PaintPreviewTabServiceTest, TestPartialAudit) {
   auto service = BuildServiceWithCache({1, 2, 3});
-  auto file_manager = service->GetFileManager();
+  auto file_manager = service->GetFileMixin()->GetFileManager();
   task_environment()->RunUntilIdle();
 
   std::vector<int> kept_tab_ids = {1, 3};
@@ -327,14 +332,14 @@
   for (const auto& id : kept_tab_ids) {
     EXPECT_TRUE(service->HasCaptureForTab(id));
     auto key = file_manager->CreateKey(id);
-    service->GetTaskRunner()->PostTaskAndReplyWithResult(
+    service->GetFileMixin()->GetTaskRunner()->PostTaskAndReplyWithResult(
         FROM_HERE,
         base::BindOnce(&FileManager::DirectoryExists, file_manager, key),
         base::BindOnce([](bool exists) { EXPECT_TRUE(exists); }));
   }
   EXPECT_FALSE(service->HasCaptureForTab(2));
   auto key = file_manager->CreateKey(2);
-  service->GetTaskRunner()->PostTaskAndReplyWithResult(
+  service->GetFileMixin()->GetTaskRunner()->PostTaskAndReplyWithResult(
       FROM_HERE,
       base::BindOnce(&FileManager::DirectoryExists, file_manager, key),
       base::BindOnce([](bool exists) { EXPECT_FALSE(exists); }));
@@ -403,9 +408,9 @@
 
   EXPECT_TRUE(service->HasCaptureForTab(kTabId));
 
-  auto file_manager = service->GetFileManager();
+  auto file_manager = service->GetFileMixin()->GetFileManager();
   auto key = file_manager->CreateKey(kTabId);
-  service->GetTaskRunner()->PostTaskAndReplyWithResult(
+  service->GetFileMixin()->GetTaskRunner()->PostTaskAndReplyWithResult(
       FROM_HERE,
       base::BindOnce(&FileManager::DirectoryExists, file_manager, key),
       base::BindOnce([](bool exists) { EXPECT_TRUE(exists); }));
@@ -413,7 +418,7 @@
 
   service->TabClosed(kTabId);
   EXPECT_FALSE(service->HasCaptureForTab(kTabId));
-  service->GetTaskRunner()->PostTaskAndReplyWithResult(
+  service->GetFileMixin()->GetTaskRunner()->PostTaskAndReplyWithResult(
       FROM_HERE,
       base::BindOnce(&FileManager::DirectoryExists, file_manager, key),
       base::BindOnce([](bool exists) { EXPECT_FALSE(exists); }));
@@ -448,9 +453,9 @@
   task_environment()->RunUntilIdle();
   EXPECT_TRUE(service->HasCaptureForTab(kTabId));
 
-  auto file_manager = service->GetFileManager();
+  auto file_manager = service->GetFileMixin()->GetFileManager();
   auto key = file_manager->CreateKey(kTabId);
-  service->GetTaskRunner()->PostTaskAndReplyWithResult(
+  service->GetFileMixin()->GetTaskRunner()->PostTaskAndReplyWithResult(
       FROM_HERE,
       base::BindOnce(&FileManager::DirectoryExists, file_manager, key),
       base::BindOnce([](bool exists) { EXPECT_TRUE(exists); }));
@@ -462,7 +467,7 @@
   service->TabClosed(kTabId);
   EXPECT_FALSE(service->HasCaptureForTab(kTabId));
   task_environment()->RunUntilIdle();
-  service->GetTaskRunner()->PostTaskAndReplyWithResult(
+  service->GetFileMixin()->GetTaskRunner()->PostTaskAndReplyWithResult(
       FROM_HERE,
       base::BindOnce(&FileManager::DirectoryExists, file_manager, key),
       base::BindOnce([](bool exists) { EXPECT_FALSE(exists); }));
diff --git a/chrome/browser/profiles/profile_manager.cc b/chrome/browser/profiles/profile_manager.cc
index de77d05..1549a38 100644
--- a/chrome/browser/profiles/profile_manager.cc
+++ b/chrome/browser/profiles/profile_manager.cc
@@ -1949,7 +1949,7 @@
   DCHECK(profile);
   bool is_ephemeral =
       profile->GetPrefs()->GetBoolean(prefs::kForceEphemeralProfiles);
-  if (!profile->IsOffTheRecord() && !is_ephemeral &&
+  if (!profile->IsOffTheRecord() && !is_ephemeral && !browser->is_type_app() &&
       ++browser_counts_[profile] == 1) {
     active_profiles_.push_back(profile);
     SaveActiveProfiles();
@@ -1964,7 +1964,8 @@
 void ProfileManager::OnBrowserClosed(Browser* browser) {
   Profile* profile = browser->profile();
   DCHECK(profile);
-  if (!profile->IsOffTheRecord() && --browser_counts_[profile] == 0) {
+  if (!profile->IsOffTheRecord() && !browser->is_type_app() &&
+      --browser_counts_[profile] == 0) {
     active_profiles_.erase(
         std::find(active_profiles_.begin(), active_profiles_.end(), profile));
     if (!closing_all_browsers_)
diff --git a/chrome/browser/resources/bookmarks/BUILD.gn b/chrome/browser/resources/bookmarks/BUILD.gn
index 6cc95050..156b3b0 100644
--- a/chrome/browser/resources/bookmarks/BUILD.gn
+++ b/chrome/browser/resources/bookmarks/BUILD.gn
@@ -5,7 +5,7 @@
 import("//chrome/common/features.gni")
 import("//third_party/closure_compiler/compile_js.gni")
 import("//tools/grit/grit_rule.gni")
-import("//tools/grit/preprocess_grit.gni")
+import("//tools/grit/preprocess_if_expr.gni")
 import("//tools/polymer/html_to_js.gni")
 import("//ui/webui/resources/tools/generate_grd.gni")
 import("../optimize_webui.gni")
@@ -54,7 +54,7 @@
   out_grd = "$target_gen_dir/${grd_prefix}_resources.grd"
 }
 
-preprocess_grit("preprocess") {
+preprocess_if_expr("preprocess") {
   in_folder = "./"
   out_folder = "$target_gen_dir/$preprocess_folder"
   out_manifest = "$target_gen_dir/$preprocess_manifest"
@@ -76,7 +76,7 @@
   ]
 }
 
-preprocess_grit("preprocess_generated") {
+preprocess_if_expr("preprocess_generated") {
   deps = [ ":web_components" ]
   in_folder = target_gen_dir
   out_folder = "$target_gen_dir/$preprocess_folder"
diff --git a/chrome/browser/resources/bookmarks/item.js b/chrome/browser/resources/bookmarks/item.js
index ff508f7..d18a2d6 100644
--- a/chrome/browser/resources/bookmarks/item.js
+++ b/chrome/browser/resources/bookmarks/item.js
@@ -194,6 +194,12 @@
       this.focus();
     } else if (e.key === 'ArrowRight') {
       this.$.menuButton.focus();
+    } else if (e.key === ' ') {
+      this.dispatch(selectItem(this.itemId, this.getState(), {
+        clear: false,
+        range: false,
+        toggle: true,
+      }));
     }
   },
 
diff --git a/chrome/browser/resources/bookmarks/list.js b/chrome/browser/resources/bookmarks/list.js
index 5e8b5c47..40e170c7 100644
--- a/chrome/browser/resources/bookmarks/list.js
+++ b/chrome/browser/resources/bookmarks/list.js
@@ -297,17 +297,6 @@
         if (e.shiftKey && this.getState().selection.anchor === null) {
           this.dispatch(updateAnchor(this.displayedIds_[oldFocusedIndex]));
         }
-
-        // If the focus moved from something other than a Ctrl + move event,
-        // update the selection.
-        const config = {
-          clear: !cursorModifier,
-          range: e.shiftKey,
-          toggle: false,
-        };
-
-        this.dispatch(selectItem(
-            this.displayedIds_[focusedIndex], this.getState(), config));
       }
     }
 
diff --git a/chrome/browser/resources/chromeos/accessibility/BUILD.gn b/chrome/browser/resources/chromeos/accessibility/BUILD.gn
index dfddba7..cd0d617 100644
--- a/chrome/browser/resources/chromeos/accessibility/BUILD.gn
+++ b/chrome/browser/resources/chromeos/accessibility/BUILD.gn
@@ -156,8 +156,10 @@
   extra_js_files = [
     "braille_ime/braille_ime.js",
     "common/constants.js",
+    "common/automation_predicate.js",
     "common/automation_util.js",
     "common/rect_util.js",
+    "common/tree_walker.js",
     "select_to_speak/paragraph_utils.js",
     "select_to_speak/select_to_speak.js",
     "select_to_speak/test_support.js",
diff --git a/chrome/browser/resources/chromeos/accessibility/select_to_speak/BUILD.gn b/chrome/browser/resources/chromeos/accessibility/select_to_speak/BUILD.gn
index c58e9cdc..a8e50ce5 100644
--- a/chrome/browser/resources/chromeos/accessibility/select_to_speak/BUILD.gn
+++ b/chrome/browser/resources/chromeos/accessibility/select_to_speak/BUILD.gn
@@ -78,6 +78,7 @@
     "paragraph_utils_overflow_test.js",
     "select_to_speak_keystroke_selection_test.js",
     "select_to_speak_mouse_selection_test.js",
+    "select_to_speak_navigation_control_test.js",
     "select_to_speak_prefs_test.js",
   ]
   gen_include_files = [
diff --git a/chrome/browser/resources/chromeos/accessibility/select_to_speak/node_utils.js b/chrome/browser/resources/chromeos/accessibility/select_to_speak/node_utils.js
index 25b6ac14..52bdf6c 100644
--- a/chrome/browser/resources/chromeos/accessibility/select_to_speak/node_utils.js
+++ b/chrome/browser/resources/chromeos/accessibility/select_to_speak/node_utils.js
@@ -458,6 +458,45 @@
       NodeUtils.sortNodeRangeByReadingOrder(nodes, startIndex, nodes.length);
     }
   }
+
+  /**
+   * @param {!AutomationNode} node Node to traverse from.
+   * @param {constants.Dir} direction Direction to traverse.
+   * @return {!Array<!AutomationNode>} Returns all selectable leaf text nodes
+   *     within the paragraph adjacent to the given node.
+   */
+  static getNextParagraph(node, direction) {
+    let nextNode = AutomationUtil.findNextNode(
+        node, direction, AutomationPredicate.leafWithText,
+        {skipInitialSubtree: true});
+    while (
+        nextNode !== null &&
+        (NodeUtils.shouldIgnoreNode(nextNode, /* includeOffscreen= */ true) ||
+         NodeUtils.isNotSelectable(nextNode) ||
+         ParagraphUtils.inSameParagraph(node, nextNode))) {
+      nextNode = AutomationUtil.findNextNode(
+          nextNode, direction, AutomationPredicate.leafWithText);
+    }
+    if (nextNode === null) {
+      return [];
+    }
+
+    // Now construct an array with all leaf nodes within the block.
+    const nodes = [];
+    do {
+      if (!NodeUtils.shouldIgnoreNode(nextNode, /* includeOffscreen= */ true) &&
+          !NodeUtils.isNotSelectable(nextNode)) {
+        nodes.push(nextNode);
+      }
+      nextNode = AutomationUtil.findNextNode(
+          nextNode, direction, AutomationPredicate.leafWithText);
+    } while (nextNode !== null &&
+             ParagraphUtils.inSameParagraph(nodes[0], nextNode));
+
+    // Reverse the nodes if we were traversing backward, so the returned result
+    // is in natural DOM order.
+    return direction === constants.Dir.BACKWARD ? nodes.reverse() : nodes;
+  }
 }
 
 /**
diff --git a/chrome/browser/resources/chromeos/accessibility/select_to_speak/node_utils_unittest.js b/chrome/browser/resources/chromeos/accessibility/select_to_speak/node_utils_unittest.js
index 3ca6147a..a44f763 100644
--- a/chrome/browser/resources/chromeos/accessibility/select_to_speak/node_utils_unittest.js
+++ b/chrome/browser/resources/chromeos/accessibility/select_to_speak/node_utils_unittest.js
@@ -15,8 +15,10 @@
   'word_utils.js',
   '../common/closure_shim.js',
   '../common/constants.js',
+  '../common/automation_predicate.js',
   '../common/automation_util.js',
   '../common/rect_util.js',
+  '../common/tree_walker.js',
 ];
 
 
@@ -486,4 +488,95 @@
       assertEquals(nodes[4].name, 'SVG 2 Node 1');
       assertEquals(nodes[5].name, 'SVG 2 Node 2');
       assertEquals(nodes[6].name, 'Text Node 3');
-    });
\ No newline at end of file
+    });
+
+TEST_F('SelectToSpeakNodeUtilsUnitTest', 'getNextParagraph', function() {
+  const root = createMockNode({role: 'rootWebArea'});
+  const paragraph1 =
+      createMockNode({role: 'paragraph', display: 'block', parent: root, root});
+  const text1 = createMockNode(
+      {role: 'staticText', parent: paragraph1, root, name: 'Line 1'});
+  const text2 = createMockNode(
+      {role: 'staticText', parent: paragraph1, root, name: 'Line 2'});
+  const paragraph2 =
+      createMockNode({role: 'paragraph', display: 'block', parent: root, root});
+  const text3 = createMockNode(
+      {role: 'staticText', parent: paragraph2, root, name: 'Line 3'});
+
+  // Forward from first text node of paragraph 1 gives paragraph 2 nodes.
+  let result = NodeUtils.getNextParagraph(text1, constants.Dir.FORWARD);
+  assertEquals(result.length, 1);
+  assertEquals(result[0], text3);
+
+  // Forward from second text node of paragraph 1 gives paragraph 2 nodes.
+  result = NodeUtils.getNextParagraph(text2, constants.Dir.FORWARD);
+  assertEquals(result.length, 1);
+  assertEquals(result[0], text3);
+
+  // Forward from paragraph 1 node gives paragraph 2 nodes.
+  result = NodeUtils.getNextParagraph(paragraph1, constants.Dir.FORWARD);
+  assertEquals(result.length, 1);
+  assertEquals(result[0], text3);
+
+  // Forward from text node of paragraph 2 returns no nodes.
+  result = NodeUtils.getNextParagraph(text3, constants.Dir.FORWARD);
+  assertEquals(result.length, 0);
+
+  // Forward from paragraph 2 returns no nodes.
+  result = NodeUtils.getNextParagraph(paragraph2, constants.Dir.FORWARD);
+  assertEquals(result.length, 0);
+
+  // Backward from text node of paragraph 2 returns paragraph 1 nodes.
+  result = NodeUtils.getNextParagraph(text3, constants.Dir.BACKWARD);
+  assertEquals(result.length, 2);
+  assertEquals(result[0], text1);
+  assertEquals(result[1], text2);
+
+  // Backward from paragraph 2 node returns paragraph 1 nodes.
+  result = NodeUtils.getNextParagraph(paragraph2, constants.Dir.BACKWARD);
+  assertEquals(result.length, 2);
+  assertEquals(result[0], text1);
+  assertEquals(result[1], text2);
+
+  // Backward from text node of paragraph 1 returns no nodes.
+  result = NodeUtils.getNextParagraph(text2, constants.Dir.BACKWARD);
+  assertEquals(result.length, 0);
+
+  // Backward from text node of paragraph 1 returns no nodes.
+  result = NodeUtils.getNextParagraph(text1, constants.Dir.BACKWARD);
+  assertEquals(result.length, 0);
+
+  // Backward from paragraph 1 node returns no nodes.
+  result = NodeUtils.getNextParagraph(paragraph1, constants.Dir.BACKWARD);
+  assertEquals(result.length, 0);
+});
+
+/**
+ * Creates a AutomationNode-like object.
+ * @param {!Object} properties
+ */
+function createMockNode(properties) {
+  const node = Object.assign(
+      {
+        htmlAttributes: [],
+        state: {},
+        children: [],
+        location: {},
+      },
+      properties);
+
+  if (node.parent) {
+    // Update children of parent and sibling properties.
+    const parent = node.parent;
+    if (parent.children.length === 0) {
+      parent.children = [];
+      parent.firstChild = node;
+    } else {
+      node.previousSibling = parent.children[parent.children.length - 1];
+      node.previousSibling.nextSibling = node;
+    }
+    parent.children.push(node);
+    parent.lastChild = node;
+  }
+  return node;
+}
\ No newline at end of file
diff --git a/chrome/browser/resources/chromeos/accessibility/select_to_speak/select_to_speak.js b/chrome/browser/resources/chromeos/accessibility/select_to_speak/select_to_speak.js
index 2a31c3a..00a3cc7 100644
--- a/chrome/browser/resources/chromeos/accessibility/select_to_speak/select_to_speak.js
+++ b/chrome/browser/resources/chromeos/accessibility/select_to_speak/select_to_speak.js
@@ -595,6 +595,12 @@
       return;
     }
     switch (panelAction) {
+      case SelectToSpeakPanelAction.NEXT_PARAGRAPH:
+        this.navigateToNextParagraph_(constants.Dir.FORWARD);
+        break;
+      case SelectToSpeakPanelAction.PREVIOUS_PARAGRAPH:
+        this.navigateToNextParagraph_(constants.Dir.BACKWARD);
+        break;
       case SelectToSpeakPanelAction.EXIT:
         this.stopAll_();
         break;
@@ -604,6 +610,27 @@
   }
 
   /**
+   * Navigates to the next text block in the given direction.
+   * @param {constants.Dir} direction
+   * @private
+   */
+  navigateToNextParagraph_(direction) {
+    if (this.currentBlockParent_ === null) {
+      return;
+    }
+    // Retrieve the nodes that make up the next/prev paragraph.
+    const nextParagraphNodes =
+        NodeUtils.getNextParagraph(this.currentBlockParent_, direction);
+    if (nextParagraphNodes.length === 0) {
+      return;
+    }
+    // Ensure the first node in the paragraph is visible.
+    nextParagraphNodes[0].makeVisible();
+
+    this.startSpeechQueue_(nextParagraphNodes);
+  }
+
+  /**
    * Enqueue speech for the single given string. The string is not associated
    * with any particular nodes, so this does not do any work around drawing
    * focus rings, unlike startSpeechQueue_ below.
diff --git a/chrome/browser/resources/chromeos/accessibility/select_to_speak/select_to_speak_e2e_test_base.js b/chrome/browser/resources/chromeos/accessibility/select_to_speak/select_to_speak_e2e_test_base.js
index c36db42..66deb67 100644
--- a/chrome/browser/resources/chromeos/accessibility/select_to_speak/select_to_speak_e2e_test_base.js
+++ b/chrome/browser/resources/chromeos/accessibility/select_to_speak/select_to_speak_e2e_test_base.js
@@ -20,6 +20,7 @@
 #include "chrome/browser/chromeos/accessibility/accessibility_manager.h"
 #include "chrome/common/extensions/extension_constants.h"
 #include "content/public/test/browser_test.h"
+#include "ui/accessibility/accessibility_features.h"
     `);
   }
 
@@ -58,4 +59,20 @@
   findTextNode(root, text) {
     return root.find({role: 'staticText', attributes: {name: text}});
   }
+
+  /**
+   * Triggers select-to-speak to read selected text at a keystroke.
+   */
+  triggerReadSelectedText() {
+    assertFalse(this.mockTts.currentlySpeaking());
+    assertEquals(this.mockTts.pendingUtterances().length, 0);
+    selectToSpeak.fireMockKeyDownEvent(
+        {keyCode: SelectToSpeak.SEARCH_KEY_CODE});
+    selectToSpeak.fireMockKeyDownEvent(
+        {keyCode: SelectToSpeak.READ_SELECTION_KEY_CODE});
+    assertTrue(selectToSpeak.inputHandler_.isSelectionKeyDown_);
+    selectToSpeak.fireMockKeyUpEvent(
+        {keyCode: SelectToSpeak.READ_SELECTION_KEY_CODE});
+    selectToSpeak.fireMockKeyUpEvent({keyCode: SelectToSpeak.SEARCH_KEY_CODE});
+  }
 };
diff --git a/chrome/browser/resources/chromeos/accessibility/select_to_speak/select_to_speak_keystroke_selection_test.js b/chrome/browser/resources/chromeos/accessibility/select_to_speak/select_to_speak_keystroke_selection_test.js
index 4a19d86..9e7b772 100644
--- a/chrome/browser/resources/chromeos/accessibility/select_to_speak/select_to_speak_keystroke_selection_test.js
+++ b/chrome/browser/resources/chromeos/accessibility/select_to_speak/select_to_speak_keystroke_selection_test.js
@@ -17,23 +17,6 @@
   }
 
   /**
-   * Function to trigger select-to-speak to read selected text at a
-   * keystroke.
-   */
-  triggerReadSelectedText() {
-    assertFalse(this.mockTts.currentlySpeaking());
-    assertEquals(this.mockTts.pendingUtterances().length, 0);
-    selectToSpeak.fireMockKeyDownEvent(
-        {keyCode: SelectToSpeak.SEARCH_KEY_CODE});
-    selectToSpeak.fireMockKeyDownEvent(
-        {keyCode: SelectToSpeak.READ_SELECTION_KEY_CODE});
-    assertTrue(selectToSpeak.inputHandler_.isSelectionKeyDown_);
-    selectToSpeak.fireMockKeyUpEvent(
-        {keyCode: SelectToSpeak.READ_SELECTION_KEY_CODE});
-    selectToSpeak.fireMockKeyUpEvent({keyCode: SelectToSpeak.SEARCH_KEY_CODE});
-  }
-
-  /**
    * Function to load a simple webpage, select some of the single text
    * node, and trigger Select-to-Speak to read that partial node. Tests
    * that the selected region creates tts output that matches the expected
diff --git a/chrome/browser/resources/chromeos/accessibility/select_to_speak/select_to_speak_navigation_control_test.js b/chrome/browser/resources/chromeos/accessibility/select_to_speak/select_to_speak_navigation_control_test.js
new file mode 100644
index 0000000..eda50cf
--- /dev/null
+++ b/chrome/browser/resources/chromeos/accessibility/select_to_speak/select_to_speak_navigation_control_test.js
@@ -0,0 +1,101 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+GEN_INCLUDE(['select_to_speak_e2e_test_base.js']);
+GEN_INCLUDE(['mock_tts.js']);
+
+/**
+ * Browser tests for select-to-speak's navigation control features.
+ */
+SelectToSpeakNavigationControlTest = class extends SelectToSpeakE2ETest {
+  constructor() {
+    super();
+    this.mockTts = new MockTts();
+    chrome.tts = this.mockTts;
+  }
+
+  /** @override */
+  get featureList() {
+    return {enabled: ['features::kSelectToSpeakNavigationControl']};
+  }
+
+  generateHtmlWithSelectedElement(elementId, bodyHtml) {
+    return `
+    <script type="text/javascript">
+      function doSelection() {
+        let selection = window.getSelection();
+        let range = document.createRange();
+        selection.removeAllRanges();
+        let node = document.getElementById("${elementId}");
+        range.selectNodeContents(node);
+        selection.addRange(range);
+      }
+    </script>
+    <body onload="doSelection()">${bodyHtml}</body>`;
+  }
+};
+
+TEST_F(
+    'SelectToSpeakNavigationControlTest', 'NavigatesToNextParagraph',
+    function() {
+      const bodyHtml = `
+    <p id="p1">Paragraph 1</p>
+    <p id="p2">Paragraph 2</p>'
+  `;
+      this.runWithLoadedTree(
+          this.generateHtmlWithSelectedElement('p1', bodyHtml), () => {
+            this.triggerReadSelectedText();
+
+            // Speaks first paragraph
+            assertTrue(this.mockTts.currentlySpeaking());
+            assertEquals(this.mockTts.pendingUtterances().length, 1);
+            this.assertEqualsCollapseWhitespace(
+                this.mockTts.pendingUtterances()[0], 'Paragraph 1');
+
+            // TODO(joelriley@google.com): Figure out a better way to trigger
+            // the actual floating panel button rather than calling private
+            // method directly.
+            selectToSpeak.onSelectToSpeakPanelAction_(
+                chrome.accessibilityPrivate.SelectToSpeakPanelAction
+                    .NEXT_PARAGRAPH);
+
+            // Speaks second paragraph
+            assertTrue(this.mockTts.currentlySpeaking());
+            assertEquals(this.mockTts.pendingUtterances().length, 1);
+            this.assertEqualsCollapseWhitespace(
+                this.mockTts.pendingUtterances()[0], 'Paragraph 2');
+          });
+    });
+
+TEST_F(
+    'SelectToSpeakNavigationControlTest', 'NavigatesToPreviousParagraph',
+    function() {
+      const bodyHtml = `
+    <p id="p1">Paragraph 1</p>
+    <p id="p2">Paragraph 2</p>'
+  `;
+      this.runWithLoadedTree(
+          this.generateHtmlWithSelectedElement('p2', bodyHtml), () => {
+            this.triggerReadSelectedText();
+
+            // Speaks first paragraph
+            assertTrue(this.mockTts.currentlySpeaking());
+            assertEquals(this.mockTts.pendingUtterances().length, 1);
+            this.assertEqualsCollapseWhitespace(
+                this.mockTts.pendingUtterances()[0], 'Paragraph 2');
+
+            // TODO(joelriley@google.com): Figure out a better way to trigger
+            // the actual floating panel button rather than calling private
+            // method directly.
+            selectToSpeak.onSelectToSpeakPanelAction_(
+                chrome.accessibilityPrivate.SelectToSpeakPanelAction
+                    .PREVIOUS_PARAGRAPH);
+
+            // Speaks second paragraph
+            assertTrue(this.mockTts.currentlySpeaking());
+            assertEquals(this.mockTts.pendingUtterances().length, 1);
+            this.assertEqualsCollapseWhitespace(
+                this.mockTts.pendingUtterances()[0], 'Paragraph 1');
+          });
+    });
diff --git a/chrome/browser/resources/component_extension_resources.grd b/chrome/browser/resources/component_extension_resources.grd
index 42fb436..c4c029f 100644
--- a/chrome/browser/resources/component_extension_resources.grd
+++ b/chrome/browser/resources/component_extension_resources.grd
@@ -32,17 +32,17 @@
         <include name="IDR_HANGOUT_SERVICES_THUNK_JS" file="hangout_services/thunk.js" type="BINDATA" />
       </if>
       <if expr="not is_android">
-        <include name="IDR_FEEDBACK_BLUETOOTHLOGSINFO_HTML" file="feedback/html/bluetooth_logs_info.html" flattenhtml="true" allowexternalscript="true" type="BINDATA" />
+        <include name="IDR_FEEDBACK_BLUETOOTHLOGSINFO_HTML" file="feedback/html/bluetooth_logs_info.html" type="BINDATA" />
         <include name="IDR_FEEDBACK_ASSISTANTLOGSINFO_HTML" file="feedback/html/assistant_logs_info.html" flattenhtml="true" allowexternalscript="true" type="BINDATA" />
         <include name="IDR_FEEDBACK_DEFAULT_HTML" file="feedback/html/default.html" preprocess="true" type="BINDATA" />
         <include name="IDR_FEEDBACK_SYSINFO_HTML" file="feedback/html/sys_info.html" flattenhtml="true" allowexternalscript="true" type="BINDATA" />
-        <include name="IDR_FEEDBACK_ASSISTANT_LOGS_INFO_JS" file="feedback/js/assistant_logs_info.js" flattenhtml="true" type="BINDATA" />
-        <include name="IDR_FEEDBACK_FEEDBACK_UTIL_JS" file="feedback/js/feedback_util.js" flattenhtml="true" type="BINDATA" />
+        <include name="IDR_FEEDBACK_ASSISTANT_LOGS_INFO_JS" file="feedback/js/assistant_logs_info.js" type="BINDATA" />
+        <include name="IDR_FEEDBACK_FEEDBACK_UTIL_JS" file="feedback/js/feedback_util.js" type="BINDATA" />
         <include name="IDR_FEEDBACK_EVENT_HANDLER_JS" file="feedback/js/event_handler.js" flattenhtml="true" type="BINDATA" />
         <include name="IDR_FEEDBACK_FEEDBACK_JS" file="feedback/js/feedback.js" flattenhtml="true" type="BINDATA" />
-        <include name="IDR_FEEDBACK_SYSINFO_JS" file="feedback/js/sys_info.js" flattenhtml="true" type="BINDATA" />
-        <include name="IDR_FEEDBACK_TAKE_SCREENSHOT_JS" file="feedback/js/take_screenshot.js" flattenhtml="true" type="BINDATA" />
-        <include name="IDR_FEEDBACK_TOPBAR_HANDLER_JS" file="feedback/js/topbar_handlers.js" flattenhtml="true" type="BINDATA" />
+        <include name="IDR_FEEDBACK_SYSINFO_JS" file="feedback/js/sys_info.js" type="BINDATA" />
+        <include name="IDR_FEEDBACK_TAKE_SCREENSHOT_JS" file="feedback/js/take_screenshot.js" type="BINDATA" />
+        <include name="IDR_FEEDBACK_TOPBAR_HANDLER_JS" file="feedback/js/topbar_handlers.js" type="BINDATA" />
         <include name="IDR_FEEDBACK_ASSISTANT_LOGS_INFO_CSS" file="feedback/css/assistant_logs_info.css" type="BINDATA" />
         <include name="IDR_FEEDBACK_FEEDBACK_CSS" file="feedback/css/feedback.css" type="BINDATA" />
         <include name="IDR_FEEDBACK_SYSINFO_CSS" file="feedback/css/sys_info.css" type="BINDATA" />
diff --git a/chrome/browser/resources/downloads/BUILD.gn b/chrome/browser/resources/downloads/BUILD.gn
index a4a7cd7..85ccbfd 100644
--- a/chrome/browser/resources/downloads/BUILD.gn
+++ b/chrome/browser/resources/downloads/BUILD.gn
@@ -5,7 +5,7 @@
 import("//chrome/common/features.gni")
 import("//third_party/closure_compiler/compile_js.gni")
 import("//tools/grit/grit_rule.gni")
-import("//tools/grit/preprocess_grit.gni")
+import("//tools/grit/preprocess_if_expr.gni")
 import("//tools/polymer/html_to_js.gni")
 import("//ui/webui/resources/tools/generate_grd.gni")
 import("../optimize_webui.gni")
@@ -65,7 +65,7 @@
   out_grd = "$target_gen_dir/${grd_prefix}_resources.grd"
 }
 
-preprocess_grit("preprocess") {
+preprocess_if_expr("preprocess") {
   in_folder = "./"
   out_folder = "$target_gen_dir/$preprocess_folder"
   out_manifest = "$target_gen_dir/$preprocess_manifest"
@@ -79,7 +79,7 @@
   ]
 }
 
-preprocess_grit("preprocess_web_components") {
+preprocess_if_expr("preprocess_web_components") {
   deps = [ ":web_components" ]
   in_folder = target_gen_dir
   out_folder = "$target_gen_dir/$preprocess_folder"
@@ -92,7 +92,7 @@
   ]
 }
 
-preprocess_grit("preprocess_mojo") {
+preprocess_if_expr("preprocess_mojo") {
   deps = [ "//chrome/browser/ui/webui/downloads:mojo_bindings_webui_js" ]
   in_folder = "$root_gen_dir/mojom-webui/chrome/browser/ui/webui/downloads/"
   out_folder = "$target_gen_dir/$preprocess_folder"
diff --git a/chrome/browser/resources/extensions/BUILD.gn b/chrome/browser/resources/extensions/BUILD.gn
index d8f5235..74f5e0dc 100644
--- a/chrome/browser/resources/extensions/BUILD.gn
+++ b/chrome/browser/resources/extensions/BUILD.gn
@@ -6,7 +6,7 @@
 import("//chrome/common/features.gni")
 import("//third_party/closure_compiler/compile_js.gni")
 import("//tools/grit/grit_rule.gni")
-import("//tools/grit/preprocess_grit.gni")
+import("//tools/grit/preprocess_if_expr.gni")
 import("//tools/polymer/html_to_js.gni")
 import("//ui/webui/resources/tools/generate_grd.gni")
 import("../optimize_webui.gni")
@@ -60,7 +60,7 @@
   }
 }
 
-preprocess_grit("preprocess") {
+preprocess_if_expr("preprocess") {
   in_folder = "./"
   out_folder = "$target_gen_dir/$preprocess_folder"
   out_manifest = "$target_gen_dir/$preprocess_manifest"
@@ -80,7 +80,7 @@
   }
 }
 
-preprocess_grit("preprocess_generated") {
+preprocess_if_expr("preprocess_generated") {
   deps = [ ":web_components" ]
   in_folder = target_gen_dir
   out_folder = "$target_gen_dir/$preprocess_folder"
diff --git a/chrome/browser/resources/history/BUILD.gn b/chrome/browser/resources/history/BUILD.gn
index 5e0a2ab..417efb4e 100644
--- a/chrome/browser/resources/history/BUILD.gn
+++ b/chrome/browser/resources/history/BUILD.gn
@@ -5,7 +5,7 @@
 import("//chrome/common/features.gni")
 import("//third_party/closure_compiler/compile_js.gni")
 import("//tools/grit/grit_rule.gni")
-import("//tools/grit/preprocess_grit.gni")
+import("//tools/grit/preprocess_if_expr.gni")
 import("//tools/polymer/html_to_js.gni")
 import("//ui/webui/resources/tools/generate_grd.gni")
 import("../optimize_webui.gni")
@@ -69,7 +69,7 @@
   }
 }
 
-preprocess_grit("preprocess") {
+preprocess_if_expr("preprocess") {
   in_folder = "./"
   out_folder = "$target_gen_dir/$preprocess_folder"
   out_manifest = "$target_gen_dir/$preprocess_manifest"
@@ -84,7 +84,7 @@
   ]
 }
 
-preprocess_grit("preprocess_generated") {
+preprocess_if_expr("preprocess_generated") {
   deps = [ ":web_components" ]
   in_folder = target_gen_dir
   out_folder = "$target_gen_dir/$preprocess_folder"
diff --git a/chrome/browser/resources/local_ntp/local_ntp_resources.grd b/chrome/browser/resources/local_ntp/local_ntp_resources.grd
index f4b5358..d751f1aa 100644
--- a/chrome/browser/resources/local_ntp/local_ntp_resources.grd
+++ b/chrome/browser/resources/local_ntp/local_ntp_resources.grd
@@ -15,18 +15,18 @@
       <include name="IDR_CUSTOM_LINKS_EDIT_JS" file="custom_links_edit.js" type="BINDATA" />
       <include name="IDR_CUSTOM_LINKS_EDIT_MENU_SVG" file="icons\edit_menu.svg" type="BINDATA" />
       <include name="IDR_LOCAL_NTP_COMMON_CSS" file="local_ntp_common.css" type="BINDATA" />
-      <include name="IDR_LOCAL_NTP_ANIMATIONS_CSS" file="animations.css" flattenhtml="true" type="BINDATA" />
-      <include name="IDR_LOCAL_NTP_ANIMATIONS_JS" file="animations.js" flattenhtml="true" type="BINDATA" />
+      <include name="IDR_LOCAL_NTP_ANIMATIONS_CSS" file="animations.css" type="BINDATA" />
+      <include name="IDR_LOCAL_NTP_ANIMATIONS_JS" file="animations.js" type="BINDATA" />
       <include name="IDR_LOCAL_NTP_CSS" file="local_ntp.css" flattenhtml="true" type="BINDATA" />
       <include name="IDR_LOCAL_NTP_CUSTOMIZE_CSS" file="customize.css" flattenhtml="true" type="BINDATA" />
-      <include name="IDR_LOCAL_NTP_CUSTOMIZE_JS" file="customize.js" flattenhtml="true" type="BINDATA" />
+      <include name="IDR_LOCAL_NTP_CUSTOMIZE_JS" file="customize.js" type="BINDATA" />
       <include name="IDR_LOCAL_NTP_DOODLES_CSS" file="doodles.css" flattenhtml="true" type="BINDATA" />
-      <include name="IDR_LOCAL_NTP_DOODLES_JS" file="doodles.js" flattenhtml="true" type="BINDATA" />
-      <include name="IDR_LOCAL_NTP_HTML" file="local_ntp.html" flattenhtml="true" allowexternalscript="true" type="BINDATA" />
-      <include name="IDR_LOCAL_NTP_JS" file="local_ntp.js" flattenhtml="true" type="BINDATA" />
-      <include name="IDR_LOCAL_NTP_UTILS_JS" file="utils.js" flattenhtml="true" type="BINDATA" />
-      <include name="IDR_LOCAL_NTP_VOICE_CSS" file="voice.css" flattenhtml="true" type="BINDATA" />
-      <include name="IDR_LOCAL_NTP_VOICE_JS" file="voice.js" flattenhtml="true" type="BINDATA" />
+      <include name="IDR_LOCAL_NTP_DOODLES_JS" file="doodles.js" type="BINDATA" />
+      <include name="IDR_LOCAL_NTP_HTML" file="local_ntp.html" type="BINDATA" />
+      <include name="IDR_LOCAL_NTP_JS" file="local_ntp.js" type="BINDATA" />
+      <include name="IDR_LOCAL_NTP_UTILS_JS" file="utils.js" type="BINDATA" />
+      <include name="IDR_LOCAL_NTP_VOICE_CSS" file="voice.css" type="BINDATA" />
+      <include name="IDR_LOCAL_NTP_VOICE_JS" file="voice.js" type="BINDATA" />
       <include name="IDR_MOST_VISITED_DONT_SHOW_PNG" file="icons\dont_show.png" type="BINDATA" />
       <include name="IDR_MOST_VISITED_DONT_SHOW_2X_PNG" file="icons\dont_show_2x.png" type="BINDATA" />
       <include name="IDR_MOST_VISITED_IFRAME_CSS" file="most_visited_iframe.css" type="BINDATA" />
@@ -36,7 +36,7 @@
       <include name="IDR_MOST_VISITED_TITLE_CSS" file="most_visited_title.css" type="BINDATA" />
       <include name="IDR_MOST_VISITED_TITLE_HTML" file="most_visited_title.html" type="BINDATA" />
       <include name="IDR_MOST_VISITED_TITLE_JS" file="most_visited_title.js" type="BINDATA" />
-      <include name="IDR_MOST_VISITED_UTIL_JS" file="most_visited_util.js" type="BINDATA" flattenhtml="true" />
+      <include name="IDR_MOST_VISITED_UTIL_JS" file="most_visited_util.js" type="BINDATA" />
     </includes>
   </release>
 </grit>
diff --git a/chrome/browser/resources/nearby_share/shared/nearby_contact_visibility.html b/chrome/browser/resources/nearby_share/shared/nearby_contact_visibility.html
index d270e63..c23d5019 100644
--- a/chrome/browser/resources/nearby_share/shared/nearby_contact_visibility.html
+++ b/chrome/browser/resources/nearby_share/shared/nearby_contact_visibility.html
@@ -198,6 +198,13 @@
         opacity: var(--cr-disabled-opacity);
       }
 
+      .elide {
+        overflow: hidden;
+        text-overflow: ellipsis;
+        white-space: nowrap;
+        width: 400px;
+      }
+
       .contact-toggle {
         align-self: center;
         margin-inline-end: 12px;
@@ -404,8 +411,10 @@
                       class="padded-icon grey-icon contact-icon">
                   </iron-icon>
                   <div>
-                    <div class="cr-title-text">[[item.name]]</div>
-                    <div class="cr-secondary-text">[[item.description]]</div>
+                    <div class="cr-title-text elide">[[item.name]]</div>
+                    <div class="cr-secondary-text elide">
+                      [[item.description]]
+                    </div>
                   </div>
                   <template is="dom-if"
                       if="[[showContactCheckBoxes_(selectedVisibility)]]">
diff --git a/chrome/browser/resources/new_tab_page/realbox.html b/chrome/browser/resources/new_tab_page/realbox.html
index 33b3ea83..41746f8 100644
--- a/chrome/browser/resources/new_tab_page/realbox.html
+++ b/chrome/browser/resources/new_tab_page/realbox.html
@@ -23,7 +23,7 @@
     font-size: 16px;
     height: 100%;
     outline: none;
-    padding-inline-end:  40px;
+    padding-inline-end:  44px;
     padding-inline-start: 52px;
     position: relative;
     width: 100%;
@@ -40,10 +40,6 @@
     color: var(--search-box-placeholder, var(--google-grey-refresh-700));
   }
 
-  input:focus::placeholder {
-    color: transparent;
-  }
-
   input:focus,
   :host([matches-are-visible]) input {
     background-color: var(--search-box-results-bg, white);
@@ -102,7 +98,7 @@
   <input id="input" type="search" autocomplete="off" spellcheck="false"
       aria-live="polite" placeholder="$i18n{searchBoxHint}"
       on-copy="onInputCutCopy_" on-cut="onInputCutCopy_"
-      on-focus="onInputFocus_" on-input="onInputInput_"
+      on-focus="onInputFocus_" on-blur="onInputBlur_" on-input="onInputInput_"
       on-keydown="onInputKeydown_" on-keyup="onInputKeyup_"
       on-mousedown="onInputMouseDown_" on-paste="onInputPaste_">
   <ntp-realbox-icon id="icon" match="[[selectedMatch_]]"
diff --git a/chrome/browser/resources/new_tab_page/realbox.js b/chrome/browser/resources/new_tab_page/realbox.js
index 8c38c374..6df803b 100644
--- a/chrome/browser/resources/new_tab_page/realbox.js
+++ b/chrome/browser/resources/new_tab_page/realbox.js
@@ -351,10 +351,20 @@
   }
 
   /**
+   * @param {!FocusEvent} e
    * @private
    */
-  onInputFocus_() {
+  onInputFocus_(e) {
     this.lastInputFocusTime_ = window.performance.now();
+    e.target.placeholder = '';
+  }
+
+  /**
+   * @param {!FocusEvent} e
+   * @private
+   */
+  onInputBlur_(e) {
+    e.target.placeholder = loadTimeData.getString('realboxHint');
   }
 
   /**
@@ -529,7 +539,9 @@
 
     if (e.key === 'Enter') {
       if ([this.$.matches, this.$.input].includes(e.target)) {
-        if (this.lastQueriedInput_ === decodeString16(this.result_.input)) {
+        if (this.lastQueriedInput_ !== null &&
+            this.lastQueriedInput_.trimLeft() ===
+                decodeString16(this.result_.input)) {
           if (this.selectedMatch_) {
             this.navigateToMatch_(this.selectedMatchIndex_, e);
           }
@@ -559,7 +571,9 @@
       return;
     }
 
-    if (e.key === 'Escape' && this.selectedMatchIndex_ === 0) {
+    // Clear the input as well as the matches when 'Escape' is pressed if the
+    // the first match is selected or there are no selected matches.
+    if (e.key === 'Escape' && this.selectedMatchIndex_ <= 0) {
       this.updateInput_({text: '', inline: ''});
       this.clearAutocompleteMatches_();
       e.preventDefault();
diff --git a/chrome/browser/resources/print_preview/BUILD.gn b/chrome/browser/resources/print_preview/BUILD.gn
index f795e29..35b3585 100644
--- a/chrome/browser/resources/print_preview/BUILD.gn
+++ b/chrome/browser/resources/print_preview/BUILD.gn
@@ -6,7 +6,7 @@
 import("//chrome/common/features.gni")
 import("//third_party/closure_compiler/compile_js.gni")
 import("//tools/grit/grit_rule.gni")
-import("//tools/grit/preprocess_grit.gni")
+import("//tools/grit/preprocess_if_expr.gni")
 import("//ui/webui/resources/tools/generate_grd.gni")
 import("../optimize_webui.gni")
 
@@ -71,7 +71,7 @@
   out_grd = "$target_gen_dir/${grd_prefix}_resources.grd"
 }
 
-preprocess_grit("preprocess") {
+preprocess_if_expr("preprocess") {
   in_folder = "./"
   out_folder = "$target_gen_dir/$preprocess_folder"
   out_manifest = "$target_gen_dir/$preprocess_manifest"
@@ -117,7 +117,7 @@
   }
 }
 
-preprocess_grit("preprocess_generated") {
+preprocess_if_expr("preprocess_generated") {
   deps = [ "ui:web_components" ]
   in_folder = target_gen_dir
   out_folder = "$target_gen_dir/$preprocess_folder"
@@ -178,14 +178,14 @@
   }
 }
 
-preprocess_grit("preprocess_pdf") {
+preprocess_if_expr("preprocess_pdf") {
   in_folder = "../"
   out_folder = "$target_gen_dir/$preprocess_folder"
   out_manifest = "$target_gen_dir/$preprocess_pdf_manifest"
   in_files = [ "pdf/index_pp.html" ]
 }
 
-preprocess_grit("preprocess_pdf_generated") {
+preprocess_if_expr("preprocess_pdf_generated") {
   deps = [ "../pdf:web_components" ]
   in_folder = get_path_info("..", "gen_dir")
   out_folder = "$target_gen_dir/$preprocess_folder"
diff --git a/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_smartlock_subpage.js b/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_smartlock_subpage.js
index 82200e5c..f0345c7 100644
--- a/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_smartlock_subpage.js
+++ b/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_smartlock_subpage.js
@@ -2,8 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-// #import {OsSettingsRoutes} from './os_settings_routes.m.js'
-
 Polymer({
   is: 'settings-multidevice-smartlock-subpage',
 
diff --git a/chrome/browser/resources/settings/chromeos/os_languages_page/os_edit_dictionary_page.js b/chrome/browser/resources/settings/chromeos/os_languages_page/os_edit_dictionary_page.js
index 14f7565..36043a659 100644
--- a/chrome/browser/resources/settings/chromeos/os_languages_page/os_edit_dictionary_page.js
+++ b/chrome/browser/resources/settings/chromeos/os_languages_page/os_edit_dictionary_page.js
@@ -7,13 +7,6 @@
  * the "dictionary" of custom words used for spell check.
  */
 
-// clang-format off
-// #import {GlobalScrollTargetBehavior} from '../../global_scroll_target_behavior.m.js';
-// #import {loadTimeData} from '../../i18n_setup.js';
-// #import {PrefsBehavior} from '../../prefs/prefs_behavior.m.js';
-// #import {LanguagesBrowserProxyImpl} from '../../languages_page/languages_browser_proxy.m.js';
-// clang-format on
-
 // Max valid word size, keep in sync with kMaxCustomDictionaryWordBytes in
 // //components/spellcheck/common/spellcheck_common.h
 const MAX_CUSTOM_DICTIONARY_WORD_BYTES = 99;
diff --git a/chrome/browser/safety_check/android/BUILD.gn b/chrome/browser/safety_check/android/BUILD.gn
index 2bf8803..6ca54da4 100644
--- a/chrome/browser/safety_check/android/BUILD.gn
+++ b/chrome/browser/safety_check/android/BUILD.gn
@@ -44,7 +44,7 @@
     "//chrome/browser/preferences:java",
     "//chrome/browser/safe_browsing/android:java",
     "//chrome/browser/settings:java",
-    "//chrome/browser/signin/android:java",
+    "//chrome/browser/signin/ui/android:java",
     "//components/browser_ui/settings/android:java",
     "//components/password_manager/core/browser:password_manager_java_enums",
     "//components/signin/public/android:java",
@@ -111,7 +111,7 @@
     "//chrome/browser/password_check/android/internal:internal_factory_java",
     "//chrome/browser/preferences:java",
     "//chrome/browser/settings:java",
-    "//chrome/browser/signin/android:java",
+    "//chrome/browser/signin/ui/android:java",
     "//chrome/test/android:chrome_java_test_support",
     "//third_party/android_deps:robolectric_all_java",
     "//third_party/junit:junit",
diff --git a/chrome/browser/safety_check/android/java/src/org/chromium/chrome/browser/safety_check/SafetyCheckCoordinator.java b/chrome/browser/safety_check/android/java/src/org/chromium/chrome/browser/safety_check/SafetyCheckCoordinator.java
index 1c53108..6ed4fb9 100644
--- a/chrome/browser/safety_check/android/java/src/org/chromium/chrome/browser/safety_check/SafetyCheckCoordinator.java
+++ b/chrome/browser/safety_check/android/java/src/org/chromium/chrome/browser/safety_check/SafetyCheckCoordinator.java
@@ -12,7 +12,7 @@
 import org.chromium.chrome.browser.flags.ChromeFeatureList;
 import org.chromium.chrome.browser.password_manager.PasswordScriptsFetcherBridge;
 import org.chromium.chrome.browser.settings.SettingsLauncher;
-import org.chromium.chrome.browser.signin.SigninActivityLauncher;
+import org.chromium.chrome.browser.signin.ui.SigninActivityLauncher;
 import org.chromium.ui.modelutil.PropertyModel;
 import org.chromium.ui.modelutil.PropertyModelChangeProcessor;
 
diff --git a/chrome/browser/safety_check/android/java/src/org/chromium/chrome/browser/safety_check/SafetyCheckMediator.java b/chrome/browser/safety_check/android/java/src/org/chromium/chrome/browser/safety_check/SafetyCheckMediator.java
index 626c512..0d28c58a 100644
--- a/chrome/browser/safety_check/android/java/src/org/chromium/chrome/browser/safety_check/SafetyCheckMediator.java
+++ b/chrome/browser/safety_check/android/java/src/org/chromium/chrome/browser/safety_check/SafetyCheckMediator.java
@@ -37,7 +37,7 @@
 import org.chromium.chrome.browser.safety_check.SafetyCheckProperties.SafeBrowsingState;
 import org.chromium.chrome.browser.safety_check.SafetyCheckProperties.UpdatesState;
 import org.chromium.chrome.browser.settings.SettingsLauncher;
-import org.chromium.chrome.browser.signin.SigninActivityLauncher;
+import org.chromium.chrome.browser.signin.ui.SigninActivityLauncher;
 import org.chromium.components.signin.metrics.SigninAccessPoint;
 import org.chromium.content_public.common.ContentUrlConstants;
 import org.chromium.ui.modelutil.PropertyModel;
diff --git a/chrome/browser/safety_check/android/javatests/src/org/chromium/chrome/browser/safety_check/SafetyCheckMediatorTest.java b/chrome/browser/safety_check/android/javatests/src/org/chromium/chrome/browser/safety_check/SafetyCheckMediatorTest.java
index 6a6db2c..3192f285 100644
--- a/chrome/browser/safety_check/android/javatests/src/org/chromium/chrome/browser/safety_check/SafetyCheckMediatorTest.java
+++ b/chrome/browser/safety_check/android/javatests/src/org/chromium/chrome/browser/safety_check/SafetyCheckMediatorTest.java
@@ -41,7 +41,7 @@
 import org.chromium.chrome.browser.safety_check.SafetyCheckProperties.SafeBrowsingState;
 import org.chromium.chrome.browser.safety_check.SafetyCheckProperties.UpdatesState;
 import org.chromium.chrome.browser.settings.SettingsLauncher;
-import org.chromium.chrome.browser.signin.SigninActivityLauncher;
+import org.chromium.chrome.browser.signin.ui.SigninActivityLauncher;
 import org.chromium.chrome.test.util.browser.Features;
 import org.chromium.ui.modelutil.PropertyModel;
 
diff --git a/chrome/browser/signin/services/android/BUILD.gn b/chrome/browser/signin/services/android/BUILD.gn
index 03f5c9d..ec4465bc 100644
--- a/chrome/browser/signin/services/android/BUILD.gn
+++ b/chrome/browser/signin/services/android/BUILD.gn
@@ -12,6 +12,7 @@
 
 android_library("java") {
   sources = [
+    "java/src/org/chromium/chrome/browser/signin/services/SigninManager.java",
     "java/src/org/chromium/chrome/browser/signin/services/SigninPreferencesManager.java",
     "java/src/org/chromium/chrome/browser/signin/services/WebSigninBridge.java",
   ]
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninManager.java b/chrome/browser/signin/services/android/java/src/org/chromium/chrome/browser/signin/services/SigninManager.java
similarity index 98%
rename from chrome/android/java/src/org/chromium/chrome/browser/signin/SigninManager.java
rename to chrome/browser/signin/services/android/java/src/org/chromium/chrome/browser/signin/services/SigninManager.java
index f3a56ae..fc962d5b 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninManager.java
+++ b/chrome/browser/signin/services/android/java/src/org/chromium/chrome/browser/signin/services/SigninManager.java
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-package org.chromium.chrome.browser.signin;
+package org.chromium.chrome.browser.signin.services;
 
 import android.accounts.Account;
 
diff --git a/chrome/browser/signin/ui/DIR_METADATA b/chrome/browser/signin/ui/DIR_METADATA
new file mode 100644
index 0000000..c22824a1
--- /dev/null
+++ b/chrome/browser/signin/ui/DIR_METADATA
@@ -0,0 +1,5 @@
+monorail {
+  component: "Services>SignIn"
+}
+team_email: "chrome-signin@chromium.org"
+os: ANDROID
diff --git a/chrome/browser/signin/ui/OWNERS b/chrome/browser/signin/ui/OWNERS
new file mode 100644
index 0000000..1c49383
--- /dev/null
+++ b/chrome/browser/signin/ui/OWNERS
@@ -0,0 +1,2 @@
+bsazonov@chromium.org
+aliceywang@chromium.org
diff --git a/chrome/browser/signin/android/BUILD.gn b/chrome/browser/signin/ui/android/BUILD.gn
similarity index 80%
rename from chrome/browser/signin/android/BUILD.gn
rename to chrome/browser/signin/ui/android/BUILD.gn
index 6b26914..728de789 100644
--- a/chrome/browser/signin/android/BUILD.gn
+++ b/chrome/browser/signin/ui/android/BUILD.gn
@@ -10,7 +10,5 @@
     "//components/signin/public/android:java",
     "//third_party/android_deps:androidx_annotation_annotation_java",
   ]
-  sources = [
-    "java/src/org/chromium/chrome/browser/signin/SigninActivityLauncher.java",
-  ]
+  sources = [ "java/src/org/chromium/chrome/browser/signin/ui/SigninActivityLauncher.java" ]
 }
diff --git a/chrome/browser/signin/android/java/src/org/chromium/chrome/browser/signin/SigninActivityLauncher.java b/chrome/browser/signin/ui/android/java/src/org/chromium/chrome/browser/signin/ui/SigninActivityLauncher.java
similarity index 97%
rename from chrome/browser/signin/android/java/src/org/chromium/chrome/browser/signin/SigninActivityLauncher.java
rename to chrome/browser/signin/ui/android/java/src/org/chromium/chrome/browser/signin/ui/SigninActivityLauncher.java
index d2863606..12db106 100644
--- a/chrome/browser/signin/android/java/src/org/chromium/chrome/browser/signin/SigninActivityLauncher.java
+++ b/chrome/browser/signin/ui/android/java/src/org/chromium/chrome/browser/signin/ui/SigninActivityLauncher.java
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-package org.chromium.chrome.browser.signin;
+package org.chromium.chrome.browser.signin.ui;
 
 import android.content.Context;
 
diff --git a/chrome/browser/sync/test/integration/await_match_status_change_checker.cc b/chrome/browser/sync/test/integration/await_match_status_change_checker.cc
index db5c2622..4dae24c 100644
--- a/chrome/browser/sync/test/integration/await_match_status_change_checker.cc
+++ b/chrome/browser/sync/test/integration/await_match_status_change_checker.cc
@@ -8,18 +8,14 @@
 #include "chrome/browser/sync/test/integration/sync_test.h"
 
 AwaitMatchStatusChangeChecker::AwaitMatchStatusChangeChecker(
-    const ExitConditionCallback& condition,
-    const std::string& debug_message)
+    const ExitConditionCallback& condition)
     : MultiClientStatusChangeChecker(
           sync_datatype_helper::test()->GetSyncServices()),
-      condition_(condition),
-      debug_message_(debug_message) {
-}
+      condition_(condition) {}
 
 AwaitMatchStatusChangeChecker::~AwaitMatchStatusChangeChecker() {
 }
 
 bool AwaitMatchStatusChangeChecker::IsExitConditionSatisfied(std::ostream* os) {
-  *os << "Waiting for: " + debug_message_;
-  return condition_.Run();
+  return condition_.Run(os);
 }
diff --git a/chrome/browser/sync/test/integration/await_match_status_change_checker.h b/chrome/browser/sync/test/integration/await_match_status_change_checker.h
index 2227da00..c46fcf4 100644
--- a/chrome/browser/sync/test/integration/await_match_status_change_checker.h
+++ b/chrome/browser/sync/test/integration/await_match_status_change_checker.h
@@ -5,7 +5,7 @@
 #ifndef CHROME_BROWSER_SYNC_TEST_INTEGRATION_AWAIT_MATCH_STATUS_CHANGE_CHECKER_H_
 #define CHROME_BROWSER_SYNC_TEST_INTEGRATION_AWAIT_MATCH_STATUS_CHANGE_CHECKER_H_
 
-#include <string>
+#include <iosfwd>
 
 #include "base/callback.h"
 #include "base/compiler_specific.h"
@@ -16,17 +16,17 @@
 // verifies the state of all the profiles involved in the test.
 class AwaitMatchStatusChangeChecker : public MultiClientStatusChangeChecker {
  public:
-  using ExitConditionCallback = base::RepeatingCallback<bool(void)>;
+  // The std::ostream allows the callback to output debug messages.
+  using ExitConditionCallback = base::RepeatingCallback<bool(std::ostream*)>;
 
-  AwaitMatchStatusChangeChecker(const ExitConditionCallback& condition,
-                                const std::string& debug_message);
+  explicit AwaitMatchStatusChangeChecker(
+      const ExitConditionCallback& condition);
   ~AwaitMatchStatusChangeChecker() override;
 
   bool IsExitConditionSatisfied(std::ostream* os) override;
 
  private:
-  ExitConditionCallback condition_;
-  std::string debug_message_;
+  const ExitConditionCallback condition_;
 };
 
 #endif  // CHROME_BROWSER_SYNC_TEST_INTEGRATION_AWAIT_MATCH_STATUS_CHANGE_CHECKER_H_
diff --git a/chrome/browser/sync/test/integration/printers_helper.cc b/chrome/browser/sync/test/integration/printers_helper.cc
index e97c70e..57a3f54 100644
--- a/chrome/browser/sync/test/integration/printers_helper.cc
+++ b/chrome/browser/sync/test/integration/printers_helper.cc
@@ -5,6 +5,7 @@
 #include "chrome/browser/sync/test/integration/printers_helper.h"
 
 #include <algorithm>
+#include <ostream>
 #include <string>
 #include <unordered_map>
 #include <utility>
@@ -153,12 +154,14 @@
   return GetPrinterStore(index)->GetSavedPrinters().size();
 }
 
-bool AllProfilesContainSamePrinters() {
+bool AllProfilesContainSamePrinters(std::ostream* os) {
   auto reference_printers = GetPrinterStore(0)->GetSavedPrinters();
   for (int i = 1; i < test()->num_clients(); ++i) {
     auto printers = GetPrinterStore(i)->GetSavedPrinters();
     if (!ListsContainTheSamePrinters(reference_printers, printers)) {
-      VLOG(1) << "Printers in client [" << i << "] don't match client 0";
+      if (os) {
+        *os << "Printers in client [" << i << "] don't match client 0";
+      }
       return false;
     }
   }
@@ -173,9 +176,8 @@
 }
 
 PrintersMatchChecker::PrintersMatchChecker()
-    : AwaitMatchStatusChangeChecker(
-          base::BindRepeating(&printers_helper::AllProfilesContainSamePrinters),
-          "All printers match") {}
+    : AwaitMatchStatusChangeChecker(base::BindRepeating(
+          &printers_helper::AllProfilesContainSamePrinters)) {}
 
 PrintersMatchChecker::~PrintersMatchChecker() {}
 
diff --git a/chrome/browser/sync/test/integration/printers_helper.h b/chrome/browser/sync/test/integration/printers_helper.h
index 463eebf..a3150c84 100644
--- a/chrome/browser/sync/test/integration/printers_helper.h
+++ b/chrome/browser/sync/test/integration/printers_helper.h
@@ -5,6 +5,7 @@
 #ifndef CHROME_BROWSER_SYNC_TEST_INTEGRATION_PRINTERS_HELPER_H_
 #define CHROME_BROWSER_SYNC_TEST_INTEGRATION_PRINTERS_HELPER_H_
 
+#include <iosfwd>
 #include <memory>
 #include <string>
 
@@ -58,7 +59,7 @@
 int GetPrinterCount(int index);
 
 // Returns true if all profiles contain the same printers as profile 0.
-bool AllProfilesContainSamePrinters();
+bool AllProfilesContainSamePrinters(std::ostream* os = nullptr);
 
 // Returns true if the verifier store and printer store |index| contain the same
 // data.
diff --git a/chrome/browser/sync/test/integration/retry_verifier.cc b/chrome/browser/sync/test/integration/retry_verifier.cc
index 72b3d98..4f0f93c 100644
--- a/chrome/browser/sync/test/integration/retry_verifier.cc
+++ b/chrome/browser/sync/test/integration/retry_verifier.cc
@@ -25,13 +25,13 @@
                              syncer::kBackoffRandomizationFactor);
   delay_info.max_delay = backoff_s + current_delay/2;
 
-  delay_info.min_delay =
-      std::max(static_cast<int64_t>(1),
-               std::min(delay_info.min_delay, syncer::kMaxBackoffSeconds));
+  delay_info.min_delay = std::max(
+      static_cast<int64_t>(1),
+      std::min(delay_info.min_delay, syncer::kMaxBackoffTime.InSeconds()));
 
-  delay_info.max_delay =
-      std::max(static_cast<int64_t>(1),
-               std::min(delay_info.max_delay, syncer::kMaxBackoffSeconds));
+  delay_info.max_delay = std::max(
+      static_cast<int64_t>(1),
+      std::min(delay_info.max_delay, syncer::kMaxBackoffTime.InSeconds()));
 
   return delay_info;
 }
@@ -111,4 +111,3 @@
     return;
   }
 }
-
diff --git a/chrome/browser/sync/test/integration/retry_verifier.h b/chrome/browser/sync/test/integration/retry_verifier.h
index ec75e991..fc1797e 100644
--- a/chrome/browser/sync/test/integration/retry_verifier.h
+++ b/chrome/browser/sync/test/integration/retry_verifier.h
@@ -18,6 +18,7 @@
 // place somewhere in this range. The algorithm that calculates the retry wait
 // time uses rand functions.
 struct DelayInfo {
+  // TODO(crbug.com/1152797): Adopt base::TimeDelta in this file.
   int64_t min_delay;
   int64_t max_delay;
 };
diff --git a/chrome/browser/sync/test/integration/single_client_extensions_sync_test.cc b/chrome/browser/sync/test/integration/single_client_extensions_sync_test.cc
index f2c7892..ff0a0265 100644
--- a/chrome/browser/sync/test/integration/single_client_extensions_sync_test.cc
+++ b/chrome/browser/sync/test/integration/single_client_extensions_sync_test.cc
@@ -65,8 +65,13 @@
 
 // Helper function for waiting to see the extension count in a profile
 // become a specific number.
-static bool ExtensionCountCheck(Profile* profile, size_t expected_count) {
-  return GetInstalledExtensions(profile).size() == expected_count;
+static bool ExtensionCountCheck(Profile* profile,
+                                size_t expected_count,
+                                std::ostream* os) {
+  const size_t actual_count = GetInstalledExtensions(profile).size();
+  *os << "Waiting for profile to have " << expected_count
+      << " extensions; actual count " << actual_count;
+  return actual_count == expected_count;
 }
 
 // Tests the case of an uninstall from the server conflicting with a local
@@ -94,9 +99,8 @@
   ASSERT_EQ(1u, GetInstalledExtensions(GetProfile(0)).size());
 
   // Expect the extension to get uninstalled locally.
-  AwaitMatchStatusChangeChecker checker(
-      base::BindRepeating(&ExtensionCountCheck, GetProfile(0), 0u),
-      "Waiting for profile to have no extensions");
+  AwaitMatchStatusChangeChecker checker(base::BindRepeating(
+      &ExtensionCountCheck, GetProfile(0), /*expected_count=*/0u));
   EXPECT_TRUE(checker.Wait());
   EXPECT_TRUE(GetInstalledExtensions(GetProfile(0)).empty());
 
diff --git a/chrome/browser/sync/test/integration/single_client_polling_sync_test.cc b/chrome/browser/sync/test/integration/single_client_polling_sync_test.cc
index 2ab3ac5..e82967d 100644
--- a/chrome/browser/sync/test/integration/single_client_polling_sync_test.cc
+++ b/chrome/browser/sync/test/integration/single_client_polling_sync_test.cc
@@ -49,8 +49,7 @@
   // Execute a sync cycle and verify the client set up (and persisted) the
   // default value.
   ASSERT_TRUE(SetupSync()) << "SetupSync() failed.";
-  EXPECT_THAT(sync_prefs.GetPollInterval().InSeconds(),
-              Eq(syncer::kDefaultPollIntervalSeconds));
+  EXPECT_THAT(sync_prefs.GetPollInterval(), Eq(syncer::kDefaultPollInterval));
 }
 
 // This test verifies that updates of the poll interval get persisted
diff --git a/chrome/browser/tab/BUILD.gn b/chrome/browser/tab/BUILD.gn
index c5bc345b7..887da91 100644
--- a/chrome/browser/tab/BUILD.gn
+++ b/chrome/browser/tab/BUILD.gn
@@ -60,6 +60,7 @@
     "//components/external_intents/android:java",
     "//components/find_in_page/android:java",
     "//components/navigation_interception/android:navigation_interception_java",
+    "//components/payments/content/android:java",
     "//content/public/android:content_java",
     "//net/android:net_java",
     "//third_party/android_deps:androidx_annotation_annotation_java",
diff --git a/chrome/browser/tab/java/src/org/chromium/chrome/browser/tab/Tab.java b/chrome/browser/tab/java/src/org/chromium/chrome/browser/tab/Tab.java
index 9c6504e..3a9f962 100644
--- a/chrome/browser/tab/java/src/org/chromium/chrome/browser/tab/Tab.java
+++ b/chrome/browser/tab/java/src/org/chromium/chrome/browser/tab/Tab.java
@@ -285,4 +285,11 @@
      */
     public void setShouldBlockNewNotificationRequests(boolean value);
     public boolean getShouldBlockNewNotificationRequests();
+
+    /**
+     * Set whether {@link Tab} metadata (specifically all {@link PersistedTabData})
+     * will be saved. Not all Tabs need to be persisted across restarts.
+     * The default value when a Tab is initialized is false.
+     */
+    void setIsTabSaveEnabled(boolean isSaveEnabled);
 }
diff --git a/chrome/browser/tab/java/src/org/chromium/chrome/browser/tab/state/DEPS b/chrome/browser/tab/java/src/org/chromium/chrome/browser/tab/state/DEPS
index 9b4ba919..1022d3cd 100644
--- a/chrome/browser/tab/java/src/org/chromium/chrome/browser/tab/state/DEPS
+++ b/chrome/browser/tab/java/src/org/chromium/chrome/browser/tab/state/DEPS
@@ -1,4 +1,5 @@
 include_rules = [
   "+chrome/browser/tabpersistence",
+  "+components/payments/content/android",
 ]
 
diff --git a/chrome/browser/tab/java/src/org/chromium/chrome/browser/tab/state/MockPersistedTabData.java b/chrome/browser/tab/java/src/org/chromium/chrome/browser/tab/state/MockPersistedTabData.java
index 59b18c9..ff568b2c 100644
--- a/chrome/browser/tab/java/src/org/chromium/chrome/browser/tab/state/MockPersistedTabData.java
+++ b/chrome/browser/tab/java/src/org/chromium/chrome/browser/tab/state/MockPersistedTabData.java
@@ -72,9 +72,6 @@
     }
 
     @Override
-    public void destroy() {}
-
-    @Override
     public String getUmaTag() {
         return "MockCritical";
     }
diff --git a/chrome/browser/tab/java/src/org/chromium/chrome/browser/tab/state/PersistedTabData.java b/chrome/browser/tab/java/src/org/chromium/chrome/browser/tab/state/PersistedTabData.java
index 9bae896..9157073 100644
--- a/chrome/browser/tab/java/src/org/chromium/chrome/browser/tab/state/PersistedTabData.java
+++ b/chrome/browser/tab/java/src/org/chromium/chrome/browser/tab/state/PersistedTabData.java
@@ -15,6 +15,7 @@
 import org.chromium.base.UserData;
 import org.chromium.base.UserDataHost;
 import org.chromium.base.metrics.RecordHistogram;
+import org.chromium.base.supplier.ObservableSupplierImpl;
 import org.chromium.base.supplier.Supplier;
 import org.chromium.base.task.PostTask;
 import org.chromium.chrome.browser.tab.Tab;
@@ -42,6 +43,9 @@
     private final PersistedTabDataStorage mPersistedTabDataStorage;
     private final String mPersistedTabDataId;
     private long mLastUpdatedMs;
+    @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
+    public ObservableSupplierImpl<Boolean> mIsTabSaveEnabledSupplier;
+    private Callback<Boolean> mTabSaveEnabledToggleCallback;
 
     /**
      * @param tab {@link Tab} {@link PersistedTabData} is being stored for
@@ -236,7 +240,9 @@
      */
     @VisibleForTesting(otherwise = VisibleForTesting.PROTECTED)
     protected void save() {
-        mPersistedTabDataStorage.save(mTab.getId(), mPersistedTabDataId, serializeAndLog());
+        if (mIsTabSaveEnabledSupplier != null && mIsTabSaveEnabledSupplier.get()) {
+            mPersistedTabDataStorage.save(mTab.getId(), mPersistedTabDataId, serializeAndLog());
+        }
     }
 
     /**
@@ -284,7 +290,12 @@
      * in memory. It will not delete the stored data on a file or database.
      */
     @Override
-    public abstract void destroy();
+    public void destroy() {
+        if (mIsTabSaveEnabledSupplier != null) {
+            mIsTabSaveEnabledSupplier.removeObserver(mTabSaveEnabledToggleCallback);
+            mTabSaveEnabledToggleCallback = null;
+        }
+    }
 
     /**
      * @return unique tag for logging in Uma
@@ -315,4 +326,22 @@
     protected long getLastUpdatedMs() {
         return mLastUpdatedMs;
     }
+
+    /**
+     * @param isTabSaveEnabledSupplier {@link ObservableSupplierImpl} which provides
+     * access to the flag indicating if the {@link Tab} metadata will be saved and
+     * forward changes to the flag's value.
+     */
+    public void registerIsTabSaveEnabledSupplier(
+            ObservableSupplierImpl<Boolean> isTabSaveEnabledSupplier) {
+        mIsTabSaveEnabledSupplier = isTabSaveEnabledSupplier;
+        mTabSaveEnabledToggleCallback = (isTabSaveEnabled) -> {
+            if (isTabSaveEnabled) {
+                save();
+            } else {
+                delete();
+            }
+        };
+        mIsTabSaveEnabledSupplier.addObserver(mTabSaveEnabledToggleCallback);
+    }
 }
diff --git a/chrome/browser/tab/java/src/org/chromium/chrome/browser/tab/state/ShoppingPersistedTabData.java b/chrome/browser/tab/java/src/org/chromium/chrome/browser/tab/state/ShoppingPersistedTabData.java
index 22ff738..76244dc 100644
--- a/chrome/browser/tab/java/src/org/chromium/chrome/browser/tab/state/ShoppingPersistedTabData.java
+++ b/chrome/browser/tab/java/src/org/chromium/chrome/browser/tab/state/ShoppingPersistedTabData.java
@@ -4,7 +4,6 @@
 
 package org.chromium.chrome.browser.tab.state;
 
-
 import androidx.annotation.Nullable;
 import androidx.annotation.VisibleForTesting;
 
@@ -15,11 +14,13 @@
 import org.json.JSONObject;
 
 import org.chromium.base.Callback;
+import org.chromium.base.LocaleUtils;
 import org.chromium.base.Log;
 import org.chromium.chrome.browser.endpoint_fetcher.EndpointFetcher;
 import org.chromium.chrome.browser.profiles.Profile;
 import org.chromium.chrome.browser.tab.Tab;
 import org.chromium.chrome.browser.tab.proto.ShoppingPersistedTabData.ShoppingPersistedTabDataProto;
+import org.chromium.components.payments.CurrencyFormatter;
 
 import java.util.Locale;
 import java.util.concurrent.TimeUnit;
@@ -42,10 +43,12 @@
     private static final String BUYABLE_PRODUCT_ANNOTATION_KEY = "BUYABLE_PRODUCT";
     private static final String BUYABLE_PRODUCT_KEY = "buyableProduct";
     private static final String CURRENT_PRICE_KEY = "currentPrice";
+    private static final String CURRENCY_CODE_KEY = "currencyCode";
     private static final String AMOUNT_MICROS_KEY = "amountMicros";
     private static final String ACCEPT_LANGUAGE_KEY = "Accept-Language";
-    // TODO(crbug.com/1130068) support all locales
-    private static final String ACCEPT_LANGUAGE_VALUE = "en-US";
+
+    private static final int FRACTIONAL_DIGITS_LESS_THAN_TEN_UNITS = 2;
+    private static final int FRACTIONAL_DIGITS_GREATER_THAN_TEN_UNITS = 0;
 
     private static final Class<ShoppingPersistedTabData> USER_DATA_KEY =
             ShoppingPersistedTabData.class;
@@ -69,6 +72,8 @@
     private long mPriceMicros = NO_PRICE_KNOWN;
     private long mPreviousPriceMicros = NO_PRICE_KNOWN;
 
+    private String mCurrencyCode;
+
     /**
      * A price drop for the offer {@link ShoppingPersistedTabData}
      * refers to
@@ -124,7 +129,8 @@
                             Profile.getLastUsedRegularProfile(),
                             String.format(ENDPOINT, tab.getUrlString()), HTTPS_METHOD, CONTENT_TYPE,
                             EMPTY_POST_DATA, TIMEOUT_MS,
-                            new String[] {ACCEPT_LANGUAGE_KEY, ACCEPT_LANGUAGE_VALUE});
+                            new String[] {
+                                    ACCEPT_LANGUAGE_KEY, LocaleUtils.getDefaultLocaleListString()});
                 },
                 ShoppingPersistedTabData.class, callback);
     }
@@ -142,6 +148,7 @@
                     JSONObject priceMetadata = metadata.getJSONObject(CURRENT_PRICE_KEY);
                     res.setPriceMicros(Long.parseLong(priceMetadata.getString(AMOUNT_MICROS_KEY)),
                             previousShoppingPersistedTabData);
+                    res.setCurrencyCode(priceMetadata.getString(CURRENCY_CODE_KEY));
                     break;
                 }
             }
@@ -178,6 +185,15 @@
         save();
     }
 
+    protected void setCurrencyCode(String currencyCode) {
+        mCurrencyCode = currencyCode;
+    }
+
+    @VisibleForTesting
+    protected String getCurrencyCode() {
+        return mCurrencyCode;
+    }
+
     @VisibleForTesting
     protected void setPreviousPriceMicros(long previousPriceMicros) {
         mPreviousPriceMicros = previousPriceMicros;
@@ -249,12 +265,21 @@
     }
 
     // TODO(crbug.com/1130068) support all currencies
-    private static String formatPrice(long priceMicros) {
+    private String formatPrice(long priceMicros) {
+        CurrencyFormatter currencyFormatter =
+                new CurrencyFormatter(mCurrencyCode, Locale.getDefault());
+        String formattedPrice;
         if (priceMicros < TEN_UNITS) {
-            return String.format(Locale.US, "$%.2f", (100 * priceMicros / MICROS_TO_UNITS) / 100.0);
+            currencyFormatter.setMaximumFractionalDigits(FRACTIONAL_DIGITS_LESS_THAN_TEN_UNITS);
+            formattedPrice = String.format(
+                    Locale.getDefault(), "%.2f", (100 * priceMicros / MICROS_TO_UNITS) / 100.0);
+        } else {
+            currencyFormatter.setMaximumFractionalDigits(FRACTIONAL_DIGITS_GREATER_THAN_TEN_UNITS);
+            formattedPrice = String.format(Locale.getDefault(), "%d",
+                    (long) Math.floor(
+                            (double) (priceMicros + MICROS_TO_UNITS / 2) / MICROS_TO_UNITS));
         }
-        return String.format(Locale.US, "$%d",
-                (int) Math.floor((double) (priceMicros + MICROS_TO_UNITS / 2) / MICROS_TO_UNITS));
+        return currencyFormatter.format(formattedPrice);
     }
 
     @Override
@@ -290,9 +315,6 @@
     }
 
     @Override
-    public void destroy() {}
-
-    @Override
     public String getUmaTag() {
         return "SPTD";
     }
diff --git a/chrome/browser/ui/startup/startup_browser_creator.h b/chrome/browser/ui/startup/startup_browser_creator.h
index b0d7614..36747ee 100644
--- a/chrome/browser/ui/startup/startup_browser_creator.h
+++ b/chrome/browser/ui/startup/startup_browser_creator.h
@@ -133,6 +133,8 @@
                            CommandLineTab);
   FRIEND_TEST_ALL_PREFIXES(web_app::WebAppEngagementBrowserTest,
                            CommandLineWindow);
+  FRIEND_TEST_ALL_PREFIXES(StartupBrowserCreatorTest,
+                           LastUsedProfilesWithWebApp);
 
   bool ProcessCmdLineImpl(const base::CommandLine& command_line,
                           const base::FilePath& cur_dir,
diff --git a/chrome/browser/ui/startup/startup_browser_creator_browsertest.cc b/chrome/browser/ui/startup/startup_browser_creator_browsertest.cc
index 6e3be8c..7c6c1b2 100644
--- a/chrome/browser/ui/startup/startup_browser_creator_browsertest.cc
+++ b/chrome/browser/ui/startup/startup_browser_creator_browsertest.cc
@@ -8,6 +8,7 @@
 #include <memory>
 #include <string>
 
+#include "base/base_switches.h"
 #include "base/command_line.h"
 #include "base/files/file_path.h"
 #include "base/files/file_util.h"
@@ -15,6 +16,7 @@
 #include "base/memory/ptr_util.h"
 #include "base/path_service.h"
 #include "base/strings/utf_string_conversions.h"
+#include "base/test/bind.h"
 #include "base/test/metrics/histogram_tester.h"
 #include "base/threading/thread_restrictions.h"
 #include "build/branding_buildflags.h"
@@ -27,7 +29,9 @@
 #include "chrome/browser/extensions/launch_util.h"
 #include "chrome/browser/first_run/first_run.h"
 #include "chrome/browser/infobars/infobar_service.h"
+#include "chrome/browser/installable/installable_metrics.h"
 #include "chrome/browser/lifetime/application_lifetime.h"
+#include "chrome/browser/prefs/chrome_pref_service_factory.h"
 #include "chrome/browser/prefs/session_startup_pref.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/profiles/profile_attributes_entry.h"
@@ -50,8 +54,13 @@
 #include "chrome/browser/ui/startup/startup_tab_provider.h"
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
 #include "chrome/browser/ui/ui_features.h"
+#include "chrome/browser/web_applications/components/install_finalizer.h"
+#include "chrome/browser/web_applications/components/install_manager.h"
+#include "chrome/browser/web_applications/components/web_application_info.h"
+#include "chrome/browser/web_applications/web_app_provider.h"
 #include "chrome/common/buildflags.h"
 #include "chrome/common/chrome_constants.h"
+#include "chrome/common/chrome_paths.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/common/extensions/extension_constants.h"
 #include "chrome/common/pref_names.h"
@@ -71,6 +80,7 @@
 #include "content/public/browser/web_contents.h"
 #include "content/public/common/content_switches.h"
 #include "content/public/test/browser_test.h"
+#include "content/public/test/test_launcher.h"
 #include "content/public/test/test_navigation_observer.h"
 #include "content/public/test/test_utils.h"
 #include "extensions/browser/extension_registry.h"
@@ -113,6 +123,11 @@
 namespace {
 
 #if !defined(OS_CHROMEOS)
+
+const char kAppId[] = "dofnemchnjfeendjmdhaldenaiabpiad";
+const char kAppName[] = "Test App";
+const char kStartUrl[] = "https://test.com";
+
 // Check that there are two browsers. Find the one that is not |browser|.
 Browser* FindOneOtherBrowser(Browser* browser) {
   // There should only be one other browser.
@@ -1174,6 +1189,184 @@
   ASSERT_EQ(1u, chrome::GetBrowserCount(profile2));
 }
 
+// An observer that returns back to test code after a new browser is added to
+// the BrowserList.
+class BrowserAddedObserver : public BrowserListObserver {
+ public:
+  BrowserAddedObserver() { BrowserList::AddObserver(this); }
+
+  ~BrowserAddedObserver() override { BrowserList::RemoveObserver(this); }
+
+  Browser* Wait() {
+    run_loop_.Run();
+    return browser_;
+  }
+
+ protected:
+  // BrowserListObserver:
+  void OnBrowserAdded(Browser* browser) override {
+    browser_ = browser;
+    run_loop_.Quit();
+  }
+
+ private:
+  Browser* browser_ = nullptr;
+  base::RunLoop run_loop_;
+};
+
+class StartupBrowserWithWebAppTest : public StartupBrowserCreatorTest {
+ protected:
+  StartupBrowserWithWebAppTest() = default;
+
+  void SetUpCommandLine(base::CommandLine* command_line) override {
+    StartupBrowserCreatorTest::SetUpCommandLine(command_line);
+    if (GetTestPreCount() == 1) {
+      // Load an app with launch.container = 'window'.
+      command_line->AppendSwitchASCII(switches::kAppId, kAppId);
+      command_line->AppendSwitchASCII(switches::kProfileDirectory, "Default");
+    }
+  }
+  web_app::WebAppProvider& provider() {
+    return *web_app::WebAppProvider::Get(profile());
+  }
+};
+
+IN_PROC_BROWSER_TEST_F(StartupBrowserWithWebAppTest,
+                       PRE_PRE_LastUsedProfilesWithWebApp) {
+  // Simulate a browser restart by creating the profiles in the PRE_PRE part.
+  ProfileManager* profile_manager = g_browser_process->profile_manager();
+
+  ASSERT_TRUE(embedded_test_server()->Start());
+
+  // Create two profiles.
+  base::FilePath dest_path = profile_manager->user_data_dir();
+
+  Profile* profile1 = nullptr;
+  Profile* profile2 = nullptr;
+  {
+    base::ScopedAllowBlockingForTesting allow_blocking;
+    profile1 = profile_manager->GetProfile(
+        dest_path.Append(FILE_PATH_LITERAL("New Profile 1")));
+    ASSERT_TRUE(profile1);
+
+    profile2 = profile_manager->GetProfile(
+        dest_path.Append(FILE_PATH_LITERAL("New Profile 2")));
+    ASSERT_TRUE(profile2);
+  }
+  DisableWelcomePages({profile1, profile2});
+
+  // Open some urls with the browsers, and close them.
+  Browser* browser1 = Browser::Create({Browser::TYPE_NORMAL, profile1, true});
+  chrome::NewTab(browser1);
+  ui_test_utils::NavigateToURL(browser1,
+                               embedded_test_server()->GetURL("/title1.html"));
+
+  Browser* browser2 = Browser::Create({Browser::TYPE_NORMAL, profile2, true});
+  chrome::NewTab(browser2);
+  ui_test_utils::NavigateToURL(browser2,
+                               embedded_test_server()->GetURL("/title2.html"));
+
+  // Set startup preferences for the 2 profiles to restore last session.
+  SessionStartupPref pref1(SessionStartupPref::LAST);
+  SessionStartupPref::SetStartupPref(profile1, pref1);
+  SessionStartupPref pref2(SessionStartupPref::LAST);
+  SessionStartupPref::SetStartupPref(profile2, pref2);
+
+  profile1->GetPrefs()->CommitPendingWrite();
+  profile2->GetPrefs()->CommitPendingWrite();
+
+  // Install a web app that we will launch from the command line in
+  // the PRE test.
+  web_app::WebAppProviderBase* const provider =
+      web_app::WebAppProviderBase::GetProviderBase(browser()->profile());
+  web_app::InstallFinalizer& web_app_finalizer = provider->install_finalizer();
+
+  web_app::InstallFinalizer::FinalizeOptions options;
+  options.install_source = WebappInstallSource::OMNIBOX_INSTALL_ICON;
+
+  // Install web app set to open as a tab.
+  {
+    web_app_finalizer.RemoveLegacyInstallFinalizerForTesting();
+
+    base::RunLoop run_loop;
+    WebApplicationInfo info;
+    info.start_url = GURL(kStartUrl);
+    info.title = base::UTF8ToUTF16(kAppName);
+    info.open_as_window = true;
+    web_app_finalizer.FinalizeInstall(
+        info, options,
+        base::BindLambdaForTesting(
+            [&](const web_app::AppId& app_id, web_app::InstallResultCode code) {
+              EXPECT_EQ(app_id, kAppId);
+              EXPECT_EQ(code, web_app::InstallResultCode::kSuccessNewInstall);
+              run_loop.Quit();
+            }));
+    run_loop.Run();
+
+    EXPECT_EQ(provider->registrar().GetAppUserDisplayMode(kAppId),
+              blink::mojom::DisplayMode::kStandalone);
+  }
+}
+
+IN_PROC_BROWSER_TEST_F(StartupBrowserWithWebAppTest,
+                       PRE_LastUsedProfilesWithWebApp) {
+  BrowserAddedObserver added_observer;
+  content::RunAllTasksUntilIdle();
+  // Launching with an app opens the app window via a task, so the test
+  // might start before SelectFirstBrowser is called.
+  if (!browser()) {
+    added_observer.Wait();
+    SelectFirstBrowser();
+  }
+  ASSERT_EQ(1u, chrome::GetBrowserCount(browser()->profile()));
+
+  // An app window should have been launched.
+  EXPECT_TRUE(browser()->is_type_app());
+  CloseBrowserAsynchronously(browser());
+}
+
+IN_PROC_BROWSER_TEST_F(StartupBrowserWithWebAppTest,
+                       LastUsedProfilesWithWebApp) {
+  ProfileManager* profile_manager = g_browser_process->profile_manager();
+
+  base::FilePath dest_path = profile_manager->user_data_dir();
+
+  Profile* profile1 = nullptr;
+  Profile* profile2 = nullptr;
+  {
+    base::ScopedAllowBlockingForTesting allow_blocking;
+    profile1 = profile_manager->GetProfile(
+        dest_path.Append(FILE_PATH_LITERAL("New Profile 1")));
+    ASSERT_TRUE(profile1);
+
+    profile2 = profile_manager->GetProfile(
+        dest_path.Append(FILE_PATH_LITERAL("New Profile 2")));
+    ASSERT_TRUE(profile2);
+  }
+
+  while (SessionRestore::IsRestoring(profile1) ||
+         SessionRestore::IsRestoring(profile2)) {
+    base::RunLoop().RunUntilIdle();
+  }
+
+  // The last open sessions should be restored.
+  EXPECT_TRUE(profile1->restored_last_session());
+  EXPECT_TRUE(profile2->restored_last_session());
+
+  Browser* new_browser = nullptr;
+  ASSERT_EQ(1u, chrome::GetBrowserCount(profile1));
+  new_browser = FindOneOtherBrowserForProfile(profile1, nullptr);
+  ASSERT_TRUE(new_browser);
+  TabStripModel* tab_strip = new_browser->tab_strip_model();
+  EXPECT_EQ("/title1.html", tab_strip->GetWebContentsAt(0)->GetURL().path());
+
+  ASSERT_EQ(1u, chrome::GetBrowserCount(profile2));
+  new_browser = FindOneOtherBrowserForProfile(profile2, nullptr);
+  ASSERT_TRUE(new_browser);
+  tab_strip = new_browser->tab_strip_model();
+  EXPECT_EQ("/title2.html", tab_strip->GetWebContentsAt(0)->GetURL().path());
+}
+
 #endif  // !defined(OS_CHROMEOS)
 
 class StartupBrowserCreatorExtensionsCheckupExperimentTest
diff --git a/chrome/browser/ui/views/extensions/extension_install_dialog_view_supervised_browsertest.cc b/chrome/browser/ui/views/extensions/extension_install_dialog_view_supervised_browsertest.cc
index d778020..3f0fd2c 100644
--- a/chrome/browser/ui/views/extensions/extension_install_dialog_view_supervised_browsertest.cc
+++ b/chrome/browser/ui/views/extensions/extension_install_dialog_view_supervised_browsertest.cc
@@ -128,8 +128,9 @@
   ExtensionInstallPrompt install_prompt(profile(), nullptr);
   base::RunLoop run_loop;
   ExtensionInstallPromptTestHelper helper(run_loop.QuitClosure());
+  const extensions::Extension* const extension = prompt->extension();
   install_prompt.ShowDialog(
-      helper.GetCallback(), prompt->extension(), nullptr, std::move(prompt),
+      helper.GetCallback(), extension, nullptr, std::move(prompt),
       ExtensionInstallPrompt::GetDefaultShowDialogCallback());
   run_loop.Run();
   EXPECT_EQ(ExtensionInstallPrompt::Result::ACCEPTED, helper.result());
@@ -202,8 +203,9 @@
   ExtensionInstallPrompt install_prompt(profile(), nullptr);
   base::RunLoop run_loop;
   ExtensionInstallPromptTestHelper helper(run_loop.QuitClosure());
+  const extensions::Extension* const extension = prompt->extension();
   install_prompt.ShowDialog(
-      helper.GetCallback(), prompt->extension(), nullptr, std::move(prompt),
+      helper.GetCallback(), extension, nullptr, std::move(prompt),
       ExtensionInstallPrompt::GetDefaultShowDialogCallback());
   run_loop.Run();
   EXPECT_EQ(ExtensionInstallPrompt::Result::USER_CANCELED, helper.result());
diff --git a/chrome/browser/ui/views/location_bar/permission_chip.cc b/chrome/browser/ui/views/location_bar/permission_chip.cc
index 63e3e625d..8f8a061 100644
--- a/chrome/browser/ui/views/location_bar/permission_chip.cc
+++ b/chrome/browser/ui/views/location_bar/permission_chip.cc
@@ -136,8 +136,11 @@
   SetVisible(true);
   // TODO(olesiamarukhno): Add tests for animation logic.
   animation_->Reset();
-  if (!delegate_->WasCurrentRequestAlreadyDisplayed())
+  is_collapsed_ = true;
+  if (!delegate_->WasCurrentRequestAlreadyDisplayed()) {
     animation_->Show();
+    is_collapsed_ = false;
+  }
   requested_time_ = base::TimeTicks::Now();
   PreferredSizeChanged();
 }
@@ -188,13 +191,10 @@
   widget->RemoveObserver(this);
   prompt_bubble_ = nullptr;
   animation_->Hide();
+  is_collapsed_ = true;
 }
 
-bool PermissionChip::IsBubbleShowing() const {
-  return prompt_bubble_ != nullptr;
-}
-
-void PermissionChip::ChipButtonPressed() {
+void PermissionChip::OpenBubble() {
   // The prompt bubble is either not opened yet or already closed on
   // deactivation.
   DCHECK(!prompt_bubble_);
@@ -203,6 +203,14 @@
       browser_, delegate_, requested_time_, PermissionPromptStyle::kChip);
   prompt_bubble_->Show();
   prompt_bubble_->GetWidget()->AddObserver(this);
+}
+
+bool PermissionChip::IsBubbleShowing() const {
+  return prompt_bubble_ != nullptr;
+}
+
+void PermissionChip::ChipButtonPressed() {
+  OpenBubble();
   // Restart the timer after user clicks on the chip to open the bubble.
   StartCollapseTimer();
   if (!already_recorded_interaction_) {
@@ -217,6 +225,7 @@
     StartCollapseTimer();
   } else {
     animation_->Hide();
+    is_collapsed_ = true;
   }
 }
 
diff --git a/chrome/browser/ui/views/location_bar/permission_chip.h b/chrome/browser/ui/views/location_bar/permission_chip.h
index 36f3c8b..7c17243a 100644
--- a/chrome/browser/ui/views/location_bar/permission_chip.h
+++ b/chrome/browser/ui/views/location_bar/permission_chip.h
@@ -41,8 +41,10 @@
 
   void Show(permissions::PermissionPrompt::Delegate* delegate);
   void Hide();
+  void OpenBubble();
 
   views::Button* button() { return chip_button_; }
+  bool is_collapsed() { return is_collapsed_; }
 
   // views::AnimationDelegateViews:
   void AnimationEnded(const gfx::Animation* animation) override;
@@ -90,6 +92,10 @@
 
   // If uma metric was already recorded on the button click.
   bool already_recorded_interaction_ = false;
+
+  // If chip is collapsed. In the collapsed state, only an icon is visible,
+  // without text.
+  bool is_collapsed_ = false;
 };
 
 #endif  // CHROME_BROWSER_UI_VIEWS_LOCATION_BAR_PERMISSION_CHIP_H_
diff --git a/chrome/browser/ui/views/permission_bubble/permission_prompt_bubble_view.cc b/chrome/browser/ui/views/permission_bubble/permission_prompt_bubble_view.cc
index f5c288f..39cb0c2 100644
--- a/chrome/browser/ui/views/permission_bubble/permission_prompt_bubble_view.cc
+++ b/chrome/browser/ui/views/permission_bubble/permission_prompt_bubble_view.cc
@@ -96,16 +96,7 @@
   SetCancelCallback(base::BindOnce(&PermissionPromptBubbleView::DenyPermission,
                                    base::Unretained(this)));
 
-  // If bubble hanging off the padlock icon, with no chip showing, it shouldn't
-  // close on deactivate and it should stick until user makes a decision.
-  // Otherwise, the chip is indicating the pending permission request and so the
-  // bubble can be opened and closed repeatedly.
-  if (prompt_style == PermissionPromptStyle::kBubbleOnly) {
-    set_close_on_deactivate(false);
-    DialogDelegate::SetCloseCallback(
-        base::BindOnce(&PermissionPromptBubbleView::ClosingPermission,
-                       base::Unretained(this)));
-  }
+  SetPromptStyle(prompt_style);
 
   SetLayoutManager(std::make_unique<views::BoxLayout>(
       views::BoxLayout::Orientation::kVertical, gfx::Insets(),
@@ -217,6 +208,23 @@
   SetArrow(configuration.bubble_arrow);
 }
 
+void PermissionPromptBubbleView::SetPromptStyle(
+    PermissionPromptStyle prompt_style) {
+  // If bubble hanging off the padlock icon, with no chip showing, it shouldn't
+  // close on deactivate and it should stick until user makes a decision.
+  // Otherwise, the chip is indicating the pending permission request and so the
+  // bubble can be opened and closed repeatedly.
+  if (prompt_style == PermissionPromptStyle::kBubbleOnly) {
+    set_close_on_deactivate(false);
+    DialogDelegate::SetCloseCallback(
+        base::BindOnce(&PermissionPromptBubbleView::ClosingPermission,
+                       base::Unretained(this)));
+  } else {
+    set_close_on_deactivate(true);
+    DialogDelegate::SetCloseCallback(base::OnceClosure());
+  }
+}
+
 void PermissionPromptBubbleView::AddedToWidget() {
   if (name_or_origin_.is_origin) {
     // There is a risk of URL spoofing from origins that are too wide to fit in
diff --git a/chrome/browser/ui/views/permission_bubble/permission_prompt_bubble_view.h b/chrome/browser/ui/views/permission_bubble/permission_prompt_bubble_view.h
index 4a978328..bf0887f9 100644
--- a/chrome/browser/ui/views/permission_bubble/permission_prompt_bubble_view.h
+++ b/chrome/browser/ui/views/permission_bubble/permission_prompt_bubble_view.h
@@ -29,6 +29,8 @@
   // bubble_anchor_util::GetPageInfoAnchorConfiguration.
   void UpdateAnchorPosition();
 
+  void SetPromptStyle(PermissionPromptStyle prompt_style);
+
   // views::BubbleDialogDelegateView:
   void AddedToWidget() override;
   bool ShouldShowCloseButton() const override;
diff --git a/chrome/browser/ui/views/permission_bubble/permission_prompt_impl.cc b/chrome/browser/ui/views/permission_bubble/permission_prompt_impl.cc
index f513de7..2c81297 100644
--- a/chrome/browser/ui/views/permission_bubble/permission_prompt_impl.cc
+++ b/chrome/browser/ui/views/permission_bubble/permission_prompt_impl.cc
@@ -47,16 +47,8 @@
     content_settings::UpdateLocationBarUiForWebContents(web_contents_);
   } else {
     LocationBarView* lbv = GetLocationBarView();
-    std::vector<permissions::PermissionRequest*> requests =
-        delegate->Requests();
-    const bool should_use_chip_ui = std::all_of(
-        requests.begin(), requests.end(),
-        [](auto* request) { return request->GetChipText().has_value(); });
-    if (base::FeatureList::IsEnabled(permissions::features::kPermissionChip) &&
-        lbv && lbv->IsDrawn() && should_use_chip_ui) {
-      permission_chip_ = lbv->permission_chip();
-      permission_chip_->Show(delegate);
-      prompt_style_ = PermissionPromptStyle::kChip;
+    if (lbv && lbv->IsDrawn() && ShouldCurrentRequestUseChipUI()) {
+      ShowChipUI();
     } else {
       ShowBubble();
     }
@@ -70,25 +62,60 @@
 }
 
 PermissionPromptImpl::~PermissionPromptImpl() {
-  if (prompt_bubble_)
-    prompt_bubble_->GetWidget()->Close();
-
-  if (prompt_style_ == PermissionPromptStyle::kQuiet) {
-    // Hides the quiet prompt.
-    content_settings::UpdateLocationBarUiForWebContents(web_contents_);
+  switch (prompt_style_) {
+    case PermissionPromptStyle::kBubbleOnly:
+      DCHECK(!permission_chip_);
+      if (prompt_bubble_)
+        prompt_bubble_->GetWidget()->Close();
+      break;
+    case PermissionPromptStyle::kChip:
+      DCHECK(!prompt_bubble_);
+      DCHECK(permission_chip_);
+      permission_chip_->Hide();
+      permission_chip_ = nullptr;
+      break;
+    case PermissionPromptStyle::kQuiet:
+      DCHECK(!prompt_bubble_);
+      DCHECK(!permission_chip_);
+      content_settings::UpdateLocationBarUiForWebContents(web_contents_);
+      break;
   }
 
-  if (prompt_style_ == PermissionPromptStyle::kChip && permission_chip_) {
-    permission_chip_->Hide();
-  }
   CHECK(!IsInObserverList());
 }
 
 void PermissionPromptImpl::UpdateAnchorPosition() {
-  // TODO(olesiamarukhno): Figure out if we need to switch UI styles (chip to
-  // bubble and vice versa) here.
-  if (prompt_bubble_)
-    prompt_bubble_->UpdateAnchorPosition();
+  LocationBarView* lbv = GetLocationBarView();
+  const bool is_location_bar_drawn = lbv && lbv->IsDrawn();
+  switch (prompt_style_) {
+    case PermissionPromptStyle::kBubbleOnly:
+      DCHECK(prompt_bubble_);
+      DCHECK(!permission_chip_);
+      if (ShouldCurrentRequestUseChipUI() && is_location_bar_drawn) {
+        // Change prompt style to chip to avoid dismissing request while
+        // switching UI style.
+        prompt_bubble_->SetPromptStyle(PermissionPromptStyle::kChip);
+        prompt_bubble_->GetWidget()->Close();
+        ShowChipUI();
+        permission_chip_->OpenBubble();
+      } else {
+        prompt_bubble_->UpdateAnchorPosition();
+      }
+      break;
+    case PermissionPromptStyle::kChip:
+      DCHECK(!prompt_bubble_);
+      DCHECK(permission_chip_);
+      // If there is fresh pending request shown as chip UI and location bar
+      // isn't visible anymore, show bubble UI instead.
+      if (!permission_chip_->is_collapsed() && !is_location_bar_drawn) {
+        permission_chip_->Hide();
+        permission_chip_ = nullptr;
+        ShowBubble();
+      }
+      break;
+    case PermissionPromptStyle::kQuiet:
+      break;
+  }
 }
 
 LocationBarView* PermissionPromptImpl::GetLocationBarView() {
@@ -96,6 +123,15 @@
   return browser_view ? browser_view->GetLocationBarView() : nullptr;
 }
 
+void PermissionPromptImpl::ShowChipUI() {
+  LocationBarView* lbv = GetLocationBarView();
+  DCHECK(lbv);
+
+  permission_chip_ = lbv->permission_chip();
+  permission_chip_->Show(delegate_);
+  prompt_style_ = PermissionPromptStyle::kChip;
+}
+
 void PermissionPromptImpl::ShowBubble() {
   prompt_style_ = PermissionPromptStyle::kBubbleOnly;
   prompt_bubble_ = new PermissionPromptBubbleView(
@@ -104,6 +140,16 @@
   prompt_bubble_->GetWidget()->AddObserver(this);
 }
 
+bool PermissionPromptImpl::ShouldCurrentRequestUseChipUI() {
+  if (!base::FeatureList::IsEnabled(permissions::features::kPermissionChip))
+    return false;
+
+  std::vector<permissions::PermissionRequest*> requests = delegate_->Requests();
+  return std::all_of(requests.begin(), requests.end(), [](auto* request) {
+    return request->GetChipText().has_value();
+  });
+}
+
 permissions::PermissionPrompt::TabSwitchingBehavior
 PermissionPromptImpl::GetTabSwitchingBehavior() {
   return permissions::PermissionPrompt::TabSwitchingBehavior::
diff --git a/chrome/browser/ui/views/permission_bubble/permission_prompt_impl.h b/chrome/browser/ui/views/permission_bubble/permission_prompt_impl.h
index 5d4e0088..6de00af 100644
--- a/chrome/browser/ui/views/permission_bubble/permission_prompt_impl.h
+++ b/chrome/browser/ui/views/permission_bubble/permission_prompt_impl.h
@@ -50,6 +50,10 @@
 
   void ShowBubble();
 
+  void ShowChipUI();
+
+  bool ShouldCurrentRequestUseChipUI();
+
   // The popup bubble. Not owned by this class; it will delete itself when a
   // decision is made.
   PermissionPromptBubbleView* prompt_bubble_;
diff --git a/chrome/browser/ui/views/tabs/tab_drag_controller_interactive_uitest.cc b/chrome/browser/ui/views/tabs/tab_drag_controller_interactive_uitest.cc
index 61b1ec4..2a1a0cd 100644
--- a/chrome/browser/ui/views/tabs/tab_drag_controller_interactive_uitest.cc
+++ b/chrome/browser/ui/views/tabs/tab_drag_controller_interactive_uitest.cc
@@ -37,6 +37,7 @@
 #include "chrome/browser/ui/tabs/tab_group.h"
 #include "chrome/browser/ui/tabs/tab_group_model.h"
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
+#include "chrome/browser/ui/tabs/tab_style.h"
 #include "chrome/browser/ui/ui_features.h"
 #include "chrome/browser/ui/views/frame/browser_view.h"
 #include "chrome/browser/ui/views/frame/native_browser_frame_factory.h"
@@ -2447,6 +2448,48 @@
   EXPECT_EQ(browser2_groups[0], group);
 }
 
+class DetachToBrowserTabDragControllerTestWithScrollableTabStripEnabled
+    : public DetachToBrowserTabDragControllerTest {
+ public:
+  DetachToBrowserTabDragControllerTestWithScrollableTabStripEnabled() {
+    scoped_feature_list_.InitWithFeatures({features::kScrollableTabStrip}, {});
+  }
+
+ private:
+  base::test::ScopedFeatureList scoped_feature_list_;
+};
+
+#if defined(OS_LINUX)
+#define MAYBE_DraggingRightExpandsTabStripSize \
+  DISABLED_DraggingRightExpandsTabStripSize
+#else
+#define MAYBE_DraggingRightExpandsTabStripSize DraggingRightExpandsTabStripSize
+#endif
+// Creates a browser with two tabs and drags the rightmost tab. Given the
+// browser window is large enough, the tabstrip should expand to accommodate
+// this tab. Note: There must be at least two tabs because dragging a singular
+// tab will drag the window.
+// Disabled for Linux due to test dragging flakiness.
+IN_PROC_BROWSER_TEST_P(
+    DetachToBrowserTabDragControllerTestWithScrollableTabStripEnabled,
+    MAYBE_DraggingRightExpandsTabStripSize) {
+  TabStrip* tab_strip = GetTabStripForBrowser(browser());
+
+  AddTabsAndResetBrowser(browser(), 1);
+
+  browser()->window()->SetBounds(
+      gfx::Rect(0, 0, TabStyle::GetStandardWidth() * 4, 400));
+
+  const int tab_strip_width = tab_strip->width();
+  const gfx::Point tab_1_center =
+      GetCenterInScreenCoordinates(tab_strip->tab_at(1));
+  ASSERT_TRUE(PressInput(tab_1_center));
+  ASSERT_TRUE(DragInputTo(tab_1_center +
+                          gfx::Vector2d(TabStyle::GetStandardWidth(), 0)));
+  EXPECT_EQ(tab_strip_width + TabStyle::GetStandardWidth(), tab_strip->width());
+  ASSERT_TRUE(ReleaseInput());
+}
+
 namespace {
 
 // Invoked from the nested run loop.
@@ -4369,6 +4412,10 @@
     TabDragging,
     DetachToBrowserTabDragControllerTestWithTabGroupsCollapseEnabled,
     ::testing::Values("mouse", "touch"));
+INSTANTIATE_TEST_SUITE_P(
+    TabDragging,
+    DetachToBrowserTabDragControllerTestWithScrollableTabStripEnabled,
+    ::testing::Values("mouse", "touch"));
 INSTANTIATE_TEST_SUITE_P(TabDragging,
                          DetachToBrowserInSeparateDisplayTabDragControllerTest,
                          ::testing::Values("mouse"));
@@ -4394,4 +4441,8 @@
     TabDragging,
     DetachToBrowserTabDragControllerTestWithTabGroupsCollapseEnabled,
     ::testing::Values("mouse"));
+INSTANTIATE_TEST_SUITE_P(
+    TabDragging,
+    DetachToBrowserTabDragControllerTestWithScrollableTabStripEnabled,
+    ::testing::Values("mouse"));
 #endif
diff --git a/chrome/browser/ui/webui/new_tab_page/new_tab_page_ui.cc b/chrome/browser/ui/webui/new_tab_page/new_tab_page_ui.cc
index 5705086..8f98687c 100644
--- a/chrome/browser/ui/webui/new_tab_page/new_tab_page_ui.cc
+++ b/chrome/browser/ui/webui/new_tab_page/new_tab_page_ui.cc
@@ -86,6 +86,8 @@
       base::FeatureList::IsEnabled(ntp_features::kRealboxUseGoogleGIcon)
           ? omnibox::kGoogleGIconResourceName
           : omnibox::kSearchIconResourceName);
+  source->AddString("realboxHint", l10n_util::GetStringUTF8(
+                                       IDS_GOOGLE_SEARCH_BOX_EMPTY_HINT_MD));
 
   source->AddBoolean(
       "handleMostVisitedNavigationExplicitly",
diff --git a/chrome/browser/video_tutorials/internal/android/java/src/org/chromium/chrome/browser/video_tutorials/languages/LanguagePickerView.java b/chrome/browser/video_tutorials/internal/android/java/src/org/chromium/chrome/browser/video_tutorials/languages/LanguagePickerView.java
index 2151693..d2b2a8fe 100644
--- a/chrome/browser/video_tutorials/internal/android/java/src/org/chromium/chrome/browser/video_tutorials/languages/LanguagePickerView.java
+++ b/chrome/browser/video_tutorials/internal/android/java/src/org/chromium/chrome/browser/video_tutorials/languages/LanguagePickerView.java
@@ -41,7 +41,6 @@
         mPropertyModelChangeProcessor =
                 PropertyModelChangeProcessor.create(mModel, mView, LanguagePickerView::bind);
         RecyclerView recyclerView = mView.findViewById(R.id.recycler_view);
-        recyclerView.setHasFixedSize(true);
         LinearLayoutManager layoutManager =
                 new LinearLayoutManager(mView.getContext(), LinearLayoutManager.VERTICAL, false);
         recyclerView.setLayoutManager(layoutManager);
diff --git a/chrome/browser/web_applications/web_app_migration_user_display_mode_clean_up_browsertest.cc b/chrome/browser/web_applications/web_app_migration_user_display_mode_clean_up_browsertest.cc
index 7e4f86b..3a4bf26 100644
--- a/chrome/browser/web_applications/web_app_migration_user_display_mode_clean_up_browsertest.cc
+++ b/chrome/browser/web_applications/web_app_migration_user_display_mode_clean_up_browsertest.cc
@@ -27,18 +27,6 @@
 const char kAppName[] = "Test App";
 const char kStartUrl[] = "https://test.com";
 
-size_t GetTestPreCount() {
-  constexpr base::StringPiece kPreTestPrefix = "PRE_";
-  base::StringPiece test_name =
-      testing::UnitTest::GetInstance()->current_test_info()->name();
-  size_t count = 0;
-  while (test_name.find(kPreTestPrefix, kPreTestPrefix.size() * count) ==
-         kPreTestPrefix.size() * count) {
-    ++count;
-  }
-  return count;
-}
-
 }  // namespace
 
 namespace web_app {
diff --git a/chrome/build/linux.pgo.txt b/chrome/build/linux.pgo.txt
index c7b38b00..cff77be0 100644
--- a/chrome/build/linux.pgo.txt
+++ b/chrome/build/linux.pgo.txt
@@ -1 +1 @@
-chrome-linux-master-1606305050-8edbd758527486c76db2fc42225801a21c253468.profdata
+chrome-linux-master-1606327120-481ff93b7112a13bdcf1248f3441d3a11742a301.profdata
diff --git a/chrome/build/mac.pgo.txt b/chrome/build/mac.pgo.txt
index c052b33a..3e576cf0 100644
--- a/chrome/build/mac.pgo.txt
+++ b/chrome/build/mac.pgo.txt
@@ -1 +1 @@
-chrome-mac-master-1606305050-ea6ce0091e94442cf03fb928da3568602c7b69e6.profdata
+chrome-mac-master-1606327120-e32add9932b9917c7d02c6e60e2518fc762f03e2.profdata
diff --git a/chrome/build/win64.pgo.txt b/chrome/build/win64.pgo.txt
index 0329116..737d8dee 100644
--- a/chrome/build/win64.pgo.txt
+++ b/chrome/build/win64.pgo.txt
@@ -1 +1 @@
-chrome-win64-master-1606283471-0c692a03b66417a93fe8e91b8a0c4f515aaad0a9.profdata
+chrome-win64-master-1606293619-712b869bfc91985e78185bbfc14de73d07d8077a.profdata
diff --git a/chrome/common/pref_names.cc b/chrome/common/pref_names.cc
index 72394e0..ae7a2c4 100644
--- a/chrome/common/pref_names.cc
+++ b/chrome/common/pref_names.cc
@@ -1605,7 +1605,13 @@
 // Directory of the last profile used.
 const char kProfileLastUsed[] = "profile.last_used";
 
-// List of directories of the profiles last active.
+// List of directories of the profiles last active in browser windows. It does
+// not include profiles active in app windows. When a browser window is opened,
+// if it's the only browser window open in the profile, its profile is added to
+// this list. When a browser window is closed, and there are no other browser
+// windows open in the profile, its profile is removed from this list. When
+// Chrome is launched with --session-restore, each of the profiles in this list
+// have their sessions restored.
 const char kProfilesLastActive[] = "profile.last_active_profiles";
 
 // Total number of profiles created for this Chrome build. Used to tag profile
diff --git a/chrome/credential_provider/gaiacp/gem_device_details_manager_unittests.cc b/chrome/credential_provider/gaiacp/gem_device_details_manager_unittests.cc
index 616a8b6..e4cb5dc 100644
--- a/chrome/credential_provider/gaiacp/gem_device_details_manager_unittests.cc
+++ b/chrome/credential_provider/gaiacp/gem_device_details_manager_unittests.cc
@@ -62,8 +62,7 @@
   }
 
   base::Value expected_response_value(base::Value::Type::DICTIONARY);
-  expected_response_value.SetStringKey("deviceResourceId",
-                                       std::move(device_resource_id));
+  expected_response_value.SetStringKey("deviceResourceId", device_resource_id);
   std::string expected_response;
   base::JSONWriter::Write(expected_response_value, &expected_response);
 
diff --git a/chrome/test/android/BUILD.gn b/chrome/test/android/BUILD.gn
index 0532e12..064d9a2 100644
--- a/chrome/test/android/BUILD.gn
+++ b/chrome/test/android/BUILD.gn
@@ -269,6 +269,7 @@
     "//chrome/browser/preferences:java",
     "//chrome/browser/profiles/android:java",
     "//chrome/browser/settings:test_support_java",
+    "//chrome/browser/signin/services/android:java",
     "//chrome/browser/tab:java",
     "//chrome/browser/tabmodel:java",
     "//chrome/browser/thumbnail/generator:java",
diff --git a/chrome/test/android/javatests/src/org/chromium/chrome/browser/history/HistoryTestUtils.java b/chrome/test/android/javatests/src/org/chromium/chrome/browser/history/HistoryTestUtils.java
index c4ca9f8b..244c8b4 100644
--- a/chrome/test/android/javatests/src/org/chromium/chrome/browser/history/HistoryTestUtils.java
+++ b/chrome/test/android/javatests/src/org/chromium/chrome/browser/history/HistoryTestUtils.java
@@ -13,7 +13,7 @@
 
 import org.chromium.base.test.util.CallbackHelper;
 import org.chromium.chrome.browser.preferences.PrefChangeRegistrar.PrefObserver;
-import org.chromium.chrome.browser.signin.SigninManager.SignInStateObserver;
+import org.chromium.chrome.browser.signin.services.SigninManager.SignInStateObserver;
 import org.chromium.components.browser_ui.widget.DateDividedAdapter.ItemViewType;
 import org.chromium.components.browser_ui.widget.selectable_list.SelectionDelegate.SelectionObserver;
 import org.chromium.content_public.browser.test.util.TestThreadUtils;
diff --git a/chrome/test/android/javatests/src/org/chromium/chrome/browser/tab/MockTab.java b/chrome/test/android/javatests/src/org/chromium/chrome/browser/tab/MockTab.java
index ae046e19..0867f8b 100644
--- a/chrome/test/android/javatests/src/org/chromium/chrome/browser/tab/MockTab.java
+++ b/chrome/test/android/javatests/src/org/chromium/chrome/browser/tab/MockTab.java
@@ -6,6 +6,7 @@
 
 import androidx.annotation.Nullable;
 
+import org.chromium.chrome.browser.tab.state.CriticalPersistedTabData;
 import org.chromium.content_public.browser.LoadUrlParams;
 import org.chromium.content_public.browser.WebContents;
 
@@ -22,6 +23,13 @@
         return tab;
     }
 
+    public static TabImpl initializeWithCriticalPersistedTabData(
+            TabImpl tab, CriticalPersistedTabData criticalPersistedTabData) {
+        tab.getUserDataHost().setUserData(CriticalPersistedTabData.class, criticalPersistedTabData);
+        tab.initialize(null, null, null, null, null, false, null, null);
+        return tab;
+    }
+
     /**
      * Constructor for id and incognito attribute. Tests often need to initialize
      * these two fields only.
diff --git a/chrome/test/android/javatests/src/org/chromium/chrome/test/util/browser/signin/SigninTestUtil.java b/chrome/test/android/javatests/src/org/chromium/chrome/test/util/browser/signin/SigninTestUtil.java
index ba88a06..9f98d3e 100644
--- a/chrome/test/android/javatests/src/org/chromium/chrome/test/util/browser/signin/SigninTestUtil.java
+++ b/chrome/test/android/javatests/src/org/chromium/chrome/test/util/browser/signin/SigninTestUtil.java
@@ -13,7 +13,7 @@
 import org.chromium.chrome.browser.SyncFirstSetupCompleteSource;
 import org.chromium.chrome.browser.profiles.Profile;
 import org.chromium.chrome.browser.signin.IdentityServicesProvider;
-import org.chromium.chrome.browser.signin.SigninManager;
+import org.chromium.chrome.browser.signin.services.SigninManager;
 import org.chromium.chrome.browser.sync.ProfileSyncService;
 import org.chromium.components.signin.AccountTrackerService;
 import org.chromium.components.signin.base.CoreAccountInfo;
diff --git a/chrome/test/base/in_process_browser_test.cc b/chrome/test/base/in_process_browser_test.cc
index 8c95a5a3..cffec30 100644
--- a/chrome/test/base/in_process_browser_test.cc
+++ b/chrome/test/base/in_process_browser_test.cc
@@ -377,6 +377,19 @@
 #endif
 }
 
+// static
+size_t InProcessBrowserTest::GetTestPreCount() {
+  constexpr base::StringPiece kPreTestPrefix = "PRE_";
+  base::StringPiece test_name =
+      testing::UnitTest::GetInstance()->current_test_info()->name();
+  size_t count = 0;
+  while (base::StartsWith(test_name, kPreTestPrefix)) {
+    ++count;
+    test_name = test_name.substr(kPreTestPrefix.size());
+  }
+  return count;
+}
+
 void InProcessBrowserTest::SelectFirstBrowser() {
   const BrowserList* browser_list = BrowserList::GetInstance();
   if (!browser_list->empty())
diff --git a/chrome/test/base/in_process_browser_test.h b/chrome/test/base/in_process_browser_test.h
index 58aa8ecbe..bb974003 100644
--- a/chrome/test/base/in_process_browser_test.h
+++ b/chrome/test/base/in_process_browser_test.h
@@ -150,6 +150,11 @@
     global_browser_set_up_function_ = set_up_function;
   }
 
+  // Counts the number of "PRE_" prefixes in the test name. This is used to
+  // differentiate between different PRE tests in browser test constructors
+  // and setup functions.
+  static size_t GetTestPreCount();
+
   // Returns the browser created by BrowserMain().
   // If no browser is created in BrowserMain(), this will return nullptr unless
   // another browser instance is created at a later time and
diff --git a/chrome/test/data/extensions/platform_apps/web_view/shim/main.js b/chrome/test/data/extensions/platform_apps/web_view/shim/main.js
index f9c8c27e8..10cbd80 100644
--- a/chrome/test/data/extensions/platform_apps/web_view/shim/main.js
+++ b/chrome/test/data/extensions/platform_apps/web_view/shim/main.js
@@ -2854,7 +2854,41 @@
 
   webview.addEventListener('loadstop', loadstopListener1);
   document.body.appendChild(webview);
-};
+}
+
+// loadDataWithBaseUrl cannot generally be used with a chrome-extension:// base
+// URL, however the embedding extension may use its own chrome-extension://
+// origin. We test that an embedder can use its own origin as the base and that
+// relative URLs resolve to it by loading something in the guest from the
+// embedder's accessible_resources.
+function testLoadDataAPIAccessibleResources() {
+  let webview = new WebView();
+  // The accessible_resources listed in the manifest file are under the
+  // "foobar" partition.
+  webview.partition = 'foobar';
+  webview.src = 'about:blank';
+
+  let loadstopListener2 = function() {
+    webview.executeScript(
+        {code: 'document.querySelector(\'img\').src'}, (e) => {
+          embedder.test.assertEq(e, location.origin + '/test.bmp');
+          embedder.test.succeed();
+        });
+  };
+
+  let loadstopListener1 = function() {
+    webview.removeEventListener('loadstop', loadstopListener1);
+    webview.addEventListener('loadstop', loadstopListener2);
+
+    let encodedData =
+        window.btoa('<html>This is a test.<br><img src="test.bmp"><br></html>');
+    webview.loadDataWithBaseUrl('data:text/html;base64,' + encodedData,
+                                location.origin);
+  };
+
+  webview.addEventListener('loadstop', loadstopListener1);
+  document.body.appendChild(webview);
+}
 
 // Test that the resize events fire with the correct values, and in the
 // correct order, when resizing occurs.
@@ -3417,6 +3451,7 @@
   'testFindAPI_findupdate': testFindAPI_findupdate,
   'testFindInMultipleWebViews': testFindInMultipleWebViews,
   'testLoadDataAPI': testLoadDataAPI,
+  'testLoadDataAPIAccessibleResources': testLoadDataAPIAccessibleResources,
   'testResizeEvents': testResizeEvents,
   'testPerOriginZoomMode': testPerOriginZoomMode,
   'testPerViewZoomMode': testPerViewZoomMode,
diff --git a/chrome/test/data/extensions/platform_apps/web_view/shim/manifest.json b/chrome/test/data/extensions/platform_apps/web_view/shim/manifest.json
index bb1ff2f..f519c9c 100644
--- a/chrome/test/data/extensions/platform_apps/web_view/shim/manifest.json
+++ b/chrome/test/data/extensions/platform_apps/web_view/shim/manifest.json
@@ -18,6 +18,7 @@
           "child_frame.html",
           "parent_frame.html",
           "guest_with_inline_script.html",
+          "test.bmp",
           "test.pdf",
           "guest_with_select.html"
         ]
diff --git a/chrome/test/data/webui/new_tab_page/realbox_test.js b/chrome/test/data/webui/new_tab_page/realbox_test.js
index c74d972f..2962a94 100644
--- a/chrome/test/data/webui/new_tab_page/realbox_test.js
+++ b/chrome/test/data/webui/new_tab_page/realbox_test.js
@@ -809,7 +809,7 @@
     // Input is expected to have been focused before any navigation.
     realbox.$.input.dispatchEvent(new Event('focus'));
 
-    realbox.$.input.value = 'hello';
+    realbox.$.input.value = '  hello  ';
     realbox.$.input.dispatchEvent(new CustomEvent('input'));
 
     const matches = [
@@ -860,7 +860,7 @@
         // Input is expected to have been focused before any navigation.
         realbox.$.input.dispatchEvent(new Event('focus'));
 
-        realbox.$.input.value = 'hello ';
+        realbox.$.input.value = '  hello  ';
         realbox.$.input.dispatchEvent(new CustomEvent('input'));
 
         const matches =
@@ -1592,6 +1592,39 @@
     assertEquals(0, matchEls.length);
     // Input is cleared.
     assertEquals('', realbox.$.input.value);
+
+    // Show zero-prefix matches.
+    realbox.$.input.dispatchEvent(new MouseEvent('mousedown', {button: 0}));
+    testProxy.callbackRouterRemote.autocompleteResultChanged({
+      input: mojoString16(''),
+      matches,
+      suggestionGroupsMap: {},
+    });
+    await testProxy.callbackRouterRemote.$.flushForTesting();
+
+    assertTrue(areMatchesShowing());
+    matchEls =
+        realbox.$.matches.shadowRoot.querySelectorAll('ntp-realbox-match');
+    assertEquals(2, matchEls.length);
+
+    // Pressing 'Escape' when no matches are selected closes the dropdown.
+    escapeEvent = new KeyboardEvent('keydown', {
+      bubbles: true,
+      cancelable: true,
+      composed: true,  // So it propagates across shadow DOM boundary.
+      key: 'Escape',
+    });
+    realbox.$.input.dispatchEvent(escapeEvent);
+    assertTrue(escapeEvent.defaultPrevented);
+
+    // Matches are hidden.
+    assertFalse(areMatchesShowing());
+    // Force a synchronous render.
+    realbox.$.matches.$.groups.render();
+    // Matches are cleared.
+    matchEls =
+        realbox.$.matches.shadowRoot.querySelectorAll('ntp-realbox-match');
+    assertEquals(0, matchEls.length);
   });
 
   test('arrow up/down moves selection / focus', async () => {
diff --git a/chromeos/chromeos_strings.grd b/chromeos/chromeos_strings.grd
index 984a536..3042f932 100644
--- a/chromeos/chromeos_strings.grd
+++ b/chromeos/chromeos_strings.grd
@@ -705,6 +705,13 @@
       <message name="IDS_DIAGNOSTICS_MEMORY_ROUTINE_TEXT" desc="The text for the memory routine." translateable="false">
         Memory
       </message>
+      <message name="IDS_CHARGE_TEST_RESULT" desc="The result text for charging routine." translateable="true">
+        Charged <ph name="RATE">$1<ex>10%</ex></ph> in <ph name="NUM_SECONDS">$1<ex>10</ex></ph> seconds.
+      </message>
+      <!-- TODO(joonbug): verify this string since it's not present in the mock -->
+      <message name="IDS_DISCHARGE_TEST_RESULT" desc="The result text for discharging routine." translateable="false">
+        Discharged <ph name="RATE">$1<ex>10%</ex></ph> in <ph name="NUM_SECONDS">$1<ex>10</ex></ph> seconds.
+      </message>
 
       <!-- Quick Answers -->
       <message name="IDS_QUICK_ANSWERS_DEFINITION_TITLE_TEXT" desc="The title text format string used for Quick Answers definition result card. The first placeholder contains the source query text and the second placeholder contains the phonetics.">
diff --git a/chromeos/chromeos_strings_grd/IDS_CHARGE_TEST_RESULT.png.sha1 b/chromeos/chromeos_strings_grd/IDS_CHARGE_TEST_RESULT.png.sha1
new file mode 100644
index 0000000..193028d
--- /dev/null
+++ b/chromeos/chromeos_strings_grd/IDS_CHARGE_TEST_RESULT.png.sha1
@@ -0,0 +1 @@
+d305ca9ee1ae6cb18466a4cd76321a90694a227d
\ No newline at end of file
diff --git a/chromeos/components/diagnostics_ui/diagnostics_ui.cc b/chromeos/components/diagnostics_ui/diagnostics_ui.cc
index f479633..9df2233 100644
--- a/chromeos/components/diagnostics_ui/diagnostics_ui.cc
+++ b/chromeos/components/diagnostics_ui/diagnostics_ui.cc
@@ -45,6 +45,7 @@
       {"chargeFullDesign", IDS_DIAGNOSTICS_DESIGNED_FULL_CHARGE_LABEL},
       {"chargeFullNow", IDS_DIAGNOSTICS_NOW_FULL_CHARGE_LABEL},
       {"chargeNow", IDS_DIAGNOSTICS_CHARGE_NOW_LABEL},
+      {"chargeTestResultText", IDS_CHARGE_TEST_RESULT},
       {"cpuCacheRoutineText", IDS_DIAGNOSTICS_CPU_CACHE_ROUTINE_TEXT},
       {"cpuChipText", IDS_DIAGNOSTICS_CPU_CHIP_TEXT},
       {"cpuFloatingPointAccuracyRoutineText",
@@ -68,6 +69,7 @@
       {"cycleCountTooltipText", IDS_DIAGNOSTICS_CYCLE_COUNT_TOOLTIP_TEXT},
       {"deviceInfo", IDS_DIAGNOSTICS_DEVICE_INFO_TEXT},
       {"diagnosticsTitle", IDS_DIAGNOSTICS_TITLE},
+      {"dischargeTestResultText", IDS_DISCHARGE_TEST_RESULT},
       {"learnMore", IDS_DIANOSTICS_LEARN_MORE_LABEL},
       {"memoryAvailable", IDS_DIAGNOSTICS_MEMORY_AVAILABLE_LABEL},
       {"memoryRoutineText", IDS_DIAGNOSTICS_MEMORY_ROUTINE_TEXT},
diff --git a/chromeos/dbus/cros_healthd/fake_cros_healthd_client.cc b/chromeos/dbus/cros_healthd/fake_cros_healthd_client.cc
index 188f7da..02f9a41f 100644
--- a/chromeos/dbus/cros_healthd/fake_cros_healthd_client.cc
+++ b/chromeos/dbus/cros_healthd/fake_cros_healthd_client.cc
@@ -173,5 +173,10 @@
   fake_service_.RunLanConnectivityRoutineForTesting(std::move(callback));
 }
 
+base::Optional<FakeCrosHealthdService::RoutineUpdateParams>
+FakeCrosHealthdClient::GetRoutineUpdateParams() {
+  return fake_service_.GetRoutineUpdateParams();
+}
+
 }  // namespace cros_healthd
 }  // namespace chromeos
diff --git a/chromeos/dbus/cros_healthd/fake_cros_healthd_client.h b/chromeos/dbus/cros_healthd/fake_cros_healthd_client.h
index f959cd6..cea4d1f 100644
--- a/chromeos/dbus/cros_healthd/fake_cros_healthd_client.h
+++ b/chromeos/dbus/cros_healthd/fake_cros_healthd_client.h
@@ -8,6 +8,7 @@
 #include "base/callback_forward.h"
 #include "base/files/scoped_file.h"
 #include "base/macros.h"
+#include "base/optional.h"
 #include "base/time/time.h"
 #include "chromeos/dbus/cros_healthd/cros_healthd_client.h"
 #include "chromeos/dbus/cros_healthd/fake_cros_healthd_service.h"
@@ -115,6 +116,11 @@
       chromeos::network_diagnostics::mojom::NetworkDiagnosticsRoutines::
           LanConnectivityCallback);
 
+  // Returns the parameters passed for the most recent call to
+  // `GetRoutineUpdate`.
+  base::Optional<FakeCrosHealthdService::RoutineUpdateParams>
+  GetRoutineUpdateParams();
+
  private:
   FakeCrosHealthdService fake_service_;
   mojo::Receiver<mojom::CrosHealthdServiceFactory> receiver_{&fake_service_};
diff --git a/chromeos/dbus/cros_healthd/fake_cros_healthd_service.cc b/chromeos/dbus/cros_healthd/fake_cros_healthd_service.cc
index 6e8fb8a..90cbb8b 100644
--- a/chromeos/dbus/cros_healthd/fake_cros_healthd_service.cc
+++ b/chromeos/dbus/cros_healthd/fake_cros_healthd_service.cc
@@ -12,6 +12,12 @@
 namespace chromeos {
 namespace cros_healthd {
 
+FakeCrosHealthdService::RoutineUpdateParams::RoutineUpdateParams(
+    int32_t id,
+    mojom::DiagnosticRoutineCommandEnum command,
+    bool include_output)
+    : id(id), command(command), include_output(include_output) {}
+
 FakeCrosHealthdService::FakeCrosHealthdService() = default;
 FakeCrosHealthdService::~FakeCrosHealthdService() = default;
 
@@ -55,6 +61,8 @@
     mojom::DiagnosticRoutineCommandEnum command,
     bool include_output,
     GetRoutineUpdateCallback callback) {
+  routine_update_params_ =
+      FakeCrosHealthdService::RoutineUpdateParams(id, command, include_output);
   base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
       FROM_HERE,
       base::BindOnce(
@@ -385,5 +393,10 @@
   network_diagnostics_routines_->LanConnectivity(std::move(callback));
 }
 
+base::Optional<FakeCrosHealthdService::RoutineUpdateParams>
+FakeCrosHealthdService::GetRoutineUpdateParams() const {
+  return routine_update_params_;
+}
+
 }  // namespace cros_healthd
 }  // namespace chromeos
diff --git a/chromeos/dbus/cros_healthd/fake_cros_healthd_service.h b/chromeos/dbus/cros_healthd/fake_cros_healthd_service.h
index 32afcd0..4e85eceb 100644
--- a/chromeos/dbus/cros_healthd/fake_cros_healthd_service.h
+++ b/chromeos/dbus/cros_healthd/fake_cros_healthd_service.h
@@ -5,9 +5,11 @@
 #ifndef CHROMEOS_DBUS_CROS_HEALTHD_FAKE_CROS_HEALTHD_SERVICE_H_
 #define CHROMEOS_DBUS_CROS_HEALTHD_FAKE_CROS_HEALTHD_SERVICE_H_
 
+#include <cstdint>
 #include <vector>
 
 #include "base/macros.h"
+#include "base/optional.h"
 #include "base/time/time.h"
 #include "chromeos/services/cros_healthd/public/mojom/cros_healthd.mojom.h"
 #include "chromeos/services/cros_healthd/public/mojom/cros_healthd_diagnostics.mojom.h"
@@ -33,6 +35,16 @@
       public mojom::CrosHealthdEventService,
       public mojom::CrosHealthdProbeService {
  public:
+  struct RoutineUpdateParams {
+    RoutineUpdateParams(int32_t id,
+                        mojom::DiagnosticRoutineCommandEnum command,
+                        bool include_output);
+
+    int32_t id;
+    mojom::DiagnosticRoutineCommandEnum command;
+    bool include_output;
+  };
+
   FakeCrosHealthdService();
   ~FakeCrosHealthdService() override;
 
@@ -203,6 +215,10 @@
       chromeos::network_diagnostics::mojom::NetworkDiagnosticsRoutines::
           LanConnectivityCallback callback);
 
+  // Returns the parameters passed for the most recent call to
+  // `GetRoutineUpdate`.
+  base::Optional<RoutineUpdateParams> GetRoutineUpdateParams() const;
+
  private:
   // Used as the response to any GetAvailableRoutines IPCs received.
   std::vector<mojom::DiagnosticRoutineEnum> available_routines_;
@@ -235,6 +251,10 @@
   // Collection of registered power observers.
   mojo::RemoteSet<mojom::CrosHealthdPowerObserver> power_observers_;
 
+  // Contains the most recent params passed to `GetRoutineUpdate`, if it has
+  // been called.
+  base::Optional<RoutineUpdateParams> routine_update_params_;
+
   // Allow |this| to call the methods on the NetworkDiagnosticsRoutines
   // interface.
   mojo::Remote<chromeos::network_diagnostics::mojom::NetworkDiagnosticsRoutines>
diff --git a/components/arc/session/arc_vm_client_adapter_unittest.cc b/components/arc/session/arc_vm_client_adapter_unittest.cc
index be9905d..fba3f72 100644
--- a/components/arc/session/arc_vm_client_adapter_unittest.cc
+++ b/components/arc/session/arc_vm_client_adapter_unittest.cc
@@ -841,6 +841,46 @@
   EXPECT_TRUE(arc_instance_stopped_called());
 }
 
+// Tests that adb sideloading is disabled by default.
+TEST_F(ArcVmClientAdapterTest, UpgradeArc_AdbSideloadingPropertyDefault) {
+  SetValidUserInfo();
+  StartMiniArc();
+
+  UpgradeArc(true);
+  EXPECT_TRUE(GetTestConciergeClient()->start_arc_vm_called());
+  EXPECT_FALSE(arc_instance_stopped_called());
+  EXPECT_TRUE(
+      base::Contains(GetTestConciergeClient()->start_arc_vm_request().params(),
+                     "androidboot.enable_adb_sideloading=0"));
+}
+
+// Tests that adb sideloading can be controlled via session_manager.
+TEST_F(ArcVmClientAdapterTest, UpgradeArc_AdbSideloadingPropertyEnabled) {
+  SetValidUserInfo();
+  StartMiniArc();
+
+  chromeos::FakeSessionManagerClient::Get()->set_adb_sideload_enabled(true);
+  UpgradeArc(true);
+  EXPECT_TRUE(GetTestConciergeClient()->start_arc_vm_called());
+  EXPECT_FALSE(arc_instance_stopped_called());
+  EXPECT_TRUE(
+      base::Contains(GetTestConciergeClient()->start_arc_vm_request().params(),
+                     "androidboot.enable_adb_sideloading=1"));
+}
+
+TEST_F(ArcVmClientAdapterTest, UpgradeArc_AdbSideloadingPropertyDisabled) {
+  SetValidUserInfo();
+  StartMiniArc();
+
+  chromeos::FakeSessionManagerClient::Get()->set_adb_sideload_enabled(false);
+  UpgradeArc(true);
+  EXPECT_TRUE(GetTestConciergeClient()->start_arc_vm_called());
+  EXPECT_FALSE(arc_instance_stopped_called());
+  EXPECT_TRUE(
+      base::Contains(GetTestConciergeClient()->start_arc_vm_request().params(),
+                     "androidboot.enable_adb_sideloading=0"));
+}
+
 // Tests that "no serial" failure is handled properly.
 TEST_F(ArcVmClientAdapterTest, UpgradeArc_NoSerial) {
   // Don't set the serial number. Note that we cannot call StartArcVm() without
diff --git a/components/autofill/core/browser/form_structure.cc b/components/autofill/core/browser/form_structure.cc
index f6354d8..d2fa11d 100644
--- a/components/autofill/core/browser/form_structure.cc
+++ b/components/autofill/core/browser/form_structure.cc
@@ -711,7 +711,7 @@
   upload->set_data_present(EncodeFieldTypes(available_field_types));
   upload->set_passwords_revealed(passwords_were_revealed_);
   upload->set_has_form_tag(is_form_tag_);
-  if (!page_language_.empty() && randomized_encoder_ != nullptr) {
+  if (!page_language_->empty() && randomized_encoder_ != nullptr) {
     upload->set_language(page_language_.value());
   }
 
diff --git a/components/autofill/core/common/language_code.h b/components/autofill/core/common/language_code.h
index ceec17be..eb7a6789 100644
--- a/components/autofill/core/common/language_code.h
+++ b/components/autofill/core/common/language_code.h
@@ -29,12 +29,9 @@
   explicit LanguageCode(std::string&& s) : BaseClass(std::move(s)) { Check(); }
   explicit LanguageCode(const std::string& s) : BaseClass(s) { Check(); }
 
-  size_t length() const { return value().length(); }
-  bool empty() const { return value().empty(); }
-
  private:
   void Check() {
-    DCHECK((length() <= 3 && base::ranges::all_of(value(), &islower)) ||
+    DCHECK(((*this)->size() <= 3 && base::ranges::all_of(value(), &islower)) ||
            value() == "zh-CN" || value() == "zh-TW")
         << "Unexpected language code '" << value() << "'";
   }
diff --git a/components/favicon/ios/web_favicon_driver.mm b/components/favicon/ios/web_favicon_driver.mm
index 963a4db..67eed96 100644
--- a/components/favicon/ios/web_favicon_driver.mm
+++ b/components/favicon/ios/web_favicon_driver.mm
@@ -71,7 +71,7 @@
         std::vector<SkBitmap> frames;
         std::vector<gfx::Size> sizes;
         if (data) {
-          frames = skia::ImageDataToSkBitmaps(data);
+          frames = skia::ImageDataToSkBitmapsWithMaxSize(data, max_image_size);
           for (const auto& frame : frames) {
             sizes.push_back(gfx::Size(frame.width(), frame.height()));
           }
diff --git a/components/feed/feed_feature_list.cc b/components/feed/feed_feature_list.cc
index f9cf11ab..58a2052 100644
--- a/components/feed/feed_feature_list.cc
+++ b/components/feed/feed_feature_list.cc
@@ -49,10 +49,6 @@
 const base::Feature kInterestFeedNoticeCardAutoDismiss{
     "InterestFeedNoticeCardAutoDismiss", base::FEATURE_DISABLED_BY_DEFAULT};
 
-// Used for A:B testing of a bug fix (crbug.com/1151391).
-const base::Feature kInterestFeedSpinnerAlwaysAnimate{
-    "InterestFeedSpinnerAlwaysAnimate", base::FEATURE_DISABLED_BY_DEFAULT};
-
 const char kDefaultReferrerUrl[] =
     "https://www.googleapis.com/auth/chrome-content-suggestions";
 
diff --git a/components/feed/feed_feature_list.h b/components/feed/feed_feature_list.h
index 432ba98..744781b 100644
--- a/components/feed/feed_feature_list.h
+++ b/components/feed/feed_feature_list.h
@@ -33,8 +33,6 @@
 
 extern const base::Feature kInterestFeedNoticeCardAutoDismiss;
 
-extern const base::Feature kInterestFeedSpinnerAlwaysAnimate;
-
 std::string GetFeedReferrerUrl();
 
 }  // namespace feed
diff --git a/components/page_info/android/java/src/org/chromium/components/page_info/PageInfoController.java b/components/page_info/android/java/src/org/chromium/components/page_info/PageInfoController.java
index b0cb261..665c995 100644
--- a/components/page_info/android/java/src/org/chromium/components/page_info/PageInfoController.java
+++ b/components/page_info/android/java/src/org/chromium/components/page_info/PageInfoController.java
@@ -488,6 +488,10 @@
             mPendingRunAfterDismissTask.run();
             mPendingRunAfterDismissTask = null;
         }
+        if (mSubpageController != null) {
+            mSubpageController.onSubpageRemoved();
+            mSubpageController = null;
+        }
         mWebContentsObserver.destroy();
         mWebContentsObserver = null;
         PageInfoControllerJni.get().destroy(mNativePageInfoController, PageInfoController.this);
diff --git a/components/paint_preview/browser/BUILD.gn b/components/paint_preview/browser/BUILD.gn
index fe905fd1..1dca29d 100644
--- a/components/paint_preview/browser/BUILD.gn
+++ b/components/paint_preview/browser/BUILD.gn
@@ -24,6 +24,8 @@
     "paint_preview_compositor_client_impl.h",
     "paint_preview_compositor_service_impl.cc",
     "paint_preview_compositor_service_impl.h",
+    "paint_preview_file_mixin.cc",
+    "paint_preview_file_mixin.h",
     "paint_preview_policy.h",
     "service_sandbox_type.h",
     "warm_compositor.cc",
diff --git a/components/paint_preview/browser/paint_preview_base_service.cc b/components/paint_preview/browser/paint_preview_base_service.cc
index 148874e8..67771f6 100644
--- a/components/paint_preview/browser/paint_preview_base_service.cc
+++ b/components/paint_preview/browser/paint_preview_base_service.cc
@@ -12,10 +12,7 @@
 #include "base/files/file_path.h"
 #include "base/logging.h"
 #include "base/metrics/histogram_functions.h"
-#include "base/task/task_traits.h"
-#include "base/task/thread_pool.h"
 #include "build/build_config.h"
-#include "components/keyed_service/core/keyed_service.h"
 #include "components/paint_preview/browser/compositor_utils.h"
 #include "components/paint_preview/browser/paint_preview_client.h"
 #include "components/paint_preview/common/mojom/paint_preview_recorder.mojom.h"
@@ -25,99 +22,23 @@
 
 namespace paint_preview {
 
-namespace {
-
-const char kPaintPreviewDir[] = "paint_preview";
-
-}  // namespace
-
 PaintPreviewBaseService::PaintPreviewBaseService(
-    const base::FilePath& path,
-    base::StringPiece ascii_feature_name,
+    std::unique_ptr<PaintPreviewFileMixin> file_mixin,
     std::unique_ptr<PaintPreviewPolicy> policy,
     bool is_off_the_record)
-    : policy_(std::move(policy)),
-      task_runner_(base::ThreadPool::CreateSequencedTaskRunner(
-          {base::MayBlock(), base::TaskPriority::USER_VISIBLE,
-           base::TaskShutdownBehavior::BLOCK_SHUTDOWN,
-           base::ThreadPolicy::MUST_USE_FOREGROUND})),
-      file_manager_(base::MakeRefCounted<FileManager>(
-          path.AppendASCII(kPaintPreviewDir).AppendASCII(ascii_feature_name),
-          task_runner_)),
+    : file_mixin_(std::move(file_mixin)),
+      policy_(std::move(policy)),
       is_off_the_record_(is_off_the_record) {}
 
 PaintPreviewBaseService::~PaintPreviewBaseService() = default;
 
-void PaintPreviewBaseService::GetCapturedPaintPreviewProto(
-    const DirectoryKey& key,
-    base::Optional<base::TimeDelta> expiry_horizon,
-    OnReadProtoCallback on_read_proto_callback) {
-  task_runner_->PostTaskAndReplyWithResult(
-      FROM_HERE,
-      base::BindOnce(
-          [](scoped_refptr<FileManager> file_manager, const DirectoryKey& key,
-             base::Optional<base::TimeDelta> expiry_horizon)
-              -> std::pair<PaintPreviewBaseService::ProtoReadStatus,
-                           std::unique_ptr<PaintPreviewProto>> {
-            if (expiry_horizon.has_value()) {
-              auto file_info = file_manager->GetInfo(key);
-              if (!file_info.has_value())
-                return std::make_pair(ProtoReadStatus::kNoProto, nullptr);
-
-              if (file_info->last_modified + expiry_horizon.value() <
-                  base::Time::NowFromSystemTime()) {
-                return std::make_pair(ProtoReadStatus::kExpired, nullptr);
-              }
-            }
-            auto result = file_manager->DeserializePaintPreviewProto(key);
-            PaintPreviewBaseService::ProtoReadStatus status =
-                ProtoReadStatus::kNoProto;
-            switch (result.first) {
-              case FileManager::ProtoReadStatus::kOk:
-                status = ProtoReadStatus::kOk;
-                break;
-              case FileManager::ProtoReadStatus::kNoProto:
-                status = ProtoReadStatus::kNoProto;
-                break;
-              case FileManager::ProtoReadStatus::kDeserializationError:
-                status = ProtoReadStatus::kDeserializationError;
-                break;
-              default:
-                NOTREACHED();
-            }
-            return std::make_pair(status, std::move(result.second));
-          },
-          file_manager_, key, expiry_horizon),
-      base::BindOnce(
-          [](OnReadProtoCallback callback,
-             std::pair<PaintPreviewBaseService::ProtoReadStatus,
-                       std::unique_ptr<PaintPreviewProto>> result) {
-            std::move(callback).Run(result.first, std::move(result.second));
-          },
-          std::move(on_read_proto_callback)));
-}
-
-void PaintPreviewBaseService::CapturePaintPreview(
-    content::WebContents* web_contents,
-    const base::FilePath& root_dir,
-    gfx::Rect clip_rect,
-    bool capture_links,
-    size_t max_per_capture_size,
-    OnCapturedCallback callback) {
-  CapturePaintPreview(web_contents, web_contents->GetMainFrame(), root_dir,
-                      clip_rect, capture_links, max_per_capture_size,
-                      std::move(callback));
-}
-
-void PaintPreviewBaseService::CapturePaintPreview(
-    content::WebContents* web_contents,
-    content::RenderFrameHost* render_frame_host,
-    const base::FilePath& root_dir,
-    gfx::Rect clip_rect,
-    bool capture_links,
-    size_t max_per_capture_size,
-    OnCapturedCallback callback) {
+void PaintPreviewBaseService::CapturePaintPreview(CaptureParams capture_params,
+                                                  OnCapturedCallback callback) {
   DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+  content::WebContents* web_contents = capture_params.web_contents;
+  content::RenderFrameHost* render_frame_host =
+      capture_params.render_frame_host ? capture_params.render_frame_host
+                                       : web_contents->GetMainFrame();
   if (policy_ && !policy_->SupportedForContents(web_contents)) {
     std::move(callback).Run(CaptureStatus::kContentUnsupported, {});
     return;
@@ -130,14 +51,15 @@
     return;
   }
 
-  PaintPreviewClient::PaintPreviewParams params(
-      RecordingPersistence::kFileSystem);
-  params.root_dir = root_dir;
-  params.inner.clip_rect = clip_rect;
+  PaintPreviewClient::PaintPreviewParams params(capture_params.persistence);
+  if (capture_params.root_dir) {
+    params.root_dir = *capture_params.root_dir;
+  }
+  params.inner.clip_rect = capture_params.clip_rect;
   params.inner.is_main_frame =
       (render_frame_host == web_contents->GetMainFrame());
-  params.inner.capture_links = capture_links;
-  params.inner.max_capture_size = max_per_capture_size;
+  params.inner.capture_links = capture_params.capture_links;
+  params.inner.max_capture_size = capture_params.max_per_capture_size;
 
   // TODO(crbug/1064253): Consider moving to client so that this always happens.
   // Although, it is harder to get this right in the client due to its
diff --git a/components/paint_preview/browser/paint_preview_base_service.h b/components/paint_preview/browser/paint_preview_base_service.h
index a9ca093e..4d3fee2 100644
--- a/components/paint_preview/browser/paint_preview_base_service.h
+++ b/components/paint_preview/browser/paint_preview_base_service.h
@@ -9,7 +9,6 @@
 
 #include "base/bind.h"
 #include "base/callback.h"
-#include "base/files/file_path.h"
 #include "base/macros.h"
 #include "base/memory/weak_ptr.h"
 #include "base/optional.h"
@@ -17,28 +16,32 @@
 #include "base/time/time.h"
 #include "base/unguessable_token.h"
 #include "build/build_config.h"
-#include "components/keyed_service/core/keyed_service.h"
-#include "components/paint_preview/browser/file_manager.h"
+#include "components/paint_preview/browser/paint_preview_file_mixin.h"
 #include "components/paint_preview/browser/paint_preview_policy.h"
 #include "components/paint_preview/common/capture_result.h"
 #include "components/paint_preview/common/file_utils.h"
 #include "components/paint_preview/common/mojom/paint_preview_recorder.mojom.h"
 #include "components/paint_preview/common/proto/paint_preview.pb.h"
+#include "components/paint_preview/common/serialized_recording.h"
 #include "content/public/browser/web_contents.h"
 
 namespace paint_preview {
 
-// A base KeyedService that serves as the Public API for Paint Previews.
+// A base class that serves as the Public API for Paint Previews.
 // Features that want to use Paint Previews should extend this class.
+// This service supports both in-memery and in-file captures.
+//
 // The KeyedService provides a 1:1 mapping between the service and a key or
 // profile allowing each feature built on Paint Previews to reliably store
 // necessary data to the right directory on disk.
 //
-// Implementations of this service should be created by implementing a factory
-// that extends one of:
-// - BrowserContextKeyedServiceFactory
-// OR preferably the
-// - SimpleKeyedServiceFactory
+// [NOTE] for file system captures:
+// - PaintPreviewFileMixin object needs to be supplied.
+// - Implementations of the service should be created by implementing a factory
+//   that extends one of:
+//   - BrowserContextKeyedServiceFactory
+//   OR preferably the
+//   - SimpleKeyedServiceFactory
 class PaintPreviewBaseService : public KeyedService {
  public:
   enum class CaptureStatus : int {
@@ -48,96 +51,77 @@
     kCaptureFailed,
   };
 
-  enum class ProtoReadStatus : int {
-    kOk = 0,
-    kNoProto,
-    kDeserializationError,
-    kExpired,
+  struct CaptureParams {
+    content::WebContents* web_contents = nullptr;
+
+    // In case of specifying, an individual |render_frame_host| and its
+    // descendents will be captured. In case of nullptr, full page contents will
+    // be captured.
+    //
+    // Generally, leaving this as nullptr is what you should be doing for most
+    // features. Specifying a |render_frame_host| is intended for capturing
+    // individual subframes and should be used for only a few use cases.
+    content::RenderFrameHost* render_frame_host = nullptr;
+
+    // Store artifacts in the file system or in memory buffers.
+    RecordingPersistence persistence;
+
+    // |root_dir| should be created using
+    // GetFileManager()->CreateOrGetDirectoryFor(). However, to provide
+    // flexibility in managing the lifetime of created objects and ease cleanup
+    // if a capture fails the service implementation is responsible for
+    // implementing this management and tracking the directories in existence.
+    // Data in a directory will contain:
+    // - a number of SKPs listed as <guid>.skp (one per frame)
+    //
+    // Will be ignored if persistence = kMemoryBuffer
+    const base::FilePath* root_dir = nullptr;
+
+    // The captured area is clipped to |clip_rect| if it is non-zero.
+    gfx::Rect clip_rect;
+
+    // Whether to record links.
+    bool capture_links;
+
+    // Cap the perframe SkPicture size to |max_per_capture_size| if non-zero.
+    size_t max_per_capture_size;
   };
 
   using OnCapturedCallback =
       base::OnceCallback<void(CaptureStatus, std::unique_ptr<CaptureResult>)>;
 
-  using OnReadProtoCallback =
-      base::OnceCallback<void(ProtoReadStatus,
-                              std::unique_ptr<PaintPreviewProto>)>;
-
   // Creates a service instance for a feature. Artifacts produced will live in
   // |profile_dir|/paint_preview/|ascii_feature_name|. Implementers of the
   // factory can also elect their factory to not construct services in the event
   // a profile |is_off_the_record|. The |policy| object is responsible for
   // determining whether or not a given WebContents is amenable to paint
   // preview. If nullptr is passed as |policy| all content is deemed amenable.
-  PaintPreviewBaseService(const base::FilePath& profile_dir,
-                          base::StringPiece ascii_feature_name,
+  //
+  // NOTE: Pass nullptr as |file_mixin| if you're planning to use the service
+  // for only in-memory captures.
+  PaintPreviewBaseService(std::unique_ptr<PaintPreviewFileMixin> file_mixin,
                           std::unique_ptr<PaintPreviewPolicy> policy,
                           bool is_off_the_record);
   ~PaintPreviewBaseService() override;
 
-  // Returns the file manager for the directory associated with the service.
-  scoped_refptr<FileManager> GetFileManager() { return file_manager_; }
-
-  // Returns the task runner that IO tasks should be scheduled on.
-  scoped_refptr<base::SequencedTaskRunner> GetTaskRunner() {
-    return task_runner_;
-  }
+  PaintPreviewFileMixin* GetFileMixin() { return file_mixin_.get(); }
 
   // Returns whether the created service is off the record.
   bool IsOffTheRecord() const { return is_off_the_record_; }
 
-  // Acquires the PaintPreviewProto that is associated with |key| and sends it
-  // to |on_read_proto_callback|. The default implementation attempts to invoke
-  // GetFileManager()->DeserializePaintPreviewProto(). If |expiry_horizon| is
-  // provided a proto that was last modified earlier than |now - expiry_horizon|
-  // will return the kExpired status.
-  //
-  // Derived classes may override this function; for example, the proto is
-  // cached in memory.
-  virtual void GetCapturedPaintPreviewProto(
-      const DirectoryKey& key,
-      base::Optional<base::TimeDelta> expiry_horizon,
-      OnReadProtoCallback on_read_proto_callback);
-
   // Captures need to run on the Browser UI thread! Captures may involve child
   // frames so the PaintPreviewClient (WebContentsObserver) must be stored as
   // WebContentsUserData which is not thread safe and must only be accessible
   // from a specific sequence i.e. the UI thread.
   //
-  // The following methods both capture a Paint Preview; however, their behavior
-  // and intended use is different. The first method is intended for capturing
-  // full page contents. Generally, this is what you should be using for most
-  // features. The second method is intended for capturing just an individual
-  // RenderFrameHost and its descendents. This is intended for capturing
-  // individual subframes and should be used for only a few use cases.
+  // Captures the main frame of |capture_params.web_contents| (an observer for
+  // capturing Paint Previews is created for web contents if it does not exist).
+  // The capture is attributed to the URL of the main frame. On completion the
+  // status of the capture is provided via |callback|.
   //
-  // NOTE: |root_dir| in the following methods should be created using
-  // GetFileManager()->CreateOrGetDirectoryFor(). However, to provide
-  // flexibility in managing the lifetime of created objects and ease cleanup
-  // if a capture fails the service implementation is responsible for
-  // implementing this management and tracking the directories in existence.
-  // Data in a directory will contain:
-  // - a number of SKPs listed as <guid>.skp (one per frame)
-  //
-  // Captures the main frame of |web_contents| (an observer for capturing Paint
-  // Previews is created for web contents if it does not exist). The capture is
-  // attributed to the URL of the main frame and is stored in |root_dir|. The
-  // captured area is clipped to |clip_rect| if it is non-zero. Caps the per
-  // frame SkPicture size to |max_per_capture_size| if non-zero. On completion
-  // the status of the capture is provided via |callback|.
-  void CapturePaintPreview(content::WebContents* web_contents,
-                           const base::FilePath& root_dir,
-                           gfx::Rect clip_rect,
-                           bool capture_links,
-                           size_t max_per_capture_size,
-                           OnCapturedCallback callback);
-  // Same as above except |render_frame_host| is directly captured rather than
-  // the main frame.
-  void CapturePaintPreview(content::WebContents* web_contents,
-                           content::RenderFrameHost* render_frame_host,
-                           const base::FilePath& root_dir,
-                           gfx::Rect clip_rect,
-                           bool capture_links,
-                           size_t max_per_capture_size,
+  // See |PaintPreviewBaseService::CaptureParams| for more info about the
+  // capture parameters.
+  void CapturePaintPreview(CaptureParams capture_params,
                            OnCapturedCallback callback);
 
  private:
@@ -148,9 +132,8 @@
                   mojom::PaintPreviewStatus status,
                   std::unique_ptr<CaptureResult> result);
 
+  std::unique_ptr<PaintPreviewFileMixin> file_mixin_ = nullptr;
   std::unique_ptr<PaintPreviewPolicy> policy_ = nullptr;
-  scoped_refptr<base::SequencedTaskRunner> task_runner_;
-  scoped_refptr<FileManager> file_manager_;
   bool is_off_the_record_;
 
   base::WeakPtrFactory<PaintPreviewBaseService> weak_ptr_factory_{this};
diff --git a/components/paint_preview/browser/paint_preview_base_service_test_factory.cc b/components/paint_preview/browser/paint_preview_base_service_test_factory.cc
index 8ae8532..f3f4f1f 100644
--- a/components/paint_preview/browser/paint_preview_base_service_test_factory.cc
+++ b/components/paint_preview/browser/paint_preview_base_service_test_factory.cc
@@ -40,7 +40,8 @@
 std::unique_ptr<KeyedService> PaintPreviewBaseServiceTestFactory::Build(
     SimpleFactoryKey* key) {
   return std::make_unique<PaintPreviewBaseService>(
-      key->GetPath(), kTestFeatureDir, nullptr, key->IsOffTheRecord());
+      std::make_unique<PaintPreviewFileMixin>(key->GetPath(), kTestFeatureDir),
+      nullptr, key->IsOffTheRecord());
 }
 
 PaintPreviewBaseServiceTestFactory::~PaintPreviewBaseServiceTestFactory() =
diff --git a/components/paint_preview/browser/paint_preview_base_service_unittest.cc b/components/paint_preview/browser/paint_preview_base_service_unittest.cc
index d8d75868..00f6944d 100644
--- a/components/paint_preview/browser/paint_preview_base_service_unittest.cc
+++ b/components/paint_preview/browser/paint_preview_base_service_unittest.cc
@@ -4,6 +4,9 @@
 
 #include "components/paint_preview/browser/paint_preview_base_service.h"
 
+#include <memory>
+#include <utility>
+
 #include "base/files/scoped_temp_dir.h"
 #include "base/macros.h"
 #include "base/no_destructor.h"
@@ -11,7 +14,9 @@
 #include "base/strings/utf_string_conversions.h"
 #include "build/build_config.h"
 #include "components/paint_preview/browser/paint_preview_base_service_test_factory.h"
+#include "components/paint_preview/browser/paint_preview_file_mixin.h"
 #include "components/paint_preview/common/mojom/paint_preview_recorder.mojom.h"
+#include "components/paint_preview/common/serialized_recording.h"
 #include "components/paint_preview/common/test_utils.h"
 #include "content/public/browser/render_process_host.h"
 #include "content/public/test/navigation_simulator.h"
@@ -46,7 +51,7 @@
 std::unique_ptr<KeyedService> BuildServiceWithRejectionPolicy(
     SimpleFactoryKey* key) {
   return std::make_unique<PaintPreviewBaseService>(
-      key->GetPath(), kTestFeatureDir,
+      std::make_unique<PaintPreviewFileMixin>(key->GetPath(), kTestFeatureDir),
       std::make_unique<RejectionPaintPreviewPolicy>(), key->IsOffTheRecord());
 }
 
@@ -120,7 +125,9 @@
   mojo::AssociatedReceiver<mojom::PaintPreviewRecorder> binding_{this};
 };
 
-class PaintPreviewBaseServiceTest : public content::RenderViewHostTestHarness {
+class PaintPreviewBaseServiceTest
+    : public content::RenderViewHostTestHarness,
+      public testing::WithParamInterface<RecordingPersistence> {
  public:
   PaintPreviewBaseServiceTest() = default;
   ~PaintPreviewBaseServiceTest() override = default;
@@ -165,12 +172,29 @@
         rejection_policy_key_.get());
   }
 
+  PaintPreviewBaseService::CaptureParams CreateCaptureParams(
+      content::WebContents* web_contents,
+      base::FilePath* root_dir,
+      RecordingPersistence persistence,
+      gfx::Rect clip_rect,
+      bool capture_links,
+      size_t max_per_capture_size) {
+    PaintPreviewBaseService::CaptureParams capture_params;
+    capture_params.web_contents = web_contents;
+    capture_params.root_dir = root_dir;
+    capture_params.persistence = persistence;
+    capture_params.clip_rect = clip_rect;
+    capture_params.capture_links = capture_links;
+    capture_params.max_per_capture_size = max_per_capture_size;
+    return capture_params;
+  }
+
  private:
   std::unique_ptr<SimpleFactoryKey> key_ = nullptr;
   std::unique_ptr<SimpleFactoryKey> rejection_policy_key_ = nullptr;
 };
 
-TEST_F(PaintPreviewBaseServiceTest, CaptureMainFrame) {
+TEST_P(PaintPreviewBaseServiceTest, CaptureMainFrame) {
   MockPaintPreviewRecorder recorder;
   auto params = mojom::PaintPreviewCaptureParams::New();
   params->clip_rect = gfx::Rect(0, 0, 0, 0);
@@ -179,18 +203,22 @@
   recorder.SetExpectedParams(std::move(params));
   auto response = mojom::PaintPreviewCaptureResponse::New();
   response->embedding_token = base::nullopt;
+  if (GetParam() == RecordingPersistence::kMemoryBuffer) {
+    response->skp.emplace(mojo_base::BigBuffer());
+  }
   recorder.SetResponse(mojom::PaintPreviewStatus::kOk, std::move(response));
   OverrideInterface(&recorder);
 
   auto* service = GetService();
   EXPECT_FALSE(service->IsOffTheRecord());
-  auto manager = service->GetFileManager();
+  auto manager = service->GetFileMixin()->GetFileManager();
   base::FilePath path = CreateDir(
       manager, manager->CreateKey(web_contents()->GetLastCommittedURL()));
 
   base::RunLoop loop;
   service->CapturePaintPreview(
-      web_contents(), path, gfx::Rect(0, 0, 0, 0), true, 50,
+      CreateCaptureParams(web_contents(), &path, GetParam(),
+                          gfx::Rect(0, 0, 0, 0), true, 50),
       base::BindOnce(
           [](base::OnceClosure quit_closure,
              PaintPreviewBaseService::CaptureStatus expected_status,
@@ -204,19 +232,32 @@
             auto token = base::UnguessableToken::Deserialize(
                 result->proto.root_frame().embedding_token_high(),
                 result->proto.root_frame().embedding_token_low());
+            switch (GetParam()) {
+              case RecordingPersistence::kFileSystem: {
 #if defined(OS_WIN)
-            base::FilePath path = base::FilePath(
-                base::UTF8ToUTF16(result->proto.root_frame().file_path()));
-            base::FilePath name(
-                base::UTF8ToUTF16(base::StrCat({token.ToString(), ".skp"})));
+                base::FilePath path = base::FilePath(
+                    base::UTF8ToUTF16(result->proto.root_frame().file_path()));
+                base::FilePath name(base::UTF8ToUTF16(
+                    base::StrCat({token.ToString(), ".skp"})));
 #else
-            base::FilePath path =
-                base::FilePath(result->proto.root_frame().file_path());
-            base::FilePath name(base::StrCat({token.ToString(), ".skp"}));
+                base::FilePath path =
+                    base::FilePath(result->proto.root_frame().file_path());
+                base::FilePath name(base::StrCat({token.ToString(), ".skp"}));
 #endif
-            EXPECT_EQ(path.DirName(), expected_path);
-            LOG(ERROR) << expected_path;
-            EXPECT_EQ(path.BaseName(), name);
+                EXPECT_EQ(path.DirName(), expected_path);
+                LOG(ERROR) << expected_path;
+                EXPECT_EQ(path.BaseName(), name);
+              } break;
+
+              case RecordingPersistence::kMemoryBuffer: {
+                EXPECT_EQ(result->serialized_skps.size(), 1u);
+                EXPECT_TRUE(result->serialized_skps.contains(token));
+              } break;
+
+              default:
+                NOTREACHED();
+                break;
+            }
             std::move(quit_closure).Run();
           },
           loop.QuitClosure(), PaintPreviewBaseService::CaptureStatus::kOk,
@@ -224,7 +265,7 @@
   loop.Run();
 }
 
-TEST_F(PaintPreviewBaseServiceTest, CaptureFailed) {
+TEST_P(PaintPreviewBaseServiceTest, CaptureFailed) {
   MockPaintPreviewRecorder recorder;
   auto params = mojom::PaintPreviewCaptureParams::New();
   params->clip_rect = gfx::Rect(0, 0, 0, 0);
@@ -238,13 +279,14 @@
 
   auto* service = GetService();
   EXPECT_FALSE(service->IsOffTheRecord());
-  auto manager = service->GetFileManager();
+  auto manager = service->GetFileMixin()->GetFileManager();
   base::FilePath path = CreateDir(
       manager, manager->CreateKey(web_contents()->GetLastCommittedURL()));
 
   base::RunLoop loop;
   service->CapturePaintPreview(
-      web_contents(), path, gfx::Rect(0, 0, 0, 0), true, 0,
+      CreateCaptureParams(web_contents(), &path, GetParam(),
+                          gfx::Rect(0, 0, 0, 0), true, 0),
       base::BindOnce(
           [](base::OnceClosure quit_closure,
              PaintPreviewBaseService::CaptureStatus expected_status,
@@ -259,7 +301,7 @@
   loop.Run();
 }
 
-TEST_F(PaintPreviewBaseServiceTest, CaptureDisallowed) {
+TEST_P(PaintPreviewBaseServiceTest, CaptureDisallowed) {
   MockPaintPreviewRecorder recorder;
   auto params = mojom::PaintPreviewCaptureParams::New();
   params->clip_rect = gfx::Rect(0, 0, 0, 0);
@@ -273,13 +315,14 @@
 
   auto* service = GetServiceWithRejectionPolicy();
   EXPECT_FALSE(service->IsOffTheRecord());
-  auto manager = service->GetFileManager();
+  auto manager = service->GetFileMixin()->GetFileManager();
   base::FilePath path = CreateDir(
       manager, manager->CreateKey(web_contents()->GetLastCommittedURL()));
 
   base::RunLoop loop;
   service->CapturePaintPreview(
-      web_contents(), path, gfx::Rect(0, 0, 0, 0), true, 0,
+      CreateCaptureParams(web_contents(), &path, GetParam(),
+                          gfx::Rect(0, 0, 0, 0), true, 0),
       base::BindOnce(
           [](base::OnceClosure quit_closure,
              PaintPreviewBaseService::CaptureStatus expected_status,
@@ -294,4 +337,10 @@
   loop.Run();
 }
 
+INSTANTIATE_TEST_SUITE_P(All,
+                         PaintPreviewBaseServiceTest,
+                         testing::Values(RecordingPersistence::kFileSystem,
+                                         RecordingPersistence::kMemoryBuffer),
+                         PersistenceParamToString);
+
 }  // namespace paint_preview
diff --git a/components/paint_preview/browser/paint_preview_file_mixin.cc b/components/paint_preview/browser/paint_preview_file_mixin.cc
new file mode 100644
index 0000000..f6700a3
--- /dev/null
+++ b/components/paint_preview/browser/paint_preview_file_mixin.cc
@@ -0,0 +1,82 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/paint_preview/browser/paint_preview_file_mixin.h"
+
+#include <utility>
+
+#include "base/task/task_traits.h"
+#include "base/task/thread_pool.h"
+
+namespace paint_preview {
+
+namespace {
+
+const char kPaintPreviewDir[] = "paint_preview";
+
+}  // namespace
+
+PaintPreviewFileMixin::PaintPreviewFileMixin(
+    const base::FilePath& path,
+    base::StringPiece ascii_feature_name)
+    : task_runner_(base::ThreadPool::CreateSequencedTaskRunner(
+          {base::MayBlock(), base::TaskPriority::USER_VISIBLE,
+           base::TaskShutdownBehavior::BLOCK_SHUTDOWN,
+           base::ThreadPolicy::MUST_USE_FOREGROUND})),
+      file_manager_(base::MakeRefCounted<FileManager>(
+          path.AppendASCII(kPaintPreviewDir).AppendASCII(ascii_feature_name),
+          task_runner_)) {}
+
+PaintPreviewFileMixin::~PaintPreviewFileMixin() = default;
+
+void PaintPreviewFileMixin::GetCapturedPaintPreviewProto(
+    const DirectoryKey& key,
+    base::Optional<base::TimeDelta> expiry_horizon,
+    OnReadProtoCallback on_read_proto_callback) {
+  task_runner_->PostTaskAndReplyWithResult(
+      FROM_HERE,
+      base::BindOnce(
+          [](scoped_refptr<FileManager> file_manager, const DirectoryKey& key,
+             base::Optional<base::TimeDelta> expiry_horizon)
+              -> std::pair<PaintPreviewFileMixin::ProtoReadStatus,
+                           std::unique_ptr<PaintPreviewProto>> {
+            if (expiry_horizon.has_value()) {
+              auto file_info = file_manager->GetInfo(key);
+              if (!file_info.has_value())
+                return std::make_pair(ProtoReadStatus::kNoProto, nullptr);
+
+              if (file_info->last_modified + expiry_horizon.value() <
+                  base::Time::NowFromSystemTime()) {
+                return std::make_pair(ProtoReadStatus::kExpired, nullptr);
+              }
+            }
+            auto result = file_manager->DeserializePaintPreviewProto(key);
+            PaintPreviewFileMixin::ProtoReadStatus status =
+                ProtoReadStatus::kNoProto;
+            switch (result.first) {
+              case FileManager::ProtoReadStatus::kOk:
+                status = ProtoReadStatus::kOk;
+                break;
+              case FileManager::ProtoReadStatus::kNoProto:
+                status = ProtoReadStatus::kNoProto;
+                break;
+              case FileManager::ProtoReadStatus::kDeserializationError:
+                status = ProtoReadStatus::kDeserializationError;
+                break;
+              default:
+                NOTREACHED();
+            }
+            return std::make_pair(status, std::move(result.second));
+          },
+          file_manager_, key, expiry_horizon),
+      base::BindOnce(
+          [](OnReadProtoCallback callback,
+             std::pair<PaintPreviewFileMixin::ProtoReadStatus,
+                       std::unique_ptr<PaintPreviewProto>> result) {
+            std::move(callback).Run(result.first, std::move(result.second));
+          },
+          std::move(on_read_proto_callback)));
+}
+
+}  // namespace paint_preview
diff --git a/components/paint_preview/browser/paint_preview_file_mixin.h b/components/paint_preview/browser/paint_preview_file_mixin.h
new file mode 100644
index 0000000..0234192e
--- /dev/null
+++ b/components/paint_preview/browser/paint_preview_file_mixin.h
@@ -0,0 +1,60 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_PAINT_PREVIEW_BROWSER_PAINT_PREVIEW_FILE_MIXIN_H_
+#define COMPONENTS_PAINT_PREVIEW_BROWSER_PAINT_PREVIEW_FILE_MIXIN_H_
+
+#include "base/files/file_path.h"
+#include "components/keyed_service/core/keyed_service.h"
+#include "components/paint_preview/browser/file_manager.h"
+
+namespace paint_preview {
+
+class PaintPreviewFileMixin {
+ public:
+  enum class ProtoReadStatus : int {
+    kOk = 0,
+    kNoProto,
+    kDeserializationError,
+    kExpired,
+  };
+
+  using OnReadProtoCallback =
+      base::OnceCallback<void(ProtoReadStatus,
+                              std::unique_ptr<PaintPreviewProto>)>;
+
+  // Creates an instance for a profile. FileManager's root directory will be set
+  // to |profile_dir|/paint_preview/|ascii_feature_name|.
+  PaintPreviewFileMixin(const base::FilePath& profile_dir,
+                        base::StringPiece ascii_feature_name);
+  PaintPreviewFileMixin(const PaintPreviewFileMixin&) = delete;
+  PaintPreviewFileMixin& operator=(const PaintPreviewFileMixin&) = delete;
+  virtual ~PaintPreviewFileMixin();
+
+  // Returns the file manager for the directory associated with the profile.
+  scoped_refptr<FileManager> GetFileManager() { return file_manager_; }
+
+  // Returns the task runner that IO tasks should be scheduled on.
+  scoped_refptr<base::SequencedTaskRunner> GetTaskRunner() {
+    return task_runner_;
+  }
+
+  // Acquires the PaintPreviewProto that is associated with |key| and sends it
+  // to |on_read_proto_callback|. The default implementation attempts to invoke
+  // GetFileManager()->DeserializePaintPreviewProto(). If |expiry_horizon| is
+  // provided a proto that was last modified earlier than 'now - expiry_horizon'
+  // will return the kExpired status.
+  virtual void GetCapturedPaintPreviewProto(
+      const DirectoryKey& key,
+      base::Optional<base::TimeDelta> expiry_horizon,
+      OnReadProtoCallback on_read_proto_callback);
+
+ private:
+  scoped_refptr<base::SequencedTaskRunner> task_runner_;
+  scoped_refptr<FileManager> file_manager_;
+};
+
+}  // namespace paint_preview
+
+#endif  // COMPONENTS_PAINT_PREVIEW_BROWSER_PAINT_PREVIEW_FILE_HELPER_H_
diff --git a/components/paint_preview/player/android/javatests/paint_preview_test_service.cc b/components/paint_preview/player/android/javatests/paint_preview_test_service.cc
index 317e353..f58536ad 100644
--- a/components/paint_preview/player/android/javatests/paint_preview_test_service.cc
+++ b/components/paint_preview/player/android/javatests/paint_preview_test_service.cc
@@ -5,6 +5,7 @@
 #include "components/paint_preview/player/android/javatests/paint_preview_test_service.h"
 
 #include <memory>
+#include <utility>
 
 #include "base/android/jni_android.h"
 #include "base/android/jni_array.h"
@@ -107,10 +108,10 @@
 }
 
 PaintPreviewTestService::PaintPreviewTestService(const base::FilePath& path)
-    : PaintPreviewBaseService(path,
-                              kTestDirName,
-                              std::make_unique<TestPaintPreviewPolicy>(),
-                              false),
+    : PaintPreviewBaseService(
+          std::make_unique<PaintPreviewFileMixin>(path, kTestDirName),
+          std::make_unique<TestPaintPreviewPolicy>(),
+          false),
       test_data_dir_(
           path.AppendASCII(kPaintPreviewDir).AppendASCII(kTestDirName)) {}
 
diff --git a/components/paint_preview/player/player_compositor_delegate.cc b/components/paint_preview/player/player_compositor_delegate.cc
index 5d65357..600346d3 100644
--- a/components/paint_preview/player/player_compositor_delegate.cc
+++ b/components/paint_preview/player/player_compositor_delegate.cc
@@ -105,10 +105,11 @@
 
 PlayerCompositorDelegate::~PlayerCompositorDelegate() {
   if (compress_on_close_ && paint_preview_service_) {
-    paint_preview_service_->GetTaskRunner()->PostTask(
+    paint_preview_service_->GetFileMixin()->GetTaskRunner()->PostTask(
         FROM_HERE,
         base::BindOnce(base::IgnoreResult(&FileManager::CompressDirectory),
-                       paint_preview_service_->GetFileManager(), key_));
+                       paint_preview_service_->GetFileMixin()->GetFileManager(),
+                       key_));
   }
 }
 
@@ -313,7 +314,7 @@
   TRACE_EVENT_NESTABLE_ASYNC_END0("paint_preview",
                                   "PlayerCompositorDelegate CreateCompositor",
                                   TRACE_ID_LOCAL(this));
-  paint_preview_service_->GetCapturedPaintPreviewProto(
+  paint_preview_service_->GetFileMixin()->GetCapturedPaintPreviewProto(
       key, base::nullopt,
       base::BindOnce(&PlayerCompositorDelegate::OnProtoAvailable,
                      weak_factory_.GetWeakPtr(), expected_url));
@@ -321,20 +322,20 @@
 
 void PlayerCompositorDelegate::OnProtoAvailable(
     const GURL& expected_url,
-    PaintPreviewBaseService::ProtoReadStatus proto_status,
+    PaintPreviewFileMixin::ProtoReadStatus proto_status,
     std::unique_ptr<PaintPreviewProto> proto) {
-  if (proto_status == PaintPreviewBaseService::ProtoReadStatus::kExpired) {
+  if (proto_status == PaintPreviewFileMixin::ProtoReadStatus::kExpired) {
     OnCompositorReady(CompositorStatus::CAPTURE_EXPIRED, nullptr);
     return;
   }
 
-  if (proto_status == PaintPreviewBaseService::ProtoReadStatus::kNoProto) {
+  if (proto_status == PaintPreviewFileMixin::ProtoReadStatus::kNoProto) {
     OnCompositorReady(CompositorStatus::NO_CAPTURE, nullptr);
     return;
   }
 
   if (proto_status ==
-          PaintPreviewBaseService::ProtoReadStatus::kDeserializationError ||
+          PaintPreviewFileMixin::ProtoReadStatus::kDeserializationError ||
       !proto || !proto->IsInitialized()) {
     OnCompositorReady(CompositorStatus::PROTOBUF_DESERIALIZATION_ERROR,
                       nullptr);
diff --git a/components/paint_preview/player/player_compositor_delegate.h b/components/paint_preview/player/player_compositor_delegate.h
index f08c6272..0c05901 100644
--- a/components/paint_preview/player/player_compositor_delegate.h
+++ b/components/paint_preview/player/player_compositor_delegate.h
@@ -141,7 +141,7 @@
   void OnCompositorTimeout();
 
   void OnProtoAvailable(const GURL& expected_url,
-                        PaintPreviewBaseService::ProtoReadStatus proto_status,
+                        PaintPreviewFileMixin::ProtoReadStatus proto_status,
                         std::unique_ptr<PaintPreviewProto> proto);
 
   void SendCompositeRequest(
diff --git a/components/paint_preview/player/player_compositor_delegate_unittest.cc b/components/paint_preview/player/player_compositor_delegate_unittest.cc
index e2728a0..f7a85d45 100644
--- a/components/paint_preview/player/player_compositor_delegate_unittest.cc
+++ b/components/paint_preview/player/player_compositor_delegate_unittest.cc
@@ -220,7 +220,8 @@
   void SetUp() override {
     ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
     service_ = std::make_unique<PaintPreviewBaseService>(
-        temp_dir.GetPath(), "test", nullptr, false);
+        std::make_unique<PaintPreviewFileMixin>(temp_dir.GetPath(), "test"),
+        nullptr, false);
   }
 
   PaintPreviewBaseService* GetBaseService() { return service_.get(); }
@@ -251,7 +252,7 @@
 
   void SerializeProtoAndCreateRootSkp(PaintPreviewProto* proto,
                                       const DirectoryKey& key) {
-    auto file_manager = GetBaseService()->GetFileManager();
+    auto file_manager = GetBaseService()->GetFileMixin()->GetFileManager();
     base::RunLoop loop;
     file_manager->GetTaskRunner()->PostTask(
         FROM_HERE,
@@ -283,7 +284,7 @@
 
 TEST_F(PlayerCompositorDelegateTest, OnClick) {
   auto* service = GetBaseService();
-  auto file_manager = service->GetFileManager();
+  auto file_manager = service->GetFileMixin()->GetFileManager();
   auto key = file_manager->CreateKey(1U);
 
   GURL url("www.example.com");
@@ -371,7 +372,7 @@
 
 TEST_F(PlayerCompositorDelegateTest, BadProto) {
   auto* service = GetBaseService();
-  auto file_manager = service->GetFileManager();
+  auto file_manager = service->GetFileMixin()->GetFileManager();
   auto key = file_manager->CreateKey(1U);
   base::RunLoop loop;
   file_manager->GetTaskRunner()->PostTask(
@@ -401,7 +402,7 @@
 
 TEST_F(PlayerCompositorDelegateTest, OldVersion) {
   auto* service = GetBaseService();
-  auto file_manager = service->GetFileManager();
+  auto file_manager = service->GetFileMixin()->GetFileManager();
   auto key = file_manager->CreateKey(1U);
   GURL url("https://www.chromium.org/");
   auto proto = CreateValidProto(url);
@@ -422,7 +423,7 @@
 
 TEST_F(PlayerCompositorDelegateTest, URLMismatch) {
   auto* service = GetBaseService();
-  auto file_manager = service->GetFileManager();
+  auto file_manager = service->GetFileMixin()->GetFileManager();
   auto key = file_manager->CreateKey(1U);
   GURL url("https://www.chromium.org/");
   auto proto = CreateValidProto(url);
@@ -442,7 +443,7 @@
 
 TEST_F(PlayerCompositorDelegateTest, ServiceDisconnect) {
   auto* service = GetBaseService();
-  auto file_manager = service->GetFileManager();
+  auto file_manager = service->GetFileMixin()->GetFileManager();
   auto key = file_manager->CreateKey(1U);
   GURL url("https://www.chromium.org/");
   auto proto = CreateValidProto(url);
@@ -474,7 +475,7 @@
 
 TEST_F(PlayerCompositorDelegateTest, ClientDisconnect) {
   auto* service = GetBaseService();
-  auto file_manager = service->GetFileManager();
+  auto file_manager = service->GetFileMixin()->GetFileManager();
   auto key = file_manager->CreateKey(1U);
   GURL url("https://www.chromium.org/");
   auto proto = CreateValidProto(url);
@@ -505,7 +506,7 @@
 
 TEST_F(PlayerCompositorDelegateTest, InvalidCompositeRequest) {
   auto* service = GetBaseService();
-  auto file_manager = service->GetFileManager();
+  auto file_manager = service->GetFileMixin()->GetFileManager();
   auto key = file_manager->CreateKey(1U);
   GURL url("https://www.chromium.org/");
   auto proto = CreateValidProto(url);
@@ -536,7 +537,7 @@
 
 TEST_F(PlayerCompositorDelegateTest, CompositorDeserializationError) {
   auto* service = GetBaseService();
-  auto file_manager = service->GetFileManager();
+  auto file_manager = service->GetFileMixin()->GetFileManager();
   auto key = file_manager->CreateKey(1U);
   GURL url("https://www.chromium.org/");
   auto proto = CreateValidProto(url);
@@ -560,7 +561,7 @@
 
 TEST_F(PlayerCompositorDelegateTest, InvalidRootSkp) {
   auto* service = GetBaseService();
-  auto file_manager = service->GetFileManager();
+  auto file_manager = service->GetFileMixin()->GetFileManager();
   auto key = file_manager->CreateKey(1U);
   GURL url("https://www.chromium.org/");
   auto proto = CreateValidProto(url);
@@ -584,7 +585,7 @@
 
 TEST_F(PlayerCompositorDelegateTest, CompressOnClose) {
   auto* service = GetBaseService();
-  auto file_manager = service->GetFileManager();
+  auto file_manager = service->GetFileMixin()->GetFileManager();
   auto key = file_manager->CreateKey(1U);
   base::FilePath dir;
   file_manager->GetTaskRunner()->PostTaskAndReplyWithResult(
@@ -616,7 +617,7 @@
 
 TEST_F(PlayerCompositorDelegateTest, RequestBitmapWithCancel) {
   auto* service = GetBaseService();
-  auto file_manager = service->GetFileManager();
+  auto file_manager = service->GetFileMixin()->GetFileManager();
   auto key = file_manager->CreateKey(1U);
   {
     // This test skips setting up files as the fakes don't use them. In normal
@@ -687,7 +688,7 @@
 
 TEST_F(PlayerCompositorDelegateTest, RequestBitmapWithCancelAll) {
   auto* service = GetBaseService();
-  auto file_manager = service->GetFileManager();
+  auto file_manager = service->GetFileMixin()->GetFileManager();
   auto key = file_manager->CreateKey(1U);
   {
     // This test skips setting up files as the fakes don't use them. In normal
@@ -739,7 +740,7 @@
 
 TEST_F(PlayerCompositorDelegateTest, RequestBitmapSuccessQueued) {
   auto* service = GetBaseService();
-  auto file_manager = service->GetFileManager();
+  auto file_manager = service->GetFileMixin()->GetFileManager();
   auto key = file_manager->CreateKey(1U);
   {
     // This test skips setting up files as the fakes don't use them. In normal
@@ -772,7 +773,7 @@
 
 TEST_F(PlayerCompositorDelegateTest, Timeout) {
   auto* service = GetBaseService();
-  auto file_manager = service->GetFileManager();
+  auto file_manager = service->GetFileMixin()->GetFileManager();
   auto key = file_manager->CreateKey(1U);
   {
     PlayerCompositorDelegateImpl player_compositor_delegate;
@@ -798,7 +799,7 @@
 
 TEST_F(PlayerCompositorDelegateTest, CriticalMemoryPressure) {
   auto* service = GetBaseService();
-  auto file_manager = service->GetFileManager();
+  auto file_manager = service->GetFileMixin()->GetFileManager();
   auto key = file_manager->CreateKey(1U);
   {
     // This test skips setting up files as the fakes don't use them. In normal
@@ -831,7 +832,7 @@
 
 TEST_F(PlayerCompositorDelegateTest, CriticalMemoryPressureBeforeStart) {
   auto* service = GetBaseService();
-  auto file_manager = service->GetFileManager();
+  auto file_manager = service->GetFileMixin()->GetFileManager();
   auto key = file_manager->CreateKey(1U);
   {
     // This test skips setting up files as the fakes don't use them. In normal
diff --git a/components/payments/DIR_METADATA b/components/payments/DIR_METADATA
new file mode 100644
index 0000000..667a28bf
--- /dev/null
+++ b/components/payments/DIR_METADATA
@@ -0,0 +1,4 @@
+monorail {
+  component: "Blink>Payments"
+}
+team_email: "payments-dev@chromium.org"
\ No newline at end of file
diff --git a/components/payments/OWNERS b/components/payments/OWNERS
index e43c518..1dbaa6ad 100644
--- a/components/payments/OWNERS
+++ b/components/payments/OWNERS
@@ -1,5 +1,3 @@
-# TEAM: payments-dev@chromium.org
-# COMPONENT: Blink>Payments
 
 rouslan@chromium.org
 danyao@chromium.org
@@ -8,4 +6,4 @@
 nburris@chromium.org
 
 # Emeritus
-gogerald@chromium.org
+gogerald@chromium.org
\ No newline at end of file
diff --git a/components/payments/content/android/BUILD.gn b/components/payments/content/android/BUILD.gn
index fd453cf..283150e3 100644
--- a/components/payments/content/android/BUILD.gn
+++ b/components/payments/content/android/BUILD.gn
@@ -105,9 +105,7 @@
   ]
 }
 
-# TODO(crbug.com/1126301): Rename this back to "java" once references in //clank
-# are updated.
-android_library("all_java") {
+android_library("java") {
   annotation_processor_deps = [ "//base/android/jni_generator:jni_processor" ]
   sources = [
     "java/src/org/chromium/components/payments/BasicCardUtils.java",
@@ -176,13 +174,6 @@
   resources_package = "org.chromium.components.payments"
 }
 
-java_group("java") {
-  deps = [
-    ":all_java",
-    ":service_java",
-  ]
-}
-
 android_aidl("payment_details_update_service_aidl") {
   interface_file = "java/src/org/chromium/components/payments/payment_details_update_service.aidl"
   sources = [
diff --git a/components/payments/content/android/DIR_METADATA b/components/payments/content/android/DIR_METADATA
new file mode 100644
index 0000000..a012b93
--- /dev/null
+++ b/components/payments/content/android/DIR_METADATA
@@ -0,0 +1 @@
+os: ANDROID
\ No newline at end of file
diff --git a/components/payments/content/android/currency_formatter_android.cc b/components/payments/content/android/currency_formatter_android.cc
index 4572f0c..e0e2201a 100644
--- a/components/payments/content/android/currency_formatter_android.cc
+++ b/components/payments/content/android/currency_formatter_android.cc
@@ -34,6 +34,12 @@
   delete this;
 }
 
+void CurrencyFormatterAndroid::SetMaxFractionalDigits(
+    JNIEnv* env,
+    jint jmax_fractional_digits) {
+  currency_formatter_->SetMaxFractionalDigits(jmax_fractional_digits);
+}
+
 base::android::ScopedJavaLocalRef<jstring> CurrencyFormatterAndroid::Format(
     JNIEnv* env,
     const JavaParamRef<jobject>& jcaller,
diff --git a/components/payments/content/android/currency_formatter_android.h b/components/payments/content/android/currency_formatter_android.h
index 76b1577..1fe5173 100644
--- a/components/payments/content/android/currency_formatter_android.h
+++ b/components/payments/content/android/currency_formatter_android.h
@@ -29,6 +29,9 @@
   void Destroy(JNIEnv* env,
                const base::android::JavaParamRef<jobject>& jcaller);
 
+  // Set the maximum number of fractional digits.
+  void SetMaxFractionalDigits(JNIEnv* env, jint jnum_fractional_digits);
+
   // Refer to CurrencyFormatter::Format documentation.
   base::android::ScopedJavaLocalRef<jstring> Format(
       JNIEnv* env,
diff --git a/components/payments/content/android/java/src/org/chromium/components/payments/CurrencyFormatter.java b/components/payments/content/android/java/src/org/chromium/components/payments/CurrencyFormatter.java
index 779d856..d4eb2bc 100644
--- a/components/payments/content/android/java/src/org/chromium/components/payments/CurrencyFormatter.java
+++ b/components/payments/content/android/java/src/org/chromium/components/payments/CurrencyFormatter.java
@@ -46,6 +46,15 @@
         }
     }
 
+    /**
+     * Set the maximum number of fractional digits in the formatted price.
+     * @param maxFractionalDigits maximum number of fractional digits
+     */
+    public void setMaximumFractionalDigits(int maxFractionalDigits) {
+        CurrencyFormatterJni.get().setMaxFractionalDigits(
+                mCurrencyFormatterAndroid, maxFractionalDigits);
+    }
+
     /** @return The currency code formatted for display. */
     public String getFormattedCurrencyCode() {
         return CurrencyFormatterJni.get().getFormattedCurrencyCode(
@@ -76,6 +85,7 @@
         void destroy(long nativeCurrencyFormatterAndroid, CurrencyFormatter caller);
         String format(
                 long nativeCurrencyFormatterAndroid, CurrencyFormatter caller, String amountValue);
+        void setMaxFractionalDigits(long nativeCurrencyFormatterAndroid, int maxFractionalDigits);
         String getFormattedCurrencyCode(
                 long nativeCurrencyFormatterAndroid, CurrencyFormatter caller);
     }
diff --git a/components/payments/content/android/java/src/org/chromium/components/payments/OWNERS b/components/payments/content/android/java/src/org/chromium/components/payments/OWNERS
index 0ccaf06..305b5e8 100644
--- a/components/payments/content/android/java/src/org/chromium/components/payments/OWNERS
+++ b/components/payments/content/android/java/src/org/chromium/components/payments/OWNERS
@@ -1,4 +1,3 @@
-# OS: Android
 
 file://components/payments/OWNERS
 
@@ -6,4 +5,4 @@
 per-file *TypeConverter*.*=file://ipc/SECURITY_OWNERS
 
 per-file *.aidl=set noparent
-per-file *.aidl=file://ipc/SECURITY_OWNERS
+per-file *.aidl=file://ipc/SECURITY_OWNERS
\ No newline at end of file
diff --git a/components/payments/content/android/java/src/org/chromium/components/payments/intent/OWNERS b/components/payments/content/android/java/src/org/chromium/components/payments/intent/OWNERS
index 901b801b..02824e0d 100644
--- a/components/payments/content/android/java/src/org/chromium/components/payments/intent/OWNERS
+++ b/components/payments/content/android/java/src/org/chromium/components/payments/intent/OWNERS
@@ -1,6 +1,5 @@
-# OS: Android
 
 file://components/payments/OWNERS
 
 per-file *TypeConverter*.*=set noparent
-per-file *TypeConverter*.*=file://ipc/SECURITY_OWNERS
+per-file *TypeConverter*.*=file://ipc/SECURITY_OWNERS
\ No newline at end of file
diff --git a/components/payments/core/currency_formatter.cc b/components/payments/core/currency_formatter.cc
index df23c63..68dc6c962 100644
--- a/components/payments/core/currency_formatter.cc
+++ b/components/payments/core/currency_formatter.cc
@@ -85,6 +85,10 @@
 
 CurrencyFormatter::~CurrencyFormatter() {}
 
+void CurrencyFormatter::SetMaxFractionalDigits(const int maxFractionalDigits) {
+  icu_formatter_->setMaximumFractionDigits(maxFractionalDigits);
+}
+
 base::string16 CurrencyFormatter::Format(const std::string& amount) {
   // It's possible that the ICU formatter didn't initialize properly.
   if (!icu_formatter_ || !icu_formatter_->getCurrency())
diff --git a/components/payments/core/currency_formatter.h b/components/payments/core/currency_formatter.h
index 26443e1..4352ffcf 100644
--- a/components/payments/core/currency_formatter.h
+++ b/components/payments/core/currency_formatter.h
@@ -27,6 +27,10 @@
                     const std::string& locale_name);
   ~CurrencyFormatter();
 
+  // Set the maximum number of fractional digits. (kMaximumNumFractionalDigits
+  // is the default if unset)
+  void SetMaxFractionalDigits(const int maxFractionalDigits);
+
   // Formats the |amount| according to the currency code that was set. The
   // result will NOT contain the currency code, nor a subset of it. Rather, the
   // caller of this function should display the currency code separately. The
diff --git a/components/permissions/DIR_METADATA b/components/permissions/DIR_METADATA
new file mode 100644
index 0000000..b1e8e6f3
--- /dev/null
+++ b/components/permissions/DIR_METADATA
@@ -0,0 +1,5 @@
+monorail {
+  component: "Internals>Permissions"
+}
+
+team_email: "permissions-dev@chromium.org"
diff --git a/components/permissions/OWNERS b/components/permissions/OWNERS
index 8aacb4a..cebe287 100644
--- a/components/permissions/OWNERS
+++ b/components/permissions/OWNERS
@@ -1,4 +1 @@
 file://components/permissions/PERMISSIONS_OWNERS
-
-# COMPONENT: Internals>Permissions
-# TEAM: permissions-dev@chromium.org
diff --git a/components/permissions/contexts/DIR_METADATA b/components/permissions/contexts/DIR_METADATA
new file mode 100644
index 0000000..b1e8e6f3
--- /dev/null
+++ b/components/permissions/contexts/DIR_METADATA
@@ -0,0 +1,5 @@
+monorail {
+  component: "Internals>Permissions"
+}
+
+team_email: "permissions-dev@chromium.org"
diff --git a/components/permissions/contexts/OWNERS b/components/permissions/contexts/OWNERS
index 4862047c..399f2b60 100644
--- a/components/permissions/contexts/OWNERS
+++ b/components/permissions/contexts/OWNERS
@@ -1,6 +1,3 @@
 file://components/permissions/PERMISSIONS_OWNERS
 
 per-file *webxr_permission_context*=file://content/browser/xr/OWNERS
-
-# COMPONENT: Internals>Permissions
-# TEAM: permissions-dev@chromium.org
diff --git a/components/permissions_strings_grdp/DIR_METADATA b/components/permissions_strings_grdp/DIR_METADATA
new file mode 100644
index 0000000..b1e8e6f3
--- /dev/null
+++ b/components/permissions_strings_grdp/DIR_METADATA
@@ -0,0 +1,5 @@
+monorail {
+  component: "Internals>Permissions"
+}
+
+team_email: "permissions-dev@chromium.org"
diff --git a/components/permissions_strings_grdp/OWNERS b/components/permissions_strings_grdp/OWNERS
index f9bdac2..d5ec220 100644
--- a/components/permissions_strings_grdp/OWNERS
+++ b/components/permissions_strings_grdp/OWNERS
@@ -1,4 +1 @@
 file://components/permissions/OWNERS
-
-# COMPONENT: Internals>Permissions
-# TEAM: permissions-dev@chromium.org
diff --git a/components/policy/DIR_METADATA b/components/policy/DIR_METADATA
new file mode 100644
index 0000000..ccb8f65
--- /dev/null
+++ b/components/policy/DIR_METADATA
@@ -0,0 +1,5 @@
+monorail {
+  component: "Enterprise>CloudPolicy"
+}
+
+team_email: "chromium-reviews@chromium.org"
diff --git a/components/policy/OWNERS b/components/policy/OWNERS
index 34eceee..12241eda 100644
--- a/components/policy/OWNERS
+++ b/components/policy/OWNERS
@@ -7,6 +7,3 @@
 poromov@chromium.org
 rsorokin@chromium.org
 zmin@chromium.org
-
-# COMPONENT: Enterprise>CloudPolicy
-# TEAM: chromium-reviews@chromium.org
diff --git a/components/policy/resources/DIR_METADATA b/components/policy/resources/DIR_METADATA
new file mode 100644
index 0000000..3ecb477
--- /dev/null
+++ b/components/policy/resources/DIR_METADATA
@@ -0,0 +1,3 @@
+monorail {
+  component: "Enterprise"
+}
diff --git a/components/policy/resources/OWNERS b/components/policy/resources/OWNERS
index b385031..6ded454 100644
--- a/components/policy/resources/OWNERS
+++ b/components/policy/resources/OWNERS
@@ -7,5 +7,3 @@
 # https://sites.google.com/a/chromium.org/dev/developers/how-tos/enterprise/adding-new-policies
 per-file policy_templates.json=set noparent
 per-file policy_templates.json=file://components/policy/resources/ENTERPRISE_POLICY_OWNERS
-
-# COMPONENT: Enterprise
diff --git a/components/policy/tools/DIR_METADATA b/components/policy/tools/DIR_METADATA
new file mode 100644
index 0000000..3ecb477
--- /dev/null
+++ b/components/policy/tools/DIR_METADATA
@@ -0,0 +1,3 @@
+monorail {
+  component: "Enterprise"
+}
diff --git a/components/policy/tools/OWNERS b/components/policy/tools/OWNERS
index d845e1f..1949419 100644
--- a/components/policy/tools/OWNERS
+++ b/components/policy/tools/OWNERS
@@ -1,4 +1,2 @@
 hendrich@chromium.org
 ydago@chromium.org
-
-# COMPONENT: Enterprise
diff --git a/components/policy/tools/template_writers/writers/ios_app_config_writer.py b/components/policy/tools/template_writers/writers/ios_app_config_writer.py
index 2018c7aa..016e621 100755
--- a/components/policy/tools/template_writers/writers/ios_app_config_writer.py
+++ b/components/policy/tools/template_writers/writers/ios_app_config_writer.py
@@ -4,6 +4,7 @@
 # found in the LICENSE file.
 
 from xml.dom import minidom
+import json
 from writers import xml_formatted_writer
 
 
@@ -19,6 +20,79 @@
   '''Simple writer that writes app_config.xml files.
   '''
 
+  def _WritePolicyPresentation(self, policy, field_group):
+    element_type = self.policy_type_to_input_type[policy['type']]
+    if element_type:
+      attributes = {'type': element_type, 'keyName': policy['name']}
+      field = self.AddElement(field_group, 'field', attributes)
+      self._AddLocalizedElement(field, 'label', policy['caption'])
+      self._AddLocalizedElement(field, 'description', policy['desc'])
+
+      if 'enum' in policy['type']:
+        options = self.AddElement(field, 'options', {})
+        for item in policy['items']:
+          self._AddLocalizedElement(options, 'option', str(item['caption']),
+                                    {'value': str(item['value'])})
+
+  def _AddLocalizedElement(self,
+                           parent,
+                           element_type,
+                           text,
+                           attributes={},
+                           localization={'value': 'en-US'}):
+    item = self.AddElement(parent, element_type, attributes)
+    localized = self.AddElement(item, 'language', localization)
+    self.AddText(localized, text)
+
+  def _WritePresentation(self, policy_list):
+    groups = [policy for policy in policy_list if policy['type'] == 'group']
+    policies_without_group = [
+        policy for policy in policy_list if policy['type'] != 'group'
+    ]
+    for policy in groups:
+      child_policies = self._GetPoliciesForWriter(policy)
+      if child_policies:
+        field_group = self.AddElement(self._presentation, 'fieldGroup', {})
+        self._AddLocalizedElement(field_group, 'name', policy['caption'])
+        for child_policy in child_policies:
+          self._WritePolicyPresentation(child_policy, field_group)
+    for policy in self._GetPoliciesForWriter(
+        {'policies': policies_without_group}):
+      self._WritePolicyPresentation(policy, self._presentation)
+
+  def _WritePolicyDefaultValue(self, parent, policy):
+    if 'default' in policy:
+      default_value = self.AddElement(parent, 'defaultValue', {})
+      value = self.AddElement(default_value, 'value', {})
+      if policy['type'] == 'main':
+        if policy['default'] == True:
+          self.AddText(value, 'true')
+        elif policy['default'] == False:
+          self.AddText(value, 'false')
+      elif policy['type'] in ['list', 'string-enum-list']:
+        for v in policy['default']:
+          if value == None:
+            value = self.AddElement(default_value, 'value', {})
+          self.AddText(value, v)
+        value = None
+      else:
+        self.AddText(value, policy['default'])
+
+  def _WritePolicyConstraint(self, parent, policy):
+    attrs = {'nullable': 'true'}
+    if 'schema' in policy:
+      if 'minimum' in policy['schema']:
+        attrs['min'] = policy['schema']['minimum']
+      if 'maximum' in policy['schema']:
+        attrs['max'] = policy['schema']['maximum']
+
+    constraint = self.AddElement(parent, 'constraint', attrs)
+    if 'enum' in policy['type']:
+      values_element = self.AddElement(constraint, 'values', {})
+      for v in policy['schema']['enum']:
+        value = self.AddElement(values_element, 'value', {})
+        self.AddText(value, str(v))
+
   def IsFuturePolicySupported(self, policy):
     # For now, include all future policies in appconfig.xml.
     return True
@@ -28,6 +102,18 @@
     return dom_impl.createDocument('http://www.w3.org/2001/XMLSchema-instance',
                                    'managedAppConfiguration', None)
 
+  def WriteTemplate(self, template):
+    self.messages = template['messages']
+    self.Init()
+    template['policy_definitions'] = \
+        self.PreprocessPolicies(template['policy_definitions'])
+    self.BeginTemplate()
+    self.WritePolicies(template['policy_definitions'])
+    self._WritePresentation(template['policy_definitions'])
+    self.EndTemplate()
+
+    return self.GetTemplateText()
+
   def BeginTemplate(self):
     self._app_config.attributes[
         'xmlns:xsi'] = 'http://www.w3.org/2001/XMLSchema-instance'
@@ -36,11 +122,14 @@
         'xsi:noNamespaceSchemaLocation'] = schema_location
 
     version = self.AddElement(self._app_config, 'version', {})
-    self.AddText(version, self.config['version'])
+    milestone = self.config['version'].split(".", 1)[0]
+    self.AddText(version, milestone)
 
     bundle_id = self.AddElement(self._app_config, 'bundleId', {})
     self.AddText(bundle_id, self.config['bundle_id'])
     self._policies = self.AddElement(self._app_config, 'dict', {})
+    self._presentation = self.AddElement(self._app_config, 'presentation',
+                                         {'defaultLocale': 'en-US'})
 
   def WritePolicy(self, policy):
     element_type = self.policy_type_to_xml_tag[policy['type']]
@@ -51,7 +140,9 @@
         for config in policy['future_on']:
           if config['platform'] == 'ios':
             attributes['future'] = 'true'
-      self.AddElement(self._policies, element_type, attributes)
+      policy_element = self.AddElement(self._policies, element_type, attributes)
+      self._WritePolicyDefaultValue(policy_element, policy)
+      self._WritePolicyConstraint(policy_element, policy)
 
   def Init(self):
     self._doc = self.CreateDocument()
@@ -66,6 +157,16 @@
         'list': 'stringArray',
         'dict': 'string',
     }
+    self.policy_type_to_input_type = {
+        'string': 'input',
+        'int': 'input',
+        'int-enum': 'select',
+        'string-enum': 'select',
+        'string-enum-list': 'multiselect',
+        'main': 'checkbox',
+        'list': 'list',
+        'dict': 'input'
+    }
 
   def GetTemplateText(self):
     return self.ToPrettyXml(self._doc)
diff --git a/components/policy/tools/template_writers/writers/ios_app_config_writer_unittest.py b/components/policy/tools/template_writers/writers/ios_app_config_writer_unittest.py
index c652d7f..848f193 100755
--- a/components/policy/tools/template_writers/writers/ios_app_config_writer_unittest.py
+++ b/components/policy/tools/template_writers/writers/ios_app_config_writer_unittest.py
@@ -8,6 +8,7 @@
 if __name__ == '__main__':
   sys.path.append(os.path.join(os.path.dirname(__file__), '../../../..'))
 
+import json
 import unittest
 
 from writers import writer_unittest_common
@@ -16,52 +17,56 @@
 class IOSAppConfigWriterUnitTests(writer_unittest_common.WriterUnittestCommon):
   '''Unit tests for IOSAppConfigWriter.'''
 
-  def _GetTestPolicyTemplate(self, policy_name, policy_type, future=False):
-    supported_or_future = ''
-    if future:
-      supported_or_future = ''''future_on':['ios']'''
-    else:
-      supported_or_future = ''''supported_on':['ios:80-']'''
-
+  def _GetTestPolicyTemplate(self, policy_definitions):
     return '''
 {
-  'policy_definitions': [
-    {
-      'name': '%s',
-      'type': '%s',
-      %s,
-      'caption': '',
-      'desc': '',
-      'items': [{
-        'name': '',
-          'value': 1,
-          'caption': '',
-        }]
-    },
-  ],
+  'policy_definitions': %s,
   'policy_atomic_group_definitions': [],
   'placeholders': [],
   'messages': {},
 }
-''' % (policy_name, policy_type, supported_or_future)
+''' % (policy_definitions)
 
-  def _GetExpectedOutput(self, version, tag):
-    if tag:
-      policies = '<dict>\n    %s\n  </dict>' % tag
+  def _GetExpectedOutput(self, version, policy_definition, policy_presentation):
+    if policy_definition:
+      definition = '<dict>\n    %s\n  </dict>' % policy_definition
     else:
-      policies = '<dict/>'
+      definition = '<dict/>'
+    if policy_presentation:
+      presentation = '<presentation defaultLocale="en-US">\n    %s\n  </presentation>' % policy_presentation
+    else:
+      presentation = '<presentation defaultLocale="en-US"/>'
 
     return '''<?xml version="1.0" ?>
 <managedAppConfiguration xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="/com.google.chrome.ios/appconfig/appconfig.xsd">
   <version>%s</version>
   <bundleId>com.google.chrome.ios</bundleId>
   %s
-</managedAppConfiguration>''' % (version, policies)
+  %s
+</managedAppConfiguration>''' % (version, definition, presentation)
 
   def testStringPolicy(self):
-    policy_json = self._GetTestPolicyTemplate('StringPolicy', 'string')
-    expected = self._GetExpectedOutput('83.0.4089.0',
-                                       '<string keyName="StringPolicy"/>')
+    policy_definition = json.dumps([{
+        'name': 'string policy',
+        'type': 'string',
+        'supported_on': ['ios:80-'],
+        'caption': 'string caption',
+        'desc': 'string description'
+    }])
+    policy_json = self._GetTestPolicyTemplate(policy_definition)
+    expected_configuration = '''<string keyName="string policy">
+      <constraint nullable="true"/>
+    </string>'''
+    expected_presentation = '''<field keyName="string policy" type="input">
+      <label>
+        <language value="en-US">string caption</language>
+      </label>
+      <description>
+        <language value="en-US">string description</language>
+      </description>
+    </field>'''
+    expected = self._GetExpectedOutput('83', expected_configuration,
+                                       expected_presentation)
     output = self.GetOutput(policy_json, {
         '_google_chrome': '1',
         'version': '83.0.4089.0'
@@ -69,9 +74,27 @@
     self.assertEquals(output.strip(), expected.strip())
 
   def testIntPolicy(self):
-    policy_json = self._GetTestPolicyTemplate('IntPolicy', 'int')
-    expected = self._GetExpectedOutput('83.0.4089.0',
-                                       '<integer keyName="IntPolicy"/>')
+    policy_definition = json.dumps([{
+        'name': 'IntPolicy',
+        'type': 'int',
+        'supported_on': ['ios:80-'],
+        'caption': 'int caption',
+        'desc': 'int description'
+    }])
+    policy_json = self._GetTestPolicyTemplate(policy_definition)
+    expected_configuration = '''<integer keyName="IntPolicy">
+      <constraint nullable="true"/>
+    </integer>'''
+    expected_presentation = '''<field keyName="IntPolicy" type="input">
+      <label>
+        <language value="en-US">int caption</language>
+      </label>
+      <description>
+        <language value="en-US">int description</language>
+      </description>
+    </field>'''
+    expected = self._GetExpectedOutput('83', expected_configuration,
+                                       expected_presentation)
     output = self.GetOutput(policy_json, {
         '_google_chrome': '1',
         'version': '83.0.4089.0'
@@ -79,9 +102,57 @@
     self.assertEquals(output.strip(), expected.strip())
 
   def testIntEnumPolicy(self):
-    policy_json = self._GetTestPolicyTemplate('IntEnumPolicy', 'int-enum')
-    expected = self._GetExpectedOutput('83.0.4089.0',
-                                       '<integer keyName="IntEnumPolicy"/>')
+    policy_definition = json.dumps([{
+        'name':
+        'IntEnumPolicy',
+        'type':
+        'int-enum',
+        'supported_on': ['ios:80-'],
+        'caption':
+        'int-enum caption',
+        'desc':
+        'int-enum description',
+        'schema': {
+          'type': 'integer',
+          'enum': [0, 1],
+        },
+        'items': [{
+            'name': 'item0',
+            'value': 0,
+            'caption': 'item 0',
+        }, {
+            'name': 'item1',
+            'value': 1,
+            'caption': 'item 1',
+        }]
+    }])
+    policy_json = self._GetTestPolicyTemplate(policy_definition)
+    expected_configuration = '''<integer keyName="IntEnumPolicy">
+      <constraint nullable="true">
+        <values>
+          <value>0</value>
+          <value>1</value>
+        </values>
+      </constraint>
+    </integer>'''
+    expected_presentation = '''<field keyName="IntEnumPolicy" type="select">
+      <label>
+        <language value="en-US">int-enum caption</language>
+      </label>
+      <description>
+        <language value="en-US">int-enum description</language>
+      </description>
+      <options>
+        <option value="0">
+          <language value="en-US">item 0</language>
+        </option>
+        <option value="1">
+          <language value="en-US">item 1</language>
+        </option>
+      </options>
+    </field>'''
+    expected = self._GetExpectedOutput('83', expected_configuration,
+                                       expected_presentation)
     output = self.GetOutput(policy_json, {
         '_google_chrome': '1',
         'version': '83.0.4089.0'
@@ -89,9 +160,57 @@
     self.assertEquals(output.strip(), expected.strip())
 
   def testStringEnumPolicy(self):
-    policy_json = self._GetTestPolicyTemplate('StringEnumPolicy', 'string-enum')
-    expected = self._GetExpectedOutput('83.0.4089.0',
-                                       '<string keyName="StringEnumPolicy"/>')
+    policy_definition = json.dumps([{
+        'name':
+        'StringEnumPolicy',
+        'type':
+        'string-enum',
+        'supported_on': ['ios:80-'],
+        'caption':
+        'string-enum caption',
+        'desc':
+        'string-enum description',
+        'schema': {
+          'type': 'string',
+          'enum': ['0', '1'],
+        },
+        'items': [{
+            'name': 'item0',
+            'value': '0',
+            'caption': 'item 0',
+        }, {
+            'name': 'item1',
+            'value': '1',
+            'caption': 'item 1',
+        }]
+    }])
+    policy_json = self._GetTestPolicyTemplate(policy_definition)
+    expected_configuration = '''<string keyName="StringEnumPolicy">
+      <constraint nullable="true">
+        <values>
+          <value>0</value>
+          <value>1</value>
+        </values>
+      </constraint>
+    </string>'''
+    expected_presentation = '''<field keyName="StringEnumPolicy" type="select">
+      <label>
+        <language value="en-US">string-enum caption</language>
+      </label>
+      <description>
+        <language value="en-US">string-enum description</language>
+      </description>
+      <options>
+        <option value="0">
+          <language value="en-US">item 0</language>
+        </option>
+        <option value="1">
+          <language value="en-US">item 1</language>
+        </option>
+      </options>
+    </field>'''
+    expected = self._GetExpectedOutput('83', expected_configuration,
+                                       expected_presentation)
     output = self.GetOutput(policy_json, {
         '_google_chrome': '1',
         'version': '83.0.4089.0'
@@ -99,10 +218,57 @@
     self.assertEquals(output.strip(), expected.strip())
 
   def testStringEnumListPolicy(self):
-    policy_json = self._GetTestPolicyTemplate('StringEnumListPolicy',
-                                              'string-enum-list')
-    expected = self._GetExpectedOutput(
-        '83.0.4089.0', '<stringArray keyName="StringEnumListPolicy"/>')
+    policy_definition = json.dumps([{
+        'name':
+        'StringEnumListPolicy',
+        'type':
+        'string-enum-list',
+        'supported_on': ['ios:80-'],
+        'caption':
+        'string-enum-list caption',
+        'desc':
+        'string-enum-list description',
+        'schema': {
+          'type': 'string',
+          'enum': ['0', '1'],
+        },
+        'items': [{
+            'name': 'item0',
+            'value': '0',
+            'caption': 'item 0',
+        }, {
+            'name': 'item1',
+            'value': '1',
+            'caption': 'item 1',
+        }]
+    }])
+    policy_json = self._GetTestPolicyTemplate(policy_definition)
+    expected_configuration = '''<stringArray keyName="StringEnumListPolicy">
+      <constraint nullable="true">
+        <values>
+          <value>0</value>
+          <value>1</value>
+        </values>
+      </constraint>
+    </stringArray>'''
+    expected_presentation = '''<field keyName="StringEnumListPolicy" type="multiselect">
+      <label>
+        <language value="en-US">string-enum-list caption</language>
+      </label>
+      <description>
+        <language value="en-US">string-enum-list description</language>
+      </description>
+      <options>
+        <option value="0">
+          <language value="en-US">item 0</language>
+        </option>
+        <option value="1">
+          <language value="en-US">item 1</language>
+        </option>
+      </options>
+    </field>'''
+    expected = self._GetExpectedOutput('83', expected_configuration,
+                                       expected_presentation)
     output = self.GetOutput(policy_json, {
         '_google_chrome': '1',
         'version': '83.0.4089.0'
@@ -110,9 +276,27 @@
     self.assertEquals(output.strip(), expected.strip())
 
   def testBooleanPolicy(self):
-    policy_json = self._GetTestPolicyTemplate('BooleanPolicy', 'main')
-    expected = self._GetExpectedOutput('83.0.4089.0',
-                                       '<boolean keyName="BooleanPolicy"/>')
+    policy_definition = json.dumps([{
+        'name': 'BooleanPolicy',
+        'type': 'main',
+        'supported_on': ['ios:80-'],
+        'caption': 'boolean caption',
+        'desc': 'boolean description'
+    }])
+    policy_json = self._GetTestPolicyTemplate(policy_definition)
+    expected_configuration = '''<boolean keyName="BooleanPolicy">
+      <constraint nullable="true"/>
+    </boolean>'''
+    expected_presentation = '''<field keyName="BooleanPolicy" type="checkbox">
+      <label>
+        <language value="en-US">boolean caption</language>
+      </label>
+      <description>
+        <language value="en-US">boolean description</language>
+      </description>
+    </field>'''
+    expected = self._GetExpectedOutput('83', expected_configuration,
+                                       expected_presentation)
     output = self.GetOutput(policy_json, {
         '_google_chrome': '1',
         'version': '83.0.4089.0'
@@ -120,9 +304,27 @@
     self.assertEquals(output.strip(), expected.strip())
 
   def testListPolicy(self):
-    policy_json = self._GetTestPolicyTemplate('ListPolicy', 'list')
-    expected = self._GetExpectedOutput('83.0.4089.0',
-                                       '<stringArray keyName="ListPolicy"/>')
+    policy_definition = json.dumps([{
+        'name': 'ListPolicy',
+        'type': 'list',
+        'supported_on': ['ios:80-'],
+        'caption': 'list caption',
+        'desc': 'list description'
+    }])
+    policy_json = self._GetTestPolicyTemplate(policy_definition)
+    expected_configuration = '''<stringArray keyName="ListPolicy">
+      <constraint nullable="true"/>
+    </stringArray>'''
+    expected_presentation = '''<field keyName="ListPolicy" type="list">
+      <label>
+        <language value="en-US">list caption</language>
+      </label>
+      <description>
+        <language value="en-US">list description</language>
+      </description>
+    </field>'''
+    expected = self._GetExpectedOutput('83', expected_configuration,
+                                       expected_presentation)
     output = self.GetOutput(policy_json, {
         '_google_chrome': '1',
         'version': '83.0.4089.0'
@@ -130,11 +332,29 @@
     self.assertEquals(output.strip(), expected.strip())
 
   def testDictPolicy(self):
-    policy_json = self._GetTestPolicyTemplate('DictPolicy', 'dict')
+    policy_definition = json.dumps([{
+        'name': 'DictPolicy',
+        'type': 'dict',
+        'supported_on': ['ios:80-'],
+        'caption': 'dict caption',
+        'desc': 'dict description'
+    }])
+    policy_json = self._GetTestPolicyTemplate(policy_definition)
     # Dict policies are not supported by the appconfig.xml format, therefore
     # they are treated as JSON strings.
-    expected = self._GetExpectedOutput('83.0.4089.0',
-                                       '<string keyName="DictPolicy"/>')
+    expected_configuration = '''<string keyName="DictPolicy">
+      <constraint nullable="true"/>
+    </string>'''
+    expected_presentation = '''<field keyName="DictPolicy" type="input">
+      <label>
+        <language value="en-US">dict caption</language>
+      </label>
+      <description>
+        <language value="en-US">dict description</language>
+      </description>
+    </field>'''
+    expected = self._GetExpectedOutput('83', expected_configuration,
+                                       expected_presentation)
     output = self.GetOutput(policy_json, {
         '_google_chrome': '1',
         'version': '83.0.4089.0'
@@ -142,11 +362,27 @@
     self.assertEquals(output.strip(), expected.strip())
 
   def testFuturePolicy(self):
-    policy_json = self._GetTestPolicyTemplate('FuturePolicy',
-                                              'string',
-                                              future=True)
-    expected = self._GetExpectedOutput(
-        '83.0.4089.0', '<string future="true" keyName="FuturePolicy"/>')
+    policy_definition = json.dumps([{
+        'name': 'FuturePolicy',
+        'type': 'string',
+        'future_on': ['ios'],
+        'caption': 'string caption',
+        'desc': 'string description'
+    }])
+    policy_json = self._GetTestPolicyTemplate(policy_definition)
+    expected_configuration = '''<string future="true" keyName="FuturePolicy">
+      <constraint nullable="true"/>
+    </string>'''
+    expected_presentation = '''<field keyName="FuturePolicy" type="input">
+      <label>
+        <language value="en-US">string caption</language>
+      </label>
+      <description>
+        <language value="en-US">string description</language>
+      </description>
+    </field>'''
+    expected = self._GetExpectedOutput('83', expected_configuration,
+                                       expected_presentation)
     output = self.GetOutput(policy_json, {
         '_google_chrome': '1',
         'version': '83.0.4089.0'
@@ -154,11 +390,66 @@
     self.assertEquals(output.strip(), expected.strip())
 
   def testNonFuturePolicy(self):
-    policy_json = self._GetTestPolicyTemplate('NonFuturePolicy',
-                                              'string',
-                                              future=False)
-    expected = self._GetExpectedOutput('83.0.4089.0',
-                                       '<string keyName="NonFuturePolicy"/>')
+    policy_definition = json.dumps([{
+        'name': 'NonFuturePolicy',
+        'type': 'string',
+        'supported_on': ['ios:80-'],
+        'caption': 'string caption',
+        'desc': 'string description'
+    }])
+    policy_json = self._GetTestPolicyTemplate(policy_definition)
+    expected_configuration = '''<string keyName="NonFuturePolicy">
+      <constraint nullable="true"/>
+    </string>'''
+    expected_presentation = '''<field keyName="NonFuturePolicy" type="input">
+      <label>
+        <language value="en-US">string caption</language>
+      </label>
+      <description>
+        <language value="en-US">string description</language>
+      </description>
+    </field>'''
+    expected = self._GetExpectedOutput('83', expected_configuration,
+                                       expected_presentation)
+    output = self.GetOutput(policy_json, {
+        '_google_chrome': '1',
+        'version': '83.0.4089.0'
+    }, 'ios_app_config')
+    self.assertEquals(output.strip(), expected.strip())
+
+  def testPolicyWithGroup(self):
+    policy_definition = json.dumps([{
+        'name': 'PolicyInGroup',
+        'type': 'string',
+        'supported_on': ['ios:80-'],
+        'caption': 'string caption',
+        'desc': 'string description'
+    }, {
+        'name': 'DummyGroup',
+        'type': 'group',
+        'caption': 'Dummy Group',
+        'desc': 'Dummy group for testing',
+        'policies': ['PolicyInGroup']
+    }])
+    policy_json = self._GetTestPolicyTemplate(policy_definition)
+    expected_configuration = '''<string keyName="PolicyInGroup">
+      <constraint nullable="true"/>
+    </string>'''
+    expected_presentation = '''<fieldGroup>
+      <name>
+        <language value="en-US">Dummy Group</language>
+      </name>
+      <field keyName="PolicyInGroup" type="input">
+        <label>
+          <language value="en-US">string caption</language>
+        </label>
+        <description>
+          <language value="en-US">string description</language>
+        </description>
+      </field>
+    </fieldGroup>'''
+    expected = self._GetExpectedOutput('83', expected_configuration,
+                                       expected_presentation)
     output = self.GetOutput(policy_json, {
         '_google_chrome': '1',
         'version': '83.0.4089.0'
diff --git a/components/policy/tools/template_writers/writers/template_writer.py b/components/policy/tools/template_writers/writers/template_writer.py
index 5678d13..0ce8ed2 100755
--- a/components/policy/tools/template_writers/writers/template_writer.py
+++ b/components/policy/tools/template_writers/writers/template_writer.py
@@ -262,7 +262,35 @@
     template['policy_definitions'] = \
         self.PreprocessPolicies(template['policy_definitions'])
     self.BeginTemplate()
-    for policy in template['policy_definitions']:
+    self.WritePolicies(template['policy_definitions'])
+    self.EndTemplate()
+
+    return self.GetTemplateText()
+
+  def PreprocessPolicies(self, policy_list):
+    '''Preprocesses a list of policies according to a given writer's needs.
+    Preprocessing steps include sorting policies and stripping unneeded
+    information such as groups (for writers that ignore them).
+    Subclasses are encouraged to override this method, overriding
+    implementations may call one of the provided specialized implementations.
+    The default behaviour is to use SortPoliciesGroupsFirst().
+
+    Args:
+      policy_list: A list containing the policies to sort.
+
+    Returns:
+      The sorted policy list.
+    '''
+    return self.SortPoliciesGroupsFirst(policy_list)
+
+  def WritePolicies(self, policy_list):
+    '''Appends the template text corresponding to all the policies into the
+    internal buffer.
+
+    Args:
+      policy_list: A list containing the policies to write.
+    '''
+    for policy in policy_list:
       if policy['type'] == 'group':
         child_policies = self._GetPoliciesForWriter(policy)
         child_recommended_policies = filter(self.CanBeRecommended,
@@ -283,25 +311,6 @@
         self.WritePolicy(policy)
         if self.CanBeRecommended(policy):
           self.WriteRecommendedPolicy(policy)
-    self.EndTemplate()
-
-    return self.GetTemplateText()
-
-  def PreprocessPolicies(self, policy_list):
-    '''Preprocesses a list of policies according to a given writer's needs.
-    Preprocessing steps include sorting policies and stripping unneeded
-    information such as groups (for writers that ignore them).
-    Subclasses are encouraged to override this method, overriding
-    implementations may call one of the provided specialized implementations.
-    The default behaviour is to use SortPoliciesGroupsFirst().
-
-    Args:
-      policy_list: A list containing the policies to sort.
-
-    Returns:
-      The sorted policy list.
-    '''
-    return self.SortPoliciesGroupsFirst(policy_list)
 
   def WritePolicy(self, policy):
     '''Appends the template text corresponding to a policy into the
diff --git a/components/resources/autofill_and_password_manager_internals_resources.grdp b/components/resources/autofill_and_password_manager_internals_resources.grdp
index 5fe4bb8..fbec179f 100644
--- a/components/resources/autofill_and_password_manager_internals_resources.grdp
+++ b/components/resources/autofill_and_password_manager_internals_resources.grdp
@@ -6,6 +6,6 @@
   <if expr="is_ios">
     <include name="IDR_AUTOFILL_AND_PASSWORD_MANAGER_INTERNALS_HTML" file="../autofill/core/browser/autofill_and_password_manager_internals/autofill_and_password_manager_internals_ios.html" flattenhtml="true" allowexternalscript="true" type="BINDATA" />
   </if>
-  <include name="IDR_AUTOFILL_AND_PASSWORD_MANAGER_INTERNALS_JS" file="../autofill/core/browser/autofill_and_password_manager_internals/autofill_and_password_manager_internals.js" flattenhtml="true" type="BINDATA" />
-  <include name="IDR_AUTOFILL_AND_PASSWORD_MANAGER_INTERNALS_CSS" file="../autofill/core/browser/autofill_and_password_manager_internals/autofill_and_password_manager_internals.css" flattenhtml="true" type="BINDATA" />
+  <include name="IDR_AUTOFILL_AND_PASSWORD_MANAGER_INTERNALS_JS" file="../autofill/core/browser/autofill_and_password_manager_internals/autofill_and_password_manager_internals.js" type="BINDATA" />
+  <include name="IDR_AUTOFILL_AND_PASSWORD_MANAGER_INTERNALS_CSS" file="../autofill/core/browser/autofill_and_password_manager_internals/autofill_and_password_manager_internals.css" type="BINDATA" />
 </grit-part>
diff --git a/components/resources/net_log_resources.grdp b/components/resources/net_log_resources.grdp
index 34e88e4..4cf3ec96 100644
--- a/components/resources/net_log_resources.grdp
+++ b/components/resources/net_log_resources.grdp
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
 <grit-part>
   <include name="IDR_NET_LOG_NET_EXPORT_HTML" file="../net_log/resources/net_export.html" flattenhtml="true" type="BINDATA" />
-  <include name="IDR_NET_LOG_NET_EXPORT_JS" file="../net_log/resources/net_export.js" flattenhtml="true" type="BINDATA" />
+  <include name="IDR_NET_LOG_NET_EXPORT_JS" file="../net_log/resources/net_export.js" type="BINDATA" />
 </grit-part>
diff --git a/components/resources/printing_resources.grdp b/components/resources/printing_resources.grdp
index 27a993e..838233b 100644
--- a/components/resources/printing_resources.grdp
+++ b/components/resources/printing_resources.grdp
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <grit-part>
   <if expr="enable_basic_printing">
-    <include name="IDR_PRINT_HEADER_FOOTER_TEMPLATE_PAGE" file="../printing/resources/print_header_footer_template_page.html" flattenhtml="true" allowexternalscript="false" type="BINDATA" />
+    <include name="IDR_PRINT_HEADER_FOOTER_TEMPLATE_PAGE" file="../printing/resources/print_header_footer_template_page.html" allowexternalscript="false" type="BINDATA" />
   </if>
 </grit-part>
diff --git a/components/resources/security_interstitials_dev_ui_resources.grdp b/components/resources/security_interstitials_dev_ui_resources.grdp
index 7a8e420..6a41517f 100644
--- a/components/resources/security_interstitials_dev_ui_resources.grdp
+++ b/components/resources/security_interstitials_dev_ui_resources.grdp
@@ -3,6 +3,5 @@
 <grit-part>
   <include name="IDR_SECURITY_INTERSTITIAL_UI_HTML"
            file="../security_interstitials/core/browser/resources/list_of_interstitials.html"
-           flattenhtml="true"
            type="BINDATA" />
 </grit-part>
diff --git a/components/safe_browsing/DIR_METADATA b/components/safe_browsing/DIR_METADATA
new file mode 100644
index 0000000..578f3dfc
--- /dev/null
+++ b/components/safe_browsing/DIR_METADATA
@@ -0,0 +1,5 @@
+monorail {
+  component: "Services>Safebrowsing"
+}
+
+team_email: "safebrowsing@chromium.org"
diff --git a/components/safe_browsing/OWNERS b/components/safe_browsing/OWNERS
index 9659c18..70e4b68 100644
--- a/components/safe_browsing/OWNERS
+++ b/components/safe_browsing/OWNERS
@@ -1,6 +1,3 @@
 drubery@chromium.org
 nparker@chromium.org
 vakh@chromium.org
-
-# COMPONENT: Services>Safebrowsing
-# TEAM: safebrowsing@chromium.org
diff --git a/components/safe_browsing/android/DIR_METADATA b/components/safe_browsing/android/DIR_METADATA
new file mode 100644
index 0000000..578f3dfc
--- /dev/null
+++ b/components/safe_browsing/android/DIR_METADATA
@@ -0,0 +1,5 @@
+monorail {
+  component: "Services>Safebrowsing"
+}
+
+team_email: "safebrowsing@chromium.org"
diff --git a/components/safe_browsing/android/OWNERS b/components/safe_browsing/android/OWNERS
index e7aac85..5ba4e22 100644
--- a/components/safe_browsing/android/OWNERS
+++ b/components/safe_browsing/android/OWNERS
@@ -1,5 +1,2 @@
 vakh@chromium.org
 xinghuilu@chromium.org
-
-# COMPONENT: Services>Safebrowsing
-# TEAM: safebrowsing@chromium.org
diff --git a/components/safe_browsing/content/password_protection/DIR_METADATA b/components/safe_browsing/content/password_protection/DIR_METADATA
new file mode 100644
index 0000000..578f3dfc
--- /dev/null
+++ b/components/safe_browsing/content/password_protection/DIR_METADATA
@@ -0,0 +1,5 @@
+monorail {
+  component: "Services>Safebrowsing"
+}
+
+team_email: "safebrowsing@chromium.org"
diff --git a/components/safe_browsing/content/password_protection/OWNERS b/components/safe_browsing/content/password_protection/OWNERS
index 7a887f4..ac5b456 100644
--- a/components/safe_browsing/content/password_protection/OWNERS
+++ b/components/safe_browsing/content/password_protection/OWNERS
@@ -1,4 +1 @@
 bdea@chromium.org
-
-# COMPONENT: Services>Safebrowsing
-# TEAM: safebrowsing@chromium.org
diff --git a/components/safe_browsing/core/realtime/DIR_METADATA b/components/safe_browsing/core/realtime/DIR_METADATA
new file mode 100644
index 0000000..578f3dfc
--- /dev/null
+++ b/components/safe_browsing/core/realtime/DIR_METADATA
@@ -0,0 +1,5 @@
+monorail {
+  component: "Services>Safebrowsing"
+}
+
+team_email: "safebrowsing@chromium.org"
diff --git a/components/safe_browsing/core/realtime/OWNERS b/components/safe_browsing/core/realtime/OWNERS
index e7aac85..5ba4e22 100644
--- a/components/safe_browsing/core/realtime/OWNERS
+++ b/components/safe_browsing/core/realtime/OWNERS
@@ -1,5 +1,2 @@
 vakh@chromium.org
 xinghuilu@chromium.org
-
-# COMPONENT: Services>Safebrowsing
-# TEAM: safebrowsing@chromium.org
diff --git a/components/safe_search_api/DIR_METADATA b/components/safe_search_api/DIR_METADATA
new file mode 100644
index 0000000..9db75de
--- /dev/null
+++ b/components/safe_search_api/DIR_METADATA
@@ -0,0 +1,3 @@
+monorail {
+  component: "FamilyLink"
+}
diff --git a/components/safe_search_api/OWNERS b/components/safe_search_api/OWNERS
index 7411752..408a9bd 100644
--- a/components/safe_search_api/OWNERS
+++ b/components/safe_search_api/OWNERS
@@ -1,4 +1,2 @@
 michaelpg@chromium.org
 treib@chromium.org
-
-# COMPONENT: FamilyLink
diff --git a/components/safety_check/DIR_METADATA b/components/safety_check/DIR_METADATA
new file mode 100644
index 0000000..a925329a
--- /dev/null
+++ b/components/safety_check/DIR_METADATA
@@ -0,0 +1 @@
+team_email: "chrome-privacy-core@google.com"
diff --git a/components/safety_check/OWNERS b/components/safety_check/OWNERS
index 0c59b82a..4f84ddb 100644
--- a/components/safety_check/OWNERS
+++ b/components/safety_check/OWNERS
@@ -3,5 +3,3 @@
 harrisonsean@chromium.org
 msramek@chromium.org
 rainhard@chromium.org
-
-# TEAM: chrome-privacy-core@google.com
diff --git a/components/search/repeatable_queries/repeatable_queries_service_unittest.cc b/components/search/repeatable_queries/repeatable_queries_service_unittest.cc
index 7208f24..7629ff6 100644
--- a/components/search/repeatable_queries/repeatable_queries_service_unittest.cc
+++ b/components/search/repeatable_queries/repeatable_queries_service_unittest.cc
@@ -444,7 +444,8 @@
 #define MAYBE_SignedIn_DefaultSearchProviderChanged \
   SignedIn_DefaultSearchProviderChanged
 #endif
-TEST_F(RepeatableQueriesServiceTest, SignedIn_DefaultSearchProviderChanged) {
+TEST_F(RepeatableQueriesServiceTest,
+       MAYBE_SignedIn_DefaultSearchProviderChanged) {
   SignIn();
   test_url_loader_factory()->AddResponse(service()->GetRequestURL().spec(),
                                          GoodServerResponse());
diff --git a/components/shared_highlighting/core/common/shared_highlighting_metrics.h b/components/shared_highlighting/core/common/shared_highlighting_metrics.h
index 011ce68d..0d7f9da 100644
--- a/components/shared_highlighting/core/common/shared_highlighting_metrics.h
+++ b/components/shared_highlighting/core/common/shared_highlighting_metrics.h
@@ -13,6 +13,7 @@
 // These values are persisted to logs. Entries should not be renumbered and
 // numeric values should never be reused.
 // The type of errors that can happen during link generation.
+// Update corresponding |LinkGenerationError| in enums.xml.
 enum class LinkGenerationError {
   kIncorrectSelector = 0,
   kNoRange = 1,
diff --git a/components/sync/driver/profile_sync_service.cc b/components/sync/driver/profile_sync_service.cc
index 94cb745..20e0778 100644
--- a/components/sync/driver/profile_sync_service.cc
+++ b/components/sync/driver/profile_sync_service.cc
@@ -607,8 +607,7 @@
   params.invalidation_versions = sync_prefs_.GetInvalidationVersions();
   params.poll_interval = sync_prefs_.GetPollInterval();
   if (params.poll_interval.is_zero()) {
-    params.poll_interval =
-        base::TimeDelta::FromSeconds(kDefaultPollIntervalSeconds);
+    params.poll_interval = kDefaultPollInterval;
   }
 
   if (!IsLocalSyncEnabled()) {
diff --git a/components/sync/driver/startup_controller.cc b/components/sync/driver/startup_controller.cc
index bf576d26..5d10ddf 100644
--- a/components/sync/driver/startup_controller.cc
+++ b/components/sync/driver/startup_controller.cc
@@ -22,7 +22,8 @@
 
 // The amount of time we'll wait to initialize sync if no data type requests
 // immediately initialization.
-const int kDefaultDeferredInitDelaySeconds = 10;
+constexpr base::TimeDelta kDefaultDeferredInitDelay =
+    base::TimeDelta::FromSeconds(10);
 
 base::TimeDelta GetDeferredInitDelay() {
   const base::CommandLine* cmdline = base::CommandLine::ForCurrentProcess();
@@ -37,7 +38,7 @@
       return base::TimeDelta::FromSeconds(timeout);
     }
   }
-  return base::TimeDelta::FromSeconds(kDefaultDeferredInitDelaySeconds);
+  return kDefaultDeferredInitDelay;
 }
 
 bool IsDeferredStartupEnabled() {
diff --git a/components/sync/driver/sync_stopped_reporter.cc b/components/sync/driver/sync_stopped_reporter.cc
index 53b919d..0ea6ade 100644
--- a/components/sync/driver/sync_stopped_reporter.cc
+++ b/components/sync/driver/sync_stopped_reporter.cc
@@ -28,7 +28,7 @@
 // plenty of time. Since sync is off when this request is started, we don't
 // want anything sync-related hanging around for very long from a human
 // perspective either. This seems like a good compromise.
-const int kRequestTimeoutSeconds = 10;
+constexpr base::TimeDelta kRequestTimeout = base::TimeDelta::FromSeconds(10);
 
 }  // namespace
 
@@ -106,8 +106,8 @@
       url_loader_factory_.get(),
       base::BindOnce(&SyncStoppedReporter::OnSimpleLoaderComplete,
                      base::Unretained(this)));
-  timer_.Start(FROM_HERE, base::TimeDelta::FromSeconds(kRequestTimeoutSeconds),
-               this, &SyncStoppedReporter::OnTimeout);
+  timer_.Start(FROM_HERE, kRequestTimeout, this,
+               &SyncStoppedReporter::OnTimeout);
 }
 
 void SyncStoppedReporter::OnSimpleLoaderComplete(
diff --git a/components/sync/engine/net/http_bridge.cc b/components/sync/engine/net/http_bridge.cc
index 90b7cdfb..0e69ef3 100644
--- a/components/sync/engine/net/http_bridge.cc
+++ b/components/sync/engine/net/http_bridge.cc
@@ -34,7 +34,7 @@
 // It's possible for an http request to be silently stalled. We set a time
 // limit for all http requests, beyond which the request is cancelled and
 // treated as a transient failure.
-const int kMaxHttpRequestTimeSeconds = 60 * 5;  // 5 minutes.
+constexpr base::TimeDelta kMaxHttpRequestTime = base::TimeDelta::FromMinutes(5);
 
 // Helper method for logging timeouts via UMA.
 void LogTimeout(bool timed_out) {
@@ -185,7 +185,7 @@
   fetch_state_.http_request_timeout_timer =
       std::make_unique<base::OneShotTimer>();
   fetch_state_.http_request_timeout_timer->Start(
-      FROM_HERE, base::TimeDelta::FromSeconds(kMaxHttpRequestTimeSeconds),
+      FROM_HERE, kMaxHttpRequestTime,
       base::BindOnce(&HttpBridge::OnURLLoadTimedOut, this));
 
   // Some tests inject |url_loader_factory_| created to operated on the
diff --git a/components/sync/engine/polling_constants.cc b/components/sync/engine/polling_constants.cc
index 61601c4..4639879 100644
--- a/components/sync/engine/polling_constants.cc
+++ b/components/sync/engine/polling_constants.cc
@@ -10,10 +10,10 @@
 // We use high values here to ensure that failure to receive poll updates from
 // the server doesn't result in rapid-fire polling from the client due to low
 // local limits.
-const int64_t kDefaultPollIntervalSeconds = 3600 * 8;
+const base::TimeDelta kDefaultPollInterval = base::TimeDelta::FromHours(8);
 
 // Maximum interval for exponential backoff.
-const int64_t kMaxBackoffSeconds = 60 * 10;  // 10 minutes.
+const base::TimeDelta kMaxBackoffTime = base::TimeDelta::FromMinutes(10);
 
 // Backoff interval randomization factor.
 const int kBackoffRandomizationFactor = 2;
@@ -21,16 +21,19 @@
 // After a failure contacting sync servers, specifies how long to wait before
 // reattempting and entering exponential backoff if consecutive failures
 // occur.
-const int kInitialBackoffRetrySeconds = 30;  // 30 seconds.
+const base::TimeDelta kInitialBackoffRetryTime =
+    base::TimeDelta::FromSeconds(30);
 
 // A dangerously short retry value that would not actually protect servers from
 // DDoS if it were used as a seed for exponential backoff, although the client
 // would still follow exponential backoff.  Useful for debugging and tests (when
 // you don't want to wait 5 minutes).
-const int kInitialBackoffShortRetrySeconds = 1;
+const base::TimeDelta kInitialBackoffShortRetryTime =
+    base::TimeDelta::FromSeconds(1);
 
-// Similar to kInitialBackoffRetrySeconds above, but only to be used in
+// Similar to kInitialBackoffRetryTime above, but only to be used in
 // certain exceptional error cases, such as MIGRATION_DONE.
-const int kInitialBackoffImmediateRetrySeconds = 0;
+const base::TimeDelta kInitialBackoffImmediateRetryTime =
+    base::TimeDelta::FromSeconds(0);
 
 }  // namespace syncer
diff --git a/components/sync/engine/polling_constants.h b/components/sync/engine/polling_constants.h
index 90613ce..bc05ef5 100644
--- a/components/sync/engine/polling_constants.h
+++ b/components/sync/engine/polling_constants.h
@@ -7,15 +7,17 @@
 
 #include <stdint.h>
 
+#include "base/time/time.h"
+
 namespace syncer {
 
 // Constants used by SyncScheduler when polling servers for updates.
-extern const int64_t kDefaultPollIntervalSeconds;
-extern const int64_t kMaxBackoffSeconds;
+extern const base::TimeDelta kDefaultPollInterval;
+extern const base::TimeDelta kMaxBackoffTime;
 extern const int kBackoffRandomizationFactor;
-extern const int kInitialBackoffRetrySeconds;
-extern const int kInitialBackoffShortRetrySeconds;
-extern const int kInitialBackoffImmediateRetrySeconds;
+extern const base::TimeDelta kInitialBackoffRetryTime;
+extern const base::TimeDelta kInitialBackoffShortRetryTime;
+extern const base::TimeDelta kInitialBackoffImmediateRetryTime;
 
 }  // namespace syncer
 
diff --git a/components/sync/engine_impl/backoff_delay_provider.cc b/components/sync/engine_impl/backoff_delay_provider.cc
index 0fa5b84..a689704 100644
--- a/components/sync/engine_impl/backoff_delay_provider.cc
+++ b/components/sync/engine_impl/backoff_delay_provider.cc
@@ -14,16 +14,13 @@
 #include "components/sync/engine/cycle/model_neutral_state.h"
 #include "components/sync/engine/polling_constants.h"
 
-using base::TimeDelta;
-
 namespace syncer {
 
 // static
 std::unique_ptr<BackoffDelayProvider> BackoffDelayProvider::FromDefaults() {
   // base::WrapUnique() used because the constructor is private.
   return base::WrapUnique(new BackoffDelayProvider(
-      TimeDelta::FromSeconds(kInitialBackoffRetrySeconds),
-      TimeDelta::FromSeconds(kInitialBackoffImmediateRetrySeconds)));
+      kInitialBackoffRetryTime, kInitialBackoffImmediateRetryTime));
 }
 
 // static
@@ -31,8 +28,7 @@
 BackoffDelayProvider::WithShortInitialRetryOverride() {
   // base::WrapUnique() used because the constructor is private.
   return base::WrapUnique(new BackoffDelayProvider(
-      TimeDelta::FromSeconds(kInitialBackoffShortRetrySeconds),
-      TimeDelta::FromSeconds(kInitialBackoffImmediateRetrySeconds)));
+      kInitialBackoffShortRetryTime, kInitialBackoffImmediateRetryTime));
 }
 
 BackoffDelayProvider::BackoffDelayProvider(
@@ -43,31 +39,30 @@
 
 BackoffDelayProvider::~BackoffDelayProvider() {}
 
-TimeDelta BackoffDelayProvider::GetDelay(const base::TimeDelta& last_delay) {
-  if (last_delay.InSeconds() >= kMaxBackoffSeconds)
-    return TimeDelta::FromSeconds(kMaxBackoffSeconds);
+base::TimeDelta BackoffDelayProvider::GetDelay(
+    const base::TimeDelta& last_delay) {
+  if (last_delay >= kMaxBackoffTime)
+    return kMaxBackoffTime;
 
-  // This calculates approx. base_delay_seconds * 2 +/- base_delay_seconds / 2
-  int64_t backoff_s =
-      std::max(static_cast<int64_t>(1),
-               last_delay.InSeconds() * kBackoffRandomizationFactor);
+  // This calculates approx. base_delay * 2 +/- base_delay / 2
+  base::TimeDelta backoff = std::max(base::TimeDelta::FromSeconds(1),
+                                     last_delay * kBackoffRandomizationFactor);
 
   // Flip a coin to randomize backoff interval by +/- 50%.
   int rand_sign = base::RandInt(0, 1) * 2 - 1;
 
   // Truncation is adequate for rounding here.
-  backoff_s =
-      backoff_s +
-      (rand_sign * (last_delay.InSeconds() / kBackoffRandomizationFactor));
+  base::TimeDelta jitter =
+      (last_delay / kBackoffRandomizationFactor)
+          .FloorToMultiple(base::TimeDelta::FromSeconds(1));
+  backoff += rand_sign * jitter;
 
-  // Cap the backoff interval.
-  backoff_s = std::max(static_cast<int64_t>(1),
-                       std::min(backoff_s, kMaxBackoffSeconds));
-
-  return TimeDelta::FromSeconds(backoff_s);
+  // Clamp backoff between 1 second and |kMaxBackoffTime|.
+  return std::max(base::TimeDelta::FromSeconds(1),
+                  std::min(backoff, kMaxBackoffTime));
 }
 
-TimeDelta BackoffDelayProvider::GetInitialDelay(
+base::TimeDelta BackoffDelayProvider::GetInitialDelay(
     const ModelNeutralState& state) const {
   // NETWORK_CONNECTION_UNAVAILABLE implies we did not receive HTTP response
   // from server because of some network error. If network is unavailable then
diff --git a/components/sync/engine_impl/backoff_delay_provider_unittest.cc b/components/sync/engine_impl/backoff_delay_provider_unittest.cc
index fbf640b3..8b5e680 100644
--- a/components/sync/engine_impl/backoff_delay_provider_unittest.cc
+++ b/components/sync/engine_impl/backoff_delay_provider_unittest.cc
@@ -30,10 +30,9 @@
             delay->GetDelay(TimeDelta::FromSeconds(50)));
   EXPECT_LE(TimeDelta::FromSeconds(10),
             delay->GetDelay(TimeDelta::FromSeconds(10)));
-  EXPECT_EQ(TimeDelta::FromSeconds(kMaxBackoffSeconds),
-            delay->GetDelay(TimeDelta::FromSeconds(kMaxBackoffSeconds)));
-  EXPECT_EQ(TimeDelta::FromSeconds(kMaxBackoffSeconds),
-            delay->GetDelay(TimeDelta::FromSeconds(kMaxBackoffSeconds + 1)));
+  EXPECT_EQ(kMaxBackoffTime, delay->GetDelay(kMaxBackoffTime));
+  EXPECT_EQ(kMaxBackoffTime,
+            delay->GetDelay(kMaxBackoffTime + TimeDelta::FromSeconds(1)));
 }
 
 TEST_F(BackoffDelayProviderTest, GetInitialDelay) {
@@ -42,48 +41,39 @@
   ModelNeutralState state;
   state.last_get_key_result =
       SyncerError::HttpError(net::HTTP_INTERNAL_SERVER_ERROR);
-  EXPECT_EQ(kInitialBackoffRetrySeconds,
-            delay->GetInitialDelay(state).InSeconds());
+  EXPECT_EQ(kInitialBackoffRetryTime, delay->GetInitialDelay(state));
 
   state.last_get_key_result = SyncerError();
   state.last_download_updates_result =
       SyncerError(SyncerError::SERVER_RETURN_MIGRATION_DONE);
-  EXPECT_EQ(kInitialBackoffImmediateRetrySeconds,
-            delay->GetInitialDelay(state).InSeconds());
+  EXPECT_EQ(kInitialBackoffImmediateRetryTime, delay->GetInitialDelay(state));
 
   state.last_download_updates_result =
       SyncerError::NetworkConnectionUnavailable(net::ERR_FAILED);
-  EXPECT_EQ(kInitialBackoffRetrySeconds,
-            delay->GetInitialDelay(state).InSeconds());
+  EXPECT_EQ(kInitialBackoffRetryTime, delay->GetInitialDelay(state));
 
   state.last_download_updates_result =
       SyncerError(SyncerError::SERVER_RETURN_TRANSIENT_ERROR);
-  EXPECT_EQ(kInitialBackoffRetrySeconds,
-            delay->GetInitialDelay(state).InSeconds());
+  EXPECT_EQ(kInitialBackoffRetryTime, delay->GetInitialDelay(state));
 
   state.last_download_updates_result =
       SyncerError(SyncerError::SERVER_RESPONSE_VALIDATION_FAILED);
-  EXPECT_EQ(kInitialBackoffRetrySeconds,
-            delay->GetInitialDelay(state).InSeconds());
+  EXPECT_EQ(kInitialBackoffRetryTime, delay->GetInitialDelay(state));
 
   state.last_download_updates_result =
       SyncerError(SyncerError::DATATYPE_TRIGGERED_RETRY);
-  EXPECT_EQ(kInitialBackoffImmediateRetrySeconds,
-            delay->GetInitialDelay(state).InSeconds());
+  EXPECT_EQ(kInitialBackoffImmediateRetryTime, delay->GetInitialDelay(state));
 
   state.last_download_updates_result = SyncerError(SyncerError::SYNCER_OK);
   state.commit_result = SyncerError(SyncerError::SERVER_RETURN_MIGRATION_DONE);
-  EXPECT_EQ(kInitialBackoffImmediateRetrySeconds,
-            delay->GetInitialDelay(state).InSeconds());
+  EXPECT_EQ(kInitialBackoffImmediateRetryTime, delay->GetInitialDelay(state));
 
   state.commit_result =
       SyncerError::NetworkConnectionUnavailable(net::ERR_FAILED);
-  EXPECT_EQ(kInitialBackoffRetrySeconds,
-            delay->GetInitialDelay(state).InSeconds());
+  EXPECT_EQ(kInitialBackoffRetryTime, delay->GetInitialDelay(state));
 
   state.commit_result = SyncerError(SyncerError::SERVER_RETURN_CONFLICT);
-  EXPECT_EQ(kInitialBackoffImmediateRetrySeconds,
-            delay->GetInitialDelay(state).InSeconds());
+  EXPECT_EQ(kInitialBackoffImmediateRetryTime, delay->GetInitialDelay(state));
 }
 
 TEST_F(BackoffDelayProviderTest, GetInitialDelayWithOverride) {
@@ -92,38 +82,31 @@
   ModelNeutralState state;
   state.last_get_key_result =
       SyncerError::HttpError(net::HTTP_INTERNAL_SERVER_ERROR);
-  EXPECT_EQ(kInitialBackoffShortRetrySeconds,
-            delay->GetInitialDelay(state).InSeconds());
+  EXPECT_EQ(kInitialBackoffShortRetryTime, delay->GetInitialDelay(state));
 
   state.last_get_key_result = SyncerError();
   state.last_download_updates_result =
       SyncerError(SyncerError::SERVER_RETURN_MIGRATION_DONE);
-  EXPECT_EQ(kInitialBackoffImmediateRetrySeconds,
-            delay->GetInitialDelay(state).InSeconds());
+  EXPECT_EQ(kInitialBackoffImmediateRetryTime, delay->GetInitialDelay(state));
 
   state.last_download_updates_result =
       SyncerError(SyncerError::SERVER_RETURN_TRANSIENT_ERROR);
-  EXPECT_EQ(kInitialBackoffShortRetrySeconds,
-            delay->GetInitialDelay(state).InSeconds());
+  EXPECT_EQ(kInitialBackoffShortRetryTime, delay->GetInitialDelay(state));
 
   state.last_download_updates_result =
       SyncerError(SyncerError::SERVER_RESPONSE_VALIDATION_FAILED);
-  EXPECT_EQ(kInitialBackoffShortRetrySeconds,
-            delay->GetInitialDelay(state).InSeconds());
+  EXPECT_EQ(kInitialBackoffShortRetryTime, delay->GetInitialDelay(state));
 
   state.last_download_updates_result =
       SyncerError(SyncerError::DATATYPE_TRIGGERED_RETRY);
-  EXPECT_EQ(kInitialBackoffImmediateRetrySeconds,
-            delay->GetInitialDelay(state).InSeconds());
+  EXPECT_EQ(kInitialBackoffImmediateRetryTime, delay->GetInitialDelay(state));
 
   state.last_download_updates_result = SyncerError(SyncerError::SYNCER_OK);
   state.commit_result = SyncerError(SyncerError::SERVER_RETURN_MIGRATION_DONE);
-  EXPECT_EQ(kInitialBackoffImmediateRetrySeconds,
-            delay->GetInitialDelay(state).InSeconds());
+  EXPECT_EQ(kInitialBackoffImmediateRetryTime, delay->GetInitialDelay(state));
 
   state.commit_result = SyncerError(SyncerError::SERVER_RETURN_CONFLICT);
-  EXPECT_EQ(kInitialBackoffImmediateRetrySeconds,
-            delay->GetInitialDelay(state).InSeconds());
+  EXPECT_EQ(kInitialBackoffImmediateRetryTime, delay->GetInitialDelay(state));
 }
 
 }  // namespace syncer
diff --git a/components/sync/engine_impl/cycle/nudge_tracker.cc b/components/sync/engine_impl/cycle/nudge_tracker.cc
index 36dcd8a..f542074c 100644
--- a/components/sync/engine_impl/cycle/nudge_tracker.cc
+++ b/components/sync/engine_impl/cycle/nudge_tracker.cc
@@ -15,10 +15,14 @@
 namespace {
 
 // Delays for syncer nudges.
-const int kDefaultNudgeDelayMilliseconds = 200;
-const int kSlowNudgeDelayMilliseconds = 2000;
-const int kSyncRefreshDelayMilliseconds = 500;
-const int kSyncSchedulerDelayMilliseconds = 250;
+constexpr base::TimeDelta kDefaultNudgeDelay =
+    base::TimeDelta::FromMilliseconds(200);
+constexpr base::TimeDelta kSlowNudgeDelay =
+    base::TimeDelta::FromMilliseconds(2000);
+constexpr base::TimeDelta kSyncRefreshDelay =
+    base::TimeDelta::FromMilliseconds(500);
+constexpr base::TimeDelta kSyncSchedulerDelay =
+    base::TimeDelta::FromMilliseconds(250);
 
 base::TimeDelta GetSharingMessageDelay(base::TimeDelta default_delay) {
   if (!base::FeatureList::IsEnabled(
@@ -37,13 +41,13 @@
     case USER_EVENTS:
       // Accompany types rely on nudges from other types, and hence have long
       // nudge delays.
-      return base::TimeDelta::FromSeconds(kDefaultPollIntervalSeconds);
+      return kDefaultPollInterval;
     case BOOKMARKS:
     case PREFERENCES:
     case SESSIONS:
       // Types with sometimes automatic changes get longer delays to allow more
       // coalescing.
-      return base::TimeDelta::FromMilliseconds(kSlowNudgeDelayMilliseconds);
+      return kSlowNudgeDelay;
     case SHARING_MESSAGE:
       return GetSharingMessageDelay(minimum_delay);
     default:
@@ -56,12 +60,9 @@
 NudgeTracker::NudgeTracker()
     : invalidations_enabled_(false),
       invalidations_out_of_sync_(true),
-      minimum_local_nudge_delay_(
-          base::TimeDelta::FromMilliseconds(kDefaultNudgeDelayMilliseconds)),
-      local_refresh_nudge_delay_(
-          base::TimeDelta::FromMilliseconds(kSyncRefreshDelayMilliseconds)),
-      remote_invalidation_nudge_delay_(
-          base::TimeDelta::FromMilliseconds(kSyncSchedulerDelayMilliseconds)) {
+      minimum_local_nudge_delay_(kDefaultNudgeDelay),
+      local_refresh_nudge_delay_(kSyncRefreshDelay),
+      remote_invalidation_nudge_delay_(kSyncSchedulerDelay) {
   // Default initialize all the type trackers.
   for (ModelType type : ProtocolTypes()) {
     type_trackers_.emplace(
@@ -144,8 +145,7 @@
 
 base::TimeDelta NudgeTracker::RecordLocalChange(ModelTypeSet types) {
   // Start with the longest delay.
-  base::TimeDelta delay =
-      base::TimeDelta::FromSeconds(kDefaultPollIntervalSeconds);
+  base::TimeDelta delay = kDefaultPollInterval;
   for (ModelType type : types) {
     TypeTrackerMap::const_iterator tracker_it = type_trackers_.find(type);
     DCHECK(tracker_it != type_trackers_.end());
diff --git a/components/sync/engine_impl/sync_scheduler_impl.cc b/components/sync/engine_impl/sync_scheduler_impl.cc
index d40805c..b6bcec10 100644
--- a/components/sync/engine_impl/sync_scheduler_impl.cc
+++ b/components/sync/engine_impl/sync_scheduler_impl.cc
@@ -829,8 +829,7 @@
 void SyncSchedulerImpl::OnTypesBackedOff(ModelTypeSet types) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   for (ModelType type : types) {
-    TimeDelta last_backoff_time =
-        TimeDelta::FromSeconds(kInitialBackoffRetrySeconds);
+    TimeDelta last_backoff_time = kInitialBackoffRetryTime;
     if (nudge_tracker_.GetTypeBlockingMode(type) ==
         WaitInterval::EXPONENTIAL_BACKOFF_RETRYING) {
       last_backoff_time = nudge_tracker_.GetTypeLastBackoffInterval(type);
diff --git a/components/sync/engine_impl/sync_scheduler_impl_unittest.cc b/components/sync/engine_impl/sync_scheduler_impl_unittest.cc
index a1bbc90..1b9736cc 100644
--- a/components/sync/engine_impl/sync_scheduler_impl_unittest.cc
+++ b/components/sync/engine_impl/sync_scheduler_impl_unittest.cc
@@ -241,9 +241,8 @@
   class MockDelayProvider : public BackoffDelayProvider {
    public:
     MockDelayProvider()
-        : BackoffDelayProvider(
-              TimeDelta::FromSeconds(kInitialBackoffRetrySeconds),
-              TimeDelta::FromSeconds(kInitialBackoffImmediateRetrySeconds)) {}
+        : BackoffDelayProvider(kInitialBackoffRetryTime,
+                               kInitialBackoffImmediateRetryTime) {}
     MOCK_METHOD(TimeDelta, GetDelay, (const TimeDelta&), (override));
   };
 
@@ -1499,7 +1498,7 @@
           DoAll(Invoke(SimulateCommitFailed),
                 RecordSyncShareMultiple(&times, kMinNumSamples, false)));
 
-  const TimeDelta first = TimeDelta::FromSeconds(kInitialBackoffRetrySeconds);
+  const TimeDelta first = kInitialBackoffRetryTime;
   const TimeDelta second = TimeDelta::FromMilliseconds(20);
   const TimeDelta third = TimeDelta::FromMilliseconds(30);
   const TimeDelta fourth = TimeDelta::FromMilliseconds(40);
diff --git a/components/sync/engine_impl/syncer_proto_util.cc b/components/sync/engine_impl/syncer_proto_util.cc
index 3939531..11e42c1 100644
--- a/components/sync/engine_impl/syncer_proto_util.cc
+++ b/components/sync/engine_impl/syncer_proto_util.cc
@@ -30,7 +30,8 @@
 namespace {
 
 // Time to backoff syncing after receiving a throttled response.
-const int kSyncDelayAfterThrottled = 2 * 60 * 60;  // 2 hours
+constexpr base::TimeDelta kSyncDelayAfterThrottled =
+    base::TimeDelta::FromHours(2);
 
 void LogResponseProfilingData(const ClientToServerResponse& response) {
   if (response.has_profiling_data()) {
@@ -383,8 +384,7 @@
 
 base::TimeDelta SyncerProtoUtil::GetThrottleDelay(
     const ClientToServerResponse& response) {
-  base::TimeDelta throttle_delay =
-      base::TimeDelta::FromSeconds(kSyncDelayAfterThrottled);
+  base::TimeDelta throttle_delay = kSyncDelayAfterThrottled;
   if (response.has_client_command()) {
     const sync_pb::ClientCommand& command = response.client_command();
     if (command.has_throttle_delay_seconds()) {
diff --git a/content/browser/dom_storage/dom_storage_browsertest.cc b/content/browser/dom_storage/dom_storage_browsertest.cc
index df21f17..e70d7d1 100644
--- a/content/browser/dom_storage/dom_storage_browsertest.cc
+++ b/content/browser/dom_storage/dom_storage_browsertest.cc
@@ -7,6 +7,7 @@
 #include "base/files/file_util.h"
 #include "base/run_loop.h"
 #include "base/test/bind.h"
+#include "base/test/scoped_feature_list.h"
 #include "base/threading/thread_restrictions.h"
 #include "build/build_config.h"
 #include "components/services/storage/dom_storage/legacy_dom_storage_database.h"
@@ -199,4 +200,28 @@
   }
 }
 
+// Verify that when kCloneSessionStorageForNoOpener is enabled, sessionStorage
+// is cloned for popups even when |noopener| is specified.
+// TODO(crbug.com/1151381): Remove in Chrome 92.
+class DOMStorageCloningBrowserTest : public ContentBrowserTest {
+ public:
+  DOMStorageCloningBrowserTest() {
+    feature_list_.InitAndEnableFeature(
+        blink::features::kCloneSessionStorageForNoOpener);
+  }
+
+  void PopupTest(const GURL& test_url, const std::string& expected) {
+    NavigateToURLBlockUntilNavigationsComplete(shell(), test_url, 2);
+    std::string result = shell()->web_contents()->GetLastCommittedURL().ref();
+    EXPECT_EQ(result, expected);
+  }
+
+ private:
+  base::test::ScopedFeatureList feature_list_;
+};
+
+IN_PROC_BROWSER_TEST_F(DOMStorageCloningBrowserTest, NoOpenerTest) {
+  PopupTest(GetTestUrl("dom_storage", "noopener_cloning.html"), "firstTab");
+}
+
 }  // namespace content
diff --git a/content/browser/navigation_browsertest.cc b/content/browser/navigation_browsertest.cc
index cb34e40a..5581688 100644
--- a/content/browser/navigation_browsertest.cc
+++ b/content/browser/navigation_browsertest.cc
@@ -3277,8 +3277,11 @@
   }
 }
 
-// Update the fragment part of the URL while it is currently displaying an error
-// page. Regression test https://crbug.com/1018385
+// A navigation that fails to navigate due to an ERR_INVALID_URL would attempt
+// to load the error page into the destination RenderFrameHost returned from
+// GetFrameHostForNavigation(). That RenderFrameHost may not be the current
+// one. And even if it is, showing an error page is not a same-document
+// navigation. Regression test for https://crbug.com/1018385
 IN_PROC_BROWSER_TEST_F(NavigationBrowserTest,
                        SameDocumentNavigationInErrorPage) {
   NavigationHandleCommitObserver navigation_0(web_contents(),
diff --git a/content/browser/renderer_host/ipc_utils.cc b/content/browser/renderer_host/ipc_utils.cc
index ff9c8100..5276474 100644
--- a/content/browser/renderer_host/ipc_utils.cc
+++ b/content/browser/renderer_host/ipc_utils.cc
@@ -31,7 +31,7 @@
     const GURL& received_url) {
   DCHECK_NE(ChildProcessHost::kInvalidUniqueID, process_id);
 
-  if (received_token) {
+  if (received_token.is_valid()) {
     if (!received_url.SchemeIsBlob()) {
       bad_message::ReceivedBadMessage(
           process_id, bad_message::BLOB_URL_TOKEN_FOR_NON_BLOB_URL);
@@ -111,18 +111,15 @@
   process->FilterURL(false, out_validated_url);
 
   // Verify |params.blob_url_token| and populate |out_blob_url_loader_factory|.
-  mojo::PendingRemote<blink::mojom::BlobURLToken> blob_url_token(
-      mojo::ScopedMessagePipeHandle(std::move(params->blob_url_token)),
-      blink::mojom::BlobURLToken::Version_);
-  if (!VerifyBlobToken(process_id, blob_url_token, params->url))
+  if (!VerifyBlobToken(process_id, params->blob_url_token, params->url))
     return false;
 
-  if (blob_url_token.is_valid()) {
+  if (params->blob_url_token.is_valid()) {
     *out_blob_url_loader_factory =
         ChromeBlobStorageContext::URLLoaderFactoryForToken(
             BrowserContext::GetStoragePartition(
                 site_instance->GetBrowserContext(), site_instance),
-            std::move(blob_url_token));
+            std::move(params->blob_url_token));
   }
 
   // Verify |params.post_body|.
diff --git a/content/browser/renderer_host/navigation_request.cc b/content/browser/renderer_host/navigation_request.cc
index 04873f3a..3886b07b 100644
--- a/content/browser/renderer_host/navigation_request.cc
+++ b/content/browser/renderer_host/navigation_request.cc
@@ -555,7 +555,7 @@
 //
 // This is currently used when:
 // 1) Restarting a same-document navigation as cross-document.
-// 2) Committing an error page after blocking a same-document navigations.
+// 2) Failing a navigation and committing an error page.
 mojom::NavigationType ConvertToCrossDocumentType(mojom::NavigationType type) {
   switch (type) {
     case mojom::NavigationType::SAME_DOCUMENT:
@@ -2622,29 +2622,36 @@
   }
 
   RenderFrameHostImpl* render_frame_host = nullptr;
-  if (SiteIsolationPolicy::IsErrorPageIsolationEnabled(
-          frame_tree_node_->IsMainFrame())) {
-    // Main frame error pages must be isolated from the source or destination
-    // process.
-    //
-    // Note: Since this navigation resulted in an error, clear the expected
-    // process for the original navigation since for main frames the error page
-    // will go into a new process.
-    // TODO(nasko): Investigate whether GetFrameHostForNavigation can properly
-    // account for clearing the expected process if it clears the speculative
-    // RenderFrameHost. See https://crbug.com/793127.
-    ResetExpectedProcess();
-    render_frame_host =
-        frame_tree_node_->render_manager()->GetFrameHostForNavigation(this);
-  } else {
-    if (ShouldKeepErrorPageInCurrentProcess(status.error_code)) {
+  switch (ComputeErrorPageProcess(status.error_code)) {
+    case ErrorPageProcess::kCurrentProcess:
+      // There's no way to get here with a same-document navigation, it would
+      // need to be on a document that was not blocked but became blocked, but
+      // same document navigations don't go to the network so it wouldn't know
+      // about the change.
+      CHECK(!IsSameDocument());
       render_frame_host = frame_tree_node_->current_frame_host();
-    } else {
+      break;
+    case ErrorPageProcess::kIsolatedProcess:
+      // In this case we are isolating the error page from the source and
+      // destination process, and want it to go to a new process.
+      //
+      // TODO(nasko): Investigate whether GetFrameHostForNavigation can properly
+      // account for clearing the expected process if it clears the speculative
+      // RenderFrameHost. See https://crbug.com/793127.
+      ResetExpectedProcess();
+      FALLTHROUGH;
+    case ErrorPageProcess::kDestinationProcess:
+      // A same-document navigation would normally attempt to navigate the
+      // current document, but since we will be presenting an error instead and
+      // there will not be a document to navigate. We always make an error here
+      // into a cross-document navigation. See https://crbug.com/1018385 and
+      // https://crbug.com/1125106.
+      common_params_->navigation_type =
+          ConvertToCrossDocumentType(common_params_->navigation_type);
       render_frame_host =
           frame_tree_node_->render_manager()->GetFrameHostForNavigation(this);
-    }
+      break;
   }
-
   // Sanity check that we haven't changed the RenderFrameHost picked for the
   // error page in OnRequestFailedInternal when running the WillFailRequest
   // checks.
@@ -2675,7 +2682,15 @@
   }
 }
 
-bool NavigationRequest::ShouldKeepErrorPageInCurrentProcess(int net_error) {
+NavigationRequest::ErrorPageProcess NavigationRequest::ComputeErrorPageProcess(
+    int net_error) {
+  // By policy we can isolate all error pages from both the current and
+  // destination processes.
+  if (SiteIsolationPolicy::IsErrorPageIsolationEnabled(
+          frame_tree_node_->IsMainFrame())) {
+    return ErrorPageProcess::kIsolatedProcess;
+  }
+
   // Decide whether to leave the error page in the original process.
   // * If this was a renderer-initiated navigation, and the request is blocked
   //   because the initiating document wasn't allowed to make the request,
@@ -2692,7 +2707,9 @@
   //   URLs should be allowed to transfer away from the current process, which
   //   didn't request the navigation and may have a higher privilege level
   //   than the blocked destination.
-  return net::IsRequestBlockedError(net_error) && !browser_initiated();
+  if (net::IsRequestBlockedError(net_error) && !browser_initiated())
+    return ErrorPageProcess::kCurrentProcess;
+  return ErrorPageProcess::kDestinationProcess;
 }
 
 void NavigationRequest::OnRequestStarted(base::TimeTicks timestamp) {
@@ -3013,29 +3030,35 @@
 
 void NavigationRequest::OnFailureChecksComplete(
     NavigationThrottle::ThrottleCheckResult result) {
+  // This method is called as a result of getting to the end of
+  // OnRequestFailedInternal(), which calls WillFailRequest(), which
+  // runs the throttles, which eventually call back to this method.
   DCHECK(result.action() != NavigationThrottle::DEFER);
 
+  // The throttle may have changed the net_error_code, so we set the
+  // `net_error_` again, overriding what OnRequestFailedInternal() set.
   net::Error old_net_error = net_error_;
   net_error_ = result.net_error_code();
 
+  // Ensure that WillFailRequest() isn't changing the error code in a way that
+  // switches the destination process for the error page - see
+  // https://crbug.com/817881.
+  CHECK_EQ(ComputeErrorPageProcess(old_net_error),
+           ComputeErrorPageProcess(net_error_))
+      << " Unsupported error code change in WillFailRequest(): from "
+      << old_net_error << " to " << net_error_;
+
+  // The new `net_error_` value may mean we want to cancel the navigation.
   if (MaybeCancelFailedNavigation())
     return;
 
-  // Ensure that WillFailRequest() isn't changing the error code in a way that
-  // switches the destination process for the error page - see
-  // https://crbug.com/817881.  This is not a concern with error page
-  // isolation, where all errors will go into one process.
-  if (!SiteIsolationPolicy::IsErrorPageIsolationEnabled(
-          frame_tree_node_->IsMainFrame())) {
-    CHECK_EQ(ShouldKeepErrorPageInCurrentProcess(old_net_error),
-             ShouldKeepErrorPageInCurrentProcess(net_error_))
-        << " Unsupported error code change in WillFailRequest(): from "
-        << old_net_error << " to " << net_error_;
-  }
-
+  // The OnRequestFailedInternal() did not commit the error page as it
+  // defered to WillFailRequest(), which has called through to here, and
+  // now we are finally ready to commit the error page. This will be committed
+  // to the RenderFrameHost previously chosen in OnRequestFailedInternal().
   CommitErrorPage(result.error_page_content());
-  // DO NOT ADD CODE after this. The previous call to CommitErrorPage caused
-  // the destruction of the NavigationRequest.
+  // DO NOT ADD CODE after this. The previous call to CommitErrorPage()
+  // caused the destruction of the NavigationRequest.
 }
 
 void NavigationRequest::OnWillProcessResponseChecksComplete(
@@ -3138,14 +3161,9 @@
 
 void NavigationRequest::CommitErrorPage(
     const base::Optional<std::string>& error_page_content) {
-  UpdateCommitNavigationParamsHistory();
+  DCHECK(!IsSameDocument());
 
-  // Error pages are always cross-document.
-  //
-  // This is useful when a same-document navigation is blocked and commit an
-  // error page instead. See https://crbug.com/1018385.
-  common_params_->navigation_type =
-      ConvertToCrossDocumentType(common_params_->navigation_type);
+  UpdateCommitNavigationParamsHistory();
 
   frame_tree_node_->TransferNavigationRequestOwnership(render_frame_host_);
   // Error pages commit in an opaque origin in the renderer process. If this
diff --git a/content/browser/renderer_host/navigation_request.h b/content/browser/renderer_host/navigation_request.h
index f398fd05..6404c50 100644
--- a/content/browser/renderer_host/navigation_request.h
+++ b/content/browser/renderer_host/navigation_request.h
@@ -784,7 +784,12 @@
 
   // Helper to determine whether an error page for the provided error code
   // should stay in the current process.
-  bool ShouldKeepErrorPageInCurrentProcess(int net_error);
+  enum ErrorPageProcess {
+    kCurrentProcess,
+    kDestinationProcess,
+    kIsolatedProcess
+  };
+  ErrorPageProcess ComputeErrorPageProcess(int net_error);
 
   // Called when the NavigationThrottles have been checked by the
   // NavigationHandle.
diff --git a/content/browser/speech/tts_linux.cc b/content/browser/speech/tts_linux.cc
index 2058d20..bb39722 100644
--- a/content/browser/speech/tts_linux.cc
+++ b/content/browser/speech/tts_linux.cc
@@ -188,6 +188,12 @@
     float pitch,
     SPDChromeVoice voice,
     base::OnceCallback<void(bool)> on_speak_finished) {
+  if (!conn_) {
+    GetUIThreadTaskRunner({})->PostTask(
+        FROM_HERE, base::BindOnce(std::move(on_speak_finished), false));
+    return;
+  }
+
   libspeechd_loader_.spd_set_output_module(conn_, voice.module.c_str());
   libspeechd_loader_.spd_set_synthesis_voice(conn_, voice.name.c_str());
 
@@ -216,17 +222,17 @@
 }
 
 void TtsPlatformImplBackgroundWorker::Pause() {
-  if (msg_uid_ != kInvalidMessageUid)
+  if (conn_ && msg_uid_ != kInvalidMessageUid)
     libspeechd_loader_.spd_pause(conn_);
 }
 
 void TtsPlatformImplBackgroundWorker::Resume() {
-  if (msg_uid_ != kInvalidMessageUid)
+  if (conn_ && msg_uid_ != kInvalidMessageUid)
     libspeechd_loader_.spd_resume(conn_);
 }
 
 void TtsPlatformImplBackgroundWorker::StopSpeaking() {
-  if (msg_uid_ != kInvalidMessageUid) {
+  if (conn_ && msg_uid_ != kInvalidMessageUid) {
     int result = libspeechd_loader_.spd_stop(conn_);
     if (result == -1) {
       CloseConnection();
@@ -312,7 +318,7 @@
 void TtsPlatformImplBackgroundWorker::OnSpeechEvent(int msg_id,
                                                     SPDNotificationType type) {
   DCHECK(BrowserThread::CurrentlyOn(content::BrowserThread::UI));
-  if (msg_id != msg_uid_)
+  if (!conn_ || msg_id != msg_uid_)
     return;
 
   switch (type) {
diff --git a/content/common/frame.mojom b/content/common/frame.mojom
index ca64f21d..88cbc26 100644
--- a/content/common/frame.mojom
+++ b/content/common/frame.mojom
@@ -372,7 +372,7 @@
 
   // Extra information about the triggering of the OpenURL.
   TriggeringEventInfo triggering_event_info;
-  handle<message_pipe>? blob_url_token;
+  pending_remote<blink.mojom.BlobURLToken>? blob_url_token;
   string href_translate;
   Impression? impression;
   NavigationDownloadPolicy download_policy;
diff --git a/content/content_resources.grd b/content/content_resources.grd
index 4a553b6..6c27e86c 100644
--- a/content/content_resources.grd
+++ b/content/content_resources.grd
@@ -24,13 +24,13 @@
       <include name="IDR_DEVTOOLS_PINCH_CURSOR_ICON_2X" file="browser/resources/devtools/devtools_pinch_cursor_2x.png" type="BINDATA" />
       <include name="IDR_DEVTOOLS_TOUCH_CURSOR_ICON" file="browser/resources/devtools/devtools_touch_cursor.png" type="BINDATA" />
       <include name="IDR_DEVTOOLS_TOUCH_CURSOR_ICON_2X" file="browser/resources/devtools/devtools_touch_cursor_2x.png" type="BINDATA" />
-      <include name="IDR_HISTOGRAMS_INTERNALS_HTML" file="browser/resources/histograms/histograms_internals.html" flattenhtml="true" allowexternalscript="true" type="BINDATA" />
-      <include name="IDR_HISTOGRAMS_INTERNALS_JS" file="browser/resources/histograms/histograms_internals.js" flattenhtml="true" type="BINDATA" />
+      <include name="IDR_HISTOGRAMS_INTERNALS_HTML" file="browser/resources/histograms/histograms_internals.html" type="BINDATA" />
+      <include name="IDR_HISTOGRAMS_INTERNALS_JS" file="browser/resources/histograms/histograms_internals.js" type="BINDATA" />
       <include name="IDR_ORIGIN_MOJO_HTML" file="${root_gen_dir}/url/mojom/origin.mojom.html" use_base_dir="false" type="BINDATA" />
       <include name="IDR_ORIGIN_MOJO_JS" file="${root_gen_dir}/url/mojom/origin.mojom-lite.js" use_base_dir="false" type="BINDATA" />
       <include name="IDR_UKM_INTERNALS_HTML" file="../components/ukm/debug/ukm_internals.html" flattenhtml="true" allowexternalscript="true" type="BINDATA" />
-      <include name="IDR_UKM_INTERNALS_JS" file="../components/ukm/debug/ukm_internals.js" flattenhtml="true" type="BINDATA" />
-      <include name="IDR_UKM_INTERNALS_CSS" file="../components/ukm/debug/ukm_internals.css" flattenhtml="true" type="BINDATA" />
+      <include name="IDR_UKM_INTERNALS_JS" file="../components/ukm/debug/ukm_internals.js" type="BINDATA" />
+      <include name="IDR_UKM_INTERNALS_CSS" file="../components/ukm/debug/ukm_internals.css" type="BINDATA" />
       <include name="IDR_UNGUESSABLE_TOKEN_MOJO_HTML" file="${root_gen_dir}/mojo/public/mojom/base/unguessable_token.mojom.html" use_base_dir="false" type="BINDATA" />
       <include name="IDR_UNGUESSABLE_TOKEN_MOJO_JS" file="${root_gen_dir}/mojo/public/mojom/base/unguessable_token.mojom-lite.js" use_base_dir="false" type="BINDATA" />
       <include name="IDR_URL_MOJO_HTML" file="${root_gen_dir}/url/mojom/url.mojom.html" use_base_dir="false" type="BINDATA" />
diff --git a/content/dev_ui_content_resources.grd b/content/dev_ui_content_resources.grd
index 8b04e46..38e132b3 100644
--- a/content/dev_ui_content_resources.grd
+++ b/content/dev_ui_content_resources.grd
@@ -17,26 +17,26 @@
     <includes>
       <include name="IDR_APPCACHE_INTERNALS_HTML" file="browser/resources/appcache/appcache_internals.html" flattenhtml="true" allowexternalscript="true" type="BINDATA" />
       <include name="IDR_APPCACHE_INTERNALS_JS" file="browser/resources/appcache/appcache_internals.js" flattenhtml="false" type="BINDATA" />
-      <include name="IDR_APPCACHE_INTERNALS_CSS" file="browser/resources/appcache/appcache_internals.css" flattenhtml="true" type="BINDATA" />
+      <include name="IDR_APPCACHE_INTERNALS_CSS" file="browser/resources/appcache/appcache_internals.css" type="BINDATA" />
       <include name="IDR_CONVERSION_INTERNALS_HTML" file="browser/resources/conversions/conversion_internals.html" flattenhtml="true" allowexternalscript="true" type="BINDATA" />
-      <include name="IDR_CONVERSION_INTERNALS_JS" file="browser/resources/conversions/conversion_internals.js" flattenhtml="true" allowexternalscript="true" type="BINDATA" />
-      <include name="IDR_CONVERSION_INTERNALS_CSS" file="browser/resources/conversions/conversion_internals.css" flattenhtml="true" allowexternalscript="true" type="BINDATA" />
+      <include name="IDR_CONVERSION_INTERNALS_JS" file="browser/resources/conversions/conversion_internals.js" type="BINDATA" />
+      <include name="IDR_CONVERSION_INTERNALS_CSS" file="browser/resources/conversions/conversion_internals.css" type="BINDATA" />
       <include name="IDR_CONVERSION_INTERNALS_MOJOM_JS" file="${root_gen_dir}/content/browser/conversions/conversion_internals.mojom-lite.js" use_base_dir="false" type="BINDATA" />
       <include name="IDR_GPU_INTERNALS_HTML" file="browser/resources/gpu/gpu_internals.html" flattenhtml="true" allowexternalscript="true" type="BINDATA" />
       <include name="IDR_GPU_INTERNALS_JS" file="browser/resources/gpu/gpu_internals.js" flattenhtml="true" type="BINDATA" />
       <include name="IDR_INDEXED_DB_INTERNALS_HTML" file="browser/resources/indexed_db/indexeddb_internals.html" flattenhtml="true" allowexternalscript="true" type="BINDATA" />
-      <include name="IDR_INDEXED_DB_INTERNALS_JS" file="browser/resources/indexed_db/indexeddb_internals.js" flattenhtml="true" type="BINDATA" />
-      <include name="IDR_INDEXED_DB_INTERNALS_CSS" file="browser/resources/indexed_db/indexeddb_internals.css" flattenhtml="true" type="BINDATA" />
+      <include name="IDR_INDEXED_DB_INTERNALS_JS" file="browser/resources/indexed_db/indexeddb_internals.js" type="BINDATA" />
+      <include name="IDR_INDEXED_DB_INTERNALS_CSS" file="browser/resources/indexed_db/indexeddb_internals.css" type="BINDATA" />
       <include name="IDR_NETWORK_ERROR_LISTING_HTML" file="browser/resources/net/network_errors_listing.html" flattenhtml="true" allowexternalscript="true" type="BINDATA" />
-      <include name="IDR_NETWORK_ERROR_LISTING_JS" file="browser/resources/net/network_errors_listing.js" flattenhtml="true" type="BINDATA" />
-      <include name="IDR_NETWORK_ERROR_LISTING_CSS" file="browser/resources/net/network_errors_listing.css" flattenhtml="true" type="BINDATA" />
+      <include name="IDR_NETWORK_ERROR_LISTING_JS" file="browser/resources/net/network_errors_listing.js" type="BINDATA" />
+      <include name="IDR_NETWORK_ERROR_LISTING_CSS" file="browser/resources/net/network_errors_listing.css" type="BINDATA" />
       <include name="IDR_PROCESS_INTERNALS_HTML" file="browser/resources/process/process_internals.html" flattenhtml="true" allowexternalscript="true" type="BINDATA" />
       <include name="IDR_PROCESS_INTERNALS_MOJO_JS" file="${root_gen_dir}/content/browser/process_internals/process_internals.mojom-lite.js" use_base_dir="false" type="BINDATA" />
       <include name="IDR_PROCESS_INTERNALS_CSS" file="browser/resources/process/process_internals.css" flattenhtml="true" type="BINDATA" />
-      <include name="IDR_PROCESS_INTERNALS_JS" file="browser/resources/process/process_internals.js" flattenhtml="true" type="BINDATA" />
+      <include name="IDR_PROCESS_INTERNALS_JS" file="browser/resources/process/process_internals.js" type="BINDATA" />
       <include name="IDR_SERVICE_WORKER_INTERNALS_HTML" file="browser/resources/service_worker/serviceworker_internals.html" flattenhtml="true" allowexternalscript="true" type="BINDATA" />
-      <include name="IDR_SERVICE_WORKER_INTERNALS_JS" file="browser/resources/service_worker/serviceworker_internals.js" flattenhtml="true" type="BINDATA" />
-      <include name="IDR_SERVICE_WORKER_INTERNALS_CSS" file="browser/resources/service_worker/serviceworker_internals.css" flattenhtml="true" type="BINDATA" />
+      <include name="IDR_SERVICE_WORKER_INTERNALS_JS" file="browser/resources/service_worker/serviceworker_internals.js" type="BINDATA" />
+      <include name="IDR_SERVICE_WORKER_INTERNALS_CSS" file="browser/resources/service_worker/serviceworker_internals.css" type="BINDATA" />
     </includes>
   </release>
 </grit>
diff --git a/content/renderer/accessibility/blink_ax_tree_source.cc b/content/renderer/accessibility/blink_ax_tree_source.cc
index c993d17..469fff5 100644
--- a/content/renderer/accessibility/blink_ax_tree_source.cc
+++ b/content/renderer/accessibility/blink_ax_tree_source.cc
@@ -275,10 +275,13 @@
     focus_ = WebAXObject::FromWebDocumentFocused(document_);
   else
     focus_ = WebAXObject();
+
+  WebAXObject::Freeze(document_);
 }
 
 void BlinkAXTreeSource::Thaw() {
   CHECK(frozen_);
+  WebAXObject::Thaw(document_);
   frozen_ = false;
 }
 
diff --git a/content/renderer/render_frame_impl.cc b/content/renderer/render_frame_impl.cc
index b9baf15..8e9a07a 100644
--- a/content/renderer/render_frame_impl.cc
+++ b/content/renderer/render_frame_impl.cc
@@ -5771,7 +5771,7 @@
       info->url_request.GetReferrerPolicy());
   params->disposition = RenderViewImpl::NavigationPolicyToDisposition(policy);
   params->triggering_event_info = info->triggering_event_info;
-  params->blob_url_token = CloneBlobURLToken(info->blob_url_token).PassPipe();
+  params->blob_url_token = CloneBlobURLToken(info->blob_url_token);
   params->should_replace_current_entry =
       info->frame_load_type == WebFrameLoadType::kReplaceCurrentItem &&
       render_view_->history_list_length_;
diff --git a/content/renderer/render_frame_proxy.cc b/content/renderer/render_frame_proxy.cc
index bad5cf3..65f3271 100644
--- a/content/renderer/render_frame_proxy.cc
+++ b/content/renderer/render_frame_proxy.cc
@@ -621,9 +621,7 @@
   params->should_replace_current_entry = should_replace_current_entry;
   params->user_gesture = request.HasUserGesture();
   params->triggering_event_info = blink::TriggeringEventInfo::kUnknown;
-  params->blob_url_token =
-      mojo::PendingRemote<blink::mojom::BlobURLToken>(std::move(blob_url_token))
-          .PassPipe();
+  params->blob_url_token = std::move(blob_url_token);
 
   RenderFrameImpl* initiator_render_frame =
       RenderFrameImpl::FromWebFrame(initiator_frame);
diff --git a/content/renderer/render_view_impl.cc b/content/renderer/render_view_impl.cc
index 51366db..3ae03a8 100644
--- a/content/renderer/render_view_impl.cc
+++ b/content/renderer/render_view_impl.cc
@@ -23,6 +23,7 @@
 #include "content/renderer/agent_scheduling_group.h"
 #include "content/renderer/render_frame_proxy.h"
 #include "content/renderer/render_thread_impl.h"
+#include "third_party/blink/public/common/features.h"
 #include "third_party/blink/public/platform/modules/video_capture/web_video_capture_impl_manager.h"
 #include "third_party/blink/public/platform/url_conversion.h"
 #include "third_party/blink/public/web/modules/mediastream/web_media_stream_device_observer.h"
@@ -364,11 +365,12 @@
   params->window_container_type = WindowFeaturesToContainerType(features);
 
   params->session_storage_namespace_id = session_storage_namespace_id;
-  // TODO(dmurph): Don't copy session storage when features.noopener is true:
-  // https://html.spec.whatwg.org/multipage/browsers.html#copy-session-storage
-  // https://crbug.com/771959
-  params->clone_from_session_storage_namespace_id =
-      session_storage_namespace_id_;
+  if (!features.noopener ||
+      base::FeatureList::IsEnabled(
+          blink::features::kCloneSessionStorageForNoOpener)) {
+    params->clone_from_session_storage_namespace_id =
+        session_storage_namespace_id_;
+  }
 
   const std::string& frame_name_utf8 = frame_name.Utf8(
       WebString::UTF8ConversionMode::kStrictReplacingErrorsWithFFFD);
diff --git a/content/test/data/accessibility/html/modal-dialog-opened-expected-blink.txt b/content/test/data/accessibility/html/modal-dialog-opened-expected-blink.txt
index a12e986..ec54a302 100644
--- a/content/test/data/accessibility/html/modal-dialog-opened-expected-blink.txt
+++ b/content/test/data/accessibility/html/modal-dialog-opened-expected-blink.txt
@@ -9,5 +9,6 @@
 ++++++++++++staticText name='Link inside the dialog.'
 ++++++++++++++inlineTextBox name='Link inside the dialog.'
 ++++++++popUpButton collapsed ignored invisible value='This should be pruned out of the tree.'
+++++++++++menuListPopup ignored invisible
 ++++++button ignored invisible name='No file chosen, Choose File' value='No file chosen'
 ++++++dialog ignored invisible
diff --git a/content/test/data/accessibility/html/modal-dialog-stack-expected-blink.txt b/content/test/data/accessibility/html/modal-dialog-stack-expected-blink.txt
index 58da506..251a6668 100644
--- a/content/test/data/accessibility/html/modal-dialog-stack-expected-blink.txt
+++ b/content/test/data/accessibility/html/modal-dialog-stack-expected-blink.txt
@@ -4,6 +4,7 @@
 ++++++section ignored invisible
 ++++++++dialog ignored invisible
 ++++++++popUpButton collapsed ignored invisible value='This should be pruned out of the tree.'
+++++++++++menuListPopup ignored invisible
 ++++++button ignored invisible name='This button should not be in the tree.'
 ++++++dialog ignored invisible
 ++++++dialog
@@ -12,4 +13,4 @@
 ++++++++button name='This is in the active dialog and should be in the tree.'
 ++++++++++staticText name='This is in the active dialog and should be in the tree.'
 ++++++++++++inlineTextBox name='This is in the active dialog and should be in the tree.'
-++++++dialog ignored invisible
\ No newline at end of file
+++++++dialog ignored invisible
diff --git a/content/test/data/dom_storage/noopener_cloning.html b/content/test/data/dom_storage/noopener_cloning.html
new file mode 100644
index 0000000..591fbe5
--- /dev/null
+++ b/content/test/data/dom_storage/noopener_cloning.html
@@ -0,0 +1,21 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+<title>Open a new window with noopener</title>
+</head>
+<body>
+<script>
+    var storage = window.sessionStorage;
+    storage.clear();
+
+    storage.setItem('setBy', 'firstTab');
+
+    let channel = new BroadcastChannel('storage_session_window_noopener');
+    channel.addEventListener('message', function(e) {
+        document.location.hash = '#'+e.data.setBy;
+    });
+
+    var win = window.open('session_storage_popup.html', '_blank', 'noopener');
+</script>
+</body>
+</html>
diff --git a/content/test/data/dom_storage/session_storage_popup.html b/content/test/data/dom_storage/session_storage_popup.html
new file mode 100644
index 0000000..1e17fe7
--- /dev/null
+++ b/content/test/data/dom_storage/session_storage_popup.html
@@ -0,0 +1,14 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+<title>Second page</title>
+</head>
+<body>
+<script>
+var storage = window.sessionStorage;
+let channel = new BroadcastChannel('storage_session_window_noopener');
+channel.postMessage({'setBy': storage.getItem('setBy')}, '*');
+window.close();
+</script>
+</body>
+</html>
diff --git a/content/test/data/gpu/webgl2_conformance_tests_output.json b/content/test/data/gpu/webgl2_conformance_tests_output.json
index 12365e8..61859a7 100644
--- a/content/test/data/gpu/webgl2_conformance_tests_output.json
+++ b/content/test/data/gpu/webgl2_conformance_tests_output.json
@@ -1,2766 +1,2795 @@
 {
   "times": {
-    "WebglExtension_EXT_color_buffer_float": 0.2869,
-    "WebglExtension_EXT_disjoint_timer_query_webgl2": 0.0793,
-    "WebglExtension_EXT_float_blend": 0.2885,
-    "WebglExtension_EXT_texture_filter_anisotropic": 0.1907,
-    "WebglExtension_KHR_parallel_shader_compile": 0.2299,
-    "WebglExtension_OES_texture_float_linear": 0.292,
+    "WebglExtension_EXT_color_buffer_float": 0.1446,
+    "WebglExtension_EXT_color_buffer_half_float": 0.339,
+    "WebglExtension_EXT_disjoint_timer_query_webgl2": 5.4755,
+    "WebglExtension_EXT_float_blend": 0.3712,
+    "WebglExtension_EXT_texture_compression_bptc": 0.4344,
+    "WebglExtension_EXT_texture_compression_rgtc": 0.1007,
+    "WebglExtension_EXT_texture_filter_anisotropic": 0.0623,
+    "WebglExtension_EXT_texture_norm16": 1.634,
+    "WebglExtension_KHR_parallel_shader_compile": 0.1973,
+    "WebglExtension_OES_draw_buffers_indexed": 0.3682,
+    "WebglExtension_OES_texture_float_linear": 0.2114,
     "WebglExtension_OVR_multiview2": 0.0,
-    "WebglExtension_TestCoverage": 0.4467,
+    "WebglExtension_TestCoverage": 1.8417,
     "WebglExtension_WEBGL_compressed_texture_astc": 0.0,
     "WebglExtension_WEBGL_compressed_texture_etc": 0.0,
     "WebglExtension_WEBGL_compressed_texture_etc1": 0.0,
     "WebglExtension_WEBGL_compressed_texture_pvrtc": 0.0,
-    "WebglExtension_WEBGL_compressed_texture_s3tc": 0.4547,
+    "WebglExtension_WEBGL_compressed_texture_s3tc": 0.2082,
     "WebglExtension_WEBGL_compressed_texture_s3tc_srgb": 0.0,
-    "WebglExtension_WEBGL_debug_renderer_info": 0.0797,
-    "WebglExtension_WEBGL_debug_shaders": 0.1963,
-    "WebglExtension_WEBGL_draw_instanced_base_vertex_base_instance": 0.2279,
-    "WebglExtension_WEBGL_lose_context": 0.0747,
-    "WebglExtension_WEBGL_multi_draw": 0.4056,
-    "WebglExtension_WEBGL_multi_draw_instanced_base_vertex_base_instance": 0.2579,
-    "WebglExtension_WEBGL_video_texture": 0.0751,
-    "conformance/attribs/gl-bindAttribLocation-aliasing.html": 0.4915,
-    "conformance/attribs/gl-bindAttribLocation-matrix.html": 0.5762,
-    "conformance/attribs/gl-bindAttribLocation-nonexistent-attribute.html": 0.3944,
-    "conformance/attribs/gl-bindAttribLocation-repeated.html": 0.2587,
-    "conformance/attribs/gl-disabled-vertex-attrib-update.html": 0.5183,
-    "conformance/attribs/gl-disabled-vertex-attrib.html": 0.8885,
-    "conformance/attribs/gl-enable-vertex-attrib.html": 0.3479,
-    "conformance/attribs/gl-matrix-attributes.html": 1.278,
-    "conformance/attribs/gl-vertex-attrib-context-switch.html": 0.6227,
-    "conformance/attribs/gl-vertex-attrib-render.html": 0.2233,
-    "conformance/attribs/gl-vertex-attrib-unconsumed-out-of-bounds.html": 0.7191,
-    "conformance/attribs/gl-vertex-attrib-zero-issues.html": 0.8311,
-    "conformance/attribs/gl-vertexattribpointer-offsets.html": 0.5675,
-    "conformance/attribs/gl-vertexattribpointer.html": 1.3594,
-    "conformance/buffers/buffer-bind-test.html": 0.2543,
-    "conformance/buffers/buffer-data-and-buffer-sub-data.html": 0.1381,
-    "conformance/buffers/buffer-data-array-buffer-delete.html": 2.3345,
-    "conformance/buffers/buffer-data-dynamic-delay.html": 0.5449,
-    "conformance/buffers/buffer-uninitialized.html": 0.5411,
-    "conformance/buffers/element-array-buffer-delete-recreate.html": 0.3643,
-    "conformance/buffers/index-validation-copies-indices.html": 0.251,
-    "conformance/buffers/index-validation-crash-with-buffer-sub-data.html": 0.0914,
-    "conformance/buffers/index-validation-large-buffer.html": 0.273,
-    "conformance/buffers/index-validation-verifies-too-many-indices.html": 0.3799,
-    "conformance/buffers/index-validation-with-resized-buffer.html": 0.2776,
-    "conformance/buffers/index-validation.html": 0.2932,
-    "conformance/buffers/vertex-buffer-updated-after-draw.html": 0.4438,
-    "conformance/canvas/buffer-offscreen-test.html": 0.3145,
-    "conformance/canvas/buffer-preserve-test.html": 0.2925,
-    "conformance/canvas/canvas-test.html": 0.4482,
-    "conformance/canvas/canvas-zero-size.html": 0.2408,
-    "conformance/canvas/draw-static-webgl-to-multiple-canvas-test.html": 0.7437,
-    "conformance/canvas/draw-webgl-to-canvas-test.html": 0.6131,
-    "conformance/canvas/drawingbuffer-hd-dpi-test.html": 0.9246,
-    "conformance/canvas/drawingbuffer-static-canvas-test.html": 0.136,
-    "conformance/canvas/drawingbuffer-test.html": 0.2574,
-    "conformance/canvas/framebuffer-bindings-affected-by-to-data-url.html": 0.2318,
-    "conformance/canvas/framebuffer-bindings-unaffected-on-resize.html": 0.3386,
-    "conformance/canvas/rapid-resizing.html": 2.553,
-    "conformance/canvas/render-after-resize-test.html": 0.6379,
-    "conformance/canvas/texture-bindings-unaffected-on-resize.html": 0.4092,
-    "conformance/canvas/to-data-url-test.html": 0.4894,
-    "conformance/canvas/viewport-unchanged-upon-resize.html": 0.2791,
-    "conformance/context/context-attribute-preserve-drawing-buffer.html": 0.5094,
-    "conformance/context/context-attributes-alpha-depth-stencil-antialias.html": 0.8128,
-    "conformance/context/context-creation-and-destruction.html": 1.0634,
-    "conformance/context/context-creation.html": 1.409,
-    "conformance/context/context-eviction-with-garbage-collection.html": 2.0976,
-    "conformance/context/context-hidden-alpha.html": 0.4056,
-    "conformance/context/context-lost-restored.html": 0.4697,
-    "conformance/context/context-lost.html": 0.3307,
-    "conformance/context/context-no-alpha-fbo-with-alpha.html": 0.1912,
-    "conformance/context/context-release-upon-reload.html": 1.8307,
-    "conformance/context/context-release-with-workers.html": 3.0651,
-    "conformance/context/context-size-change.html": 0.3609,
-    "conformance/context/incorrect-context-object-behaviour.html": 0.602,
-    "conformance/context/premultiplyalpha-test.html": 0.7513,
-    "conformance/context/user-defined-properties-on-context.html": 0.1407,
-    "conformance/extensions/ext-disjoint-timer-query.html": 0.0864,
-    "conformance/extensions/ext-float-blend.html": 0.3021,
-    "conformance/extensions/ext-texture-compression-bptc.html": 0.2276,
-    "conformance/extensions/ext-texture-compression-rgtc.html": 0.1823,
-    "conformance/extensions/ext-texture-filter-anisotropic.html": 0.1468,
-    "conformance/extensions/get-extension.html": 0.5077,
-    "conformance/extensions/oes-texture-float-linear.html": 0.5452,
-    "conformance/extensions/webgl-compressed-texture-astc.html": 0.1553,
-    "conformance/extensions/webgl-compressed-texture-etc.html": 0.1887,
-    "conformance/extensions/webgl-compressed-texture-etc1.html": 0.1477,
-    "conformance/extensions/webgl-compressed-texture-pvrtc.html": 0.3173,
-    "conformance/extensions/webgl-compressed-texture-s3tc-srgb.html": 0.1118,
-    "conformance/extensions/webgl-compressed-texture-s3tc.html": 1.8155,
-    "conformance/extensions/webgl-compressed-texture-size-limit.html": 4.6617,
-    "conformance/extensions/webgl-debug-renderer-info.html": 0.1597,
-    "conformance/extensions/webgl-debug-shaders.html": 0.1482,
-    "conformance/extensions/webgl-multi-draw.html": 1.1833,
-    "conformance/glsl/bugs/angle-ambiguous-function-call.html": 0.4474,
-    "conformance/glsl/bugs/angle-constructor-invalid-parameters.html": 0.3898,
-    "conformance/glsl/bugs/angle-d3d11-compiler-error.html": 0.1393,
-    "conformance/glsl/bugs/angle-dx-variable-bug.html": 0.1094,
-    "conformance/glsl/bugs/array-of-struct-with-int-first-position.html": 0.3541,
-    "conformance/glsl/bugs/assign-to-swizzled-twice-in-function.html": 0.1833,
-    "conformance/glsl/bugs/bool-type-cast-bug-int-float.html": 0.2299,
-    "conformance/glsl/bugs/compare-loop-index-to-uniform.html": 0.4096,
-    "conformance/glsl/bugs/complex-glsl-does-not-crash.html": 3.045,
-    "conformance/glsl/bugs/compound-assignment-type-combination.html": 1.6579,
-    "conformance/glsl/bugs/conditional-discard-in-loop.html": 0.5571,
-    "conformance/glsl/bugs/conditional-discard-optimization.html": 0.5035,
-    "conformance/glsl/bugs/conditional-texture-fetch.html": 0.242,
-    "conformance/glsl/bugs/constant-precision-qualifier.html": 0.4809,
-    "conformance/glsl/bugs/floor-div-cos-should-not-truncate.html": 0.3789,
-    "conformance/glsl/bugs/floored-division-accuracy.html": 0.2016,
-    "conformance/glsl/bugs/fragcoord-linking-bug.html": 0.1313,
-    "conformance/glsl/bugs/gl-fragcoord-multisampling-bug.html": 0.5324,
-    "conformance/glsl/bugs/global-invariant-does-not-leak-across-shaders.html": 0.2553,
-    "conformance/glsl/bugs/if-return-and-elseif.html": 0.5127,
-    "conformance/glsl/bugs/in-parameter-passed-as-inout-argument-and-global.html": 0.2905,
-    "conformance/glsl/bugs/init-array-with-loop.html": 0.3041,
-    "conformance/glsl/bugs/invariant-does-not-leak-across-shaders.html": 0.1121,
-    "conformance/glsl/bugs/logic-inside-block-without-braces.html": 0.3774,
-    "conformance/glsl/bugs/long-expressions-should-not-crash.html": 1.0295,
-    "conformance/glsl/bugs/loop-if-loop-gradient.html": 0.3219,
-    "conformance/glsl/bugs/modulo-arithmetic-accuracy.html": 0.611,
-    "conformance/glsl/bugs/multiplication-assignment.html": 0.2416,
-    "conformance/glsl/bugs/nested-functions-should-not-crash.html": 0.6006,
-    "conformance/glsl/bugs/nested-loops-with-break-and-continue.html": 0.5376,
-    "conformance/glsl/bugs/nested-sequence-operator.html": 0.3051,
-    "conformance/glsl/bugs/pow-of-small-constant-in-user-defined-function.html": 0.4495,
-    "conformance/glsl/bugs/pow-with-constant-exponent-should-not-crash.html": 0.5272,
-    "conformance/glsl/bugs/qualcomm-crash.html": 0.4106,
-    "conformance/glsl/bugs/qualcomm-loop-with-continue-crash.html": 0.3388,
-    "conformance/glsl/bugs/sampler-array-struct-function-arg.html": 0.4057,
-    "conformance/glsl/bugs/sampler-array-using-loop-index.html": 0.2649,
-    "conformance/glsl/bugs/sampler-struct-function-arg.html": 0.4318,
-    "conformance/glsl/bugs/sequence-operator-evaluation-order.html": 0.357,
-    "conformance/glsl/bugs/sketchfab-lighting-shader-crash.html": 0.3181,
-    "conformance/glsl/bugs/struct-constructor-highp-bug.html": 0.3555,
-    "conformance/glsl/bugs/struct-with-single-member-constructor.html": 0.3487,
-    "conformance/glsl/bugs/temp-expressions-should-not-crash.html": 1.3547,
-    "conformance/glsl/bugs/unary-minus-operator-float-bug.html": 0.1732,
-    "conformance/glsl/bugs/undefined-index-should-not-crash.html": 0.4692,
-    "conformance/glsl/bugs/uniforms-should-not-lose-values.html": 0.4488,
-    "conformance/glsl/bugs/varying-arrays-should-not-be-reversed.html": 0.351,
-    "conformance/glsl/bugs/vector-scalar-arithmetic-inside-loop-complex.html": 0.5292,
-    "conformance/glsl/bugs/vector-scalar-arithmetic-inside-loop.html": 0.4999,
-    "conformance/glsl/constructors/glsl-construct-bvec2.html": 0.7343,
-    "conformance/glsl/constructors/glsl-construct-bvec3.html": 1.0265,
-    "conformance/glsl/constructors/glsl-construct-bvec4.html": 1.0085,
-    "conformance/glsl/constructors/glsl-construct-ivec2.html": 1.1214,
-    "conformance/glsl/constructors/glsl-construct-ivec3.html": 0.9382,
-    "conformance/glsl/constructors/glsl-construct-ivec4.html": 1.1248,
-    "conformance/glsl/constructors/glsl-construct-mat2.html": 1.0183,
-    "conformance/glsl/constructors/glsl-construct-mat3.html": 0.8844,
-    "conformance/glsl/constructors/glsl-construct-mat4.html": 0.8429,
-    "conformance/glsl/constructors/glsl-construct-vec-mat-corner-cases.html": 0.4783,
-    "conformance/glsl/constructors/glsl-construct-vec-mat-index.html": 0.4215,
-    "conformance/glsl/constructors/glsl-construct-vec2.html": 0.8878,
-    "conformance/glsl/constructors/glsl-construct-vec3.html": 0.7861,
-    "conformance/glsl/constructors/glsl-construct-vec4.html": 1.1436,
-    "conformance/glsl/functions/glsl-function-abs.html": 0.9999,
-    "conformance/glsl/functions/glsl-function-acos.html": 0.7573,
-    "conformance/glsl/functions/glsl-function-asin.html": 0.9544,
-    "conformance/glsl/functions/glsl-function-atan-xy.html": 1.2727,
-    "conformance/glsl/functions/glsl-function-atan.html": 1.1137,
-    "conformance/glsl/functions/glsl-function-ceil.html": 0.7743,
-    "conformance/glsl/functions/glsl-function-clamp-float.html": 0.8227,
-    "conformance/glsl/functions/glsl-function-clamp-gentype.html": 1.0022,
-    "conformance/glsl/functions/glsl-function-cos.html": 0.9351,
-    "conformance/glsl/functions/glsl-function-cross.html": 0.5652,
-    "conformance/glsl/functions/glsl-function-distance.html": 0.8207,
-    "conformance/glsl/functions/glsl-function-dot.html": 0.9714,
-    "conformance/glsl/functions/glsl-function-faceforward.html": 0.9491,
-    "conformance/glsl/functions/glsl-function-floor.html": 0.9221,
-    "conformance/glsl/functions/glsl-function-fract.html": 0.8905,
-    "conformance/glsl/functions/glsl-function-length.html": 0.9298,
-    "conformance/glsl/functions/glsl-function-max-float.html": 0.9769,
-    "conformance/glsl/functions/glsl-function-max-gentype.html": 1.2693,
-    "conformance/glsl/functions/glsl-function-min-float.html": 0.8214,
-    "conformance/glsl/functions/glsl-function-min-gentype.html": 0.7212,
-    "conformance/glsl/functions/glsl-function-mix-float.html": 0.7596,
-    "conformance/glsl/functions/glsl-function-mix-gentype.html": 0.7333,
-    "conformance/glsl/functions/glsl-function-mod-float.html": 0.8949,
-    "conformance/glsl/functions/glsl-function-mod-gentype.html": 0.9528,
-    "conformance/glsl/functions/glsl-function-normalize.html": 0.8825,
-    "conformance/glsl/functions/glsl-function-reflect.html": 0.977,
-    "conformance/glsl/functions/glsl-function-sign.html": 0.961,
-    "conformance/glsl/functions/glsl-function-sin.html": 0.8937,
-    "conformance/glsl/functions/glsl-function-smoothstep-float.html": 0.9502,
-    "conformance/glsl/functions/glsl-function-smoothstep-gentype.html": 0.7938,
-    "conformance/glsl/functions/glsl-function-step-float.html": 0.7023,
-    "conformance/glsl/functions/glsl-function-step-gentype.html": 0.8436,
-    "conformance/glsl/functions/glsl-function.html": 0.7405,
-    "conformance/glsl/implicit/add_int_float.vert.html": 0.2647,
-    "conformance/glsl/implicit/add_int_mat2.vert.html": 0.4285,
-    "conformance/glsl/implicit/add_int_mat3.vert.html": 0.4461,
-    "conformance/glsl/implicit/add_int_mat4.vert.html": 0.4444,
-    "conformance/glsl/implicit/add_int_vec2.vert.html": 0.4873,
-    "conformance/glsl/implicit/add_int_vec3.vert.html": 0.1577,
-    "conformance/glsl/implicit/add_int_vec4.vert.html": 0.4388,
-    "conformance/glsl/implicit/add_ivec2_vec2.vert.html": 0.3244,
-    "conformance/glsl/implicit/add_ivec3_vec3.vert.html": 0.6937,
-    "conformance/glsl/implicit/add_ivec4_vec4.vert.html": 0.2505,
-    "conformance/glsl/implicit/assign_int_to_float.vert.html": 0.4134,
-    "conformance/glsl/implicit/assign_ivec2_to_vec2.vert.html": 0.4147,
-    "conformance/glsl/implicit/assign_ivec3_to_vec3.vert.html": 0.1787,
-    "conformance/glsl/implicit/assign_ivec4_to_vec4.vert.html": 0.1026,
-    "conformance/glsl/implicit/construct_struct.vert.html": 0.475,
-    "conformance/glsl/implicit/divide_int_float.vert.html": 0.1083,
-    "conformance/glsl/implicit/divide_int_mat2.vert.html": 0.2242,
-    "conformance/glsl/implicit/divide_int_mat3.vert.html": 0.1889,
-    "conformance/glsl/implicit/divide_int_mat4.vert.html": 0.424,
-    "conformance/glsl/implicit/divide_int_vec2.vert.html": 0.1444,
-    "conformance/glsl/implicit/divide_int_vec3.vert.html": 0.1377,
-    "conformance/glsl/implicit/divide_int_vec4.vert.html": 0.1725,
-    "conformance/glsl/implicit/divide_ivec2_vec2.vert.html": 0.0991,
-    "conformance/glsl/implicit/divide_ivec3_vec3.vert.html": 0.1922,
-    "conformance/glsl/implicit/divide_ivec4_vec4.vert.html": 0.136,
-    "conformance/glsl/implicit/equal_int_float.vert.html": 0.1016,
-    "conformance/glsl/implicit/equal_ivec2_vec2.vert.html": 0.1104,
-    "conformance/glsl/implicit/equal_ivec3_vec3.vert.html": 0.1553,
-    "conformance/glsl/implicit/equal_ivec4_vec4.vert.html": 0.0994,
-    "conformance/glsl/implicit/function_int_float.vert.html": 0.2162,
-    "conformance/glsl/implicit/function_ivec2_vec2.vert.html": 0.4333,
-    "conformance/glsl/implicit/function_ivec3_vec3.vert.html": 0.4464,
-    "conformance/glsl/implicit/function_ivec4_vec4.vert.html": 0.0927,
-    "conformance/glsl/implicit/greater_than.vert.html": 0.2225,
-    "conformance/glsl/implicit/greater_than_equal.vert.html": 0.1107,
-    "conformance/glsl/implicit/less_than.vert.html": 0.0906,
-    "conformance/glsl/implicit/less_than_equal.vert.html": 0.2155,
-    "conformance/glsl/implicit/multiply_int_float.vert.html": 0.1019,
-    "conformance/glsl/implicit/multiply_int_mat2.vert.html": 0.1157,
-    "conformance/glsl/implicit/multiply_int_mat3.vert.html": 0.1471,
-    "conformance/glsl/implicit/multiply_int_mat4.vert.html": 0.948,
-    "conformance/glsl/implicit/multiply_int_vec2.vert.html": 0.1562,
-    "conformance/glsl/implicit/multiply_int_vec3.vert.html": 0.1787,
-    "conformance/glsl/implicit/multiply_int_vec4.vert.html": 0.1934,
-    "conformance/glsl/implicit/multiply_ivec2_vec2.vert.html": 0.1727,
-    "conformance/glsl/implicit/multiply_ivec3_vec3.vert.html": 0.2145,
-    "conformance/glsl/implicit/multiply_ivec4_vec4.vert.html": 0.2256,
-    "conformance/glsl/implicit/not_equal_int_float.vert.html": 0.138,
-    "conformance/glsl/implicit/not_equal_ivec2_vec2.vert.html": 0.4392,
-    "conformance/glsl/implicit/not_equal_ivec3_vec3.vert.html": 0.1499,
-    "conformance/glsl/implicit/not_equal_ivec4_vec4.vert.html": 0.2232,
-    "conformance/glsl/implicit/subtract_int_float.vert.html": 0.4312,
-    "conformance/glsl/implicit/subtract_int_mat2.vert.html": 0.1768,
-    "conformance/glsl/implicit/subtract_int_mat3.vert.html": 0.1323,
-    "conformance/glsl/implicit/subtract_int_mat4.vert.html": 0.1005,
-    "conformance/glsl/implicit/subtract_int_vec2.vert.html": 0.1239,
-    "conformance/glsl/implicit/subtract_int_vec3.vert.html": 0.1136,
-    "conformance/glsl/implicit/subtract_int_vec4.vert.html": 0.1997,
-    "conformance/glsl/implicit/subtract_ivec2_vec2.vert.html": 0.0873,
-    "conformance/glsl/implicit/subtract_ivec3_vec3.vert.html": 0.0995,
-    "conformance/glsl/implicit/subtract_ivec4_vec4.vert.html": 0.1062,
-    "conformance/glsl/implicit/ternary_int_float.vert.html": 0.1224,
-    "conformance/glsl/implicit/ternary_ivec2_vec2.vert.html": 0.4348,
-    "conformance/glsl/implicit/ternary_ivec3_vec3.vert.html": 0.2042,
-    "conformance/glsl/implicit/ternary_ivec4_vec4.vert.html": 0.152,
-    "conformance/glsl/literals/float_literal.vert.html": 0.1232,
-    "conformance/glsl/literals/literal_precision.html": 0.1918,
-    "conformance/glsl/literals/overflow_leak.vert.html": 0.0936,
-    "conformance/glsl/matrices/glsl-mat3-construction.html": 0.5011,
-    "conformance/glsl/matrices/glsl-mat4-to-mat3.html": 0.3862,
-    "conformance/glsl/matrices/matrix-compound-multiply.html": 0.4507,
-    "conformance/glsl/misc/boolean_precision.html": 0.4976,
-    "conformance/glsl/misc/const-variable-initialization.html": 1.7328,
-    "conformance/glsl/misc/embedded-struct-definitions-forbidden.html": 0.3597,
-    "conformance/glsl/misc/empty-declaration.html": 0.1573,
-    "conformance/glsl/misc/empty_main.vert.html": 0.1827,
-    "conformance/glsl/misc/expression-list-in-declarator-initializer.html": 0.5344,
-    "conformance/glsl/misc/fragcolor-fragdata-invariant.html": 0.1938,
-    "conformance/glsl/misc/gl_position_unset.vert.html": 0.2985,
-    "conformance/glsl/misc/global-variable-init.html": 0.6686,
-    "conformance/glsl/misc/glsl-function-nodes.html": 0.4746,
-    "conformance/glsl/misc/glsl-long-variable-names.html": 0.5213,
-    "conformance/glsl/misc/glsl-vertex-branch.html": 0.4506,
-    "conformance/glsl/misc/large-loop-compile.html": 0.6976,
-    "conformance/glsl/misc/local-variable-shadowing-outer-function.html": 0.1314,
-    "conformance/glsl/misc/non-ascii-comments.vert.html": 0.2396,
-    "conformance/glsl/misc/non-ascii.vert.html": 0.5372,
-    "conformance/glsl/misc/re-compile-re-link.html": 0.1525,
-    "conformance/glsl/misc/sampler-operand.html": 0.3744,
-    "conformance/glsl/misc/sequence-operator-returns-constant.html": 0.2793,
-    "conformance/glsl/misc/shader-precision-format-obeyed.html": 0.3009,
-    "conformance/glsl/misc/shader-struct-scope.html": 0.2919,
-    "conformance/glsl/misc/shader-uniform-packing-restrictions.html": 3.741,
-    "conformance/glsl/misc/shader-varying-packing-restrictions.html": 0.9811,
-    "conformance/glsl/misc/shader-with-256-character-define.html": 0.4658,
-    "conformance/glsl/misc/shader-with-256-character-identifier.frag.html": 0.1658,
-    "conformance/glsl/misc/shader-with-_webgl-identifier.vert.html": 0.2828,
-    "conformance/glsl/misc/shader-with-arbitrary-indexing.frag.html": 0.1117,
-    "conformance/glsl/misc/shader-with-arbitrary-indexing.vert.html": 0.4599,
-    "conformance/glsl/misc/shader-with-array-of-structs-containing-arrays.html": 0.5019,
-    "conformance/glsl/misc/shader-with-array-of-structs-uniform.html": 0.5014,
-    "conformance/glsl/misc/shader-with-attrib-array.vert.html": 0.1754,
-    "conformance/glsl/misc/shader-with-attrib-struct.vert.html": 0.1199,
-    "conformance/glsl/misc/shader-with-clipvertex.vert.html": 0.3281,
-    "conformance/glsl/misc/shader-with-comma-assignment.html": 0.2813,
-    "conformance/glsl/misc/shader-with-comma-conditional-assignment.html": 0.5028,
-    "conformance/glsl/misc/shader-with-comma-separated-variable-declarations.html": 0.4256,
-    "conformance/glsl/misc/shader-with-conditional-scoping-negative.html": 0.2159,
-    "conformance/glsl/misc/shader-with-conditional-scoping.html": 0.2991,
-    "conformance/glsl/misc/shader-with-default-precision.frag.html": 0.2312,
-    "conformance/glsl/misc/shader-with-default-precision.vert.html": 0.1037,
-    "conformance/glsl/misc/shader-with-dfdx-no-ext.frag.html": 0.8677,
-    "conformance/glsl/misc/shader-with-dfdx.frag.html": 0.0859,
-    "conformance/glsl/misc/shader-with-do-loop.html": 0.3018,
-    "conformance/glsl/misc/shader-with-error-directive.html": 0.3545,
-    "conformance/glsl/misc/shader-with-explicit-int-cast.vert.html": 0.2981,
-    "conformance/glsl/misc/shader-with-float-return-value.frag.html": 0.3706,
-    "conformance/glsl/misc/shader-with-for-loop.html": 0.1534,
-    "conformance/glsl/misc/shader-with-for-scoping.html": 0.2455,
-    "conformance/glsl/misc/shader-with-frag-depth.frag.html": 0.3453,
-    "conformance/glsl/misc/shader-with-function-recursion.frag.html": 0.4297,
-    "conformance/glsl/misc/shader-with-function-scoped-struct.html": 0.4402,
-    "conformance/glsl/misc/shader-with-functional-scoping.html": 0.1078,
-    "conformance/glsl/misc/shader-with-glcolor.vert.html": 0.1871,
-    "conformance/glsl/misc/shader-with-gles-1.frag.html": 0.1641,
-    "conformance/glsl/misc/shader-with-gles-symbol.frag.html": 0.2004,
-    "conformance/glsl/misc/shader-with-global-variable-precision-mismatch.html": 0.3769,
-    "conformance/glsl/misc/shader-with-glprojectionmatrix.vert.html": 0.172,
-    "conformance/glsl/misc/shader-with-hex-int-constant-macro.html": 0.102,
-    "conformance/glsl/misc/shader-with-implicit-vec3-to-vec4-cast.vert.html": 0.2414,
-    "conformance/glsl/misc/shader-with-include.vert.html": 0.3848,
-    "conformance/glsl/misc/shader-with-int-return-value.frag.html": 0.3654,
-    "conformance/glsl/misc/shader-with-invalid-identifier.frag.html": 0.2529,
-    "conformance/glsl/misc/shader-with-ivec2-return-value.frag.html": 0.2884,
-    "conformance/glsl/misc/shader-with-ivec3-return-value.frag.html": 0.25,
-    "conformance/glsl/misc/shader-with-ivec4-return-value.frag.html": 0.2404,
-    "conformance/glsl/misc/shader-with-limited-indexing.frag.html": 0.2095,
-    "conformance/glsl/misc/shader-with-long-line.html": 0.2511,
-    "conformance/glsl/misc/shader-with-non-ascii-error.frag.html": 0.2307,
-    "conformance/glsl/misc/shader-with-non-reserved-words.html": 31.2691,
-    "conformance/glsl/misc/shader-with-precision.frag.html": 0.2107,
-    "conformance/glsl/misc/shader-with-preprocessor-whitespace.html": 0.0985,
-    "conformance/glsl/misc/shader-with-quoted-error.frag.html": 0.392,
-    "conformance/glsl/misc/shader-with-reserved-words.html": 3.4683,
-    "conformance/glsl/misc/shader-with-short-circuiting-operators.html": 0.4882,
-    "conformance/glsl/misc/shader-with-similar-uniform-array-names.html": 0.3349,
-    "conformance/glsl/misc/shader-with-too-many-uniforms.html": 0.5555,
-    "conformance/glsl/misc/shader-with-two-initializer-types.html": 0.2273,
-    "conformance/glsl/misc/shader-with-undefined-preprocessor-symbol.frag.html": 0.179,
-    "conformance/glsl/misc/shader-with-uniform-in-loop-condition.vert.html": 0.4405,
-    "conformance/glsl/misc/shader-with-vec2-return-value.frag.html": 0.1245,
-    "conformance/glsl/misc/shader-with-vec3-return-value.frag.html": 0.1886,
-    "conformance/glsl/misc/shader-with-vec4-return-value.frag.html": 0.3755,
-    "conformance/glsl/misc/shader-with-vec4-vec3-vec4-conditional.html": 0.3728,
-    "conformance/glsl/misc/shader-with-version-100.frag.html": 0.1309,
-    "conformance/glsl/misc/shader-with-version-100.vert.html": 0.2228,
-    "conformance/glsl/misc/shader-with-version-120.vert.html": 0.1883,
-    "conformance/glsl/misc/shader-with-version-130.vert.html": 0.1931,
-    "conformance/glsl/misc/shader-with-webgl-identifier.vert.html": 0.3087,
-    "conformance/glsl/misc/shader-with-while-loop.html": 0.1369,
-    "conformance/glsl/misc/shader-without-precision.frag.html": 0.1998,
-    "conformance/glsl/misc/shaders-with-constant-expression-loop-conditions.html": 0.3886,
-    "conformance/glsl/misc/shaders-with-invariance.html": 0.4335,
-    "conformance/glsl/misc/shaders-with-mis-matching-uniforms.html": 0.3616,
-    "conformance/glsl/misc/shaders-with-mis-matching-varyings.html": 0.3416,
-    "conformance/glsl/misc/shaders-with-missing-varyings.html": 0.5415,
-    "conformance/glsl/misc/shaders-with-name-conflicts.html": 0.1844,
-    "conformance/glsl/misc/shaders-with-uniform-structs.html": 0.4423,
-    "conformance/glsl/misc/shaders-with-varyings.html": 0.3408,
-    "conformance/glsl/misc/shared.html": 0.2145,
-    "conformance/glsl/misc/struct-as-inout-parameter.html": 0.4871,
-    "conformance/glsl/misc/struct-as-out-parameter.html": 0.5724,
-    "conformance/glsl/misc/struct-assign.html": 0.571,
-    "conformance/glsl/misc/struct-equals.html": 0.2183,
-    "conformance/glsl/misc/struct-mixed-array-declarators.html": 0.8844,
-    "conformance/glsl/misc/struct-nesting-exceeds-maximum.html": 0.4162,
-    "conformance/glsl/misc/struct-nesting-of-variable-names.html": 1.6443,
-    "conformance/glsl/misc/struct-nesting-under-maximum.html": 0.4733,
-    "conformance/glsl/misc/struct-specifiers-in-uniforms.html": 0.5015,
-    "conformance/glsl/misc/struct-unary-operators.html": 0.6148,
-    "conformance/glsl/misc/ternary-operator-on-arrays.html": 0.1649,
-    "conformance/glsl/misc/ternary-operators-in-global-initializers.html": 0.5738,
-    "conformance/glsl/misc/ternary-operators-in-initializers.html": 0.6447,
-    "conformance/glsl/misc/uninitialized-local-global-variables.html": 0.5446,
-    "conformance/glsl/preprocessor/macro-expansion-tricky.html": 0.4313,
-    "conformance/glsl/reserved/_webgl_field.vert.html": 0.3469,
-    "conformance/glsl/reserved/_webgl_function.vert.html": 0.222,
-    "conformance/glsl/reserved/_webgl_struct.vert.html": 0.1632,
-    "conformance/glsl/reserved/_webgl_variable.vert.html": 0.1169,
-    "conformance/glsl/reserved/webgl_field.vert.html": 0.1761,
-    "conformance/glsl/reserved/webgl_function.vert.html": 0.3486,
-    "conformance/glsl/reserved/webgl_struct.vert.html": 0.2778,
-    "conformance/glsl/reserved/webgl_variable.vert.html": 0.1007,
-    "conformance/glsl/samplers/glsl-function-texture2d-bias.html": 0.4308,
-    "conformance/glsl/samplers/glsl-function-texture2dlod.html": 0.4996,
-    "conformance/glsl/samplers/glsl-function-texture2dproj.html": 0.688,
-    "conformance/glsl/samplers/glsl-function-texture2dprojlod.html": 1.4179,
-    "conformance/glsl/variables/gl-fragcoord-xy-values.html": 0.2409,
-    "conformance/glsl/variables/gl-fragcoord.html": 0.1557,
-    "conformance/glsl/variables/gl-fragdata-and-fragcolor.html": 0.3499,
-    "conformance/glsl/variables/gl-frontfacing.html": 0.1251,
-    "conformance/glsl/variables/gl-pointcoord.html": 0.3745,
-    "conformance/glsl/variables/glsl-built-ins.html": 0.6401,
-    "conformance/limits/gl-line-width.html": 0.1802,
-    "conformance/limits/gl-max-texture-dimensions.html": 0.2655,
-    "conformance/limits/gl-min-attribs.html": 0.308,
-    "conformance/limits/gl-min-textures.html": 0.3021,
-    "conformance/limits/gl-min-uniforms.html": 0.1626,
-    "conformance/misc/bad-arguments-test.html": 0.4447,
-    "conformance/misc/boolean-argument-conversion.html": 0.4376,
-    "conformance/misc/delayed-drawing.html": 1.1509,
-    "conformance/misc/error-reporting.html": 0.1132,
-    "conformance/misc/expando-loss.html": 0.409,
-    "conformance/misc/functions-returning-strings.html": 0.1995,
-    "conformance/misc/invalid-passed-params.html": 0.1768,
-    "conformance/misc/is-object.html": 0.2447,
-    "conformance/misc/null-object-behaviour.html": 0.1548,
-    "conformance/misc/object-deletion-behaviour.html": 0.4387,
-    "conformance/misc/shader-precision-format.html": 0.1897,
-    "conformance/misc/type-conversion-test.html": 0.1885,
-    "conformance/misc/uninitialized-test.html": 0.4569,
-    "conformance/misc/webgl-specific-stencil-settings.html": 1.0069,
-    "conformance/misc/webgl-specific.html": 0.1686,
-    "conformance/more/conformance/constants.html": 0.1393,
-    "conformance/more/conformance/getContext.html": 0.1362,
-    "conformance/more/conformance/methods.html": 0.1488,
-    "conformance/more/conformance/quickCheckAPI-A.html": 0.324,
-    "conformance/more/conformance/quickCheckAPI-B1.html": 0.6737,
-    "conformance/more/conformance/quickCheckAPI-B2.html": 0.2691,
-    "conformance/more/conformance/quickCheckAPI-B3.html": 0.3313,
-    "conformance/more/conformance/quickCheckAPI-B4.html": 0.294,
-    "conformance/more/conformance/quickCheckAPI-C.html": 0.211,
-    "conformance/more/conformance/quickCheckAPI-D_G.html": 0.2869,
-    "conformance/more/conformance/quickCheckAPI-G_I.html": 0.4242,
-    "conformance/more/conformance/quickCheckAPI-L_S.html": 0.3827,
-    "conformance/more/conformance/quickCheckAPI-S_V.html": 0.318,
-    "conformance/more/conformance/webGLArrays.html": 0.1931,
-    "conformance/more/functions/bindBuffer.html": 0.1655,
-    "conformance/more/functions/bindBufferBadArgs.html": 0.1473,
-    "conformance/more/functions/bindFramebufferLeaveNonZero.html": 0.2067,
-    "conformance/more/functions/bufferData.html": 0.1255,
-    "conformance/more/functions/bufferDataBadArgs.html": 0.2004,
-    "conformance/more/functions/bufferSubData.html": 0.1715,
-    "conformance/more/functions/bufferSubDataBadArgs.html": 0.1272,
-    "conformance/more/functions/copyTexImage2D.html": 0.229,
-    "conformance/more/functions/copyTexImage2DBadArgs.html": 0.4002,
-    "conformance/more/functions/copyTexSubImage2D.html": 0.2132,
-    "conformance/more/functions/copyTexSubImage2DBadArgs.html": 0.2529,
-    "conformance/more/functions/deleteBufferBadArgs.html": 0.265,
-    "conformance/more/functions/drawArrays.html": 0.1956,
-    "conformance/more/functions/drawElements.html": 0.1821,
-    "conformance/more/functions/isTests.html": 0.5108,
-    "conformance/more/functions/isTestsBadArgs.html": 0.0803,
-    "conformance/more/functions/readPixels.html": 0.1523,
-    "conformance/more/functions/readPixelsBadArgs.html": 0.1885,
-    "conformance/more/functions/texImage2D.html": 0.2642,
-    "conformance/more/functions/texImage2DBadArgs.html": 0.3565,
-    "conformance/more/functions/texImage2DHTML.html": 0.2847,
-    "conformance/more/functions/texImage2DHTMLBadArgs.html": 0.3331,
-    "conformance/more/functions/texSubImage2D.html": 0.311,
-    "conformance/more/functions/texSubImage2DBadArgs.html": 0.1927,
-    "conformance/more/functions/texSubImage2DHTML.html": 0.5116,
-    "conformance/more/functions/texSubImage2DHTMLBadArgs.html": 0.1265,
-    "conformance/more/functions/uniformMatrix.html": 0.1662,
-    "conformance/more/functions/uniformMatrixBadArgs.html": 0.3508,
-    "conformance/more/functions/uniformf.html": 0.3621,
-    "conformance/more/functions/uniformfArrayLen1.html": 0.2079,
-    "conformance/more/functions/uniformfBadArgs.html": 0.363,
-    "conformance/more/functions/uniformi.html": 0.3472,
-    "conformance/more/functions/uniformiBadArgs.html": 0.2388,
-    "conformance/more/functions/vertexAttrib.html": 0.1934,
-    "conformance/more/functions/vertexAttribBadArgs.html": 0.3293,
-    "conformance/more/functions/vertexAttribPointer.html": 0.3084,
-    "conformance/more/functions/vertexAttribPointerBadArgs.html": 0.3147,
-    "conformance/more/glsl/arrayOutOfBounds.html": 0.1891,
-    "conformance/more/glsl/uniformOutOfBounds.html": 0.1282,
-    "conformance/offscreencanvas/context-attribute-preserve-drawing-buffer.html": 0.8711,
-    "conformance/offscreencanvas/context-creation-worker.html": 0.1608,
-    "conformance/offscreencanvas/context-creation.html": 0.1709,
-    "conformance/offscreencanvas/context-lost-restored-worker.html": 0.3615,
-    "conformance/offscreencanvas/context-lost-restored.html": 0.3649,
-    "conformance/offscreencanvas/context-lost-worker.html": 0.5312,
-    "conformance/offscreencanvas/context-lost.html": 0.1443,
-    "conformance/offscreencanvas/methods-worker.html": 0.369,
-    "conformance/offscreencanvas/methods.html": 0.1623,
-    "conformance/offscreencanvas/offscreencanvas-resize.html": 0.1579,
-    "conformance/offscreencanvas/offscreencanvas-transfer-image-bitmap.html": 0.2604,
-    "conformance/ogles/GL/abs/abs_001_to_006.html": 2.6246,
-    "conformance/ogles/GL/acos/acos_001_to_006.html": 2.8133,
-    "conformance/ogles/GL/all/all_001_to_004.html": 2.3314,
-    "conformance/ogles/GL/any/any_001_to_004.html": 2.4614,
-    "conformance/ogles/GL/array/array_001_to_006.html": 0.7198,
-    "conformance/ogles/GL/asin/asin_001_to_006.html": 2.8088,
-    "conformance/ogles/GL/atan/atan_001_to_008.html": 3.474,
-    "conformance/ogles/GL/atan/atan_009_to_012.html": 2.6935,
-    "conformance/ogles/GL/biConstants/biConstants_001_to_008.html": 2.7834,
-    "conformance/ogles/GL/biConstants/biConstants_009_to_016.html": 2.6955,
-    "conformance/ogles/GL/biuDepthRange/biuDepthRange_001_to_002.html": 1.9828,
-    "conformance/ogles/GL/build/build_001_to_008.html": 0.568,
-    "conformance/ogles/GL/build/build_009_to_016.html": 0.4447,
-    "conformance/ogles/GL/build/build_017_to_024.html": 0.5911,
-    "conformance/ogles/GL/build/build_025_to_032.html": 0.4664,
-    "conformance/ogles/GL/build/build_033_to_040.html": 0.2865,
-    "conformance/ogles/GL/build/build_041_to_048.html": 0.4338,
-    "conformance/ogles/GL/build/build_049_to_056.html": 0.499,
-    "conformance/ogles/GL/build/build_057_to_064.html": 0.2553,
-    "conformance/ogles/GL/build/build_065_to_072.html": 0.3603,
-    "conformance/ogles/GL/build/build_073_to_080.html": 0.1819,
-    "conformance/ogles/GL/build/build_081_to_088.html": 0.3288,
-    "conformance/ogles/GL/build/build_089_to_096.html": 0.2889,
-    "conformance/ogles/GL/build/build_097_to_104.html": 0.359,
-    "conformance/ogles/GL/build/build_105_to_112.html": 0.3905,
-    "conformance/ogles/GL/build/build_113_to_120.html": 0.4197,
-    "conformance/ogles/GL/build/build_121_to_128.html": 0.1559,
-    "conformance/ogles/GL/build/build_129_to_136.html": 0.4336,
-    "conformance/ogles/GL/build/build_137_to_144.html": 0.4458,
-    "conformance/ogles/GL/build/build_145_to_152.html": 0.2999,
-    "conformance/ogles/GL/build/build_153_to_160.html": 0.2455,
-    "conformance/ogles/GL/build/build_161_to_168.html": 0.4288,
-    "conformance/ogles/GL/build/build_169_to_176.html": 0.4617,
-    "conformance/ogles/GL/build/build_177_to_178.html": 0.3592,
-    "conformance/ogles/GL/built_in_varying_array_out_of_bounds/built_in_varying_array_out_of_bounds_001_to_001.html": 0.1428,
-    "conformance/ogles/GL/ceil/ceil_001_to_006.html": 2.3532,
-    "conformance/ogles/GL/clamp/clamp_001_to_006.html": 2.7016,
-    "conformance/ogles/GL/control_flow/control_flow_001_to_008.html": 0.8874,
-    "conformance/ogles/GL/control_flow/control_flow_009_to_010.html": 0.5291,
-    "conformance/ogles/GL/cos/cos_001_to_006.html": 2.6238,
-    "conformance/ogles/GL/cross/cross_001_to_002.html": 2.4736,
-    "conformance/ogles/GL/default/default_001_to_001.html": 0.4881,
-    "conformance/ogles/GL/degrees/degrees_001_to_006.html": 2.7296,
-    "conformance/ogles/GL/discard/discard_001_to_002.html": 0.7454,
-    "conformance/ogles/GL/distance/distance_001_to_006.html": 3.0314,
-    "conformance/ogles/GL/dot/dot_001_to_006.html": 2.6291,
-    "conformance/ogles/GL/equal/equal_001_to_008.html": 2.5194,
-    "conformance/ogles/GL/equal/equal_009_to_012.html": 2.5794,
-    "conformance/ogles/GL/exp/exp_001_to_008.html": 2.8233,
-    "conformance/ogles/GL/exp/exp_009_to_012.html": 2.5799,
-    "conformance/ogles/GL/exp2/exp2_001_to_008.html": 2.7901,
-    "conformance/ogles/GL/exp2/exp2_009_to_012.html": 2.5139,
-    "conformance/ogles/GL/faceforward/faceforward_001_to_006.html": 2.5913,
-    "conformance/ogles/GL/floor/floor_001_to_006.html": 2.5667,
-    "conformance/ogles/GL/fract/fract_001_to_006.html": 2.6038,
-    "conformance/ogles/GL/functions/functions_001_to_008.html": 2.5175,
-    "conformance/ogles/GL/functions/functions_009_to_016.html": 0.9274,
-    "conformance/ogles/GL/functions/functions_017_to_024.html": 0.8874,
-    "conformance/ogles/GL/functions/functions_025_to_032.html": 0.7534,
-    "conformance/ogles/GL/functions/functions_033_to_040.html": 1.2597,
-    "conformance/ogles/GL/functions/functions_041_to_048.html": 0.9662,
-    "conformance/ogles/GL/functions/functions_049_to_056.html": 0.9171,
-    "conformance/ogles/GL/functions/functions_057_to_064.html": 0.7547,
-    "conformance/ogles/GL/functions/functions_065_to_072.html": 0.9355,
-    "conformance/ogles/GL/functions/functions_073_to_080.html": 0.9609,
-    "conformance/ogles/GL/functions/functions_081_to_088.html": 0.9376,
-    "conformance/ogles/GL/functions/functions_089_to_096.html": 0.8003,
-    "conformance/ogles/GL/functions/functions_097_to_104.html": 0.9472,
-    "conformance/ogles/GL/functions/functions_105_to_112.html": 0.8556,
-    "conformance/ogles/GL/functions/functions_113_to_120.html": 0.8994,
-    "conformance/ogles/GL/functions/functions_121_to_126.html": 0.8458,
-    "conformance/ogles/GL/gl_FragCoord/gl_FragCoord_001_to_003.html": 0.6056,
-    "conformance/ogles/GL/gl_FrontFacing/gl_FrontFacing_001_to_001.html": 0.4385,
-    "conformance/ogles/GL/greaterThan/greaterThan_001_to_008.html": 2.7317,
-    "conformance/ogles/GL/greaterThanEqual/greaterThanEqual_001_to_008.html": 2.8919,
-    "conformance/ogles/GL/inversesqrt/inversesqrt_001_to_006.html": 2.6473,
-    "conformance/ogles/GL/length/length_001_to_006.html": 2.6505,
-    "conformance/ogles/GL/lessThan/lessThan_001_to_008.html": 2.9516,
-    "conformance/ogles/GL/lessThanEqual/lessThanEqual_001_to_008.html": 2.7689,
-    "conformance/ogles/GL/log/log_001_to_008.html": 2.8627,
-    "conformance/ogles/GL/log/log_009_to_012.html": 2.5831,
-    "conformance/ogles/GL/log2/log2_001_to_008.html": 2.8031,
-    "conformance/ogles/GL/log2/log2_009_to_012.html": 2.3487,
-    "conformance/ogles/GL/mat/mat_001_to_008.html": 0.7514,
-    "conformance/ogles/GL/mat/mat_009_to_016.html": 0.9042,
-    "conformance/ogles/GL/mat/mat_017_to_024.html": 1.1684,
-    "conformance/ogles/GL/mat/mat_025_to_032.html": 2.7987,
-    "conformance/ogles/GL/mat/mat_033_to_040.html": 2.5012,
-    "conformance/ogles/GL/mat/mat_041_to_046.html": 0.7821,
-    "conformance/ogles/GL/mat3/mat3_001_to_006.html": 0.9656,
-    "conformance/ogles/GL/matrixCompMult/matrixCompMult_001_to_004.html": 2.5478,
-    "conformance/ogles/GL/max/max_001_to_006.html": 2.3965,
-    "conformance/ogles/GL/min/min_001_to_006.html": 2.5524,
-    "conformance/ogles/GL/mix/mix_001_to_006.html": 2.7131,
-    "conformance/ogles/GL/mod/mod_001_to_008.html": 2.6437,
-    "conformance/ogles/GL/normalize/normalize_001_to_006.html": 2.9749,
-    "conformance/ogles/GL/not/not_001_to_004.html": 2.4499,
-    "conformance/ogles/GL/notEqual/notEqual_001_to_008.html": 2.5023,
-    "conformance/ogles/GL/notEqual/notEqual_009_to_012.html": 2.4886,
-    "conformance/ogles/GL/operators/operators_001_to_008.html": 0.8244,
-    "conformance/ogles/GL/operators/operators_009_to_016.html": 0.7507,
-    "conformance/ogles/GL/operators/operators_017_to_024.html": 0.867,
-    "conformance/ogles/GL/operators/operators_025_to_026.html": 0.76,
-    "conformance/ogles/GL/pow/pow_001_to_008.html": 1.1403,
-    "conformance/ogles/GL/pow/pow_009_to_016.html": 2.7182,
-    "conformance/ogles/GL/pow/pow_017_to_024.html": 2.9056,
-    "conformance/ogles/GL/radians/radians_001_to_006.html": 2.4924,
-    "conformance/ogles/GL/reflect/reflect_001_to_006.html": 2.6409,
-    "conformance/ogles/GL/refract/refract_001_to_006.html": 2.4997,
-    "conformance/ogles/GL/sign/sign_001_to_006.html": 2.6397,
-    "conformance/ogles/GL/sin/sin_001_to_006.html": 2.6017,
-    "conformance/ogles/GL/smoothstep/smoothstep_001_to_006.html": 2.4752,
-    "conformance/ogles/GL/sqrt/sqrt_001_to_006.html": 2.4861,
-    "conformance/ogles/GL/step/step_001_to_006.html": 2.4126,
-    "conformance/ogles/GL/struct/struct_001_to_008.html": 2.6586,
-    "conformance/ogles/GL/struct/struct_009_to_016.html": 2.5738,
-    "conformance/ogles/GL/struct/struct_017_to_024.html": 2.7237,
-    "conformance/ogles/GL/struct/struct_025_to_032.html": 2.748,
-    "conformance/ogles/GL/struct/struct_033_to_040.html": 2.5988,
-    "conformance/ogles/GL/struct/struct_041_to_048.html": 2.6587,
-    "conformance/ogles/GL/struct/struct_049_to_056.html": 2.6343,
-    "conformance/ogles/GL/swizzlers/swizzlers_001_to_008.html": 3.0011,
-    "conformance/ogles/GL/swizzlers/swizzlers_009_to_016.html": 2.6893,
-    "conformance/ogles/GL/swizzlers/swizzlers_017_to_024.html": 2.7196,
-    "conformance/ogles/GL/swizzlers/swizzlers_025_to_032.html": 2.5545,
-    "conformance/ogles/GL/swizzlers/swizzlers_033_to_040.html": 2.8705,
-    "conformance/ogles/GL/swizzlers/swizzlers_041_to_048.html": 3.0213,
-    "conformance/ogles/GL/swizzlers/swizzlers_049_to_056.html": 2.7349,
-    "conformance/ogles/GL/swizzlers/swizzlers_057_to_064.html": 2.6012,
-    "conformance/ogles/GL/swizzlers/swizzlers_065_to_072.html": 2.6269,
-    "conformance/ogles/GL/swizzlers/swizzlers_073_to_080.html": 2.8248,
-    "conformance/ogles/GL/swizzlers/swizzlers_081_to_088.html": 2.6384,
-    "conformance/ogles/GL/swizzlers/swizzlers_089_to_096.html": 2.7797,
-    "conformance/ogles/GL/swizzlers/swizzlers_097_to_104.html": 2.7782,
-    "conformance/ogles/GL/swizzlers/swizzlers_105_to_112.html": 2.7573,
-    "conformance/ogles/GL/swizzlers/swizzlers_113_to_120.html": 2.9639,
-    "conformance/ogles/GL/tan/tan_001_to_006.html": 2.5845,
-    "conformance/ogles/GL/vec/vec_001_to_008.html": 0.8276,
-    "conformance/ogles/GL/vec/vec_009_to_016.html": 0.8496,
-    "conformance/ogles/GL/vec/vec_017_to_018.html": 0.7456,
-    "conformance/ogles/GL/vec3/vec3_001_to_008.html": 0.828,
-    "conformance/programs/get-active-test.html": 0.5526,
-    "conformance/programs/gl-bind-attrib-location-long-names-test.html": 0.4451,
-    "conformance/programs/gl-bind-attrib-location-test.html": 0.2823,
-    "conformance/programs/gl-get-active-attribute.html": 0.3636,
-    "conformance/programs/gl-get-active-uniform.html": 0.5659,
-    "conformance/programs/gl-getshadersource.html": 0.2569,
-    "conformance/programs/gl-shader-test.html": 0.2159,
-    "conformance/programs/invalid-UTF-16.html": 0.1478,
-    "conformance/programs/program-handling.html": 3.9307,
-    "conformance/programs/program-infolog.html": 0.2975,
-    "conformance/programs/program-test.html": 3.1344,
-    "conformance/programs/use-program-crash-with-discard-in-fragment-shader.html": 0.2531,
-    "conformance/reading/fbo-remains-unchanged-after-read-pixels.html": 0.4787,
-    "conformance/reading/read-pixels-pack-alignment.html": 0.5223,
-    "conformance/reading/read-pixels-test.html": 8.0426,
-    "conformance/renderbuffers/depth-renderbuffer-initialization.html": 0.5002,
-    "conformance/renderbuffers/feedback-loop.html": 0.3141,
-    "conformance/renderbuffers/framebuffer-state-restoration.html": 0.6083,
-    "conformance/renderbuffers/renderbuffer-initialization.html": 0.5116,
-    "conformance/renderbuffers/stencil-renderbuffer-initialization.html": 0.4691,
-    "conformance/rendering/blending.html": 14.1506,
-    "conformance/rendering/canvas-alpha-bug.html": 0.1762,
-    "conformance/rendering/clear-after-copyTexImage2D.html": 0.4158,
-    "conformance/rendering/color-mask-preserved-during-implicit-clears.html": 2.1044,
-    "conformance/rendering/culling.html": 0.1876,
-    "conformance/rendering/default-texture-draw-bug.html": 0.462,
-    "conformance/rendering/draw-arrays-out-of-bounds.html": 12.2198,
-    "conformance/rendering/draw-elements-out-of-bounds.html": 0.1973,
-    "conformance/rendering/draw-webgl-to-canvas-2d-repeatedly.html": 0.4022,
-    "conformance/rendering/draw-with-changing-start-vertex-bug.html": 0.2707,
-    "conformance/rendering/framebuffer-switch.html": 0.6345,
-    "conformance/rendering/framebuffer-texture-clear.html": 0.3842,
-    "conformance/rendering/framebuffer-texture-switch.html": 0.4499,
-    "conformance/rendering/gl-clear.html": 0.2638,
-    "conformance/rendering/gl-drawarrays.html": 0.2775,
-    "conformance/rendering/gl-drawelements.html": 0.2324,
-    "conformance/rendering/gl-scissor-canvas-dimensions.html": 0.5953,
-    "conformance/rendering/gl-scissor-fbo-test.html": 0.3173,
-    "conformance/rendering/gl-scissor-test.html": 0.746,
-    "conformance/rendering/gl-viewport-test.html": 0.7654,
-    "conformance/rendering/line-loop-tri-fan.html": 0.2824,
-    "conformance/rendering/line-rendering-quality.html": 0.4261,
-    "conformance/rendering/many-draw-calls.html": 4.8468,
-    "conformance/rendering/more-than-65536-indices.html": 1.0791,
-    "conformance/rendering/multisample-corruption.html": 4.0014,
-    "conformance/rendering/negative-one-index.html": 0.2286,
-    "conformance/rendering/out-of-bounds-array-buffers.html": 0.3727,
-    "conformance/rendering/out-of-bounds-index-buffers.html": 0.1722,
-    "conformance/rendering/point-no-attributes.html": 0.3334,
-    "conformance/rendering/point-size.html": 0.2006,
-    "conformance/rendering/point-specific-shader-variables.html": 0.2833,
-    "conformance/rendering/point-with-gl-pointcoord-in-fragment-shader.html": 0.199,
-    "conformance/rendering/polygon-offset.html": 0.4672,
-    "conformance/rendering/preservedrawingbuffer-leak.html": 1.0196,
-    "conformance/rendering/rendering-sampling-feedback-loop.html": 0.0917,
-    "conformance/rendering/rendering-stencil-large-viewport.html": 0.2227,
-    "conformance/rendering/scissor-rect-repeated-rendering.html": 0.3612,
-    "conformance/rendering/simple.html": 0.3545,
+    "WebglExtension_WEBGL_debug_renderer_info": 0.0776,
+    "WebglExtension_WEBGL_debug_shaders": 6.2764,
+    "WebglExtension_WEBGL_draw_instanced_base_vertex_base_instance": 0.176,
+    "WebglExtension_WEBGL_lose_context": 0.0706,
+    "WebglExtension_WEBGL_multi_draw": 0.1945,
+    "WebglExtension_WEBGL_multi_draw_instanced_base_vertex_base_instance": 0.2916,
+    "WebglExtension_WEBGL_video_texture": 0.0669,
+    "conformance/attribs/gl-bindAttribLocation-aliasing.html": 0.4895,
+    "conformance/attribs/gl-bindAttribLocation-matrix.html": 0.3794,
+    "conformance/attribs/gl-bindAttribLocation-nonexistent-attribute.html": 0.4129,
+    "conformance/attribs/gl-bindAttribLocation-repeated.html": 0.3472,
+    "conformance/attribs/gl-disabled-vertex-attrib-update.html": 0.4586,
+    "conformance/attribs/gl-disabled-vertex-attrib.html": 0.995,
+    "conformance/attribs/gl-enable-vertex-attrib.html": 0.223,
+    "conformance/attribs/gl-matrix-attributes.html": 0.5769,
+    "conformance/attribs/gl-vertex-attrib-context-switch.html": 0.5057,
+    "conformance/attribs/gl-vertex-attrib-render.html": 0.2694,
+    "conformance/attribs/gl-vertex-attrib-unconsumed-out-of-bounds.html": 0.3603,
+    "conformance/attribs/gl-vertex-attrib-zero-issues.html": 0.6158,
+    "conformance/attribs/gl-vertexattribpointer-offsets.html": 0.8643,
+    "conformance/attribs/gl-vertexattribpointer.html": 1.3879,
+    "conformance/buffers/buffer-bind-test.html": 0.2172,
+    "conformance/buffers/buffer-data-and-buffer-sub-data.html": 1.2211,
+    "conformance/buffers/buffer-data-array-buffer-delete.html": 2.4015,
+    "conformance/buffers/buffer-data-dynamic-delay.html": 0.7789,
+    "conformance/buffers/buffer-uninitialized.html": 1.0194,
+    "conformance/buffers/element-array-buffer-delete-recreate.html": 0.2787,
+    "conformance/buffers/index-validation-copies-indices.html": 0.2881,
+    "conformance/buffers/index-validation-crash-with-buffer-sub-data.html": 0.0851,
+    "conformance/buffers/index-validation-large-buffer.html": 0.3838,
+    "conformance/buffers/index-validation-verifies-too-many-indices.html": 0.1526,
+    "conformance/buffers/index-validation-with-resized-buffer.html": 0.297,
+    "conformance/buffers/index-validation.html": 0.191,
+    "conformance/buffers/vertex-buffer-updated-after-draw.html": 1.9063,
+    "conformance/canvas/buffer-offscreen-test.html": 0.3196,
+    "conformance/canvas/buffer-preserve-test.html": 0.2688,
+    "conformance/canvas/canvas-test.html": 0.4515,
+    "conformance/canvas/canvas-zero-size.html": 0.289,
+    "conformance/canvas/draw-static-webgl-to-multiple-canvas-test.html": 0.9275,
+    "conformance/canvas/draw-webgl-to-canvas-test.html": 0.8584,
+    "conformance/canvas/drawingbuffer-hd-dpi-test.html": 0.8333,
+    "conformance/canvas/drawingbuffer-static-canvas-test.html": 0.5107,
+    "conformance/canvas/drawingbuffer-test.html": 0.1335,
+    "conformance/canvas/framebuffer-bindings-affected-by-to-data-url.html": 0.4639,
+    "conformance/canvas/framebuffer-bindings-unaffected-on-resize.html": 0.2776,
+    "conformance/canvas/rapid-resizing.html": 2.605,
+    "conformance/canvas/render-after-resize-test.html": 0.2717,
+    "conformance/canvas/texture-bindings-unaffected-on-resize.html": 0.291,
+    "conformance/canvas/to-data-url-test.html": 0.6358,
+    "conformance/canvas/viewport-unchanged-upon-resize.html": 0.3316,
+    "conformance/canvas/webgl-to-2d-canvas.html": 0.5602,
+    "conformance/context/context-attribute-preserve-drawing-buffer.html": 0.6075,
+    "conformance/context/context-attributes-alpha-depth-stencil-antialias.html": 1.0126,
+    "conformance/context/context-creation-and-destruction.html": 1.5589,
+    "conformance/context/context-creation.html": 1.1439,
+    "conformance/context/context-eviction-with-garbage-collection.html": 1.6105,
+    "conformance/context/context-hidden-alpha.html": 0.2025,
+    "conformance/context/context-lost-restored.html": 0.288,
+    "conformance/context/context-lost.html": 1.0573,
+    "conformance/context/context-no-alpha-fbo-with-alpha.html": 0.2481,
+    "conformance/context/context-release-upon-reload.html": 1.7807,
+    "conformance/context/context-release-with-workers.html": 2.213,
+    "conformance/context/context-size-change.html": 0.1493,
+    "conformance/context/deleted-object-behavior.html": 0.6698,
+    "conformance/context/incorrect-context-object-behaviour.html": 0.4213,
+    "conformance/context/premultiplyalpha-test.html": 1.0625,
+    "conformance/context/user-defined-properties-on-context.html": 0.2104,
+    "conformance/context/zero-sized-canvas.html": 0.069,
+    "conformance/extensions/ext-color-buffer-half-float.html": 0.0,
+    "conformance/extensions/ext-disjoint-timer-query.html": 0.1016,
+    "conformance/extensions/ext-float-blend.html": 0.2848,
+    "conformance/extensions/ext-texture-compression-bptc.html": 0.315,
+    "conformance/extensions/ext-texture-compression-rgtc.html": 0.1444,
+    "conformance/extensions/ext-texture-filter-anisotropic.html": 0.1643,
+    "conformance/extensions/get-extension.html": 0.4339,
+    "conformance/extensions/oes-texture-float-linear.html": 0.4881,
+    "conformance/extensions/s3tc-and-rgtc.html": 4.6884,
+    "conformance/extensions/webgl-compressed-texture-astc.html": 0.227,
+    "conformance/extensions/webgl-compressed-texture-etc.html": 0.2149,
+    "conformance/extensions/webgl-compressed-texture-etc1.html": 0.1875,
+    "conformance/extensions/webgl-compressed-texture-pvrtc.html": 0.1104,
+    "conformance/extensions/webgl-compressed-texture-s3tc-srgb.html": 1.717,
+    "conformance/extensions/webgl-compressed-texture-size-limit.html": 5.9294,
+    "conformance/extensions/webgl-debug-renderer-info.html": 0.1108,
+    "conformance/extensions/webgl-debug-shaders.html": 0.2096,
+    "conformance/extensions/webgl-multi-draw.html": 1.611,
+    "conformance/glsl/bugs/angle-ambiguous-function-call.html": 0.2301,
+    "conformance/glsl/bugs/angle-constructor-invalid-parameters.html": 0.2836,
+    "conformance/glsl/bugs/angle-d3d11-compiler-error.html": 0.3521,
+    "conformance/glsl/bugs/angle-dx-variable-bug.html": 0.0745,
+    "conformance/glsl/bugs/array-of-struct-with-int-first-position.html": 0.312,
+    "conformance/glsl/bugs/assign-to-swizzled-twice-in-function.html": 0.3659,
+    "conformance/glsl/bugs/bool-type-cast-bug-int-float.html": 3.0214,
+    "conformance/glsl/bugs/character-set.html": 0.3041,
+    "conformance/glsl/bugs/compare-loop-index-to-uniform.html": 0.1749,
+    "conformance/glsl/bugs/complex-glsl-does-not-crash.html": 3.041,
+    "conformance/glsl/bugs/compound-assignment-type-combination.html": 1.5136,
+    "conformance/glsl/bugs/conditional-discard-in-loop.html": 0.5011,
+    "conformance/glsl/bugs/conditional-discard-optimization.html": 0.2688,
+    "conformance/glsl/bugs/conditional-texture-fetch.html": 0.3407,
+    "conformance/glsl/bugs/constant-precision-qualifier.html": 0.5494,
+    "conformance/glsl/bugs/floor-div-cos-should-not-truncate.html": 0.5171,
+    "conformance/glsl/bugs/floored-division-accuracy.html": 0.5226,
+    "conformance/glsl/bugs/fragcoord-linking-bug.html": 0.0931,
+    "conformance/glsl/bugs/gl-fragcoord-multisampling-bug.html": 0.644,
+    "conformance/glsl/bugs/global-invariant-does-not-leak-across-shaders.html": 0.391,
+    "conformance/glsl/bugs/if-return-and-elseif.html": 0.1594,
+    "conformance/glsl/bugs/in-parameter-passed-as-inout-argument-and-global.html": 0.2757,
+    "conformance/glsl/bugs/init-array-with-loop.html": 0.3403,
+    "conformance/glsl/bugs/invariant-does-not-leak-across-shaders.html": 0.4131,
+    "conformance/glsl/bugs/logic-inside-block-without-braces.html": 0.3268,
+    "conformance/glsl/bugs/long-expressions-should-not-crash.html": 0.7808,
+    "conformance/glsl/bugs/loop-if-loop-gradient.html": 0.31,
+    "conformance/glsl/bugs/modulo-arithmetic-accuracy.html": 0.4432,
+    "conformance/glsl/bugs/multiplication-assignment.html": 0.1757,
+    "conformance/glsl/bugs/nested-functions-should-not-crash.html": 0.5921,
+    "conformance/glsl/bugs/nested-loops-with-break-and-continue.html": 0.5785,
+    "conformance/glsl/bugs/nested-sequence-operator.html": 0.4366,
+    "conformance/glsl/bugs/pow-of-small-constant-in-user-defined-function.html": 0.5392,
+    "conformance/glsl/bugs/pow-with-constant-exponent-should-not-crash.html": 0.3955,
+    "conformance/glsl/bugs/qualcomm-crash.html": 0.3475,
+    "conformance/glsl/bugs/qualcomm-loop-with-continue-crash.html": 0.3541,
+    "conformance/glsl/bugs/sampler-array-struct-function-arg.html": 0.4902,
+    "conformance/glsl/bugs/sampler-array-using-loop-index.html": 0.3675,
+    "conformance/glsl/bugs/sampler-struct-function-arg.html": 0.4003,
+    "conformance/glsl/bugs/sequence-operator-evaluation-order.html": 0.341,
+    "conformance/glsl/bugs/sketchfab-lighting-shader-crash.html": 0.3448,
+    "conformance/glsl/bugs/struct-constructor-highp-bug.html": 0.4313,
+    "conformance/glsl/bugs/struct-with-single-member-constructor.html": 0.2464,
+    "conformance/glsl/bugs/temp-expressions-should-not-crash.html": 1.4905,
+    "conformance/glsl/bugs/unary-minus-operator-float-bug.html": 0.5167,
+    "conformance/glsl/bugs/undefined-index-should-not-crash.html": 0.3446,
+    "conformance/glsl/bugs/uniforms-should-not-lose-values.html": 0.4116,
+    "conformance/glsl/bugs/varying-arrays-should-not-be-reversed.html": 0.4057,
+    "conformance/glsl/bugs/vector-scalar-arithmetic-inside-loop-complex.html": 0.3038,
+    "conformance/glsl/bugs/vector-scalar-arithmetic-inside-loop.html": 0.4566,
+    "conformance/glsl/constructors/glsl-construct-bvec2.html": 1.1621,
+    "conformance/glsl/constructors/glsl-construct-bvec3.html": 1.1095,
+    "conformance/glsl/constructors/glsl-construct-bvec4.html": 1.1536,
+    "conformance/glsl/constructors/glsl-construct-ivec2.html": 0.8524,
+    "conformance/glsl/constructors/glsl-construct-ivec3.html": 0.9845,
+    "conformance/glsl/constructors/glsl-construct-ivec4.html": 1.3377,
+    "conformance/glsl/constructors/glsl-construct-mat2.html": 0.8593,
+    "conformance/glsl/constructors/glsl-construct-mat3.html": 0.9434,
+    "conformance/glsl/constructors/glsl-construct-mat4.html": 0.824,
+    "conformance/glsl/constructors/glsl-construct-vec-mat-corner-cases.html": 0.4875,
+    "conformance/glsl/constructors/glsl-construct-vec-mat-index.html": 0.3762,
+    "conformance/glsl/constructors/glsl-construct-vec2.html": 0.7901,
+    "conformance/glsl/constructors/glsl-construct-vec3.html": 1.3774,
+    "conformance/glsl/constructors/glsl-construct-vec4.html": 1.3519,
+    "conformance/glsl/functions/glsl-function-abs.html": 0.8284,
+    "conformance/glsl/functions/glsl-function-acos.html": 0.8312,
+    "conformance/glsl/functions/glsl-function-asin.html": 0.865,
+    "conformance/glsl/functions/glsl-function-atan-xy.html": 1.0475,
+    "conformance/glsl/functions/glsl-function-atan.html": 1.0772,
+    "conformance/glsl/functions/glsl-function-ceil.html": 0.7161,
+    "conformance/glsl/functions/glsl-function-clamp-float.html": 0.8463,
+    "conformance/glsl/functions/glsl-function-clamp-gentype.html": 0.9166,
+    "conformance/glsl/functions/glsl-function-cos.html": 1.0381,
+    "conformance/glsl/functions/glsl-function-cross.html": 0.5805,
+    "conformance/glsl/functions/glsl-function-distance.html": 0.9042,
+    "conformance/glsl/functions/glsl-function-dot.html": 0.8602,
+    "conformance/glsl/functions/glsl-function-faceforward.html": 1.1866,
+    "conformance/glsl/functions/glsl-function-floor.html": 0.9898,
+    "conformance/glsl/functions/glsl-function-fract.html": 0.8808,
+    "conformance/glsl/functions/glsl-function-length.html": 0.8301,
+    "conformance/glsl/functions/glsl-function-max-float.html": 0.8771,
+    "conformance/glsl/functions/glsl-function-max-gentype.html": 1.057,
+    "conformance/glsl/functions/glsl-function-min-float.html": 0.8541,
+    "conformance/glsl/functions/glsl-function-min-gentype.html": 0.7176,
+    "conformance/glsl/functions/glsl-function-mix-float.html": 0.9797,
+    "conformance/glsl/functions/glsl-function-mix-gentype.html": 0.751,
+    "conformance/glsl/functions/glsl-function-mod-float.html": 0.7948,
+    "conformance/glsl/functions/glsl-function-mod-gentype.html": 0.6914,
+    "conformance/glsl/functions/glsl-function-normalize.html": 0.7828,
+    "conformance/glsl/functions/glsl-function-reflect.html": 0.8241,
+    "conformance/glsl/functions/glsl-function-sign.html": 0.7659,
+    "conformance/glsl/functions/glsl-function-sin.html": 0.831,
+    "conformance/glsl/functions/glsl-function-smoothstep-float.html": 0.8082,
+    "conformance/glsl/functions/glsl-function-smoothstep-gentype.html": 0.8956,
+    "conformance/glsl/functions/glsl-function-step-float.html": 0.8082,
+    "conformance/glsl/functions/glsl-function-step-gentype.html": 0.7362,
+    "conformance/glsl/functions/glsl-function.html": 0.8774,
+    "conformance/glsl/implicit/add_int_float.vert.html": 0.4669,
+    "conformance/glsl/implicit/add_int_mat2.vert.html": 0.3664,
+    "conformance/glsl/implicit/add_int_mat3.vert.html": 0.4483,
+    "conformance/glsl/implicit/add_int_mat4.vert.html": 0.439,
+    "conformance/glsl/implicit/add_int_vec2.vert.html": 0.4223,
+    "conformance/glsl/implicit/add_int_vec3.vert.html": 0.4367,
+    "conformance/glsl/implicit/add_int_vec4.vert.html": 0.4457,
+    "conformance/glsl/implicit/add_ivec2_vec2.vert.html": 0.4617,
+    "conformance/glsl/implicit/add_ivec3_vec3.vert.html": 0.4304,
+    "conformance/glsl/implicit/add_ivec4_vec4.vert.html": 0.2706,
+    "conformance/glsl/implicit/assign_int_to_float.vert.html": 0.4795,
+    "conformance/glsl/implicit/assign_ivec2_to_vec2.vert.html": 0.2609,
+    "conformance/glsl/implicit/assign_ivec3_to_vec3.vert.html": 0.0958,
+    "conformance/glsl/implicit/assign_ivec4_to_vec4.vert.html": 0.441,
+    "conformance/glsl/implicit/construct_struct.vert.html": 0.3721,
+    "conformance/glsl/implicit/divide_int_float.vert.html": 0.4406,
+    "conformance/glsl/implicit/divide_int_mat2.vert.html": 0.459,
+    "conformance/glsl/implicit/divide_int_mat3.vert.html": 0.4584,
+    "conformance/glsl/implicit/divide_int_mat4.vert.html": 0.2481,
+    "conformance/glsl/implicit/divide_int_vec2.vert.html": 0.4643,
+    "conformance/glsl/implicit/divide_int_vec3.vert.html": 0.3318,
+    "conformance/glsl/implicit/divide_int_vec4.vert.html": 0.2886,
+    "conformance/glsl/implicit/divide_ivec2_vec2.vert.html": 0.198,
+    "conformance/glsl/implicit/divide_ivec3_vec3.vert.html": 0.2115,
+    "conformance/glsl/implicit/divide_ivec4_vec4.vert.html": 0.2602,
+    "conformance/glsl/implicit/equal_int_float.vert.html": 0.4401,
+    "conformance/glsl/implicit/equal_ivec2_vec2.vert.html": 0.28,
+    "conformance/glsl/implicit/equal_ivec3_vec3.vert.html": 0.4677,
+    "conformance/glsl/implicit/equal_ivec4_vec4.vert.html": 0.1936,
+    "conformance/glsl/implicit/function_int_float.vert.html": 0.1064,
+    "conformance/glsl/implicit/function_ivec2_vec2.vert.html": 0.1103,
+    "conformance/glsl/implicit/function_ivec3_vec3.vert.html": 0.2541,
+    "conformance/glsl/implicit/function_ivec4_vec4.vert.html": 0.1767,
+    "conformance/glsl/implicit/greater_than.vert.html": 0.2212,
+    "conformance/glsl/implicit/greater_than_equal.vert.html": 0.192,
+    "conformance/glsl/implicit/less_than.vert.html": 0.2212,
+    "conformance/glsl/implicit/less_than_equal.vert.html": 0.1708,
+    "conformance/glsl/implicit/multiply_int_float.vert.html": 0.1796,
+    "conformance/glsl/implicit/multiply_int_mat2.vert.html": 0.1052,
+    "conformance/glsl/implicit/multiply_int_mat3.vert.html": 0.2136,
+    "conformance/glsl/implicit/multiply_int_mat4.vert.html": 0.2222,
+    "conformance/glsl/implicit/multiply_int_vec2.vert.html": 0.4773,
+    "conformance/glsl/implicit/multiply_int_vec3.vert.html": 0.1356,
+    "conformance/glsl/implicit/multiply_int_vec4.vert.html": 0.4785,
+    "conformance/glsl/implicit/multiply_ivec2_vec2.vert.html": 0.2363,
+    "conformance/glsl/implicit/multiply_ivec3_vec3.vert.html": 0.1335,
+    "conformance/glsl/implicit/multiply_ivec4_vec4.vert.html": 0.1903,
+    "conformance/glsl/implicit/not_equal_int_float.vert.html": 0.1752,
+    "conformance/glsl/implicit/not_equal_ivec2_vec2.vert.html": 0.2073,
+    "conformance/glsl/implicit/not_equal_ivec3_vec3.vert.html": 0.1577,
+    "conformance/glsl/implicit/not_equal_ivec4_vec4.vert.html": 0.1997,
+    "conformance/glsl/implicit/subtract_int_float.vert.html": 0.1245,
+    "conformance/glsl/implicit/subtract_int_mat2.vert.html": 0.1228,
+    "conformance/glsl/implicit/subtract_int_mat3.vert.html": 0.2576,
+    "conformance/glsl/implicit/subtract_int_mat4.vert.html": 0.2012,
+    "conformance/glsl/implicit/subtract_int_vec2.vert.html": 0.1392,
+    "conformance/glsl/implicit/subtract_int_vec3.vert.html": 0.1209,
+    "conformance/glsl/implicit/subtract_int_vec4.vert.html": 0.1254,
+    "conformance/glsl/implicit/subtract_ivec2_vec2.vert.html": 0.1105,
+    "conformance/glsl/implicit/subtract_ivec3_vec3.vert.html": 0.1897,
+    "conformance/glsl/implicit/subtract_ivec4_vec4.vert.html": 0.113,
+    "conformance/glsl/implicit/ternary_int_float.vert.html": 0.1375,
+    "conformance/glsl/implicit/ternary_ivec2_vec2.vert.html": 0.2385,
+    "conformance/glsl/implicit/ternary_ivec3_vec3.vert.html": 0.1474,
+    "conformance/glsl/implicit/ternary_ivec4_vec4.vert.html": 0.2302,
+    "conformance/glsl/literals/float_literal.vert.html": 0.0948,
+    "conformance/glsl/literals/literal_precision.html": 0.1684,
+    "conformance/glsl/literals/overflow_leak.vert.html": 0.1469,
+    "conformance/glsl/matrices/glsl-mat3-construction.html": 0.2523,
+    "conformance/glsl/matrices/glsl-mat4-to-mat3.html": 0.3233,
+    "conformance/glsl/matrices/matrix-compound-multiply.html": 0.3388,
+    "conformance/glsl/misc/boolean_precision.html": 0.1941,
+    "conformance/glsl/misc/const-variable-initialization.html": 1.5408,
+    "conformance/glsl/misc/embedded-struct-definitions-forbidden.html": 0.3347,
+    "conformance/glsl/misc/empty-declaration.html": 0.237,
+    "conformance/glsl/misc/empty_main.vert.html": 0.2195,
+    "conformance/glsl/misc/expression-list-in-declarator-initializer.html": 0.5647,
+    "conformance/glsl/misc/fragcolor-fragdata-invariant.html": 0.4964,
+    "conformance/glsl/misc/gl_position_unset.vert.html": 0.1935,
+    "conformance/glsl/misc/global-variable-init.html": 0.523,
+    "conformance/glsl/misc/glsl-function-nodes.html": 0.4583,
+    "conformance/glsl/misc/glsl-long-variable-names.html": 0.1952,
+    "conformance/glsl/misc/glsl-vertex-branch.html": 0.5753,
+    "conformance/glsl/misc/large-loop-compile.html": 0.6931,
+    "conformance/glsl/misc/local-variable-shadowing-outer-function.html": 0.3474,
+    "conformance/glsl/misc/non-ascii-comments.vert.html": 0.4314,
+    "conformance/glsl/misc/non-ascii.vert.html": 0.3597,
+    "conformance/glsl/misc/re-compile-re-link.html": 0.3326,
+    "conformance/glsl/misc/sampler-operand.html": 0.2456,
+    "conformance/glsl/misc/sequence-operator-returns-constant.html": 0.1999,
+    "conformance/glsl/misc/shader-precision-format-obeyed.html": 0.3936,
+    "conformance/glsl/misc/shader-struct-scope.html": 0.2901,
+    "conformance/glsl/misc/shader-uniform-packing-restrictions.html": 3.7248,
+    "conformance/glsl/misc/shader-varying-packing-restrictions.html": 0.8898,
+    "conformance/glsl/misc/shader-with-256-character-define.html": 0.2663,
+    "conformance/glsl/misc/shader-with-256-character-identifier.frag.html": 0.5193,
+    "conformance/glsl/misc/shader-with-_webgl-identifier.vert.html": 0.3245,
+    "conformance/glsl/misc/shader-with-arbitrary-indexing.frag.html": 0.4265,
+    "conformance/glsl/misc/shader-with-arbitrary-indexing.vert.html": 0.2754,
+    "conformance/glsl/misc/shader-with-array-of-structs-containing-arrays.html": 0.3348,
+    "conformance/glsl/misc/shader-with-array-of-structs-uniform.html": 0.3434,
+    "conformance/glsl/misc/shader-with-attrib-array.vert.html": 0.1666,
+    "conformance/glsl/misc/shader-with-attrib-struct.vert.html": 0.2106,
+    "conformance/glsl/misc/shader-with-clipvertex.vert.html": 0.3668,
+    "conformance/glsl/misc/shader-with-comma-assignment.html": 0.1207,
+    "conformance/glsl/misc/shader-with-comma-conditional-assignment.html": 0.4367,
+    "conformance/glsl/misc/shader-with-comma-separated-variable-declarations.html": 0.3736,
+    "conformance/glsl/misc/shader-with-conditional-scoping-negative.html": 0.3607,
+    "conformance/glsl/misc/shader-with-conditional-scoping.html": 0.2103,
+    "conformance/glsl/misc/shader-with-default-precision.frag.html": 0.4185,
+    "conformance/glsl/misc/shader-with-default-precision.vert.html": 0.3749,
+    "conformance/glsl/misc/shader-with-dfdx-no-ext.frag.html": 0.3656,
+    "conformance/glsl/misc/shader-with-dfdx.frag.html": 0.4711,
+    "conformance/glsl/misc/shader-with-do-loop.html": 0.2024,
+    "conformance/glsl/misc/shader-with-error-directive.html": 0.4718,
+    "conformance/glsl/misc/shader-with-explicit-int-cast.vert.html": 0.3355,
+    "conformance/glsl/misc/shader-with-float-return-value.frag.html": 0.3475,
+    "conformance/glsl/misc/shader-with-for-loop.html": 0.488,
+    "conformance/glsl/misc/shader-with-for-scoping.html": 0.2942,
+    "conformance/glsl/misc/shader-with-frag-depth.frag.html": 0.2329,
+    "conformance/glsl/misc/shader-with-function-recursion.frag.html": 0.1895,
+    "conformance/glsl/misc/shader-with-function-scoped-struct.html": 0.1785,
+    "conformance/glsl/misc/shader-with-functional-scoping.html": 0.4807,
+    "conformance/glsl/misc/shader-with-glcolor.vert.html": 0.4859,
+    "conformance/glsl/misc/shader-with-gles-1.frag.html": 0.1646,
+    "conformance/glsl/misc/shader-with-gles-symbol.frag.html": 0.3333,
+    "conformance/glsl/misc/shader-with-global-variable-precision-mismatch.html": 0.1884,
+    "conformance/glsl/misc/shader-with-glprojectionmatrix.vert.html": 0.4312,
+    "conformance/glsl/misc/shader-with-hex-int-constant-macro.html": 0.1978,
+    "conformance/glsl/misc/shader-with-implicit-vec3-to-vec4-cast.vert.html": 0.231,
+    "conformance/glsl/misc/shader-with-include.vert.html": 0.2379,
+    "conformance/glsl/misc/shader-with-int-return-value.frag.html": 0.4418,
+    "conformance/glsl/misc/shader-with-invalid-identifier.frag.html": 0.0904,
+    "conformance/glsl/misc/shader-with-ivec2-return-value.frag.html": 0.1299,
+    "conformance/glsl/misc/shader-with-ivec3-return-value.frag.html": 0.2529,
+    "conformance/glsl/misc/shader-with-ivec4-return-value.frag.html": 0.1261,
+    "conformance/glsl/misc/shader-with-limited-indexing.frag.html": 0.207,
+    "conformance/glsl/misc/shader-with-long-line.html": 0.5647,
+    "conformance/glsl/misc/shader-with-non-ascii-error.frag.html": 0.2984,
+    "conformance/glsl/misc/shader-with-non-reserved-words.html": 24.5731,
+    "conformance/glsl/misc/shader-with-precision.frag.html": 0.4102,
+    "conformance/glsl/misc/shader-with-preprocessor-whitespace.html": 0.3581,
+    "conformance/glsl/misc/shader-with-quoted-error.frag.html": 0.1949,
+    "conformance/glsl/misc/shader-with-reserved-words.html": 3.5616,
+    "conformance/glsl/misc/shader-with-short-circuiting-operators.html": 0.7058,
+    "conformance/glsl/misc/shader-with-similar-uniform-array-names.html": 0.5579,
+    "conformance/glsl/misc/shader-with-too-many-uniforms.html": 0.7147,
+    "conformance/glsl/misc/shader-with-two-initializer-types.html": 0.0933,
+    "conformance/glsl/misc/shader-with-undefined-preprocessor-symbol.frag.html": 0.0994,
+    "conformance/glsl/misc/shader-with-uniform-in-loop-condition.vert.html": 0.1855,
+    "conformance/glsl/misc/shader-with-vec2-return-value.frag.html": 0.1923,
+    "conformance/glsl/misc/shader-with-vec3-return-value.frag.html": 0.2326,
+    "conformance/glsl/misc/shader-with-vec4-return-value.frag.html": 0.2824,
+    "conformance/glsl/misc/shader-with-vec4-vec3-vec4-conditional.html": 0.1068,
+    "conformance/glsl/misc/shader-with-version-100.frag.html": 0.3557,
+    "conformance/glsl/misc/shader-with-version-100.vert.html": 0.3608,
+    "conformance/glsl/misc/shader-with-version-120.vert.html": 0.3765,
+    "conformance/glsl/misc/shader-with-version-130.vert.html": 0.2631,
+    "conformance/glsl/misc/shader-with-webgl-identifier.vert.html": 0.354,
+    "conformance/glsl/misc/shader-with-while-loop.html": 0.4428,
+    "conformance/glsl/misc/shader-without-precision.frag.html": 0.2672,
+    "conformance/glsl/misc/shaders-with-constant-expression-loop-conditions.html": 0.5665,
+    "conformance/glsl/misc/shaders-with-invariance.html": 0.5648,
+    "conformance/glsl/misc/shaders-with-mis-matching-uniforms.html": 0.6591,
+    "conformance/glsl/misc/shaders-with-mis-matching-varyings.html": 0.2648,
+    "conformance/glsl/misc/shaders-with-missing-varyings.html": 0.5394,
+    "conformance/glsl/misc/shaders-with-name-conflicts.html": 0.2408,
+    "conformance/glsl/misc/shaders-with-uniform-structs.html": 0.3083,
+    "conformance/glsl/misc/shaders-with-varyings.html": 0.2468,
+    "conformance/glsl/misc/shared.html": 0.2872,
+    "conformance/glsl/misc/struct-as-inout-parameter.html": 0.5966,
+    "conformance/glsl/misc/struct-as-out-parameter.html": 0.4828,
+    "conformance/glsl/misc/struct-assign.html": 0.3487,
+    "conformance/glsl/misc/struct-equals.html": 0.4301,
+    "conformance/glsl/misc/struct-mixed-array-declarators.html": 0.7232,
+    "conformance/glsl/misc/struct-nesting-exceeds-maximum.html": 0.5163,
+    "conformance/glsl/misc/struct-nesting-of-variable-names.html": 1.5487,
+    "conformance/glsl/misc/struct-nesting-under-maximum.html": 0.3882,
+    "conformance/glsl/misc/struct-specifiers-in-uniforms.html": 0.3926,
+    "conformance/glsl/misc/struct-unary-operators.html": 0.6256,
+    "conformance/glsl/misc/ternary-operator-on-arrays.html": 0.0924,
+    "conformance/glsl/misc/ternary-operators-in-global-initializers.html": 0.5131,
+    "conformance/glsl/misc/ternary-operators-in-initializers.html": 0.4914,
+    "conformance/glsl/misc/uninitialized-local-global-variables.html": 0.4744,
+    "conformance/glsl/preprocessor/comments.html": 0.4767,
+    "conformance/glsl/preprocessor/macro-expansion-tricky.html": 0.3929,
+    "conformance/glsl/reserved/_webgl_field.vert.html": 0.3942,
+    "conformance/glsl/reserved/_webgl_function.vert.html": 0.4717,
+    "conformance/glsl/reserved/_webgl_struct.vert.html": 0.4779,
+    "conformance/glsl/reserved/_webgl_variable.vert.html": 0.3865,
+    "conformance/glsl/reserved/webgl_field.vert.html": 0.2591,
+    "conformance/glsl/reserved/webgl_function.vert.html": 0.4175,
+    "conformance/glsl/reserved/webgl_struct.vert.html": 0.1721,
+    "conformance/glsl/reserved/webgl_variable.vert.html": 0.373,
+    "conformance/glsl/samplers/glsl-function-texture2d-bias.html": 0.532,
+    "conformance/glsl/samplers/glsl-function-texture2dlod.html": 0.4188,
+    "conformance/glsl/samplers/glsl-function-texture2dproj.html": 0.6005,
+    "conformance/glsl/samplers/glsl-function-texture2dprojlod.html": 0.9578,
+    "conformance/glsl/variables/gl-fragcoord-xy-values.html": 0.4841,
+    "conformance/glsl/variables/gl-fragcoord.html": 0.3376,
+    "conformance/glsl/variables/gl-fragdata-and-fragcolor.html": 0.3513,
+    "conformance/glsl/variables/gl-frontfacing.html": 0.1422,
+    "conformance/glsl/variables/gl-pointcoord.html": 0.3862,
+    "conformance/glsl/variables/glsl-built-ins.html": 0.5214,
+    "conformance/limits/gl-line-width.html": 0.3252,
+    "conformance/limits/gl-max-texture-dimensions.html": 0.5233,
+    "conformance/limits/gl-min-attribs.html": 0.2764,
+    "conformance/limits/gl-min-textures.html": 0.2667,
+    "conformance/limits/gl-min-uniforms.html": 0.323,
+    "conformance/misc/bad-arguments-test.html": 0.2999,
+    "conformance/misc/boolean-argument-conversion.html": 0.2967,
+    "conformance/misc/delayed-drawing.html": 1.4444,
+    "conformance/misc/error-reporting.html": 0.1056,
+    "conformance/misc/expando-loss.html": 0.3118,
+    "conformance/misc/functions-returning-strings.html": 0.2009,
+    "conformance/misc/invalid-passed-params.html": 0.2076,
+    "conformance/misc/is-object.html": 0.1392,
+    "conformance/misc/null-object-behaviour.html": 0.3171,
+    "conformance/misc/object-deletion-behaviour.html": 0.6722,
+    "conformance/misc/shader-precision-format.html": 0.3142,
+    "conformance/misc/type-conversion-test.html": 0.0,
+    "conformance/misc/uninitialized-test.html": 0.58,
+    "conformance/misc/webgl-specific-stencil-settings.html": 0.7486,
+    "conformance/misc/webgl-specific.html": 0.1152,
+    "conformance/more/conformance/constants.html": 0.1519,
+    "conformance/more/conformance/getContext.html": 0.1571,
+    "conformance/more/conformance/methods.html": 0.1915,
+    "conformance/more/conformance/quickCheckAPI-A.html": 0.2608,
+    "conformance/more/conformance/quickCheckAPI-B1.html": 0.5021,
+    "conformance/more/conformance/quickCheckAPI-B2.html": 0.3133,
+    "conformance/more/conformance/quickCheckAPI-B3.html": 0.4429,
+    "conformance/more/conformance/quickCheckAPI-B4.html": 0.2515,
+    "conformance/more/conformance/quickCheckAPI-C.html": 0.2303,
+    "conformance/more/conformance/quickCheckAPI-D_G.html": 0.4424,
+    "conformance/more/conformance/quickCheckAPI-G_I.html": 0.4384,
+    "conformance/more/conformance/quickCheckAPI-L_S.html": 0.3755,
+    "conformance/more/conformance/quickCheckAPI-S_V.html": 0.5229,
+    "conformance/more/conformance/webGLArrays.html": 0.2304,
+    "conformance/more/functions/bindBuffer.html": 0.4035,
+    "conformance/more/functions/bindBufferBadArgs.html": 0.2527,
+    "conformance/more/functions/bindFramebufferLeaveNonZero.html": 0.1885,
+    "conformance/more/functions/bufferData.html": 0.1338,
+    "conformance/more/functions/bufferDataBadArgs.html": 0.2168,
+    "conformance/more/functions/bufferSubData.html": 0.4199,
+    "conformance/more/functions/bufferSubDataBadArgs.html": 0.2891,
+    "conformance/more/functions/copyTexImage2D.html": 0.1762,
+    "conformance/more/functions/copyTexImage2DBadArgs.html": 0.2746,
+    "conformance/more/functions/copyTexSubImage2D.html": 0.5313,
+    "conformance/more/functions/copyTexSubImage2DBadArgs.html": 0.2437,
+    "conformance/more/functions/deleteBufferBadArgs.html": 0.1614,
+    "conformance/more/functions/drawArrays.html": 0.2299,
+    "conformance/more/functions/drawElements.html": 0.5292,
+    "conformance/more/functions/isTests.html": 0.3642,
+    "conformance/more/functions/isTestsBadArgs.html": 0.1044,
+    "conformance/more/functions/readPixels.html": 0.4773,
+    "conformance/more/functions/readPixelsBadArgs.html": 0.249,
+    "conformance/more/functions/texImage2D.html": 0.2797,
+    "conformance/more/functions/texImage2DBadArgs.html": 0.2473,
+    "conformance/more/functions/texImage2DHTML.html": 0.331,
+    "conformance/more/functions/texImage2DHTMLBadArgs.html": 0.1837,
+    "conformance/more/functions/texSubImage2D.html": 0.4245,
+    "conformance/more/functions/texSubImage2DBadArgs.html": 0.1425,
+    "conformance/more/functions/texSubImage2DHTML.html": 0.3317,
+    "conformance/more/functions/texSubImage2DHTMLBadArgs.html": 0.2148,
+    "conformance/more/functions/uniformMatrix.html": 0.2408,
+    "conformance/more/functions/uniformMatrixBadArgs.html": 0.2427,
+    "conformance/more/functions/uniformf.html": 0.2757,
+    "conformance/more/functions/uniformfArrayLen1.html": 0.1742,
+    "conformance/more/functions/uniformfBadArgs.html": 0.2018,
+    "conformance/more/functions/uniformi.html": 0.1787,
+    "conformance/more/functions/uniformiBadArgs.html": 0.3966,
+    "conformance/more/functions/vertexAttrib.html": 0.1872,
+    "conformance/more/functions/vertexAttribBadArgs.html": 0.2519,
+    "conformance/more/functions/vertexAttribPointer.html": 0.2014,
+    "conformance/more/functions/vertexAttribPointerBadArgs.html": 0.4793,
+    "conformance/more/glsl/arrayOutOfBounds.html": 0.3352,
+    "conformance/more/glsl/uniformOutOfBounds.html": 0.2434,
+    "conformance/offscreencanvas/context-attribute-preserve-drawing-buffer.html": 0.9041,
+    "conformance/offscreencanvas/context-creation-worker.html": 0.357,
+    "conformance/offscreencanvas/context-creation.html": 0.4214,
+    "conformance/offscreencanvas/context-lost-restored-worker.html": 0.3107,
+    "conformance/offscreencanvas/context-lost-restored.html": 0.217,
+    "conformance/offscreencanvas/context-lost-worker.html": 0.1722,
+    "conformance/offscreencanvas/context-lost.html": 0.1747,
+    "conformance/offscreencanvas/methods-worker.html": 0.3401,
+    "conformance/offscreencanvas/methods.html": 0.2968,
+    "conformance/offscreencanvas/offscreencanvas-resize.html": 0.346,
+    "conformance/offscreencanvas/offscreencanvas-timer-query.html": 0.1885,
+    "conformance/offscreencanvas/offscreencanvas-transfer-image-bitmap.html": 0.4679,
+    "conformance/ogles/GL/abs/abs_001_to_006.html": 2.8082,
+    "conformance/ogles/GL/acos/acos_001_to_006.html": 2.8989,
+    "conformance/ogles/GL/all/all_001_to_004.html": 2.8114,
+    "conformance/ogles/GL/any/any_001_to_004.html": 2.9161,
+    "conformance/ogles/GL/array/array_001_to_006.html": 0.7714,
+    "conformance/ogles/GL/asin/asin_001_to_006.html": 3.0866,
+    "conformance/ogles/GL/atan/atan_001_to_008.html": 3.318,
+    "conformance/ogles/GL/atan/atan_009_to_012.html": 3.1781,
+    "conformance/ogles/GL/biConstants/biConstants_001_to_008.html": 2.8982,
+    "conformance/ogles/GL/biConstants/biConstants_009_to_016.html": 3.0389,
+    "conformance/ogles/GL/biuDepthRange/biuDepthRange_001_to_002.html": 2.2809,
+    "conformance/ogles/GL/build/build_001_to_008.html": 0.4116,
+    "conformance/ogles/GL/build/build_009_to_016.html": 0.3277,
+    "conformance/ogles/GL/build/build_017_to_024.html": 0.3927,
+    "conformance/ogles/GL/build/build_025_to_032.html": 0.3831,
+    "conformance/ogles/GL/build/build_033_to_040.html": 0.576,
+    "conformance/ogles/GL/build/build_041_to_048.html": 0.2773,
+    "conformance/ogles/GL/build/build_049_to_056.html": 0.5383,
+    "conformance/ogles/GL/build/build_057_to_064.html": 0.2933,
+    "conformance/ogles/GL/build/build_065_to_072.html": 0.2955,
+    "conformance/ogles/GL/build/build_073_to_080.html": 0.3316,
+    "conformance/ogles/GL/build/build_081_to_088.html": 0.3243,
+    "conformance/ogles/GL/build/build_089_to_096.html": 0.4849,
+    "conformance/ogles/GL/build/build_097_to_104.html": 0.3877,
+    "conformance/ogles/GL/build/build_105_to_112.html": 0.4099,
+    "conformance/ogles/GL/build/build_113_to_120.html": 0.2886,
+    "conformance/ogles/GL/build/build_121_to_128.html": 0.4447,
+    "conformance/ogles/GL/build/build_129_to_136.html": 0.2887,
+    "conformance/ogles/GL/build/build_137_to_144.html": 0.4072,
+    "conformance/ogles/GL/build/build_145_to_152.html": 0.2937,
+    "conformance/ogles/GL/build/build_153_to_160.html": 0.3612,
+    "conformance/ogles/GL/build/build_161_to_168.html": 0.2547,
+    "conformance/ogles/GL/build/build_169_to_176.html": 0.2161,
+    "conformance/ogles/GL/build/build_177_to_178.html": 0.3134,
+    "conformance/ogles/GL/built_in_varying_array_out_of_bounds/built_in_varying_array_out_of_bounds_001_to_001.html": 0.1731,
+    "conformance/ogles/GL/ceil/ceil_001_to_006.html": 2.6012,
+    "conformance/ogles/GL/clamp/clamp_001_to_006.html": 2.9544,
+    "conformance/ogles/GL/control_flow/control_flow_001_to_008.html": 0.8169,
+    "conformance/ogles/GL/control_flow/control_flow_009_to_010.html": 0.4405,
+    "conformance/ogles/GL/cos/cos_001_to_006.html": 3.1236,
+    "conformance/ogles/GL/cross/cross_001_to_002.html": 2.4583,
+    "conformance/ogles/GL/default/default_001_to_001.html": 0.6329,
+    "conformance/ogles/GL/degrees/degrees_001_to_006.html": 2.8479,
+    "conformance/ogles/GL/discard/discard_001_to_002.html": 0.6362,
+    "conformance/ogles/GL/distance/distance_001_to_006.html": 2.7963,
+    "conformance/ogles/GL/dot/dot_001_to_006.html": 3.0436,
+    "conformance/ogles/GL/equal/equal_001_to_008.html": 2.8562,
+    "conformance/ogles/GL/equal/equal_009_to_012.html": 2.7881,
+    "conformance/ogles/GL/exp/exp_001_to_008.html": 2.9173,
+    "conformance/ogles/GL/exp/exp_009_to_012.html": 2.577,
+    "conformance/ogles/GL/exp2/exp2_001_to_008.html": 3.3721,
+    "conformance/ogles/GL/exp2/exp2_009_to_012.html": 2.803,
+    "conformance/ogles/GL/faceforward/faceforward_001_to_006.html": 2.9212,
+    "conformance/ogles/GL/floor/floor_001_to_006.html": 2.9441,
+    "conformance/ogles/GL/fract/fract_001_to_006.html": 2.9293,
+    "conformance/ogles/GL/functions/functions_001_to_008.html": 3.0274,
+    "conformance/ogles/GL/functions/functions_009_to_016.html": 0.9209,
+    "conformance/ogles/GL/functions/functions_017_to_024.html": 0.779,
+    "conformance/ogles/GL/functions/functions_025_to_032.html": 0.874,
+    "conformance/ogles/GL/functions/functions_033_to_040.html": 0.8912,
+    "conformance/ogles/GL/functions/functions_041_to_048.html": 0.9953,
+    "conformance/ogles/GL/functions/functions_049_to_056.html": 1.0501,
+    "conformance/ogles/GL/functions/functions_057_to_064.html": 0.9192,
+    "conformance/ogles/GL/functions/functions_065_to_072.html": 1.0992,
+    "conformance/ogles/GL/functions/functions_073_to_080.html": 0.9976,
+    "conformance/ogles/GL/functions/functions_081_to_088.html": 0.7684,
+    "conformance/ogles/GL/functions/functions_089_to_096.html": 0.8455,
+    "conformance/ogles/GL/functions/functions_097_to_104.html": 0.8402,
+    "conformance/ogles/GL/functions/functions_105_to_112.html": 0.8285,
+    "conformance/ogles/GL/functions/functions_113_to_120.html": 0.9833,
+    "conformance/ogles/GL/functions/functions_121_to_126.html": 0.8891,
+    "conformance/ogles/GL/gl_FragCoord/gl_FragCoord_001_to_003.html": 0.7293,
+    "conformance/ogles/GL/gl_FrontFacing/gl_FrontFacing_001_to_001.html": 0.652,
+    "conformance/ogles/GL/greaterThan/greaterThan_001_to_008.html": 2.9623,
+    "conformance/ogles/GL/greaterThanEqual/greaterThanEqual_001_to_008.html": 3.2424,
+    "conformance/ogles/GL/inversesqrt/inversesqrt_001_to_006.html": 2.909,
+    "conformance/ogles/GL/length/length_001_to_006.html": 2.8937,
+    "conformance/ogles/GL/lessThan/lessThan_001_to_008.html": 3.0495,
+    "conformance/ogles/GL/lessThanEqual/lessThanEqual_001_to_008.html": 3.0615,
+    "conformance/ogles/GL/log/log_001_to_008.html": 3.079,
+    "conformance/ogles/GL/log/log_009_to_012.html": 2.8898,
+    "conformance/ogles/GL/log2/log2_001_to_008.html": 3.008,
+    "conformance/ogles/GL/log2/log2_009_to_012.html": 2.9547,
+    "conformance/ogles/GL/mat/mat_001_to_008.html": 0.8573,
+    "conformance/ogles/GL/mat/mat_009_to_016.html": 0.9535,
+    "conformance/ogles/GL/mat/mat_017_to_024.html": 0.8951,
+    "conformance/ogles/GL/mat/mat_025_to_032.html": 3.0759,
+    "conformance/ogles/GL/mat/mat_033_to_040.html": 3.098,
+    "conformance/ogles/GL/mat/mat_041_to_046.html": 0.6759,
+    "conformance/ogles/GL/mat3/mat3_001_to_006.html": 0.8285,
+    "conformance/ogles/GL/matrixCompMult/matrixCompMult_001_to_004.html": 2.67,
+    "conformance/ogles/GL/max/max_001_to_006.html": 2.728,
+    "conformance/ogles/GL/min/min_001_to_006.html": 2.9185,
+    "conformance/ogles/GL/mix/mix_001_to_006.html": 2.8366,
+    "conformance/ogles/GL/mod/mod_001_to_008.html": 2.9838,
+    "conformance/ogles/GL/normalize/normalize_001_to_006.html": 2.921,
+    "conformance/ogles/GL/not/not_001_to_004.html": 2.8664,
+    "conformance/ogles/GL/notEqual/notEqual_001_to_008.html": 3.2451,
+    "conformance/ogles/GL/notEqual/notEqual_009_to_012.html": 2.7443,
+    "conformance/ogles/GL/operators/operators_001_to_008.html": 0.8589,
+    "conformance/ogles/GL/operators/operators_009_to_016.html": 0.9565,
+    "conformance/ogles/GL/operators/operators_017_to_024.html": 0.9056,
+    "conformance/ogles/GL/operators/operators_025_to_026.html": 0.6206,
+    "conformance/ogles/GL/pow/pow_001_to_008.html": 1.1036,
+    "conformance/ogles/GL/pow/pow_009_to_016.html": 3.0634,
+    "conformance/ogles/GL/pow/pow_017_to_024.html": 3.186,
+    "conformance/ogles/GL/radians/radians_001_to_006.html": 2.8656,
+    "conformance/ogles/GL/reflect/reflect_001_to_006.html": 3.4024,
+    "conformance/ogles/GL/refract/refract_001_to_006.html": 2.728,
+    "conformance/ogles/GL/sign/sign_001_to_006.html": 3.0497,
+    "conformance/ogles/GL/sin/sin_001_to_006.html": 3.0811,
+    "conformance/ogles/GL/smoothstep/smoothstep_001_to_006.html": 2.9807,
+    "conformance/ogles/GL/sqrt/sqrt_001_to_006.html": 2.8298,
+    "conformance/ogles/GL/step/step_001_to_006.html": 2.7911,
+    "conformance/ogles/GL/struct/struct_001_to_008.html": 3.2044,
+    "conformance/ogles/GL/struct/struct_009_to_016.html": 2.8258,
+    "conformance/ogles/GL/struct/struct_017_to_024.html": 2.9781,
+    "conformance/ogles/GL/struct/struct_025_to_032.html": 3.1905,
+    "conformance/ogles/GL/struct/struct_033_to_040.html": 3.126,
+    "conformance/ogles/GL/struct/struct_041_to_048.html": 3.0655,
+    "conformance/ogles/GL/struct/struct_049_to_056.html": 3.3849,
+    "conformance/ogles/GL/swizzlers/swizzlers_001_to_008.html": 3.0182,
+    "conformance/ogles/GL/swizzlers/swizzlers_009_to_016.html": 2.9678,
+    "conformance/ogles/GL/swizzlers/swizzlers_017_to_024.html": 3.1438,
+    "conformance/ogles/GL/swizzlers/swizzlers_025_to_032.html": 3.136,
+    "conformance/ogles/GL/swizzlers/swizzlers_033_to_040.html": 3.416,
+    "conformance/ogles/GL/swizzlers/swizzlers_041_to_048.html": 3.0388,
+    "conformance/ogles/GL/swizzlers/swizzlers_049_to_056.html": 3.1373,
+    "conformance/ogles/GL/swizzlers/swizzlers_057_to_064.html": 3.1467,
+    "conformance/ogles/GL/swizzlers/swizzlers_065_to_072.html": 3.187,
+    "conformance/ogles/GL/swizzlers/swizzlers_073_to_080.html": 3.2781,
+    "conformance/ogles/GL/swizzlers/swizzlers_081_to_088.html": 3.1533,
+    "conformance/ogles/GL/swizzlers/swizzlers_089_to_096.html": 3.1221,
+    "conformance/ogles/GL/swizzlers/swizzlers_097_to_104.html": 3.0734,
+    "conformance/ogles/GL/swizzlers/swizzlers_105_to_112.html": 3.0303,
+    "conformance/ogles/GL/swizzlers/swizzlers_113_to_120.html": 3.0807,
+    "conformance/ogles/GL/tan/tan_001_to_006.html": 2.8305,
+    "conformance/ogles/GL/vec/vec_001_to_008.html": 0.8871,
+    "conformance/ogles/GL/vec/vec_009_to_016.html": 0.9646,
+    "conformance/ogles/GL/vec/vec_017_to_018.html": 0.6801,
+    "conformance/ogles/GL/vec3/vec3_001_to_008.html": 0.9221,
+    "conformance/programs/get-active-test.html": 0.7471,
+    "conformance/programs/gl-bind-attrib-location-long-names-test.html": 0.3845,
+    "conformance/programs/gl-bind-attrib-location-test.html": 0.313,
+    "conformance/programs/gl-get-active-attribute.html": 0.3972,
+    "conformance/programs/gl-get-active-uniform.html": 0.4713,
+    "conformance/programs/gl-getshadersource.html": 0.3665,
+    "conformance/programs/gl-shader-test.html": 0.3991,
+    "conformance/programs/invalid-UTF-16.html": 0.1172,
+    "conformance/programs/program-handling.html": 0.9312,
+    "conformance/programs/program-infolog.html": 0.3138,
+    "conformance/programs/program-test.html": 0.4099,
+    "conformance/programs/use-program-crash-with-discard-in-fragment-shader.html": 0.3397,
+    "conformance/reading/fbo-remains-unchanged-after-read-pixels.html": 0.3127,
+    "conformance/reading/read-pixels-pack-alignment.html": 0.6994,
+    "conformance/reading/read-pixels-test.html": 3.376,
+    "conformance/renderbuffers/depth-renderbuffer-initialization.html": 0.7315,
+    "conformance/renderbuffers/feedback-loop.html": 0.4758,
+    "conformance/renderbuffers/framebuffer-state-restoration.html": 0.5003,
+    "conformance/renderbuffers/renderbuffer-initialization.html": 0.5334,
+    "conformance/renderbuffers/stencil-renderbuffer-initialization.html": 0.4215,
+    "conformance/rendering/bind-framebuffer-flush-bug.html": 0.3009,
+    "conformance/rendering/blending.html": 0.5112,
+    "conformance/rendering/canvas-alpha-bug.html": 0.3398,
+    "conformance/rendering/clear-after-copyTexImage2D.html": 0.5182,
+    "conformance/rendering/color-mask-preserved-during-implicit-clears.html": 1.9128,
+    "conformance/rendering/culling.html": 0.4259,
+    "conformance/rendering/default-texture-draw-bug.html": 0.307,
+    "conformance/rendering/draw-arrays-out-of-bounds.html": 0.2992,
+    "conformance/rendering/draw-elements-out-of-bounds.html": 0.2988,
+    "conformance/rendering/draw-webgl-to-canvas-2d-repeatedly.html": 0.3927,
+    "conformance/rendering/draw-with-changing-start-vertex-bug.html": 0.4792,
+    "conformance/rendering/framebuffer-switch.html": 0.6096,
+    "conformance/rendering/framebuffer-texture-clear.html": 0.1997,
+    "conformance/rendering/framebuffer-texture-switch.html": 0.5418,
+    "conformance/rendering/gl-clear.html": 12.8384,
+    "conformance/rendering/gl-drawarrays.html": 0.3864,
+    "conformance/rendering/gl-drawelements.html": 0.3714,
+    "conformance/rendering/gl-scissor-canvas-dimensions.html": 0.169,
+    "conformance/rendering/gl-scissor-fbo-test.html": 0.5317,
+    "conformance/rendering/gl-scissor-test.html": 0.7793,
+    "conformance/rendering/gl-viewport-test.html": 0.7521,
+    "conformance/rendering/line-loop-tri-fan.html": 0.1273,
+    "conformance/rendering/line-rendering-quality.html": 0.5506,
+    "conformance/rendering/many-draw-calls.html": 2.0114,
+    "conformance/rendering/more-than-65536-indices.html": 0.9717,
+    "conformance/rendering/multisample-corruption.html": 3.9421,
+    "conformance/rendering/negative-one-index.html": 0.1301,
+    "conformance/rendering/out-of-bounds-array-buffers.html": 0.4088,
+    "conformance/rendering/out-of-bounds-index-buffers.html": 0.2027,
+    "conformance/rendering/point-no-attributes.html": 0.141,
+    "conformance/rendering/point-size.html": 0.1725,
+    "conformance/rendering/point-specific-shader-variables.html": 0.3947,
+    "conformance/rendering/point-with-gl-pointcoord-in-fragment-shader.html": 0.3224,
+    "conformance/rendering/polygon-offset.html": 0.1939,
+    "conformance/rendering/preservedrawingbuffer-leak.html": 1.0959,
+    "conformance/rendering/rendering-sampling-feedback-loop.html": 0.311,
+    "conformance/rendering/rendering-stencil-large-viewport.html": 0.5551,
+    "conformance/rendering/scissor-rect-repeated-rendering.html": 0.3991,
+    "conformance/rendering/simple.html": 0.3077,
     "conformance/rendering/texture-switch-performance.html": 0.0,
-    "conformance/rendering/triangle.html": 0.134,
-    "conformance/state/gl-enable-enum-test.html": 0.5989,
-    "conformance/state/gl-get-calls.html": 0.2198,
-    "conformance/state/gl-geterror.html": 0.3228,
-    "conformance/state/gl-initial-state.html": 0.0641,
-    "conformance/state/state-uneffected-after-compositing.html": 0.5678,
-    "conformance/textures/canvas/tex-2d-alpha-alpha-unsigned_byte.html": 1.0847,
-    "conformance/textures/canvas/tex-2d-luminance-luminance-unsigned_byte.html": 1.2243,
-    "conformance/textures/canvas/tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html": 1.322,
-    "conformance/textures/canvas/tex-2d-rgb-rgb-unsigned_byte.html": 2.7994,
-    "conformance/textures/canvas/tex-2d-rgb-rgb-unsigned_short_5_6_5.html": 1.0596,
-    "conformance/textures/canvas/tex-2d-rgba-rgba-unsigned_byte.html": 2.5564,
-    "conformance/textures/canvas/tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html": 1.6829,
-    "conformance/textures/canvas/tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html": 0.9767,
-    "conformance/textures/canvas_sub_rectangle/tex-2d-alpha-alpha-unsigned_byte.html": 2.5402,
-    "conformance/textures/canvas_sub_rectangle/tex-2d-luminance-luminance-unsigned_byte.html": 1.2943,
-    "conformance/textures/canvas_sub_rectangle/tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html": 1.3063,
-    "conformance/textures/canvas_sub_rectangle/tex-2d-rgb-rgb-unsigned_byte.html": 1.3511,
-    "conformance/textures/canvas_sub_rectangle/tex-2d-rgb-rgb-unsigned_short_5_6_5.html": 1.5985,
-    "conformance/textures/canvas_sub_rectangle/tex-2d-rgba-rgba-unsigned_byte.html": 1.3997,
-    "conformance/textures/canvas_sub_rectangle/tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html": 1.2823,
-    "conformance/textures/canvas_sub_rectangle/tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html": 1.6971,
-    "conformance/textures/image/tex-2d-alpha-alpha-unsigned_byte.html": 0.4045,
-    "conformance/textures/image/tex-2d-luminance-luminance-unsigned_byte.html": 0.3356,
-    "conformance/textures/image/tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html": 0.7969,
-    "conformance/textures/image/tex-2d-rgb-rgb-unsigned_byte.html": 0.5111,
-    "conformance/textures/image/tex-2d-rgb-rgb-unsigned_short_5_6_5.html": 0.5981,
-    "conformance/textures/image/tex-2d-rgba-rgba-unsigned_byte.html": 0.6935,
-    "conformance/textures/image/tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html": 0.5227,
-    "conformance/textures/image/tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html": 0.7033,
-    "conformance/textures/image_bitmap_from_blob/tex-2d-alpha-alpha-unsigned_byte.html": 0.659,
-    "conformance/textures/image_bitmap_from_blob/tex-2d-luminance-luminance-unsigned_byte.html": 0.611,
-    "conformance/textures/image_bitmap_from_blob/tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html": 0.3653,
-    "conformance/textures/image_bitmap_from_blob/tex-2d-rgb-rgb-unsigned_byte.html": 0.6999,
-    "conformance/textures/image_bitmap_from_blob/tex-2d-rgb-rgb-unsigned_short_5_6_5.html": 0.5399,
-    "conformance/textures/image_bitmap_from_blob/tex-2d-rgba-rgba-unsigned_byte.html": 0.3605,
-    "conformance/textures/image_bitmap_from_blob/tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html": 0.3911,
-    "conformance/textures/image_bitmap_from_blob/tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html": 0.5187,
-    "conformance/textures/image_bitmap_from_canvas/tex-2d-alpha-alpha-unsigned_byte.html": 1.387,
-    "conformance/textures/image_bitmap_from_canvas/tex-2d-luminance-luminance-unsigned_byte.html": 1.2749,
-    "conformance/textures/image_bitmap_from_canvas/tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html": 0.8402,
-    "conformance/textures/image_bitmap_from_canvas/tex-2d-rgb-rgb-unsigned_byte.html": 1.1109,
-    "conformance/textures/image_bitmap_from_canvas/tex-2d-rgb-rgb-unsigned_short_5_6_5.html": 0.6137,
-    "conformance/textures/image_bitmap_from_canvas/tex-2d-rgba-rgba-unsigned_byte.html": 0.7593,
-    "conformance/textures/image_bitmap_from_canvas/tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html": 0.9121,
-    "conformance/textures/image_bitmap_from_canvas/tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html": 0.9172,
-    "conformance/textures/image_bitmap_from_image/tex-2d-alpha-alpha-unsigned_byte.html": 0.6815,
-    "conformance/textures/image_bitmap_from_image/tex-2d-luminance-luminance-unsigned_byte.html": 0.4637,
-    "conformance/textures/image_bitmap_from_image/tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html": 0.5945,
-    "conformance/textures/image_bitmap_from_image/tex-2d-rgb-rgb-unsigned_byte.html": 0.4335,
-    "conformance/textures/image_bitmap_from_image/tex-2d-rgb-rgb-unsigned_short_5_6_5.html": 0.5021,
-    "conformance/textures/image_bitmap_from_image/tex-2d-rgba-rgba-unsigned_byte.html": 0.4349,
-    "conformance/textures/image_bitmap_from_image/tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html": 0.5585,
-    "conformance/textures/image_bitmap_from_image/tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html": 0.4105,
-    "conformance/textures/image_bitmap_from_image_bitmap/tex-2d-alpha-alpha-unsigned_byte.html": 0.4921,
-    "conformance/textures/image_bitmap_from_image_bitmap/tex-2d-luminance-luminance-unsigned_byte.html": 0.7403,
-    "conformance/textures/image_bitmap_from_image_bitmap/tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html": 0.4249,
-    "conformance/textures/image_bitmap_from_image_bitmap/tex-2d-rgb-rgb-unsigned_byte.html": 0.3943,
-    "conformance/textures/image_bitmap_from_image_bitmap/tex-2d-rgb-rgb-unsigned_short_5_6_5.html": 0.5201,
-    "conformance/textures/image_bitmap_from_image_bitmap/tex-2d-rgba-rgba-unsigned_byte.html": 0.446,
-    "conformance/textures/image_bitmap_from_image_bitmap/tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html": 0.4439,
-    "conformance/textures/image_bitmap_from_image_bitmap/tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html": 0.4007,
-    "conformance/textures/image_bitmap_from_image_data/tex-2d-alpha-alpha-unsigned_byte.html": 0.6508,
-    "conformance/textures/image_bitmap_from_image_data/tex-2d-luminance-luminance-unsigned_byte.html": 0.5361,
-    "conformance/textures/image_bitmap_from_image_data/tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html": 0.6,
-    "conformance/textures/image_bitmap_from_image_data/tex-2d-rgb-rgb-unsigned_byte.html": 0.4762,
-    "conformance/textures/image_bitmap_from_image_data/tex-2d-rgb-rgb-unsigned_short_5_6_5.html": 0.4188,
-    "conformance/textures/image_bitmap_from_image_data/tex-2d-rgba-rgba-unsigned_byte.html": 0.3037,
-    "conformance/textures/image_bitmap_from_image_data/tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html": 0.5449,
-    "conformance/textures/image_bitmap_from_image_data/tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html": 0.3695,
-    "conformance/textures/image_bitmap_from_video/tex-2d-alpha-alpha-unsigned_byte.html": 0.649,
-    "conformance/textures/image_bitmap_from_video/tex-2d-luminance-luminance-unsigned_byte.html": 3.0531,
-    "conformance/textures/image_bitmap_from_video/tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html": 2.8122,
-    "conformance/textures/image_bitmap_from_video/tex-2d-rgb-rgb-unsigned_byte.html": 3.1465,
-    "conformance/textures/image_bitmap_from_video/tex-2d-rgb-rgb-unsigned_short_5_6_5.html": 0.6525,
-    "conformance/textures/image_bitmap_from_video/tex-2d-rgba-rgba-unsigned_byte.html": 0.5111,
-    "conformance/textures/image_bitmap_from_video/tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html": 2.8391,
-    "conformance/textures/image_bitmap_from_video/tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html": 2.992,
-    "conformance/textures/image_data/tex-2d-alpha-alpha-unsigned_byte.html": 0.568,
-    "conformance/textures/image_data/tex-2d-luminance-luminance-unsigned_byte.html": 1.0587,
-    "conformance/textures/image_data/tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html": 0.5827,
-    "conformance/textures/image_data/tex-2d-rgb-rgb-unsigned_byte.html": 1.7083,
-    "conformance/textures/image_data/tex-2d-rgb-rgb-unsigned_short_5_6_5.html": 1.0177,
-    "conformance/textures/image_data/tex-2d-rgba-rgba-unsigned_byte.html": 0.7774,
-    "conformance/textures/image_data/tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html": 1.4213,
-    "conformance/textures/image_data/tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html": 0.6073,
-    "conformance/textures/misc/canvas-teximage-after-multiple-drawimages.html": 0.3287,
-    "conformance/textures/misc/compressed-tex-image.html": 0.2854,
-    "conformance/textures/misc/copy-tex-image-2d-formats.html": 0.7199,
-    "conformance/textures/misc/copy-tex-image-and-sub-image-2d.html": 0.5709,
-    "conformance/textures/misc/copy-tex-image-crash.html": 0.1457,
-    "conformance/textures/misc/copytexsubimage2d-large-partial-copy-corruption.html": 0.6498,
-    "conformance/textures/misc/copytexsubimage2d-subrects.html": 0.0802,
-    "conformance/textures/misc/cube-incomplete-fbo.html": 0.2259,
-    "conformance/textures/misc/cube-map-uploads-out-of-order.html": 1.2214,
-    "conformance/textures/misc/default-texture.html": 0.1728,
-    "conformance/textures/misc/gl-pixelstorei.html": 0.1504,
-    "conformance/textures/misc/gl-teximage.html": 0.9555,
-    "conformance/textures/misc/mipmap-fbo.html": 0.2016,
-    "conformance/textures/misc/origin-clean-conformance-offscreencanvas.html": 0.2804,
-    "conformance/textures/misc/origin-clean-conformance.html": 0.1605,
-    "conformance/textures/misc/tex-image-and-sub-image-2d-with-array-buffer-view.html": 3.2298,
-    "conformance/textures/misc/tex-image-and-uniform-binding-bugs.html": 0.0872,
-    "conformance/textures/misc/tex-image-canvas-corruption.html": 0.5789,
-    "conformance/textures/misc/tex-image-webgl.html": 0.3046,
-    "conformance/textures/misc/tex-image-with-format-and-type.html": 0.7719,
-    "conformance/textures/misc/tex-image-with-invalid-data.html": 0.1242,
-    "conformance/textures/misc/tex-sub-image-2d-bad-args.html": 0.1526,
-    "conformance/textures/misc/tex-sub-image-2d.html": 0.1335,
-    "conformance/textures/misc/tex-video-using-tex-unit-non-zero.html": 3.203,
-    "conformance/textures/misc/texparameter-test.html": 0.2186,
-    "conformance/textures/misc/texture-active-bind-2.html": 0.1131,
-    "conformance/textures/misc/texture-active-bind.html": 0.1529,
-    "conformance/textures/misc/texture-attachment-formats.html": 0.1999,
-    "conformance/textures/misc/texture-clear.html": 0.1216,
-    "conformance/textures/misc/texture-complete.html": 0.1356,
-    "conformance/textures/misc/texture-copying-feedback-loops.html": 0.2493,
-    "conformance/textures/misc/texture-corner-case-videos.html": 0.3204,
-    "conformance/textures/misc/texture-cube-as-fbo-attachment.html": 0.2758,
-    "conformance/textures/misc/texture-draw-with-2d-and-cube.html": 0.1493,
-    "conformance/textures/misc/texture-hd-dpi.html": 0.2345,
-    "conformance/textures/misc/texture-mips.html": 0.2731,
-    "conformance/textures/misc/texture-size-cube-maps.html": 0.933,
-    "conformance/textures/misc/texture-size-limit.html": 0.8109,
-    "conformance/textures/misc/texture-size.html": 0.9014,
-    "conformance/textures/misc/texture-sub-image-cube-maps.html": 0.2734,
-    "conformance/textures/misc/texture-transparent-pixels-initialized.html": 0.3433,
-    "conformance/textures/misc/texture-upload-cube-maps.html": 0.3791,
-    "conformance/textures/misc/texture-upload-size.html": 2.9173,
-    "conformance/textures/misc/texture-video-transparent.html": 2.3875,
-    "conformance/textures/misc/texture-with-flip-y-and-premultiply-alpha.html": 0.2668,
-    "conformance/textures/svg_image/tex-2d-alpha-alpha-unsigned_byte.html": 0.4531,
-    "conformance/textures/svg_image/tex-2d-luminance-luminance-unsigned_byte.html": 0.53,
-    "conformance/textures/svg_image/tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html": 0.3204,
-    "conformance/textures/svg_image/tex-2d-rgb-rgb-unsigned_byte.html": 0.4627,
-    "conformance/textures/svg_image/tex-2d-rgb-rgb-unsigned_short_5_6_5.html": 0.3215,
-    "conformance/textures/svg_image/tex-2d-rgba-rgba-unsigned_byte.html": 0.5671,
-    "conformance/textures/svg_image/tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html": 0.4959,
-    "conformance/textures/svg_image/tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html": 0.3145,
-    "conformance/textures/video/tex-2d-alpha-alpha-unsigned_byte.html": 3.0823,
-    "conformance/textures/video/tex-2d-luminance-luminance-unsigned_byte.html": 3.0213,
-    "conformance/textures/video/tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html": 0.7555,
-    "conformance/textures/video/tex-2d-rgb-rgb-unsigned_byte.html": 2.9754,
-    "conformance/textures/video/tex-2d-rgb-rgb-unsigned_short_5_6_5.html": 0.8547,
-    "conformance/textures/video/tex-2d-rgba-rgba-unsigned_byte.html": 3.1836,
-    "conformance/textures/video/tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html": 1.0706,
-    "conformance/textures/video/tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html": 0.8155,
-    "conformance/textures/webgl_canvas/tex-2d-alpha-alpha-unsigned_byte.html": 0.8462,
-    "conformance/textures/webgl_canvas/tex-2d-luminance-luminance-unsigned_byte.html": 0.9043,
-    "conformance/textures/webgl_canvas/tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html": 0.8538,
-    "conformance/textures/webgl_canvas/tex-2d-rgb-rgb-unsigned_byte.html": 2.4074,
-    "conformance/textures/webgl_canvas/tex-2d-rgb-rgb-unsigned_short_5_6_5.html": 0.8424,
-    "conformance/textures/webgl_canvas/tex-2d-rgba-rgba-unsigned_byte.html": 2.6169,
-    "conformance/textures/webgl_canvas/tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html": 1.2362,
-    "conformance/textures/webgl_canvas/tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html": 1.0602,
-    "conformance/typedarrays/array-buffer-crash.html": 0.1637,
-    "conformance/typedarrays/array-buffer-view-crash.html": 0.0647,
-    "conformance/typedarrays/array-large-array-tests.html": 0.1752,
-    "conformance/typedarrays/array-unit-tests.html": 0.17,
-    "conformance/typedarrays/data-view-crash.html": 0.0594,
-    "conformance/typedarrays/data-view-test.html": 0.1149,
-    "conformance/typedarrays/typed-arrays-in-workers.html": 0.2716,
-    "conformance/uniforms/gl-uniform-arrays.html": 0.4282,
-    "conformance/uniforms/gl-uniform-bool.html": 0.2751,
-    "conformance/uniforms/gl-uniformmatrix4fv.html": 0.2476,
-    "conformance/uniforms/gl-unknown-uniform.html": 0.0783,
-    "conformance/uniforms/no-over-optimization-on-uniform-array-00.html": 1.6621,
-    "conformance/uniforms/no-over-optimization-on-uniform-array-01.html": 2.2634,
-    "conformance/uniforms/no-over-optimization-on-uniform-array-02.html": 1.3287,
-    "conformance/uniforms/no-over-optimization-on-uniform-array-03.html": 1.8586,
-    "conformance/uniforms/no-over-optimization-on-uniform-array-04.html": 1.7311,
-    "conformance/uniforms/no-over-optimization-on-uniform-array-05.html": 1.8728,
-    "conformance/uniforms/no-over-optimization-on-uniform-array-06.html": 1.5145,
-    "conformance/uniforms/no-over-optimization-on-uniform-array-07.html": 1.0921,
-    "conformance/uniforms/no-over-optimization-on-uniform-array-08.html": 1.3643,
-    "conformance/uniforms/no-over-optimization-on-uniform-array-09.html": 1.4283,
-    "conformance/uniforms/no-over-optimization-on-uniform-array-10.html": 1.7072,
-    "conformance/uniforms/no-over-optimization-on-uniform-array-11.html": 1.5103,
-    "conformance/uniforms/no-over-optimization-on-uniform-array-12.html": 1.8111,
-    "conformance/uniforms/no-over-optimization-on-uniform-array-13.html": 1.8623,
-    "conformance/uniforms/no-over-optimization-on-uniform-array-14.html": 1.3646,
-    "conformance/uniforms/no-over-optimization-on-uniform-array-15.html": 2.3477,
-    "conformance/uniforms/no-over-optimization-on-uniform-array-16.html": 1.5075,
-    "conformance/uniforms/no-over-optimization-on-uniform-array-17.html": 1.6,
-    "conformance/uniforms/null-uniform-location.html": 0.2099,
-    "conformance/uniforms/out-of-bounds-uniform-array-access.html": 2.915,
-    "conformance/uniforms/uniform-default-values.html": 1.8311,
-    "conformance/uniforms/uniform-location.html": 0.5064,
-    "conformance/uniforms/uniform-samplers-test.html": 84.3505,
-    "conformance/uniforms/uniform-values-per-program.html": 1.3762,
-    "conformance2/attribs/gl-bindAttribLocation-aliasing-inactive.html": 1.04,
-    "conformance2/attribs/gl-vertex-attrib-i-render.html": 0.7977,
-    "conformance2/attribs/gl-vertex-attrib-normalized-int.html": 0.2909,
-    "conformance2/attribs/gl-vertex-attrib.html": 1.5948,
-    "conformance2/attribs/gl-vertexattribipointer-offsets.html": 0.8638,
-    "conformance2/attribs/gl-vertexattribipointer.html": 2.1657,
-    "conformance2/attribs/render-no-enabled-attrib-arrays.html": 0.3067,
-    "conformance2/buffers/bound-buffer-size-change-test.html": 0.29,
-    "conformance2/buffers/buffer-copying-contents.html": 0.5794,
-    "conformance2/buffers/buffer-copying-restrictions.html": 0.3623,
-    "conformance2/buffers/buffer-data-and-buffer-sub-data-sub-source.html": 0.4988,
-    "conformance2/buffers/buffer-overflow-test.html": 0.1815,
-    "conformance2/buffers/buffer-type-restrictions.html": 0.4463,
-    "conformance2/buffers/delete-buffer.html": 0.1621,
-    "conformance2/buffers/get-buffer-sub-data-validity.html": 0.2816,
-    "conformance2/buffers/get-buffer-sub-data.html": 0.4017,
-    "conformance2/buffers/one-large-uniform-buffer.html": 0.4562,
-    "conformance2/buffers/uniform-buffers-second-compile.html": 0.1216,
-    "conformance2/buffers/uniform-buffers-state-restoration.html": 0.5542,
-    "conformance2/buffers/uniform-buffers.html": 0.3963,
-    "conformance2/canvas/to-data-url-with-pack-params.html": 0.0854,
-    "conformance2/context/constants-and-properties-2.html": 0.2327,
-    "conformance2/context/context-attributes-depth-stencil-antialias-obeyed.html": 0.1487,
-    "conformance2/context/context-mode.html": 0.3958,
-    "conformance2/context/context-resize-changes-buffer-binding-bug.html": 0.3295,
-    "conformance2/context/context-sharing-texture2darray-texture3d-data-bug.html": 0.684,
-    "conformance2/context/context-type-test-2.html": 0.0949,
-    "conformance2/context/incorrect-context-object-behaviour.html": 0.9393,
-    "conformance2/context/methods-2.html": 0.154,
-    "conformance2/context/no-experimental-webgl2.html": 0.1706,
-    "conformance2/extensions/ext-color-buffer-float.html": 0.6523,
-    "conformance2/extensions/ext-disjoint-timer-query-webgl2.html": 9.136,
-    "conformance2/extensions/ext-texture-filter-anisotropic.html": 0.2888,
-    "conformance2/extensions/ovr_multiview2.html": 5.5374,
-    "conformance2/extensions/ovr_multiview2_depth.html": 0.4723,
-    "conformance2/extensions/ovr_multiview2_draw_buffers.html": 0.5941,
-    "conformance2/extensions/ovr_multiview2_flat_varying.html": 0.4462,
-    "conformance2/extensions/ovr_multiview2_instanced_draw.html": 8.5958,
-    "conformance2/extensions/ovr_multiview2_non_multiview_shaders.html": 0.3145,
-    "conformance2/extensions/ovr_multiview2_single_view_operations.html": 0.6837,
-    "conformance2/extensions/ovr_multiview2_timer_query.html": 0.707,
-    "conformance2/extensions/ovr_multiview2_transform_feedback.html": 0.5493,
-    "conformance2/extensions/promoted-extensions-in-shaders.html": 1.2483,
-    "conformance2/extensions/promoted-extensions.html": 0.0744,
-    "conformance2/extensions/webgl-multi-draw-instanced-base-vertex-base-instance.html": 1.0248,
-    "conformance2/glsl3/array-as-return-value.html": 0.3167,
-    "conformance2/glsl3/array-assign-constructor.html": 0.142,
-    "conformance2/glsl3/array-assign.html": 0.5231,
-    "conformance2/glsl3/array-complex-indexing.html": 0.1483,
-    "conformance2/glsl3/array-element-increment.html": 0.3396,
-    "conformance2/glsl3/array-equality.html": 0.2933,
-    "conformance2/glsl3/array-in-complex-expression.html": 0.6044,
-    "conformance2/glsl3/array-initialize-with-same-name-array.html": 0.3578,
-    "conformance2/glsl3/array-length-side-effects.html": 0.5819,
-    "conformance2/glsl3/attrib-location-length-limits.html": 0.303,
-    "conformance2/glsl3/bool-type-cast-bug-uint-ivec-uvec.html": 0.2646,
-    "conformance2/glsl3/compare-structs-containing-arrays.html": 0.268,
-    "conformance2/glsl3/compound-assignment-type-combination.html": 3.385,
-    "conformance2/glsl3/const-array-init.html": 0.3302,
-    "conformance2/glsl3/const-struct-from-array-as-function-parameter.html": 0.4675,
-    "conformance2/glsl3/float-parsing.html": 0.4174,
-    "conformance2/glsl3/forbidden-operators.html": 0.5008,
-    "conformance2/glsl3/forward-declaration.html": 0.3439,
-    "conformance2/glsl3/frag-depth.html": 0.3569,
-    "conformance2/glsl3/gradient-in-discontinuous-loop.html": 0.5678,
-    "conformance2/glsl3/input-with-interpotaion-as-lvalue.html": 0.175,
-    "conformance2/glsl3/invalid-default-precision.html": 0.2614,
-    "conformance2/glsl3/invalid-invariant.html": 0.1805,
-    "conformance2/glsl3/loops-with-side-effects.html": 0.8415,
-    "conformance2/glsl3/matrix-row-major.html": 0.4133,
-    "conformance2/glsl3/misplaced-version-directive.html": 0.4772,
-    "conformance2/glsl3/no-attribute-vertex-shader.html": 0.2983,
-    "conformance2/glsl3/sampler-array-indexing.html": 0.3704,
-    "conformance2/glsl3/sampler-no-precision.html": 0.5007,
-    "conformance2/glsl3/sequence-operator-returns-non-constant.html": 0.2435,
-    "conformance2/glsl3/shader-linking.html": 0.3694,
-    "conformance2/glsl3/shader-with-1024-character-define.html": 0.1713,
-    "conformance2/glsl3/shader-with-1024-character-identifier.frag.html": 0.3861,
-    "conformance2/glsl3/shader-with-1025-character-define.html": 0.4773,
-    "conformance2/glsl3/shader-with-1025-character-identifier.frag.html": 0.4485,
-    "conformance2/glsl3/shader-with-invalid-characters.html": 0.3182,
-    "conformance2/glsl3/shader-with-mis-matching-uniform-block.html": 0.1511,
-    "conformance2/glsl3/short-circuiting-in-loop-condition.html": 0.5803,
-    "conformance2/glsl3/switch-case.html": 0.472,
-    "conformance2/glsl3/texture-offset-non-constant-offset.html": 0.3112,
-    "conformance2/glsl3/texture-offset-out-of-range.html": 0.3699,
-    "conformance2/glsl3/texture-offset-uniform-texture-coordinate.html": 0.3194,
-    "conformance2/glsl3/tricky-loop-conditions.html": 1.3557,
-    "conformance2/glsl3/unary-minus-operator-in-dynamic-loop.html": 0.5665,
-    "conformance2/glsl3/uniform-block-layout-match.html": 0.4411,
-    "conformance2/glsl3/uniform-block-layouts.html": 0.2189,
-    "conformance2/glsl3/uniform-location-length-limits.html": 0.4627,
-    "conformance2/glsl3/uniform-struct-with-non-square-matrix.html": 0.1663,
-    "conformance2/glsl3/uninitialized-local-global-variables.html": 0.3688,
-    "conformance2/glsl3/valid-invariant.html": 0.3544,
-    "conformance2/glsl3/varying-struct-inline-definition.html": 0.4134,
-    "conformance2/glsl3/vector-dynamic-indexing-nv-driver-bug.html": 0.237,
-    "conformance2/glsl3/vector-dynamic-indexing-swizzled-lvalue.html": 0.4107,
-    "conformance2/glsl3/vector-dynamic-indexing.html": 0.5368,
-    "conformance2/misc/expando-loss-2.html": 0.4035,
-    "conformance2/misc/getextension-while-pbo-bound-stability.html": 0.2807,
-    "conformance2/misc/instanceof-test.html": 0.1853,
-    "conformance2/misc/object-deletion-behaviour-2.html": 0.1011,
-    "conformance2/misc/uninitialized-test-2.html": 15.0602,
-    "conformance2/misc/views-with-offsets.html": 0.3324,
-    "conformance2/offscreencanvas/context-creation-worker.html": 0.1588,
-    "conformance2/offscreencanvas/context-creation.html": 0.1718,
-    "conformance2/offscreencanvas/methods-2-worker.html": 0.192,
-    "conformance2/offscreencanvas/methods-2.html": 0.1658,
-    "conformance2/offscreencanvas/offscreencanvas-transfer-image-bitmap.html": 0.4352,
-    "conformance2/programs/active-built-in-attribs.html": 0.2618,
-    "conformance2/programs/gl-get-frag-data-location.html": 0.1507,
-    "conformance2/programs/sampler-uniforms.html": 0.6105,
-    "conformance2/query/occlusion-query.html": 3.7636,
-    "conformance2/query/query.html": 0.2864,
-    "conformance2/reading/format-r11f-g11f-b10f.html": 0.3879,
-    "conformance2/reading/read-pixels-from-fbo-test.html": 0.4296,
-    "conformance2/reading/read-pixels-from-rgb8-into-pbo-bug.html": 0.1911,
-    "conformance2/reading/read-pixels-into-pixel-pack-buffer.html": 0.1274,
-    "conformance2/reading/read-pixels-pack-parameters.html": 0.7117,
-    "conformance2/renderbuffers/framebuffer-object-attachment.html": 0.3901,
-    "conformance2/renderbuffers/framebuffer-test.html": 0.3462,
-    "conformance2/renderbuffers/framebuffer-texture-layer.html": 0.3063,
-    "conformance2/renderbuffers/invalidate-framebuffer.html": 0.1292,
-    "conformance2/renderbuffers/multisample-with-full-sample-counts.html": 0.2782,
-    "conformance2/renderbuffers/multisampled-depth-renderbuffer-initialization.html": 0.4562,
-    "conformance2/renderbuffers/multisampled-renderbuffer-initialization.html": 0.4071,
-    "conformance2/renderbuffers/multisampled-stencil-renderbuffer-initialization.html": 0.3675,
-    "conformance2/renderbuffers/readbuffer.html": 0.2668,
-    "conformance2/rendering/attrib-type-match.html": 0.5203,
-    "conformance2/rendering/blitframebuffer-filter-outofbounds.html": 0.8305,
-    "conformance2/rendering/blitframebuffer-filter-srgb.html": 0.2764,
-    "conformance2/rendering/blitframebuffer-multisampled-readbuffer.html": 0.1347,
-    "conformance2/rendering/blitframebuffer-outside-readbuffer.html": 0.2641,
-    "conformance2/rendering/blitframebuffer-r11f-g11f-b10f.html": 0.267,
-    "conformance2/rendering/blitframebuffer-resolve-to-back-buffer.html": 0.3527,
-    "conformance2/rendering/blitframebuffer-scissor-enabled.html": 0.1987,
-    "conformance2/rendering/blitframebuffer-size-overflow.html": 0.1164,
-    "conformance2/rendering/blitframebuffer-srgb-and-linear-drawbuffers.html": 0.5182,
-    "conformance2/rendering/blitframebuffer-stencil-only.html": 0.1266,
-    "conformance2/rendering/blitframebuffer-test.html": 0.243,
-    "conformance2/rendering/canvas-resizing-with-pbo-bound.html": 0.5905,
-    "conformance2/rendering/clear-func-buffer-type-match.html": 0.3342,
-    "conformance2/rendering/clear-srgb-color-buffer.html": 0.0979,
-    "conformance2/rendering/clearbuffer-sub-source.html": 0.0981,
-    "conformance2/rendering/clearbufferfv-with-alpha-false.html": 0.1026,
-    "conformance2/rendering/clipping-wide-points.html": 0.1563,
-    "conformance2/rendering/depth-stencil-feedback-loop.html": 0.1211,
-    "conformance2/rendering/draw-buffers-dirty-state-bug.html": 0.1196,
-    "conformance2/rendering/draw-buffers-driver-hang.html": 0.4304,
-    "conformance2/rendering/draw-buffers.html": 0.8265,
-    "conformance2/rendering/draw-with-integer-texture-base-level.html": 0.1724,
-    "conformance2/rendering/element-index-uint.html": 1.0999,
-    "conformance2/rendering/framebuffer-completeness-draw-framebuffer.html": 0.3706,
-    "conformance2/rendering/framebuffer-completeness-unaffected.html": 0.0966,
-    "conformance2/rendering/framebuffer-texture-changing-base-level.html": 0.2609,
-    "conformance2/rendering/framebuffer-texture-level1.html": 0.1946,
-    "conformance2/rendering/framebuffer-unsupported.html": 0.1049,
-    "conformance2/rendering/fs-color-type-mismatch-color-buffer-type.html": 0.1796,
-    "conformance2/rendering/instanced-arrays.html": 0.432,
-    "conformance2/rendering/instanced-rendering-bug.html": 0.5477,
-    "conformance2/rendering/instanced-rendering-large-divisor.html": 0.4336,
-    "conformance2/rendering/line-rendering-quality.html": 0.2654,
-    "conformance2/rendering/multisampling-fragment-evaluation.html": 0.1423,
-    "conformance2/rendering/out-of-bounds-index-buffers-after-copying.html": 0.1171,
-    "conformance2/rendering/read-draw-when-missing-image.html": 0.2062,
-    "conformance2/rendering/rgb-format-support.html": 0.2829,
+    "conformance/rendering/triangle.html": 0.1666,
+    "conformance/state/fb-attach-implicit-target-assignment.html": 0.1657,
+    "conformance/state/gl-enable-enum-test.html": 0.6183,
+    "conformance/state/gl-get-calls.html": 0.1468,
+    "conformance/state/gl-geterror.html": 0.3911,
+    "conformance/state/gl-initial-state.html": 0.2913,
+    "conformance/state/state-uneffected-after-compositing.html": 0.3369,
+    "conformance/textures/canvas/tex-2d-alpha-alpha-unsigned_byte.html": 1.0636,
+    "conformance/textures/canvas/tex-2d-luminance-luminance-unsigned_byte.html": 1.2659,
+    "conformance/textures/canvas/tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html": 0.8792,
+    "conformance/textures/canvas/tex-2d-rgb-rgb-unsigned_byte.html": 4.3671,
+    "conformance/textures/canvas/tex-2d-rgb-rgb-unsigned_short_5_6_5.html": 1.5835,
+    "conformance/textures/canvas/tex-2d-rgba-rgba-unsigned_byte.html": 4.1579,
+    "conformance/textures/canvas/tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html": 1.2177,
+    "conformance/textures/canvas/tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html": 1.6446,
+    "conformance/textures/canvas_sub_rectangle/tex-2d-alpha-alpha-unsigned_byte.html": 1.2265,
+    "conformance/textures/canvas_sub_rectangle/tex-2d-luminance-luminance-unsigned_byte.html": 1.3077,
+    "conformance/textures/canvas_sub_rectangle/tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html": 1.1277,
+    "conformance/textures/canvas_sub_rectangle/tex-2d-rgb-rgb-unsigned_byte.html": 2.3804,
+    "conformance/textures/canvas_sub_rectangle/tex-2d-rgb-rgb-unsigned_short_5_6_5.html": 1.1499,
+    "conformance/textures/canvas_sub_rectangle/tex-2d-rgba-rgba-unsigned_byte.html": 1.2218,
+    "conformance/textures/canvas_sub_rectangle/tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html": 1.8558,
+    "conformance/textures/canvas_sub_rectangle/tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html": 1.6429,
+    "conformance/textures/image/tex-2d-alpha-alpha-unsigned_byte.html": 0.5052,
+    "conformance/textures/image/tex-2d-luminance-luminance-unsigned_byte.html": 0.7716,
+    "conformance/textures/image/tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html": 0.7081,
+    "conformance/textures/image/tex-2d-rgb-rgb-unsigned_byte.html": 0.561,
+    "conformance/textures/image/tex-2d-rgb-rgb-unsigned_short_5_6_5.html": 0.4089,
+    "conformance/textures/image/tex-2d-rgba-rgba-unsigned_byte.html": 0.5432,
+    "conformance/textures/image/tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html": 0.7802,
+    "conformance/textures/image/tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html": 0.4981,
+    "conformance/textures/image_bitmap_from_blob/tex-2d-alpha-alpha-unsigned_byte.html": 0.7137,
+    "conformance/textures/image_bitmap_from_blob/tex-2d-luminance-luminance-unsigned_byte.html": 0.6308,
+    "conformance/textures/image_bitmap_from_blob/tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html": 0.845,
+    "conformance/textures/image_bitmap_from_blob/tex-2d-rgb-rgb-unsigned_byte.html": 0.7933,
+    "conformance/textures/image_bitmap_from_blob/tex-2d-rgb-rgb-unsigned_short_5_6_5.html": 0.7071,
+    "conformance/textures/image_bitmap_from_blob/tex-2d-rgba-rgba-unsigned_byte.html": 0.8659,
+    "conformance/textures/image_bitmap_from_blob/tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html": 0.5938,
+    "conformance/textures/image_bitmap_from_blob/tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html": 0.6079,
+    "conformance/textures/image_bitmap_from_canvas/tex-2d-alpha-alpha-unsigned_byte.html": 1.2433,
+    "conformance/textures/image_bitmap_from_canvas/tex-2d-luminance-luminance-unsigned_byte.html": 0.8987,
+    "conformance/textures/image_bitmap_from_canvas/tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html": 1.0699,
+    "conformance/textures/image_bitmap_from_canvas/tex-2d-rgb-rgb-unsigned_byte.html": 1.01,
+    "conformance/textures/image_bitmap_from_canvas/tex-2d-rgb-rgb-unsigned_short_5_6_5.html": 1.2122,
+    "conformance/textures/image_bitmap_from_canvas/tex-2d-rgba-rgba-unsigned_byte.html": 1.0518,
+    "conformance/textures/image_bitmap_from_canvas/tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html": 0.9415,
+    "conformance/textures/image_bitmap_from_canvas/tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html": 0.876,
+    "conformance/textures/image_bitmap_from_image/tex-2d-alpha-alpha-unsigned_byte.html": 0.7912,
+    "conformance/textures/image_bitmap_from_image/tex-2d-luminance-luminance-unsigned_byte.html": 0.4553,
+    "conformance/textures/image_bitmap_from_image/tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html": 0.6666,
+    "conformance/textures/image_bitmap_from_image/tex-2d-rgb-rgb-unsigned_byte.html": 0.7378,
+    "conformance/textures/image_bitmap_from_image/tex-2d-rgb-rgb-unsigned_short_5_6_5.html": 0.5827,
+    "conformance/textures/image_bitmap_from_image/tex-2d-rgba-rgba-unsigned_byte.html": 0.6331,
+    "conformance/textures/image_bitmap_from_image/tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html": 0.8023,
+    "conformance/textures/image_bitmap_from_image/tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html": 0.6594,
+    "conformance/textures/image_bitmap_from_image_bitmap/tex-2d-alpha-alpha-unsigned_byte.html": 0.472,
+    "conformance/textures/image_bitmap_from_image_bitmap/tex-2d-luminance-luminance-unsigned_byte.html": 0.5334,
+    "conformance/textures/image_bitmap_from_image_bitmap/tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html": 0.4734,
+    "conformance/textures/image_bitmap_from_image_bitmap/tex-2d-rgb-rgb-unsigned_byte.html": 0.4122,
+    "conformance/textures/image_bitmap_from_image_bitmap/tex-2d-rgb-rgb-unsigned_short_5_6_5.html": 0.3514,
+    "conformance/textures/image_bitmap_from_image_bitmap/tex-2d-rgba-rgba-unsigned_byte.html": 0.3492,
+    "conformance/textures/image_bitmap_from_image_bitmap/tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html": 0.5301,
+    "conformance/textures/image_bitmap_from_image_bitmap/tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html": 0.7807,
+    "conformance/textures/image_bitmap_from_image_data/tex-2d-alpha-alpha-unsigned_byte.html": 0.5333,
+    "conformance/textures/image_bitmap_from_image_data/tex-2d-luminance-luminance-unsigned_byte.html": 0.7805,
+    "conformance/textures/image_bitmap_from_image_data/tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html": 0.5639,
+    "conformance/textures/image_bitmap_from_image_data/tex-2d-rgb-rgb-unsigned_byte.html": 0.4064,
+    "conformance/textures/image_bitmap_from_image_data/tex-2d-rgb-rgb-unsigned_short_5_6_5.html": 0.4742,
+    "conformance/textures/image_bitmap_from_image_data/tex-2d-rgba-rgba-unsigned_byte.html": 0.4776,
+    "conformance/textures/image_bitmap_from_image_data/tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html": 0.5741,
+    "conformance/textures/image_bitmap_from_image_data/tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html": 0.4453,
+    "conformance/textures/image_bitmap_from_video/tex-2d-alpha-alpha-unsigned_byte.html": 0.7061,
+    "conformance/textures/image_bitmap_from_video/tex-2d-luminance-luminance-unsigned_byte.html": 0.6327,
+    "conformance/textures/image_bitmap_from_video/tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html": 0.497,
+    "conformance/textures/image_bitmap_from_video/tex-2d-rgb-rgb-unsigned_byte.html": 0.6112,
+    "conformance/textures/image_bitmap_from_video/tex-2d-rgb-rgb-unsigned_short_5_6_5.html": 0.5755,
+    "conformance/textures/image_bitmap_from_video/tex-2d-rgba-rgba-unsigned_byte.html": 0.6547,
+    "conformance/textures/image_bitmap_from_video/tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html": 0.4888,
+    "conformance/textures/image_bitmap_from_video/tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html": 0.7575,
+    "conformance/textures/image_data/tex-2d-alpha-alpha-unsigned_byte.html": 1.4108,
+    "conformance/textures/image_data/tex-2d-luminance-luminance-unsigned_byte.html": 0.745,
+    "conformance/textures/image_data/tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html": 0.9405,
+    "conformance/textures/image_data/tex-2d-rgb-rgb-unsigned_byte.html": 0.5918,
+    "conformance/textures/image_data/tex-2d-rgb-rgb-unsigned_short_5_6_5.html": 0.7854,
+    "conformance/textures/image_data/tex-2d-rgba-rgba-unsigned_byte.html": 0.6035,
+    "conformance/textures/image_data/tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html": 0.8457,
+    "conformance/textures/image_data/tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html": 0.7936,
+    "conformance/textures/misc/canvas-teximage-after-multiple-drawimages.html": 0.3199,
+    "conformance/textures/misc/copy-tex-image-2d-formats.html": 0.4395,
+    "conformance/textures/misc/copy-tex-image-and-sub-image-2d.html": 0.7348,
+    "conformance/textures/misc/copy-tex-image-crash.html": 0.1905,
+    "conformance/textures/misc/copytexsubimage2d-large-partial-copy-corruption.html": 0.4188,
+    "conformance/textures/misc/copytexsubimage2d-subrects.html": 0.1826,
+    "conformance/textures/misc/cube-incomplete-fbo.html": 0.1486,
+    "conformance/textures/misc/cube-map-uploads-out-of-order.html": 1.1393,
+    "conformance/textures/misc/default-texture.html": 0.1779,
+    "conformance/textures/misc/exif-orientation.html": 0.7674,
+    "conformance/textures/misc/gl-pixelstorei.html": 0.2008,
+    "conformance/textures/misc/gl-teximage.html": 1.1086,
+    "conformance/textures/misc/mipmap-fbo.html": 0.3335,
+    "conformance/textures/misc/origin-clean-conformance-offscreencanvas.html": 0.3235,
+    "conformance/textures/misc/origin-clean-conformance.html": 0.1855,
+    "conformance/textures/misc/tex-image-and-sub-image-2d-with-array-buffer-view.html": 2.0769,
+    "conformance/textures/misc/tex-image-and-uniform-binding-bugs.html": 0.1094,
+    "conformance/textures/misc/tex-image-canvas-corruption.html": 0.5558,
+    "conformance/textures/misc/tex-image-webgl.html": 0.3179,
+    "conformance/textures/misc/tex-image-with-format-and-type.html": 0.9681,
+    "conformance/textures/misc/tex-image-with-invalid-data.html": 0.1058,
+    "conformance/textures/misc/tex-sub-image-2d-bad-args.html": 0.2039,
+    "conformance/textures/misc/tex-sub-image-2d.html": 0.161,
+    "conformance/textures/misc/tex-video-using-tex-unit-non-zero.html": 0.746,
+    "conformance/textures/misc/texparameter-test.html": 0.3683,
+    "conformance/textures/misc/texture-active-bind-2.html": 0.3354,
+    "conformance/textures/misc/texture-active-bind.html": 0.2007,
+    "conformance/textures/misc/texture-attachment-formats.html": 0.4068,
+    "conformance/textures/misc/texture-clear.html": 0.1715,
+    "conformance/textures/misc/texture-complete.html": 0.1533,
+    "conformance/textures/misc/texture-copying-and-deletion.html": 1.2349,
+    "conformance/textures/misc/texture-copying-feedback-loops.html": 0.1142,
+    "conformance/textures/misc/texture-corner-case-videos.html": 0.3093,
+    "conformance/textures/misc/texture-cube-as-fbo-attachment.html": 0.231,
+    "conformance/textures/misc/texture-draw-with-2d-and-cube.html": 0.1019,
+    "conformance/textures/misc/texture-hd-dpi.html": 0.353,
+    "conformance/textures/misc/texture-mips.html": 0.3779,
+    "conformance/textures/misc/texture-size-cube-maps.html": 0.8743,
+    "conformance/textures/misc/texture-size-limit.html": 0.5067,
+    "conformance/textures/misc/texture-size.html": 1.2286,
+    "conformance/textures/misc/texture-sub-image-cube-maps.html": 0.5006,
+    "conformance/textures/misc/texture-transparent-pixels-initialized.html": 0.4271,
+    "conformance/textures/misc/texture-upload-cube-maps.html": 0.4384,
+    "conformance/textures/misc/texture-upload-size.html": 0.5463,
+    "conformance/textures/misc/texture-video-transparent.html": 2.4005,
+    "conformance/textures/misc/texture-with-flip-y-and-premultiply-alpha.html": 0.1244,
+    "conformance/textures/misc/upload-from-srcset-with-empty-data.html": 0.216,
+    "conformance/textures/svg_image/tex-2d-alpha-alpha-unsigned_byte.html": 0.4354,
+    "conformance/textures/svg_image/tex-2d-luminance-luminance-unsigned_byte.html": 0.1914,
+    "conformance/textures/svg_image/tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html": 0.3896,
+    "conformance/textures/svg_image/tex-2d-rgb-rgb-unsigned_byte.html": 0.3765,
+    "conformance/textures/svg_image/tex-2d-rgb-rgb-unsigned_short_5_6_5.html": 0.1852,
+    "conformance/textures/svg_image/tex-2d-rgba-rgba-unsigned_byte.html": 0.423,
+    "conformance/textures/svg_image/tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html": 0.3915,
+    "conformance/textures/svg_image/tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html": 0.3032,
+    "conformance/textures/video/tex-2d-alpha-alpha-unsigned_byte.html": 0.7933,
+    "conformance/textures/video/tex-2d-luminance-luminance-unsigned_byte.html": 0.9321,
+    "conformance/textures/video/tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html": 0.5761,
+    "conformance/textures/video/tex-2d-rgb-rgb-unsigned_byte.html": 0.8117,
+    "conformance/textures/video/tex-2d-rgb-rgb-unsigned_short_5_6_5.html": 0.8596,
+    "conformance/textures/video/tex-2d-rgba-rgba-unsigned_byte.html": 0.6039,
+    "conformance/textures/video/tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html": 0.8286,
+    "conformance/textures/video/tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html": 0.866,
+    "conformance/textures/webgl_canvas/tex-2d-alpha-alpha-unsigned_byte.html": 2.099,
+    "conformance/textures/webgl_canvas/tex-2d-luminance-luminance-unsigned_byte.html": 1.3863,
+    "conformance/textures/webgl_canvas/tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html": 1.5391,
+    "conformance/textures/webgl_canvas/tex-2d-rgb-rgb-unsigned_byte.html": 4.9072,
+    "conformance/textures/webgl_canvas/tex-2d-rgb-rgb-unsigned_short_5_6_5.html": 1.5133,
+    "conformance/textures/webgl_canvas/tex-2d-rgba-rgba-unsigned_byte.html": 5.3275,
+    "conformance/textures/webgl_canvas/tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html": 1.7977,
+    "conformance/textures/webgl_canvas/tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html": 1.4056,
+    "conformance/typedarrays/array-buffer-crash.html": 0.0671,
+    "conformance/typedarrays/array-buffer-view-crash.html": 0.0867,
+    "conformance/typedarrays/array-large-array-tests.html": 0.3225,
+    "conformance/typedarrays/array-unit-tests.html": 0.1226,
+    "conformance/typedarrays/data-view-crash.html": 0.1066,
+    "conformance/typedarrays/data-view-test.html": 0.1462,
+    "conformance/typedarrays/typed-arrays-in-workers.html": 0.162,
+    "conformance/uniforms/gl-uniform-arrays.html": 0.4747,
+    "conformance/uniforms/gl-uniform-bool.html": 0.2007,
+    "conformance/uniforms/gl-uniformmatrix4fv.html": 0.2121,
+    "conformance/uniforms/gl-unknown-uniform.html": 0.1349,
+    "conformance/uniforms/no-over-optimization-on-uniform-array-00.html": 1.341,
+    "conformance/uniforms/no-over-optimization-on-uniform-array-01.html": 1.0657,
+    "conformance/uniforms/no-over-optimization-on-uniform-array-02.html": 1.5066,
+    "conformance/uniforms/no-over-optimization-on-uniform-array-03.html": 1.0568,
+    "conformance/uniforms/no-over-optimization-on-uniform-array-04.html": 1.7469,
+    "conformance/uniforms/no-over-optimization-on-uniform-array-05.html": 1.6042,
+    "conformance/uniforms/no-over-optimization-on-uniform-array-06.html": 1.3688,
+    "conformance/uniforms/no-over-optimization-on-uniform-array-07.html": 1.4745,
+    "conformance/uniforms/no-over-optimization-on-uniform-array-08.html": 1.4427,
+    "conformance/uniforms/no-over-optimization-on-uniform-array-09.html": 2.1216,
+    "conformance/uniforms/no-over-optimization-on-uniform-array-10.html": 1.3261,
+    "conformance/uniforms/no-over-optimization-on-uniform-array-11.html": 1.3819,
+    "conformance/uniforms/no-over-optimization-on-uniform-array-12.html": 2.2069,
+    "conformance/uniforms/no-over-optimization-on-uniform-array-13.html": 1.1593,
+    "conformance/uniforms/no-over-optimization-on-uniform-array-14.html": 1.6884,
+    "conformance/uniforms/no-over-optimization-on-uniform-array-15.html": 1.6679,
+    "conformance/uniforms/no-over-optimization-on-uniform-array-16.html": 1.5267,
+    "conformance/uniforms/no-over-optimization-on-uniform-array-17.html": 1.3343,
+    "conformance/uniforms/null-uniform-location.html": 0.3938,
+    "conformance/uniforms/out-of-bounds-uniform-array-access.html": 3.477,
+    "conformance/uniforms/uniform-default-values.html": 1.9935,
+    "conformance/uniforms/uniform-location.html": 0.5463,
+    "conformance/uniforms/uniform-samplers-test.html": 24.516,
+    "conformance/uniforms/uniform-values-per-program.html": 1.0317,
+    "conformance2/attribs/gl-bindAttribLocation-aliasing-inactive.html": 0.7929,
+    "conformance2/attribs/gl-vertex-attrib-i-render.html": 0.2106,
+    "conformance2/attribs/gl-vertex-attrib-normalized-int.html": 0.1165,
+    "conformance2/attribs/gl-vertex-attrib.html": 0.9694,
+    "conformance2/attribs/gl-vertexattribipointer-offsets.html": 0.5687,
+    "conformance2/attribs/gl-vertexattribipointer.html": 1.3529,
+    "conformance2/attribs/render-no-enabled-attrib-arrays.html": 0.2172,
+    "conformance2/buffers/bound-buffer-size-change-test.html": 0.2984,
+    "conformance2/buffers/buffer-copying-contents.html": 0.6368,
+    "conformance2/buffers/buffer-copying-restrictions.html": 0.123,
+    "conformance2/buffers/buffer-data-and-buffer-sub-data-sub-source.html": 0.355,
+    "conformance2/buffers/buffer-overflow-test.html": 0.1775,
+    "conformance2/buffers/buffer-type-restrictions.html": 0.5574,
+    "conformance2/buffers/delete-buffer.html": 0.2169,
+    "conformance2/buffers/get-buffer-sub-data-validity.html": 0.4969,
+    "conformance2/buffers/get-buffer-sub-data.html": 0.1622,
+    "conformance2/buffers/one-large-uniform-buffer.html": 0.4448,
+    "conformance2/buffers/uniform-buffers-second-compile.html": 0.1541,
+    "conformance2/buffers/uniform-buffers-state-restoration.html": 0.6353,
+    "conformance2/buffers/uniform-buffers.html": 0.431,
+    "conformance2/canvas/to-data-url-with-pack-params.html": 0.2331,
+    "conformance2/context/constants-and-properties-2.html": 0.2124,
+    "conformance2/context/context-attributes-depth-stencil-antialias-obeyed.html": 0.2031,
+    "conformance2/context/context-mode.html": 0.2001,
+    "conformance2/context/context-resize-changes-buffer-binding-bug.html": 0.4545,
+    "conformance2/context/context-sharing-texture2darray-texture3d-data-bug.html": 0.9247,
+    "conformance2/context/context-type-test-2.html": 0.1318,
+    "conformance2/context/incorrect-context-object-behaviour.html": 0.4204,
+    "conformance2/context/methods-2.html": 0.0949,
+    "conformance2/context/no-experimental-webgl2.html": 0.0649,
+    "conformance2/extensions/ext-color-buffer-float.html": 0.7638,
+    "conformance2/extensions/ext-color-buffer-half-float.html": 0.8968,
+    "conformance2/extensions/ext-disjoint-timer-query-webgl2.html": 8.168,
+    "conformance2/extensions/ext-texture-filter-anisotropic.html": 0.1492,
+    "conformance2/extensions/ext-texture-norm16.html": 0.3666,
+    "conformance2/extensions/oes-draw-buffers-indexed.html": 0.5775,
+    "conformance2/extensions/ovr_multiview2.html": 1.6216,
+    "conformance2/extensions/ovr_multiview2_depth.html": 0.4598,
+    "conformance2/extensions/ovr_multiview2_draw_buffers.html": 0.5874,
+    "conformance2/extensions/ovr_multiview2_flat_varying.html": 0.5047,
+    "conformance2/extensions/ovr_multiview2_instanced_draw.html": 0.7869,
+    "conformance2/extensions/ovr_multiview2_non_multiview_shaders.html": 1.006,
+    "conformance2/extensions/ovr_multiview2_single_view_operations.html": 0.9591,
+    "conformance2/extensions/ovr_multiview2_timer_query.html": 0.4799,
+    "conformance2/extensions/ovr_multiview2_transform_feedback.html": 0.4464,
+    "conformance2/extensions/promoted-extensions-in-shaders.html": 0.6803,
+    "conformance2/extensions/promoted-extensions.html": 0.1411,
+    "conformance2/extensions/webgl-multi-draw-instanced-base-vertex-base-instance.html": 1.7593,
+    "conformance2/glsl3/array-as-return-value.html": 0.3873,
+    "conformance2/glsl3/array-assign-constructor.html": 0.16,
+    "conformance2/glsl3/array-assign.html": 0.17,
+    "conformance2/glsl3/array-complex-indexing.html": 0.6304,
+    "conformance2/glsl3/array-element-increment.html": 0.5941,
+    "conformance2/glsl3/array-equality.html": 0.4129,
+    "conformance2/glsl3/array-in-complex-expression.html": 0.3775,
+    "conformance2/glsl3/array-initialize-with-same-name-array.html": 0.3577,
+    "conformance2/glsl3/array-length-side-effects.html": 0.4921,
+    "conformance2/glsl3/attrib-location-length-limits.html": 0.2775,
+    "conformance2/glsl3/bool-type-cast-bug-uint-ivec-uvec.html": 0.3611,
+    "conformance2/glsl3/compare-structs-containing-arrays.html": 0.3623,
+    "conformance2/glsl3/compound-assignment-type-combination.html": 2.675,
+    "conformance2/glsl3/const-array-init.html": 0.3337,
+    "conformance2/glsl3/const-struct-from-array-as-function-parameter.html": 0.1667,
+    "conformance2/glsl3/float-parsing.html": 0.682,
+    "conformance2/glsl3/forbidden-operators.html": 0.4363,
+    "conformance2/glsl3/forward-declaration.html": 0.3527,
+    "conformance2/glsl3/frag-depth.html": 0.1993,
+    "conformance2/glsl3/gradient-in-discontinuous-loop.html": 0.1966,
+    "conformance2/glsl3/input-with-interpotaion-as-lvalue.html": 0.4151,
+    "conformance2/glsl3/invalid-default-precision.html": 0.4497,
+    "conformance2/glsl3/invalid-invariant.html": 0.3589,
+    "conformance2/glsl3/loops-with-side-effects.html": 0.698,
+    "conformance2/glsl3/matrix-row-major-dynamic-indexing.html": 0.4338,
+    "conformance2/glsl3/matrix-row-major.html": 0.4156,
+    "conformance2/glsl3/misplaced-version-directive.html": 0.5199,
+    "conformance2/glsl3/no-attribute-vertex-shader.html": 0.5508,
+    "conformance2/glsl3/sampler-array-indexing.html": 0.4845,
+    "conformance2/glsl3/sampler-no-precision.html": 0.3665,
+    "conformance2/glsl3/sequence-operator-returns-non-constant.html": 0.3764,
+    "conformance2/glsl3/shader-linking.html": 0.2088,
+    "conformance2/glsl3/shader-with-1024-character-define.html": 0.4969,
+    "conformance2/glsl3/shader-with-1024-character-identifier.frag.html": 0.3899,
+    "conformance2/glsl3/shader-with-1025-character-define.html": 0.3832,
+    "conformance2/glsl3/shader-with-1025-character-identifier.frag.html": 0.1559,
+    "conformance2/glsl3/shader-with-invalid-characters.html": 0.1278,
+    "conformance2/glsl3/shader-with-mis-matching-uniform-block.html": 0.2273,
+    "conformance2/glsl3/short-circuiting-in-loop-condition.html": 0.4605,
+    "conformance2/glsl3/switch-case.html": 0.6012,
+    "conformance2/glsl3/texture-offset-non-constant-offset.html": 0.2811,
+    "conformance2/glsl3/texture-offset-out-of-range.html": 0.2314,
+    "conformance2/glsl3/texture-offset-uniform-texture-coordinate.html": 0.2732,
+    "conformance2/glsl3/tricky-loop-conditions.html": 1.0059,
+    "conformance2/glsl3/unary-minus-operator-in-dynamic-loop.html": 0.7658,
+    "conformance2/glsl3/uniform-block-layout-match.html": 0.2462,
+    "conformance2/glsl3/uniform-block-layouts.html": 0.4879,
+    "conformance2/glsl3/uniform-location-length-limits.html": 0.431,
+    "conformance2/glsl3/uniform-struct-with-non-square-matrix.html": 0.4353,
+    "conformance2/glsl3/uninitialized-local-global-variables.html": 0.3166,
+    "conformance2/glsl3/valid-invariant.html": 0.1278,
+    "conformance2/glsl3/varying-struct-inline-definition.html": 0.5139,
+    "conformance2/glsl3/vector-dynamic-indexing-nv-driver-bug.html": 0.2139,
+    "conformance2/glsl3/vector-dynamic-indexing-swizzled-lvalue.html": 0.5175,
+    "conformance2/glsl3/vector-dynamic-indexing.html": 0.6785,
+    "conformance2/misc/expando-loss-2.html": 0.5043,
+    "conformance2/misc/getextension-while-pbo-bound-stability.html": 0.2805,
+    "conformance2/misc/instanceof-test.html": 0.3835,
+    "conformance2/misc/null-object-behaviour-2.html": 0.2713,
+    "conformance2/misc/object-deletion-behaviour-2.html": 0.3203,
+    "conformance2/misc/uninitialized-test-2.html": 15.5432,
+    "conformance2/misc/views-with-offsets.html": 0.4898,
+    "conformance2/offscreencanvas/context-creation-worker.html": 0.2157,
+    "conformance2/offscreencanvas/context-creation.html": 0.2026,
+    "conformance2/offscreencanvas/methods-2-worker.html": 0.1736,
+    "conformance2/offscreencanvas/methods-2.html": 0.2034,
+    "conformance2/offscreencanvas/offscreencanvas-query.html": 0.2062,
+    "conformance2/offscreencanvas/offscreencanvas-sync.html": 0.1611,
+    "conformance2/offscreencanvas/offscreencanvas-timer-query.html": 0.3943,
+    "conformance2/offscreencanvas/offscreencanvas-transfer-image-bitmap.html": 0.2117,
+    "conformance2/programs/active-built-in-attribs.html": 0.2781,
+    "conformance2/programs/gl-get-frag-data-location.html": 0.4567,
+    "conformance2/programs/sampler-uniforms.html": 0.5902,
+    "conformance2/query/occlusion-query.html": 3.4598,
+    "conformance2/query/query.html": 0.1032,
+    "conformance2/reading/format-r11f-g11f-b10f.html": 0.4098,
+    "conformance2/reading/read-pixels-from-fbo-test.html": 0.7119,
+    "conformance2/reading/read-pixels-from-rgb8-into-pbo-bug.html": 0.247,
+    "conformance2/reading/read-pixels-into-pixel-pack-buffer.html": 0.1061,
+    "conformance2/reading/read-pixels-pack-parameters.html": 0.4235,
+    "conformance2/renderbuffers/framebuffer-object-attachment.html": 0.2328,
+    "conformance2/renderbuffers/framebuffer-test.html": 0.1204,
+    "conformance2/renderbuffers/framebuffer-texture-layer.html": 0.1181,
+    "conformance2/renderbuffers/invalidate-framebuffer.html": 0.1152,
+    "conformance2/renderbuffers/multisample-with-full-sample-counts.html": 0.2597,
+    "conformance2/renderbuffers/multisampled-depth-renderbuffer-initialization.html": 0.745,
+    "conformance2/renderbuffers/multisampled-renderbuffer-initialization.html": 0.8211,
+    "conformance2/renderbuffers/multisampled-stencil-renderbuffer-initialization.html": 0.6727,
+    "conformance2/renderbuffers/readbuffer.html": 0.435,
+    "conformance2/rendering/attrib-type-match.html": 0.5153,
+    "conformance2/rendering/blitframebuffer-filter-outofbounds.html": 0.7073,
+    "conformance2/rendering/blitframebuffer-filter-srgb.html": 0.2962,
+    "conformance2/rendering/blitframebuffer-multisampled-readbuffer.html": 0.1846,
+    "conformance2/rendering/blitframebuffer-outside-readbuffer.html": 0.1914,
+    "conformance2/rendering/blitframebuffer-r11f-g11f-b10f.html": 0.2701,
+    "conformance2/rendering/blitframebuffer-resolve-to-back-buffer.html": 0.2987,
+    "conformance2/rendering/blitframebuffer-scissor-enabled.html": 0.2491,
+    "conformance2/rendering/blitframebuffer-size-overflow.html": 0.3128,
+    "conformance2/rendering/blitframebuffer-srgb-and-linear-drawbuffers.html": 0.2414,
+    "conformance2/rendering/blitframebuffer-stencil-only.html": 0.4163,
+    "conformance2/rendering/blitframebuffer-test.html": 0.3189,
+    "conformance2/rendering/canvas-resizing-with-pbo-bound.html": 0.3677,
+    "conformance2/rendering/clear-func-buffer-type-match.html": 0.1486,
+    "conformance2/rendering/clear-srgb-color-buffer.html": 0.2518,
+    "conformance2/rendering/clearbuffer-sub-source.html": 0.4455,
+    "conformance2/rendering/clearbufferfv-with-alpha-false.html": 0.1287,
+    "conformance2/rendering/clipping-wide-points.html": 0.1907,
+    "conformance2/rendering/depth-stencil-feedback-loop.html": 0.3786,
+    "conformance2/rendering/draw-buffers-dirty-state-bug.html": 0.3008,
+    "conformance2/rendering/draw-buffers-driver-hang.html": 0.3098,
+    "conformance2/rendering/draw-buffers.html": 0.9372,
+    "conformance2/rendering/draw-with-integer-texture-base-level.html": 0.1583,
+    "conformance2/rendering/element-index-uint.html": 0.7611,
+    "conformance2/rendering/framebuffer-completeness-draw-framebuffer.html": 0.3241,
+    "conformance2/rendering/framebuffer-completeness-unaffected.html": 0.1674,
+    "conformance2/rendering/framebuffer-mismatched-attachment-targets.html": 0.2425,
+    "conformance2/rendering/framebuffer-render-to-layer-angle-issue.html": 0.1436,
+    "conformance2/rendering/framebuffer-render-to-layer.html": 2.3018,
+    "conformance2/rendering/framebuffer-texture-changing-base-level.html": 0.2115,
+    "conformance2/rendering/framebuffer-texture-level1.html": 0.0864,
+    "conformance2/rendering/framebuffer-unsupported.html": 0.1101,
+    "conformance2/rendering/fs-color-type-mismatch-color-buffer-type.html": 0.1375,
+    "conformance2/rendering/instanced-arrays.html": 0.4483,
+    "conformance2/rendering/instanced-rendering-bug.html": 0.5029,
+    "conformance2/rendering/instanced-rendering-large-divisor.html": 0.1833,
+    "conformance2/rendering/line-rendering-quality.html": 0.3471,
+    "conformance2/rendering/multisampling-fragment-evaluation.html": 0.182,
+    "conformance2/rendering/out-of-bounds-index-buffers-after-copying.html": 0.2799,
+    "conformance2/rendering/rasterizer-discard-and-implicit-clear.html": 0.8586,
+    "conformance2/rendering/read-draw-when-missing-image.html": 0.2873,
+    "conformance2/rendering/rgb-format-support.html": 0.3084,
     "conformance2/rendering/texture-switch-performance.html": 0.0,
-    "conformance2/rendering/uniform-block-buffer-size.html": 0.4581,
-    "conformance2/rendering/vertex-id.html": 0.4498,
-    "conformance2/samplers/multi-context-sampler-test.html": 0.1525,
-    "conformance2/samplers/sampler-drawing-test.html": 0.2336,
-    "conformance2/samplers/samplers.html": 0.215,
-    "conformance2/state/gl-enum-tests.html": 0.2241,
-    "conformance2/state/gl-get-calls.html": 0.0984,
-    "conformance2/state/gl-getstring.html": 0.0711,
-    "conformance2/state/gl-object-get-calls.html": 18.2718,
-    "conformance2/sync/sync-webgl-specific.html": 25.8725,
-    "conformance2/textures/canvas/tex-2d-r11f_g11f_b10f-rgb-float.html": 1.2989,
-    "conformance2/textures/canvas/tex-2d-r11f_g11f_b10f-rgb-half_float.html": 1.4922,
-    "conformance2/textures/canvas/tex-2d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html": 1.6149,
-    "conformance2/textures/canvas/tex-2d-r16f-red-float.html": 1.6331,
-    "conformance2/textures/canvas/tex-2d-r16f-red-half_float.html": 1.5275,
-    "conformance2/textures/canvas/tex-2d-r32f-red-float.html": 1.041,
-    "conformance2/textures/canvas/tex-2d-r8-red-unsigned_byte.html": 1.4868,
-    "conformance2/textures/canvas/tex-2d-r8ui-red_integer-unsigned_byte.html": 1.9753,
-    "conformance2/textures/canvas/tex-2d-rg16f-rg-float.html": 1.235,
-    "conformance2/textures/canvas/tex-2d-rg16f-rg-half_float.html": 1.4854,
-    "conformance2/textures/canvas/tex-2d-rg32f-rg-float.html": 1.7225,
-    "conformance2/textures/canvas/tex-2d-rg8-rg-unsigned_byte.html": 1.6199,
-    "conformance2/textures/canvas/tex-2d-rg8ui-rg_integer-unsigned_byte.html": 1.5025,
-    "conformance2/textures/canvas/tex-2d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html": 1.5003,
-    "conformance2/textures/canvas/tex-2d-rgb16f-rgb-float.html": 1.5533,
-    "conformance2/textures/canvas/tex-2d-rgb16f-rgb-half_float.html": 1.4709,
-    "conformance2/textures/canvas/tex-2d-rgb32f-rgb-float.html": 1.368,
-    "conformance2/textures/canvas/tex-2d-rgb565-rgb-unsigned_byte.html": 1.2081,
-    "conformance2/textures/canvas/tex-2d-rgb565-rgb-unsigned_short_5_6_5.html": 1.6977,
-    "conformance2/textures/canvas/tex-2d-rgb5_a1-rgba-unsigned_byte.html": 4.0303,
-    "conformance2/textures/canvas/tex-2d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html": 1.313,
-    "conformance2/textures/canvas/tex-2d-rgb8-rgb-unsigned_byte.html": 1.2114,
-    "conformance2/textures/canvas/tex-2d-rgb8ui-rgb_integer-unsigned_byte.html": 1.358,
-    "conformance2/textures/canvas/tex-2d-rgb9_e5-rgb-float.html": 1.8148,
-    "conformance2/textures/canvas/tex-2d-rgb9_e5-rgb-half_float.html": 1.7993,
-    "conformance2/textures/canvas/tex-2d-rgba16f-rgba-float.html": 1.5486,
-    "conformance2/textures/canvas/tex-2d-rgba16f-rgba-half_float.html": 1.5343,
-    "conformance2/textures/canvas/tex-2d-rgba32f-rgba-float.html": 1.618,
-    "conformance2/textures/canvas/tex-2d-rgba4-rgba-unsigned_byte.html": 0.9496,
-    "conformance2/textures/canvas/tex-2d-rgba4-rgba-unsigned_short_4_4_4_4.html": 1.5675,
-    "conformance2/textures/canvas/tex-2d-rgba8-rgba-unsigned_byte.html": 1.4778,
-    "conformance2/textures/canvas/tex-2d-rgba8ui-rgba_integer-unsigned_byte.html": 1.3155,
-    "conformance2/textures/canvas/tex-2d-srgb8-rgb-unsigned_byte.html": 1.5999,
-    "conformance2/textures/canvas/tex-2d-srgb8_alpha8-rgba-unsigned_byte.html": 1.5065,
-    "conformance2/textures/canvas/tex-3d-r11f_g11f_b10f-rgb-float.html": 8.2686,
-    "conformance2/textures/canvas/tex-3d-r11f_g11f_b10f-rgb-half_float.html": 5.5188,
-    "conformance2/textures/canvas/tex-3d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html": 5.8156,
-    "conformance2/textures/canvas/tex-3d-r16f-red-float.html": 6.0722,
-    "conformance2/textures/canvas/tex-3d-r16f-red-half_float.html": 6.0192,
-    "conformance2/textures/canvas/tex-3d-r32f-red-float.html": 5.9517,
-    "conformance2/textures/canvas/tex-3d-r8-red-unsigned_byte.html": 6.043,
-    "conformance2/textures/canvas/tex-3d-r8ui-red_integer-unsigned_byte.html": 5.7687,
-    "conformance2/textures/canvas/tex-3d-rg16f-rg-float.html": 5.8425,
-    "conformance2/textures/canvas/tex-3d-rg16f-rg-half_float.html": 5.5425,
-    "conformance2/textures/canvas/tex-3d-rg32f-rg-float.html": 5.3087,
-    "conformance2/textures/canvas/tex-3d-rg8-rg-unsigned_byte.html": 5.5529,
-    "conformance2/textures/canvas/tex-3d-rg8ui-rg_integer-unsigned_byte.html": 5.5468,
-    "conformance2/textures/canvas/tex-3d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html": 5.8226,
-    "conformance2/textures/canvas/tex-3d-rgb16f-rgb-float.html": 5.5813,
-    "conformance2/textures/canvas/tex-3d-rgb16f-rgb-half_float.html": 5.998,
-    "conformance2/textures/canvas/tex-3d-rgb32f-rgb-float.html": 6.3995,
-    "conformance2/textures/canvas/tex-3d-rgb565-rgb-unsigned_byte.html": 5.4252,
-    "conformance2/textures/canvas/tex-3d-rgb565-rgb-unsigned_short_5_6_5.html": 5.9547,
-    "conformance2/textures/canvas/tex-3d-rgb5_a1-rgba-unsigned_byte.html": 5.8558,
-    "conformance2/textures/canvas/tex-3d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html": 5.8425,
-    "conformance2/textures/canvas/tex-3d-rgb8-rgb-unsigned_byte.html": 5.551,
-    "conformance2/textures/canvas/tex-3d-rgb8ui-rgb_integer-unsigned_byte.html": 5.5618,
-    "conformance2/textures/canvas/tex-3d-rgb9_e5-rgb-float.html": 5.9221,
-    "conformance2/textures/canvas/tex-3d-rgb9_e5-rgb-half_float.html": 5.9154,
-    "conformance2/textures/canvas/tex-3d-rgba16f-rgba-float.html": 5.7695,
-    "conformance2/textures/canvas/tex-3d-rgba16f-rgba-half_float.html": 5.6364,
-    "conformance2/textures/canvas/tex-3d-rgba32f-rgba-float.html": 5.2877,
-    "conformance2/textures/canvas/tex-3d-rgba4-rgba-unsigned_byte.html": 5.7906,
-    "conformance2/textures/canvas/tex-3d-rgba4-rgba-unsigned_short_4_4_4_4.html": 5.8958,
-    "conformance2/textures/canvas/tex-3d-rgba8-rgba-unsigned_byte.html": 5.7857,
-    "conformance2/textures/canvas/tex-3d-rgba8ui-rgba_integer-unsigned_byte.html": 5.4232,
-    "conformance2/textures/canvas/tex-3d-srgb8-rgb-unsigned_byte.html": 5.5383,
-    "conformance2/textures/canvas/tex-3d-srgb8_alpha8-rgba-unsigned_byte.html": 5.6301,
-    "conformance2/textures/canvas_sub_rectangle/tex-2d-r11f_g11f_b10f-rgb-float.html": 1.1867,
-    "conformance2/textures/canvas_sub_rectangle/tex-2d-r11f_g11f_b10f-rgb-half_float.html": 1.2764,
-    "conformance2/textures/canvas_sub_rectangle/tex-2d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html": 2.0469,
-    "conformance2/textures/canvas_sub_rectangle/tex-2d-r16f-red-float.html": 2.5983,
-    "conformance2/textures/canvas_sub_rectangle/tex-2d-r16f-red-half_float.html": 1.4798,
-    "conformance2/textures/canvas_sub_rectangle/tex-2d-r32f-red-float.html": 1.9426,
-    "conformance2/textures/canvas_sub_rectangle/tex-2d-r8-red-unsigned_byte.html": 2.2494,
-    "conformance2/textures/canvas_sub_rectangle/tex-2d-r8ui-red_integer-unsigned_byte.html": 2.0036,
-    "conformance2/textures/canvas_sub_rectangle/tex-2d-rg16f-rg-float.html": 2.2215,
-    "conformance2/textures/canvas_sub_rectangle/tex-2d-rg16f-rg-half_float.html": 2.2359,
-    "conformance2/textures/canvas_sub_rectangle/tex-2d-rg32f-rg-float.html": 2.1051,
-    "conformance2/textures/canvas_sub_rectangle/tex-2d-rg8-rg-unsigned_byte.html": 1.0893,
-    "conformance2/textures/canvas_sub_rectangle/tex-2d-rg8ui-rg_integer-unsigned_byte.html": 2.1694,
-    "conformance2/textures/canvas_sub_rectangle/tex-2d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html": 1.1025,
-    "conformance2/textures/canvas_sub_rectangle/tex-2d-rgb16f-rgb-float.html": 1.9954,
-    "conformance2/textures/canvas_sub_rectangle/tex-2d-rgb16f-rgb-half_float.html": 2.1881,
-    "conformance2/textures/canvas_sub_rectangle/tex-2d-rgb32f-rgb-float.html": 1.5516,
-    "conformance2/textures/canvas_sub_rectangle/tex-2d-rgb565-rgb-unsigned_byte.html": 1.737,
-    "conformance2/textures/canvas_sub_rectangle/tex-2d-rgb565-rgb-unsigned_short_5_6_5.html": 1.0621,
-    "conformance2/textures/canvas_sub_rectangle/tex-2d-rgb5_a1-rgba-unsigned_byte.html": 1.1392,
-    "conformance2/textures/canvas_sub_rectangle/tex-2d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html": 0.9406,
-    "conformance2/textures/canvas_sub_rectangle/tex-2d-rgb8-rgb-unsigned_byte.html": 1.7185,
-    "conformance2/textures/canvas_sub_rectangle/tex-2d-rgb8ui-rgb_integer-unsigned_byte.html": 1.5491,
-    "conformance2/textures/canvas_sub_rectangle/tex-2d-rgb9_e5-rgb-float.html": 2.4548,
-    "conformance2/textures/canvas_sub_rectangle/tex-2d-rgb9_e5-rgb-half_float.html": 2.3172,
-    "conformance2/textures/canvas_sub_rectangle/tex-2d-rgba16f-rgba-float.html": 1.3227,
-    "conformance2/textures/canvas_sub_rectangle/tex-2d-rgba16f-rgba-half_float.html": 1.8575,
-    "conformance2/textures/canvas_sub_rectangle/tex-2d-rgba32f-rgba-float.html": 1.3338,
-    "conformance2/textures/canvas_sub_rectangle/tex-2d-rgba4-rgba-unsigned_byte.html": 1.1847,
-    "conformance2/textures/canvas_sub_rectangle/tex-2d-rgba4-rgba-unsigned_short_4_4_4_4.html": 1.6336,
-    "conformance2/textures/canvas_sub_rectangle/tex-2d-rgba8-rgba-unsigned_byte.html": 1.1184,
-    "conformance2/textures/canvas_sub_rectangle/tex-2d-rgba8ui-rgba_integer-unsigned_byte.html": 1.8736,
-    "conformance2/textures/canvas_sub_rectangle/tex-2d-srgb8-rgb-unsigned_byte.html": 1.2429,
-    "conformance2/textures/canvas_sub_rectangle/tex-2d-srgb8_alpha8-rgba-unsigned_byte.html": 1.0233,
-    "conformance2/textures/canvas_sub_rectangle/tex-3d-r11f_g11f_b10f-rgb-float.html": 1.8381,
-    "conformance2/textures/canvas_sub_rectangle/tex-3d-r11f_g11f_b10f-rgb-half_float.html": 2.1263,
-    "conformance2/textures/canvas_sub_rectangle/tex-3d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html": 2.7509,
-    "conformance2/textures/canvas_sub_rectangle/tex-3d-r16f-red-float.html": 1.8068,
-    "conformance2/textures/canvas_sub_rectangle/tex-3d-r16f-red-half_float.html": 1.7496,
-    "conformance2/textures/canvas_sub_rectangle/tex-3d-r32f-red-float.html": 1.9945,
-    "conformance2/textures/canvas_sub_rectangle/tex-3d-r8-red-unsigned_byte.html": 2.7817,
-    "conformance2/textures/canvas_sub_rectangle/tex-3d-r8ui-red_integer-unsigned_byte.html": 2.7183,
-    "conformance2/textures/canvas_sub_rectangle/tex-3d-rg16f-rg-float.html": 2.931,
-    "conformance2/textures/canvas_sub_rectangle/tex-3d-rg16f-rg-half_float.html": 2.0565,
-    "conformance2/textures/canvas_sub_rectangle/tex-3d-rg32f-rg-float.html": 1.9887,
-    "conformance2/textures/canvas_sub_rectangle/tex-3d-rg8-rg-unsigned_byte.html": 1.5647,
-    "conformance2/textures/canvas_sub_rectangle/tex-3d-rg8ui-rg_integer-unsigned_byte.html": 1.6955,
-    "conformance2/textures/canvas_sub_rectangle/tex-3d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html": 3.1125,
-    "conformance2/textures/canvas_sub_rectangle/tex-3d-rgb16f-rgb-float.html": 2.0114,
-    "conformance2/textures/canvas_sub_rectangle/tex-3d-rgb16f-rgb-half_float.html": 1.6012,
-    "conformance2/textures/canvas_sub_rectangle/tex-3d-rgb32f-rgb-float.html": 2.383,
-    "conformance2/textures/canvas_sub_rectangle/tex-3d-rgb565-rgb-unsigned_byte.html": 2.9142,
-    "conformance2/textures/canvas_sub_rectangle/tex-3d-rgb565-rgb-unsigned_short_5_6_5.html": 1.8121,
-    "conformance2/textures/canvas_sub_rectangle/tex-3d-rgb5_a1-rgba-unsigned_byte.html": 2.4196,
-    "conformance2/textures/canvas_sub_rectangle/tex-3d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html": 1.3974,
-    "conformance2/textures/canvas_sub_rectangle/tex-3d-rgb8-rgb-unsigned_byte.html": 1.4145,
-    "conformance2/textures/canvas_sub_rectangle/tex-3d-rgb8ui-rgb_integer-unsigned_byte.html": 1.7285,
-    "conformance2/textures/canvas_sub_rectangle/tex-3d-rgb9_e5-rgb-float.html": 1.4016,
-    "conformance2/textures/canvas_sub_rectangle/tex-3d-rgb9_e5-rgb-half_float.html": 1.9827,
-    "conformance2/textures/canvas_sub_rectangle/tex-3d-rgba16f-rgba-float.html": 1.6826,
-    "conformance2/textures/canvas_sub_rectangle/tex-3d-rgba16f-rgba-half_float.html": 1.3878,
-    "conformance2/textures/canvas_sub_rectangle/tex-3d-rgba32f-rgba-float.html": 3.0708,
-    "conformance2/textures/canvas_sub_rectangle/tex-3d-rgba4-rgba-unsigned_byte.html": 2.6568,
-    "conformance2/textures/canvas_sub_rectangle/tex-3d-rgba4-rgba-unsigned_short_4_4_4_4.html": 1.6675,
-    "conformance2/textures/canvas_sub_rectangle/tex-3d-rgba8-rgba-unsigned_byte.html": 1.6064,
-    "conformance2/textures/canvas_sub_rectangle/tex-3d-rgba8ui-rgba_integer-unsigned_byte.html": 1.5298,
-    "conformance2/textures/canvas_sub_rectangle/tex-3d-srgb8-rgb-unsigned_byte.html": 1.1985,
-    "conformance2/textures/canvas_sub_rectangle/tex-3d-srgb8_alpha8-rgba-unsigned_byte.html": 2.3782,
-    "conformance2/textures/image/tex-2d-r11f_g11f_b10f-rgb-float.html": 0.4872,
-    "conformance2/textures/image/tex-2d-r11f_g11f_b10f-rgb-half_float.html": 0.4859,
-    "conformance2/textures/image/tex-2d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html": 0.5396,
-    "conformance2/textures/image/tex-2d-r16f-red-float.html": 0.6281,
-    "conformance2/textures/image/tex-2d-r16f-red-half_float.html": 0.8211,
-    "conformance2/textures/image/tex-2d-r32f-red-float.html": 0.5848,
-    "conformance2/textures/image/tex-2d-r8-red-unsigned_byte.html": 0.5243,
-    "conformance2/textures/image/tex-2d-r8ui-red_integer-unsigned_byte.html": 0.6918,
-    "conformance2/textures/image/tex-2d-rg16f-rg-float.html": 0.5796,
-    "conformance2/textures/image/tex-2d-rg16f-rg-half_float.html": 0.5054,
-    "conformance2/textures/image/tex-2d-rg32f-rg-float.html": 0.3733,
-    "conformance2/textures/image/tex-2d-rg8-rg-unsigned_byte.html": 0.4056,
-    "conformance2/textures/image/tex-2d-rg8ui-rg_integer-unsigned_byte.html": 0.7105,
-    "conformance2/textures/image/tex-2d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html": 0.5163,
-    "conformance2/textures/image/tex-2d-rgb16f-rgb-float.html": 0.6723,
-    "conformance2/textures/image/tex-2d-rgb16f-rgb-half_float.html": 0.6801,
-    "conformance2/textures/image/tex-2d-rgb32f-rgb-float.html": 0.5588,
-    "conformance2/textures/image/tex-2d-rgb565-rgb-unsigned_byte.html": 0.5076,
-    "conformance2/textures/image/tex-2d-rgb565-rgb-unsigned_short_5_6_5.html": 0.491,
-    "conformance2/textures/image/tex-2d-rgb5_a1-rgba-unsigned_byte.html": 0.6857,
-    "conformance2/textures/image/tex-2d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html": 0.7239,
-    "conformance2/textures/image/tex-2d-rgb8-rgb-unsigned_byte.html": 0.9313,
-    "conformance2/textures/image/tex-2d-rgb8ui-rgb_integer-unsigned_byte.html": 0.4361,
-    "conformance2/textures/image/tex-2d-rgb9_e5-rgb-float.html": 0.5699,
-    "conformance2/textures/image/tex-2d-rgb9_e5-rgb-half_float.html": 0.5114,
-    "conformance2/textures/image/tex-2d-rgba16f-rgba-float.html": 0.4929,
-    "conformance2/textures/image/tex-2d-rgba16f-rgba-half_float.html": 0.5652,
-    "conformance2/textures/image/tex-2d-rgba32f-rgba-float.html": 0.3486,
-    "conformance2/textures/image/tex-2d-rgba4-rgba-unsigned_byte.html": 0.7768,
-    "conformance2/textures/image/tex-2d-rgba4-rgba-unsigned_short_4_4_4_4.html": 0.5848,
-    "conformance2/textures/image/tex-2d-rgba8-rgba-unsigned_byte.html": 0.7156,
-    "conformance2/textures/image/tex-2d-rgba8ui-rgba_integer-unsigned_byte.html": 0.4974,
-    "conformance2/textures/image/tex-2d-srgb8-rgb-unsigned_byte.html": 0.5054,
-    "conformance2/textures/image/tex-2d-srgb8_alpha8-rgba-unsigned_byte.html": 0.5025,
-    "conformance2/textures/image/tex-3d-r11f_g11f_b10f-rgb-float.html": 0.4968,
-    "conformance2/textures/image/tex-3d-r11f_g11f_b10f-rgb-half_float.html": 0.9269,
-    "conformance2/textures/image/tex-3d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html": 0.5866,
-    "conformance2/textures/image/tex-3d-r16f-red-float.html": 0.5882,
-    "conformance2/textures/image/tex-3d-r16f-red-half_float.html": 0.4428,
-    "conformance2/textures/image/tex-3d-r32f-red-float.html": 0.5488,
-    "conformance2/textures/image/tex-3d-r8-red-unsigned_byte.html": 0.6157,
-    "conformance2/textures/image/tex-3d-r8ui-red_integer-unsigned_byte.html": 0.4394,
-    "conformance2/textures/image/tex-3d-rg16f-rg-float.html": 0.5192,
-    "conformance2/textures/image/tex-3d-rg16f-rg-half_float.html": 0.6224,
-    "conformance2/textures/image/tex-3d-rg32f-rg-float.html": 0.4424,
-    "conformance2/textures/image/tex-3d-rg8-rg-unsigned_byte.html": 0.4058,
-    "conformance2/textures/image/tex-3d-rg8ui-rg_integer-unsigned_byte.html": 0.5237,
-    "conformance2/textures/image/tex-3d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html": 0.681,
-    "conformance2/textures/image/tex-3d-rgb16f-rgb-float.html": 0.4531,
-    "conformance2/textures/image/tex-3d-rgb16f-rgb-half_float.html": 0.427,
-    "conformance2/textures/image/tex-3d-rgb32f-rgb-float.html": 0.6522,
-    "conformance2/textures/image/tex-3d-rgb565-rgb-unsigned_byte.html": 0.6389,
-    "conformance2/textures/image/tex-3d-rgb565-rgb-unsigned_short_5_6_5.html": 0.4431,
-    "conformance2/textures/image/tex-3d-rgb5_a1-rgba-unsigned_byte.html": 0.4699,
-    "conformance2/textures/image/tex-3d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html": 0.587,
-    "conformance2/textures/image/tex-3d-rgb8-rgb-unsigned_byte.html": 0.6276,
-    "conformance2/textures/image/tex-3d-rgb8ui-rgb_integer-unsigned_byte.html": 0.4084,
-    "conformance2/textures/image/tex-3d-rgb9_e5-rgb-float.html": 0.6024,
-    "conformance2/textures/image/tex-3d-rgb9_e5-rgb-half_float.html": 0.5629,
-    "conformance2/textures/image/tex-3d-rgba16f-rgba-float.html": 0.4626,
-    "conformance2/textures/image/tex-3d-rgba16f-rgba-half_float.html": 0.3738,
-    "conformance2/textures/image/tex-3d-rgba32f-rgba-float.html": 0.548,
-    "conformance2/textures/image/tex-3d-rgba4-rgba-unsigned_byte.html": 0.4082,
-    "conformance2/textures/image/tex-3d-rgba4-rgba-unsigned_short_4_4_4_4.html": 0.7147,
-    "conformance2/textures/image/tex-3d-rgba8-rgba-unsigned_byte.html": 0.4829,
-    "conformance2/textures/image/tex-3d-rgba8ui-rgba_integer-unsigned_byte.html": 0.4693,
-    "conformance2/textures/image/tex-3d-srgb8-rgb-unsigned_byte.html": 0.5994,
-    "conformance2/textures/image/tex-3d-srgb8_alpha8-rgba-unsigned_byte.html": 0.5471,
-    "conformance2/textures/image_bitmap_from_blob/tex-2d-r11f_g11f_b10f-rgb-float.html": 0.4226,
-    "conformance2/textures/image_bitmap_from_blob/tex-2d-r11f_g11f_b10f-rgb-half_float.html": 0.4544,
-    "conformance2/textures/image_bitmap_from_blob/tex-2d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html": 0.4322,
-    "conformance2/textures/image_bitmap_from_blob/tex-2d-r16f-red-float.html": 0.4142,
-    "conformance2/textures/image_bitmap_from_blob/tex-2d-r16f-red-half_float.html": 0.4257,
-    "conformance2/textures/image_bitmap_from_blob/tex-2d-r32f-red-float.html": 0.5065,
-    "conformance2/textures/image_bitmap_from_blob/tex-2d-r8-red-unsigned_byte.html": 0.3984,
-    "conformance2/textures/image_bitmap_from_blob/tex-2d-r8ui-red_integer-unsigned_byte.html": 0.4696,
-    "conformance2/textures/image_bitmap_from_blob/tex-2d-rg16f-rg-float.html": 0.3748,
-    "conformance2/textures/image_bitmap_from_blob/tex-2d-rg16f-rg-half_float.html": 0.3892,
-    "conformance2/textures/image_bitmap_from_blob/tex-2d-rg32f-rg-float.html": 0.4616,
-    "conformance2/textures/image_bitmap_from_blob/tex-2d-rg8-rg-unsigned_byte.html": 0.3845,
-    "conformance2/textures/image_bitmap_from_blob/tex-2d-rg8ui-rg_integer-unsigned_byte.html": 0.4822,
-    "conformance2/textures/image_bitmap_from_blob/tex-2d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html": 0.3855,
-    "conformance2/textures/image_bitmap_from_blob/tex-2d-rgb16f-rgb-float.html": 0.5071,
-    "conformance2/textures/image_bitmap_from_blob/tex-2d-rgb16f-rgb-half_float.html": 0.4614,
-    "conformance2/textures/image_bitmap_from_blob/tex-2d-rgb32f-rgb-float.html": 0.4064,
-    "conformance2/textures/image_bitmap_from_blob/tex-2d-rgb565-rgb-unsigned_byte.html": 0.525,
-    "conformance2/textures/image_bitmap_from_blob/tex-2d-rgb565-rgb-unsigned_short_5_6_5.html": 0.3696,
-    "conformance2/textures/image_bitmap_from_blob/tex-2d-rgb5_a1-rgba-unsigned_byte.html": 0.509,
-    "conformance2/textures/image_bitmap_from_blob/tex-2d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html": 0.497,
-    "conformance2/textures/image_bitmap_from_blob/tex-2d-rgb8-rgb-unsigned_byte.html": 0.3837,
-    "conformance2/textures/image_bitmap_from_blob/tex-2d-rgb8ui-rgb_integer-unsigned_byte.html": 0.5234,
-    "conformance2/textures/image_bitmap_from_blob/tex-2d-rgb9_e5-rgb-float.html": 0.412,
-    "conformance2/textures/image_bitmap_from_blob/tex-2d-rgb9_e5-rgb-half_float.html": 0.46,
-    "conformance2/textures/image_bitmap_from_blob/tex-2d-rgba16f-rgba-float.html": 0.4026,
-    "conformance2/textures/image_bitmap_from_blob/tex-2d-rgba16f-rgba-half_float.html": 0.3972,
-    "conformance2/textures/image_bitmap_from_blob/tex-2d-rgba32f-rgba-float.html": 0.4445,
-    "conformance2/textures/image_bitmap_from_blob/tex-2d-rgba4-rgba-unsigned_byte.html": 0.4817,
-    "conformance2/textures/image_bitmap_from_blob/tex-2d-rgba4-rgba-unsigned_short_4_4_4_4.html": 0.4636,
-    "conformance2/textures/image_bitmap_from_blob/tex-2d-rgba8-rgba-unsigned_byte.html": 0.4189,
-    "conformance2/textures/image_bitmap_from_blob/tex-2d-rgba8ui-rgba_integer-unsigned_byte.html": 0.5111,
-    "conformance2/textures/image_bitmap_from_blob/tex-2d-srgb8-rgb-unsigned_byte.html": 0.4161,
-    "conformance2/textures/image_bitmap_from_blob/tex-2d-srgb8_alpha8-rgba-unsigned_byte.html": 0.5363,
-    "conformance2/textures/image_bitmap_from_blob/tex-3d-r11f_g11f_b10f-rgb-float.html": 0.3082,
-    "conformance2/textures/image_bitmap_from_blob/tex-3d-r11f_g11f_b10f-rgb-half_float.html": 0.3505,
-    "conformance2/textures/image_bitmap_from_blob/tex-3d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html": 0.328,
-    "conformance2/textures/image_bitmap_from_blob/tex-3d-r16f-red-float.html": 0.3658,
-    "conformance2/textures/image_bitmap_from_blob/tex-3d-r16f-red-half_float.html": 0.3489,
-    "conformance2/textures/image_bitmap_from_blob/tex-3d-r32f-red-float.html": 0.5849,
-    "conformance2/textures/image_bitmap_from_blob/tex-3d-r8-red-unsigned_byte.html": 0.3082,
-    "conformance2/textures/image_bitmap_from_blob/tex-3d-r8ui-red_integer-unsigned_byte.html": 0.3628,
-    "conformance2/textures/image_bitmap_from_blob/tex-3d-rg16f-rg-float.html": 0.3728,
-    "conformance2/textures/image_bitmap_from_blob/tex-3d-rg16f-rg-half_float.html": 0.3391,
-    "conformance2/textures/image_bitmap_from_blob/tex-3d-rg32f-rg-float.html": 0.2187,
-    "conformance2/textures/image_bitmap_from_blob/tex-3d-rg8-rg-unsigned_byte.html": 0.3784,
-    "conformance2/textures/image_bitmap_from_blob/tex-3d-rg8ui-rg_integer-unsigned_byte.html": 0.3408,
-    "conformance2/textures/image_bitmap_from_blob/tex-3d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html": 0.3077,
-    "conformance2/textures/image_bitmap_from_blob/tex-3d-rgb16f-rgb-float.html": 0.343,
-    "conformance2/textures/image_bitmap_from_blob/tex-3d-rgb16f-rgb-half_float.html": 0.3288,
-    "conformance2/textures/image_bitmap_from_blob/tex-3d-rgb32f-rgb-float.html": 0.2932,
-    "conformance2/textures/image_bitmap_from_blob/tex-3d-rgb565-rgb-unsigned_byte.html": 0.3412,
-    "conformance2/textures/image_bitmap_from_blob/tex-3d-rgb565-rgb-unsigned_short_5_6_5.html": 0.3802,
-    "conformance2/textures/image_bitmap_from_blob/tex-3d-rgb5_a1-rgba-unsigned_byte.html": 0.1978,
-    "conformance2/textures/image_bitmap_from_blob/tex-3d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html": 0.2874,
-    "conformance2/textures/image_bitmap_from_blob/tex-3d-rgb8-rgb-unsigned_byte.html": 0.322,
-    "conformance2/textures/image_bitmap_from_blob/tex-3d-rgb8ui-rgb_integer-unsigned_byte.html": 0.5959,
-    "conformance2/textures/image_bitmap_from_blob/tex-3d-rgb9_e5-rgb-float.html": 0.3371,
-    "conformance2/textures/image_bitmap_from_blob/tex-3d-rgb9_e5-rgb-half_float.html": 0.2246,
-    "conformance2/textures/image_bitmap_from_blob/tex-3d-rgba16f-rgba-float.html": 0.3144,
-    "conformance2/textures/image_bitmap_from_blob/tex-3d-rgba16f-rgba-half_float.html": 0.2081,
-    "conformance2/textures/image_bitmap_from_blob/tex-3d-rgba32f-rgba-float.html": 0.3102,
-    "conformance2/textures/image_bitmap_from_blob/tex-3d-rgba4-rgba-unsigned_byte.html": 0.3255,
-    "conformance2/textures/image_bitmap_from_blob/tex-3d-rgba4-rgba-unsigned_short_4_4_4_4.html": 0.2221,
-    "conformance2/textures/image_bitmap_from_blob/tex-3d-rgba8-rgba-unsigned_byte.html": 0.2347,
-    "conformance2/textures/image_bitmap_from_blob/tex-3d-rgba8ui-rgba_integer-unsigned_byte.html": 0.3572,
-    "conformance2/textures/image_bitmap_from_blob/tex-3d-srgb8-rgb-unsigned_byte.html": 0.3647,
-    "conformance2/textures/image_bitmap_from_blob/tex-3d-srgb8_alpha8-rgba-unsigned_byte.html": 0.605,
-    "conformance2/textures/image_bitmap_from_canvas/tex-2d-r11f_g11f_b10f-rgb-float.html": 1.1593,
-    "conformance2/textures/image_bitmap_from_canvas/tex-2d-r11f_g11f_b10f-rgb-half_float.html": 1.4546,
-    "conformance2/textures/image_bitmap_from_canvas/tex-2d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html": 1.2217,
-    "conformance2/textures/image_bitmap_from_canvas/tex-2d-r16f-red-float.html": 1.0105,
-    "conformance2/textures/image_bitmap_from_canvas/tex-2d-r16f-red-half_float.html": 1.4569,
-    "conformance2/textures/image_bitmap_from_canvas/tex-2d-r32f-red-float.html": 0.8056,
-    "conformance2/textures/image_bitmap_from_canvas/tex-2d-r8-red-unsigned_byte.html": 0.9127,
-    "conformance2/textures/image_bitmap_from_canvas/tex-2d-r8ui-red_integer-unsigned_byte.html": 1.7155,
-    "conformance2/textures/image_bitmap_from_canvas/tex-2d-rg16f-rg-float.html": 0.8863,
-    "conformance2/textures/image_bitmap_from_canvas/tex-2d-rg16f-rg-half_float.html": 1.2358,
-    "conformance2/textures/image_bitmap_from_canvas/tex-2d-rg32f-rg-float.html": 1.019,
-    "conformance2/textures/image_bitmap_from_canvas/tex-2d-rg8-rg-unsigned_byte.html": 1.2669,
-    "conformance2/textures/image_bitmap_from_canvas/tex-2d-rg8ui-rg_integer-unsigned_byte.html": 1.4138,
-    "conformance2/textures/image_bitmap_from_canvas/tex-2d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html": 1.4374,
-    "conformance2/textures/image_bitmap_from_canvas/tex-2d-rgb16f-rgb-float.html": 1.428,
-    "conformance2/textures/image_bitmap_from_canvas/tex-2d-rgb16f-rgb-half_float.html": 0.8673,
-    "conformance2/textures/image_bitmap_from_canvas/tex-2d-rgb32f-rgb-float.html": 1.2986,
-    "conformance2/textures/image_bitmap_from_canvas/tex-2d-rgb565-rgb-unsigned_byte.html": 1.3959,
-    "conformance2/textures/image_bitmap_from_canvas/tex-2d-rgb565-rgb-unsigned_short_5_6_5.html": 1.4037,
-    "conformance2/textures/image_bitmap_from_canvas/tex-2d-rgb5_a1-rgba-unsigned_byte.html": 1.1566,
-    "conformance2/textures/image_bitmap_from_canvas/tex-2d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html": 1.0275,
-    "conformance2/textures/image_bitmap_from_canvas/tex-2d-rgb8-rgb-unsigned_byte.html": 0.9899,
-    "conformance2/textures/image_bitmap_from_canvas/tex-2d-rgb8ui-rgb_integer-unsigned_byte.html": 1.2229,
-    "conformance2/textures/image_bitmap_from_canvas/tex-2d-rgb9_e5-rgb-float.html": 1.7125,
-    "conformance2/textures/image_bitmap_from_canvas/tex-2d-rgb9_e5-rgb-half_float.html": 1.9452,
-    "conformance2/textures/image_bitmap_from_canvas/tex-2d-rgba16f-rgba-float.html": 1.5924,
-    "conformance2/textures/image_bitmap_from_canvas/tex-2d-rgba16f-rgba-half_float.html": 0.8469,
-    "conformance2/textures/image_bitmap_from_canvas/tex-2d-rgba32f-rgba-float.html": 1.3442,
-    "conformance2/textures/image_bitmap_from_canvas/tex-2d-rgba4-rgba-unsigned_byte.html": 0.6345,
-    "conformance2/textures/image_bitmap_from_canvas/tex-2d-rgba4-rgba-unsigned_short_4_4_4_4.html": 0.7351,
-    "conformance2/textures/image_bitmap_from_canvas/tex-2d-rgba8-rgba-unsigned_byte.html": 1.4723,
-    "conformance2/textures/image_bitmap_from_canvas/tex-2d-rgba8ui-rgba_integer-unsigned_byte.html": 1.0222,
-    "conformance2/textures/image_bitmap_from_canvas/tex-2d-srgb8-rgb-unsigned_byte.html": 0.8678,
-    "conformance2/textures/image_bitmap_from_canvas/tex-2d-srgb8_alpha8-rgba-unsigned_byte.html": 1.4428,
-    "conformance2/textures/image_bitmap_from_canvas/tex-3d-r11f_g11f_b10f-rgb-float.html": 0.7716,
-    "conformance2/textures/image_bitmap_from_canvas/tex-3d-r11f_g11f_b10f-rgb-half_float.html": 0.866,
-    "conformance2/textures/image_bitmap_from_canvas/tex-3d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html": 0.4761,
-    "conformance2/textures/image_bitmap_from_canvas/tex-3d-r16f-red-float.html": 0.5368,
-    "conformance2/textures/image_bitmap_from_canvas/tex-3d-r16f-red-half_float.html": 0.5663,
-    "conformance2/textures/image_bitmap_from_canvas/tex-3d-r32f-red-float.html": 0.7838,
-    "conformance2/textures/image_bitmap_from_canvas/tex-3d-r8-red-unsigned_byte.html": 0.7666,
-    "conformance2/textures/image_bitmap_from_canvas/tex-3d-r8ui-red_integer-unsigned_byte.html": 0.425,
-    "conformance2/textures/image_bitmap_from_canvas/tex-3d-rg16f-rg-float.html": 0.6452,
-    "conformance2/textures/image_bitmap_from_canvas/tex-3d-rg16f-rg-half_float.html": 0.771,
-    "conformance2/textures/image_bitmap_from_canvas/tex-3d-rg32f-rg-float.html": 0.8131,
-    "conformance2/textures/image_bitmap_from_canvas/tex-3d-rg8-rg-unsigned_byte.html": 0.7617,
-    "conformance2/textures/image_bitmap_from_canvas/tex-3d-rg8ui-rg_integer-unsigned_byte.html": 0.7589,
-    "conformance2/textures/image_bitmap_from_canvas/tex-3d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html": 0.5578,
-    "conformance2/textures/image_bitmap_from_canvas/tex-3d-rgb16f-rgb-float.html": 0.4984,
-    "conformance2/textures/image_bitmap_from_canvas/tex-3d-rgb16f-rgb-half_float.html": 0.4829,
-    "conformance2/textures/image_bitmap_from_canvas/tex-3d-rgb32f-rgb-float.html": 0.472,
-    "conformance2/textures/image_bitmap_from_canvas/tex-3d-rgb565-rgb-unsigned_byte.html": 0.4744,
-    "conformance2/textures/image_bitmap_from_canvas/tex-3d-rgb565-rgb-unsigned_short_5_6_5.html": 0.3789,
-    "conformance2/textures/image_bitmap_from_canvas/tex-3d-rgb5_a1-rgba-unsigned_byte.html": 0.4696,
-    "conformance2/textures/image_bitmap_from_canvas/tex-3d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html": 0.5245,
-    "conformance2/textures/image_bitmap_from_canvas/tex-3d-rgb8-rgb-unsigned_byte.html": 0.4088,
-    "conformance2/textures/image_bitmap_from_canvas/tex-3d-rgb8ui-rgb_integer-unsigned_byte.html": 0.4251,
-    "conformance2/textures/image_bitmap_from_canvas/tex-3d-rgb9_e5-rgb-float.html": 0.8239,
-    "conformance2/textures/image_bitmap_from_canvas/tex-3d-rgb9_e5-rgb-half_float.html": 0.7798,
-    "conformance2/textures/image_bitmap_from_canvas/tex-3d-rgba16f-rgba-float.html": 0.544,
-    "conformance2/textures/image_bitmap_from_canvas/tex-3d-rgba16f-rgba-half_float.html": 0.3476,
-    "conformance2/textures/image_bitmap_from_canvas/tex-3d-rgba32f-rgba-float.html": 0.8577,
-    "conformance2/textures/image_bitmap_from_canvas/tex-3d-rgba4-rgba-unsigned_byte.html": 0.7345,
-    "conformance2/textures/image_bitmap_from_canvas/tex-3d-rgba4-rgba-unsigned_short_4_4_4_4.html": 0.4741,
-    "conformance2/textures/image_bitmap_from_canvas/tex-3d-rgba8-rgba-unsigned_byte.html": 0.4563,
-    "conformance2/textures/image_bitmap_from_canvas/tex-3d-rgba8ui-rgba_integer-unsigned_byte.html": 0.6553,
-    "conformance2/textures/image_bitmap_from_canvas/tex-3d-srgb8-rgb-unsigned_byte.html": 0.7496,
-    "conformance2/textures/image_bitmap_from_canvas/tex-3d-srgb8_alpha8-rgba-unsigned_byte.html": 0.4458,
-    "conformance2/textures/image_bitmap_from_image/tex-2d-r11f_g11f_b10f-rgb-float.html": 0.4703,
-    "conformance2/textures/image_bitmap_from_image/tex-2d-r11f_g11f_b10f-rgb-half_float.html": 0.642,
-    "conformance2/textures/image_bitmap_from_image/tex-2d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html": 0.4884,
-    "conformance2/textures/image_bitmap_from_image/tex-2d-r16f-red-float.html": 0.3821,
-    "conformance2/textures/image_bitmap_from_image/tex-2d-r16f-red-half_float.html": 0.4585,
-    "conformance2/textures/image_bitmap_from_image/tex-2d-r32f-red-float.html": 0.6953,
-    "conformance2/textures/image_bitmap_from_image/tex-2d-r8-red-unsigned_byte.html": 0.679,
-    "conformance2/textures/image_bitmap_from_image/tex-2d-r8ui-red_integer-unsigned_byte.html": 0.4889,
-    "conformance2/textures/image_bitmap_from_image/tex-2d-rg16f-rg-float.html": 0.694,
-    "conformance2/textures/image_bitmap_from_image/tex-2d-rg16f-rg-half_float.html": 0.4481,
-    "conformance2/textures/image_bitmap_from_image/tex-2d-rg32f-rg-float.html": 0.4865,
-    "conformance2/textures/image_bitmap_from_image/tex-2d-rg8-rg-unsigned_byte.html": 0.6497,
-    "conformance2/textures/image_bitmap_from_image/tex-2d-rg8ui-rg_integer-unsigned_byte.html": 0.4633,
-    "conformance2/textures/image_bitmap_from_image/tex-2d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html": 0.4356,
-    "conformance2/textures/image_bitmap_from_image/tex-2d-rgb16f-rgb-float.html": 0.6536,
-    "conformance2/textures/image_bitmap_from_image/tex-2d-rgb16f-rgb-half_float.html": 0.4981,
-    "conformance2/textures/image_bitmap_from_image/tex-2d-rgb32f-rgb-float.html": 0.5238,
-    "conformance2/textures/image_bitmap_from_image/tex-2d-rgb565-rgb-unsigned_byte.html": 0.5182,
-    "conformance2/textures/image_bitmap_from_image/tex-2d-rgb565-rgb-unsigned_short_5_6_5.html": 0.6339,
-    "conformance2/textures/image_bitmap_from_image/tex-2d-rgb5_a1-rgba-unsigned_byte.html": 0.6448,
-    "conformance2/textures/image_bitmap_from_image/tex-2d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html": 0.4467,
-    "conformance2/textures/image_bitmap_from_image/tex-2d-rgb8-rgb-unsigned_byte.html": 0.6954,
-    "conformance2/textures/image_bitmap_from_image/tex-2d-rgb8ui-rgb_integer-unsigned_byte.html": 0.494,
-    "conformance2/textures/image_bitmap_from_image/tex-2d-rgb9_e5-rgb-float.html": 0.4521,
-    "conformance2/textures/image_bitmap_from_image/tex-2d-rgb9_e5-rgb-half_float.html": 0.5144,
-    "conformance2/textures/image_bitmap_from_image/tex-2d-rgba16f-rgba-float.html": 0.5126,
-    "conformance2/textures/image_bitmap_from_image/tex-2d-rgba16f-rgba-half_float.html": 0.718,
-    "conformance2/textures/image_bitmap_from_image/tex-2d-rgba32f-rgba-float.html": 0.474,
-    "conformance2/textures/image_bitmap_from_image/tex-2d-rgba4-rgba-unsigned_byte.html": 0.499,
-    "conformance2/textures/image_bitmap_from_image/tex-2d-rgba4-rgba-unsigned_short_4_4_4_4.html": 0.4893,
-    "conformance2/textures/image_bitmap_from_image/tex-2d-rgba8-rgba-unsigned_byte.html": 0.4982,
-    "conformance2/textures/image_bitmap_from_image/tex-2d-rgba8ui-rgba_integer-unsigned_byte.html": 0.4518,
-    "conformance2/textures/image_bitmap_from_image/tex-2d-srgb8-rgb-unsigned_byte.html": 0.6904,
-    "conformance2/textures/image_bitmap_from_image/tex-2d-srgb8_alpha8-rgba-unsigned_byte.html": 0.4999,
-    "conformance2/textures/image_bitmap_from_image/tex-3d-r11f_g11f_b10f-rgb-float.html": 0.4616,
-    "conformance2/textures/image_bitmap_from_image/tex-3d-r11f_g11f_b10f-rgb-half_float.html": 0.498,
-    "conformance2/textures/image_bitmap_from_image/tex-3d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html": 0.5033,
-    "conformance2/textures/image_bitmap_from_image/tex-3d-r16f-red-float.html": 0.34,
-    "conformance2/textures/image_bitmap_from_image/tex-3d-r16f-red-half_float.html": 0.4941,
-    "conformance2/textures/image_bitmap_from_image/tex-3d-r32f-red-float.html": 0.3467,
-    "conformance2/textures/image_bitmap_from_image/tex-3d-r8-red-unsigned_byte.html": 0.3389,
-    "conformance2/textures/image_bitmap_from_image/tex-3d-r8ui-red_integer-unsigned_byte.html": 0.3861,
-    "conformance2/textures/image_bitmap_from_image/tex-3d-rg16f-rg-float.html": 0.4482,
-    "conformance2/textures/image_bitmap_from_image/tex-3d-rg16f-rg-half_float.html": 0.3811,
-    "conformance2/textures/image_bitmap_from_image/tex-3d-rg32f-rg-float.html": 0.3271,
-    "conformance2/textures/image_bitmap_from_image/tex-3d-rg8-rg-unsigned_byte.html": 0.3137,
-    "conformance2/textures/image_bitmap_from_image/tex-3d-rg8ui-rg_integer-unsigned_byte.html": 0.4623,
-    "conformance2/textures/image_bitmap_from_image/tex-3d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html": 0.6244,
-    "conformance2/textures/image_bitmap_from_image/tex-3d-rgb16f-rgb-float.html": 0.3322,
-    "conformance2/textures/image_bitmap_from_image/tex-3d-rgb16f-rgb-half_float.html": 0.3449,
-    "conformance2/textures/image_bitmap_from_image/tex-3d-rgb32f-rgb-float.html": 0.3863,
-    "conformance2/textures/image_bitmap_from_image/tex-3d-rgb565-rgb-unsigned_byte.html": 0.3423,
-    "conformance2/textures/image_bitmap_from_image/tex-3d-rgb565-rgb-unsigned_short_5_6_5.html": 0.4603,
-    "conformance2/textures/image_bitmap_from_image/tex-3d-rgb5_a1-rgba-unsigned_byte.html": 0.487,
-    "conformance2/textures/image_bitmap_from_image/tex-3d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html": 0.367,
-    "conformance2/textures/image_bitmap_from_image/tex-3d-rgb8-rgb-unsigned_byte.html": 0.3532,
-    "conformance2/textures/image_bitmap_from_image/tex-3d-rgb8ui-rgb_integer-unsigned_byte.html": 0.39,
-    "conformance2/textures/image_bitmap_from_image/tex-3d-rgb9_e5-rgb-float.html": 0.3462,
-    "conformance2/textures/image_bitmap_from_image/tex-3d-rgb9_e5-rgb-half_float.html": 0.3356,
-    "conformance2/textures/image_bitmap_from_image/tex-3d-rgba16f-rgba-float.html": 0.3453,
-    "conformance2/textures/image_bitmap_from_image/tex-3d-rgba16f-rgba-half_float.html": 0.3764,
-    "conformance2/textures/image_bitmap_from_image/tex-3d-rgba32f-rgba-float.html": 0.292,
-    "conformance2/textures/image_bitmap_from_image/tex-3d-rgba4-rgba-unsigned_byte.html": 0.414,
-    "conformance2/textures/image_bitmap_from_image/tex-3d-rgba4-rgba-unsigned_short_4_4_4_4.html": 0.4855,
-    "conformance2/textures/image_bitmap_from_image/tex-3d-rgba8-rgba-unsigned_byte.html": 0.3367,
-    "conformance2/textures/image_bitmap_from_image/tex-3d-rgba8ui-rgba_integer-unsigned_byte.html": 0.3393,
-    "conformance2/textures/image_bitmap_from_image/tex-3d-srgb8-rgb-unsigned_byte.html": 0.3349,
-    "conformance2/textures/image_bitmap_from_image/tex-3d-srgb8_alpha8-rgba-unsigned_byte.html": 0.3522,
-    "conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-r11f_g11f_b10f-rgb-float.html": 0.4054,
-    "conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-r11f_g11f_b10f-rgb-half_float.html": 0.7319,
-    "conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html": 0.443,
-    "conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-r16f-red-float.html": 0.4581,
-    "conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-r16f-red-half_float.html": 0.4935,
-    "conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-r32f-red-float.html": 0.5034,
-    "conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-r8-red-unsigned_byte.html": 0.3843,
-    "conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-r8ui-red_integer-unsigned_byte.html": 0.4253,
-    "conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-rg16f-rg-float.html": 0.5615,
-    "conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-rg16f-rg-half_float.html": 0.4756,
-    "conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-rg32f-rg-float.html": 0.3948,
-    "conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-rg8-rg-unsigned_byte.html": 0.4347,
-    "conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-rg8ui-rg_integer-unsigned_byte.html": 0.5022,
-    "conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html": 0.3834,
-    "conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-rgb16f-rgb-float.html": 0.4369,
-    "conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-rgb16f-rgb-half_float.html": 0.3923,
-    "conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-rgb32f-rgb-float.html": 0.4264,
-    "conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-rgb565-rgb-unsigned_byte.html": 0.7086,
-    "conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-rgb565-rgb-unsigned_short_5_6_5.html": 0.6736,
-    "conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-rgb5_a1-rgba-unsigned_byte.html": 0.3297,
-    "conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html": 0.3189,
-    "conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-rgb8-rgb-unsigned_byte.html": 0.6903,
-    "conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-rgb8ui-rgb_integer-unsigned_byte.html": 0.3617,
-    "conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-rgb9_e5-rgb-float.html": 0.4292,
-    "conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-rgb9_e5-rgb-half_float.html": 0.3812,
-    "conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-rgba16f-rgba-float.html": 0.6086,
-    "conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-rgba16f-rgba-half_float.html": 0.4098,
-    "conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-rgba32f-rgba-float.html": 0.4765,
-    "conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-rgba4-rgba-unsigned_byte.html": 0.7483,
-    "conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-rgba4-rgba-unsigned_short_4_4_4_4.html": 0.4427,
-    "conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-rgba8-rgba-unsigned_byte.html": 0.5265,
-    "conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-rgba8ui-rgba_integer-unsigned_byte.html": 0.3869,
-    "conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-srgb8-rgb-unsigned_byte.html": 0.5627,
-    "conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-srgb8_alpha8-rgba-unsigned_byte.html": 0.3752,
-    "conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-r11f_g11f_b10f-rgb-float.html": 0.296,
-    "conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-r11f_g11f_b10f-rgb-half_float.html": 0.303,
-    "conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html": 0.3596,
-    "conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-r16f-red-float.html": 0.3234,
-    "conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-r16f-red-half_float.html": 0.4339,
-    "conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-r32f-red-float.html": 0.294,
-    "conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-r8-red-unsigned_byte.html": 0.3209,
-    "conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-r8ui-red_integer-unsigned_byte.html": 0.3544,
-    "conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-rg16f-rg-float.html": 0.2989,
-    "conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-rg16f-rg-half_float.html": 0.2797,
-    "conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-rg32f-rg-float.html": 0.4093,
-    "conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-rg8-rg-unsigned_byte.html": 0.2217,
-    "conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-rg8ui-rg_integer-unsigned_byte.html": 0.2957,
-    "conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html": 0.336,
-    "conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-rgb16f-rgb-float.html": 0.4526,
-    "conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-rgb16f-rgb-half_float.html": 0.3778,
-    "conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-rgb32f-rgb-float.html": 0.2467,
-    "conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-rgb565-rgb-unsigned_byte.html": 0.5252,
-    "conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-rgb565-rgb-unsigned_short_5_6_5.html": 0.215,
-    "conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-rgb5_a1-rgba-unsigned_byte.html": 0.3638,
-    "conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html": 0.2898,
-    "conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-rgb8-rgb-unsigned_byte.html": 0.2364,
-    "conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-rgb8ui-rgb_integer-unsigned_byte.html": 0.2364,
-    "conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-rgb9_e5-rgb-float.html": 0.293,
-    "conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-rgb9_e5-rgb-half_float.html": 0.1865,
-    "conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-rgba16f-rgba-float.html": 0.4821,
-    "conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-rgba16f-rgba-half_float.html": 0.4724,
-    "conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-rgba32f-rgba-float.html": 0.3108,
-    "conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-rgba4-rgba-unsigned_byte.html": 0.3322,
-    "conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-rgba4-rgba-unsigned_short_4_4_4_4.html": 0.2181,
-    "conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-rgba8-rgba-unsigned_byte.html": 0.3318,
-    "conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-rgba8ui-rgba_integer-unsigned_byte.html": 0.2747,
-    "conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-srgb8-rgb-unsigned_byte.html": 0.4184,
-    "conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-srgb8_alpha8-rgba-unsigned_byte.html": 0.6019,
-    "conformance2/textures/image_bitmap_from_image_data/tex-2d-r11f_g11f_b10f-rgb-float.html": 0.6074,
-    "conformance2/textures/image_bitmap_from_image_data/tex-2d-r11f_g11f_b10f-rgb-half_float.html": 0.4184,
-    "conformance2/textures/image_bitmap_from_image_data/tex-2d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html": 0.4113,
-    "conformance2/textures/image_bitmap_from_image_data/tex-2d-r16f-red-float.html": 0.675,
-    "conformance2/textures/image_bitmap_from_image_data/tex-2d-r16f-red-half_float.html": 0.7555,
-    "conformance2/textures/image_bitmap_from_image_data/tex-2d-r32f-red-float.html": 0.4896,
-    "conformance2/textures/image_bitmap_from_image_data/tex-2d-r8-red-unsigned_byte.html": 0.6779,
-    "conformance2/textures/image_bitmap_from_image_data/tex-2d-r8ui-red_integer-unsigned_byte.html": 0.6751,
-    "conformance2/textures/image_bitmap_from_image_data/tex-2d-rg16f-rg-float.html": 0.4039,
-    "conformance2/textures/image_bitmap_from_image_data/tex-2d-rg16f-rg-half_float.html": 0.6443,
-    "conformance2/textures/image_bitmap_from_image_data/tex-2d-rg32f-rg-float.html": 0.7598,
-    "conformance2/textures/image_bitmap_from_image_data/tex-2d-rg8-rg-unsigned_byte.html": 0.5061,
-    "conformance2/textures/image_bitmap_from_image_data/tex-2d-rg8ui-rg_integer-unsigned_byte.html": 0.7777,
-    "conformance2/textures/image_bitmap_from_image_data/tex-2d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html": 0.6733,
-    "conformance2/textures/image_bitmap_from_image_data/tex-2d-rgb16f-rgb-float.html": 0.4836,
-    "conformance2/textures/image_bitmap_from_image_data/tex-2d-rgb16f-rgb-half_float.html": 0.774,
-    "conformance2/textures/image_bitmap_from_image_data/tex-2d-rgb32f-rgb-float.html": 0.4547,
-    "conformance2/textures/image_bitmap_from_image_data/tex-2d-rgb565-rgb-unsigned_byte.html": 0.7815,
-    "conformance2/textures/image_bitmap_from_image_data/tex-2d-rgb565-rgb-unsigned_short_5_6_5.html": 0.63,
-    "conformance2/textures/image_bitmap_from_image_data/tex-2d-rgb5_a1-rgba-unsigned_byte.html": 0.3356,
-    "conformance2/textures/image_bitmap_from_image_data/tex-2d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html": 0.7133,
-    "conformance2/textures/image_bitmap_from_image_data/tex-2d-rgb8-rgb-unsigned_byte.html": 0.4919,
-    "conformance2/textures/image_bitmap_from_image_data/tex-2d-rgb8ui-rgb_integer-unsigned_byte.html": 0.6357,
-    "conformance2/textures/image_bitmap_from_image_data/tex-2d-rgb9_e5-rgb-float.html": 0.4937,
-    "conformance2/textures/image_bitmap_from_image_data/tex-2d-rgb9_e5-rgb-half_float.html": 0.4638,
-    "conformance2/textures/image_bitmap_from_image_data/tex-2d-rgba16f-rgba-float.html": 0.4228,
-    "conformance2/textures/image_bitmap_from_image_data/tex-2d-rgba16f-rgba-half_float.html": 0.5542,
-    "conformance2/textures/image_bitmap_from_image_data/tex-2d-rgba32f-rgba-float.html": 0.412,
-    "conformance2/textures/image_bitmap_from_image_data/tex-2d-rgba4-rgba-unsigned_byte.html": 0.4133,
-    "conformance2/textures/image_bitmap_from_image_data/tex-2d-rgba4-rgba-unsigned_short_4_4_4_4.html": 0.4395,
-    "conformance2/textures/image_bitmap_from_image_data/tex-2d-rgba8-rgba-unsigned_byte.html": 0.4239,
-    "conformance2/textures/image_bitmap_from_image_data/tex-2d-rgba8ui-rgba_integer-unsigned_byte.html": 0.3881,
-    "conformance2/textures/image_bitmap_from_image_data/tex-2d-srgb8-rgb-unsigned_byte.html": 0.8279,
-    "conformance2/textures/image_bitmap_from_image_data/tex-2d-srgb8_alpha8-rgba-unsigned_byte.html": 0.3055,
-    "conformance2/textures/image_bitmap_from_image_data/tex-3d-r11f_g11f_b10f-rgb-float.html": 0.3645,
-    "conformance2/textures/image_bitmap_from_image_data/tex-3d-r11f_g11f_b10f-rgb-half_float.html": 0.4465,
-    "conformance2/textures/image_bitmap_from_image_data/tex-3d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html": 0.4672,
-    "conformance2/textures/image_bitmap_from_image_data/tex-3d-r16f-red-float.html": 0.3227,
-    "conformance2/textures/image_bitmap_from_image_data/tex-3d-r16f-red-half_float.html": 0.34,
-    "conformance2/textures/image_bitmap_from_image_data/tex-3d-r32f-red-float.html": 0.3153,
-    "conformance2/textures/image_bitmap_from_image_data/tex-3d-r8-red-unsigned_byte.html": 0.3418,
-    "conformance2/textures/image_bitmap_from_image_data/tex-3d-r8ui-red_integer-unsigned_byte.html": 0.3714,
-    "conformance2/textures/image_bitmap_from_image_data/tex-3d-rg16f-rg-float.html": 0.3726,
-    "conformance2/textures/image_bitmap_from_image_data/tex-3d-rg16f-rg-half_float.html": 0.2971,
-    "conformance2/textures/image_bitmap_from_image_data/tex-3d-rg32f-rg-float.html": 0.3537,
-    "conformance2/textures/image_bitmap_from_image_data/tex-3d-rg8-rg-unsigned_byte.html": 0.6266,
-    "conformance2/textures/image_bitmap_from_image_data/tex-3d-rg8ui-rg_integer-unsigned_byte.html": 0.315,
-    "conformance2/textures/image_bitmap_from_image_data/tex-3d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html": 0.3306,
-    "conformance2/textures/image_bitmap_from_image_data/tex-3d-rgb16f-rgb-float.html": 0.3393,
-    "conformance2/textures/image_bitmap_from_image_data/tex-3d-rgb16f-rgb-half_float.html": 0.3608,
-    "conformance2/textures/image_bitmap_from_image_data/tex-3d-rgb32f-rgb-float.html": 0.4364,
-    "conformance2/textures/image_bitmap_from_image_data/tex-3d-rgb565-rgb-unsigned_byte.html": 0.455,
-    "conformance2/textures/image_bitmap_from_image_data/tex-3d-rgb565-rgb-unsigned_short_5_6_5.html": 0.4484,
-    "conformance2/textures/image_bitmap_from_image_data/tex-3d-rgb5_a1-rgba-unsigned_byte.html": 0.3933,
-    "conformance2/textures/image_bitmap_from_image_data/tex-3d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html": 0.3258,
-    "conformance2/textures/image_bitmap_from_image_data/tex-3d-rgb8-rgb-unsigned_byte.html": 0.3565,
-    "conformance2/textures/image_bitmap_from_image_data/tex-3d-rgb8ui-rgb_integer-unsigned_byte.html": 0.3736,
-    "conformance2/textures/image_bitmap_from_image_data/tex-3d-rgb9_e5-rgb-float.html": 0.2527,
-    "conformance2/textures/image_bitmap_from_image_data/tex-3d-rgb9_e5-rgb-half_float.html": 0.3767,
-    "conformance2/textures/image_bitmap_from_image_data/tex-3d-rgba16f-rgba-float.html": 0.3021,
-    "conformance2/textures/image_bitmap_from_image_data/tex-3d-rgba16f-rgba-half_float.html": 0.2733,
-    "conformance2/textures/image_bitmap_from_image_data/tex-3d-rgba32f-rgba-float.html": 0.2217,
-    "conformance2/textures/image_bitmap_from_image_data/tex-3d-rgba4-rgba-unsigned_byte.html": 0.472,
-    "conformance2/textures/image_bitmap_from_image_data/tex-3d-rgba4-rgba-unsigned_short_4_4_4_4.html": 0.4709,
-    "conformance2/textures/image_bitmap_from_image_data/tex-3d-rgba8-rgba-unsigned_byte.html": 0.3042,
-    "conformance2/textures/image_bitmap_from_image_data/tex-3d-rgba8ui-rgba_integer-unsigned_byte.html": 0.2826,
-    "conformance2/textures/image_bitmap_from_image_data/tex-3d-srgb8-rgb-unsigned_byte.html": 0.3875,
-    "conformance2/textures/image_bitmap_from_image_data/tex-3d-srgb8_alpha8-rgba-unsigned_byte.html": 0.4954,
-    "conformance2/textures/image_bitmap_from_video/tex-2d-r11f_g11f_b10f-rgb-float.html": 2.8298,
-    "conformance2/textures/image_bitmap_from_video/tex-2d-r11f_g11f_b10f-rgb-half_float.html": 2.522,
-    "conformance2/textures/image_bitmap_from_video/tex-2d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html": 3.2162,
-    "conformance2/textures/image_bitmap_from_video/tex-2d-r16f-red-float.html": 2.7282,
-    "conformance2/textures/image_bitmap_from_video/tex-2d-r16f-red-half_float.html": 0.5467,
-    "conformance2/textures/image_bitmap_from_video/tex-2d-r32f-red-float.html": 2.7619,
-    "conformance2/textures/image_bitmap_from_video/tex-2d-r8-red-unsigned_byte.html": 3.0709,
-    "conformance2/textures/image_bitmap_from_video/tex-2d-r8ui-red_integer-unsigned_byte.html": 2.9971,
-    "conformance2/textures/image_bitmap_from_video/tex-2d-rg16f-rg-float.html": 0.789,
-    "conformance2/textures/image_bitmap_from_video/tex-2d-rg16f-rg-half_float.html": 3.0258,
-    "conformance2/textures/image_bitmap_from_video/tex-2d-rg32f-rg-float.html": 0.6129,
-    "conformance2/textures/image_bitmap_from_video/tex-2d-rg8-rg-unsigned_byte.html": 0.6915,
-    "conformance2/textures/image_bitmap_from_video/tex-2d-rg8ui-rg_integer-unsigned_byte.html": 2.8352,
-    "conformance2/textures/image_bitmap_from_video/tex-2d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html": 3.0191,
-    "conformance2/textures/image_bitmap_from_video/tex-2d-rgb16f-rgb-float.html": 2.7442,
-    "conformance2/textures/image_bitmap_from_video/tex-2d-rgb16f-rgb-half_float.html": 0.6198,
-    "conformance2/textures/image_bitmap_from_video/tex-2d-rgb32f-rgb-float.html": 0.7602,
-    "conformance2/textures/image_bitmap_from_video/tex-2d-rgb565-rgb-unsigned_byte.html": 3.2518,
-    "conformance2/textures/image_bitmap_from_video/tex-2d-rgb565-rgb-unsigned_short_5_6_5.html": 2.8379,
-    "conformance2/textures/image_bitmap_from_video/tex-2d-rgb5_a1-rgba-unsigned_byte.html": 0.5807,
-    "conformance2/textures/image_bitmap_from_video/tex-2d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html": 0.811,
-    "conformance2/textures/image_bitmap_from_video/tex-2d-rgb8-rgb-unsigned_byte.html": 0.6689,
-    "conformance2/textures/image_bitmap_from_video/tex-2d-rgb8ui-rgb_integer-unsigned_byte.html": 0.6137,
-    "conformance2/textures/image_bitmap_from_video/tex-2d-rgb9_e5-rgb-float.html": 0.6538,
-    "conformance2/textures/image_bitmap_from_video/tex-2d-rgb9_e5-rgb-half_float.html": 0.463,
-    "conformance2/textures/image_bitmap_from_video/tex-2d-rgba16f-rgba-float.html": 0.6425,
-    "conformance2/textures/image_bitmap_from_video/tex-2d-rgba16f-rgba-half_float.html": 0.6289,
-    "conformance2/textures/image_bitmap_from_video/tex-2d-rgba32f-rgba-float.html": 0.6011,
-    "conformance2/textures/image_bitmap_from_video/tex-2d-rgba4-rgba-unsigned_byte.html": 0.7441,
-    "conformance2/textures/image_bitmap_from_video/tex-2d-rgba4-rgba-unsigned_short_4_4_4_4.html": 0.7502,
-    "conformance2/textures/image_bitmap_from_video/tex-2d-rgba8-rgba-unsigned_byte.html": 0.59,
-    "conformance2/textures/image_bitmap_from_video/tex-2d-rgba8ui-rgba_integer-unsigned_byte.html": 3.1494,
-    "conformance2/textures/image_bitmap_from_video/tex-2d-srgb8-rgb-unsigned_byte.html": 0.7168,
-    "conformance2/textures/image_bitmap_from_video/tex-2d-srgb8_alpha8-rgba-unsigned_byte.html": 0.487,
-    "conformance2/textures/image_bitmap_from_video/tex-3d-r11f_g11f_b10f-rgb-float.html": 0.5969,
-    "conformance2/textures/image_bitmap_from_video/tex-3d-r11f_g11f_b10f-rgb-half_float.html": 0.8872,
-    "conformance2/textures/image_bitmap_from_video/tex-3d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html": 0.6514,
-    "conformance2/textures/image_bitmap_from_video/tex-3d-r16f-red-float.html": 0.654,
-    "conformance2/textures/image_bitmap_from_video/tex-3d-r16f-red-half_float.html": 0.6847,
-    "conformance2/textures/image_bitmap_from_video/tex-3d-r32f-red-float.html": 0.6308,
-    "conformance2/textures/image_bitmap_from_video/tex-3d-r8-red-unsigned_byte.html": 0.5141,
-    "conformance2/textures/image_bitmap_from_video/tex-3d-r8ui-red_integer-unsigned_byte.html": 0.6542,
-    "conformance2/textures/image_bitmap_from_video/tex-3d-rg16f-rg-float.html": 0.6698,
-    "conformance2/textures/image_bitmap_from_video/tex-3d-rg16f-rg-half_float.html": 0.5606,
-    "conformance2/textures/image_bitmap_from_video/tex-3d-rg32f-rg-float.html": 0.8579,
-    "conformance2/textures/image_bitmap_from_video/tex-3d-rg8-rg-unsigned_byte.html": 0.5805,
-    "conformance2/textures/image_bitmap_from_video/tex-3d-rg8ui-rg_integer-unsigned_byte.html": 0.5716,
-    "conformance2/textures/image_bitmap_from_video/tex-3d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html": 3.0791,
-    "conformance2/textures/image_bitmap_from_video/tex-3d-rgb16f-rgb-float.html": 0.9448,
-    "conformance2/textures/image_bitmap_from_video/tex-3d-rgb16f-rgb-half_float.html": 0.6029,
-    "conformance2/textures/image_bitmap_from_video/tex-3d-rgb32f-rgb-float.html": 0.6138,
-    "conformance2/textures/image_bitmap_from_video/tex-3d-rgb565-rgb-unsigned_byte.html": 0.5508,
-    "conformance2/textures/image_bitmap_from_video/tex-3d-rgb565-rgb-unsigned_short_5_6_5.html": 0.7624,
-    "conformance2/textures/image_bitmap_from_video/tex-3d-rgb5_a1-rgba-unsigned_byte.html": 0.5486,
-    "conformance2/textures/image_bitmap_from_video/tex-3d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html": 0.5532,
-    "conformance2/textures/image_bitmap_from_video/tex-3d-rgb8-rgb-unsigned_byte.html": 0.524,
-    "conformance2/textures/image_bitmap_from_video/tex-3d-rgb8ui-rgb_integer-unsigned_byte.html": 2.4744,
-    "conformance2/textures/image_bitmap_from_video/tex-3d-rgb9_e5-rgb-float.html": 0.5187,
-    "conformance2/textures/image_bitmap_from_video/tex-3d-rgb9_e5-rgb-half_float.html": 0.6138,
-    "conformance2/textures/image_bitmap_from_video/tex-3d-rgba16f-rgba-float.html": 2.8192,
-    "conformance2/textures/image_bitmap_from_video/tex-3d-rgba16f-rgba-half_float.html": 0.5168,
-    "conformance2/textures/image_bitmap_from_video/tex-3d-rgba32f-rgba-float.html": 0.6194,
-    "conformance2/textures/image_bitmap_from_video/tex-3d-rgba4-rgba-unsigned_byte.html": 0.5951,
-    "conformance2/textures/image_bitmap_from_video/tex-3d-rgba4-rgba-unsigned_short_4_4_4_4.html": 0.5074,
-    "conformance2/textures/image_bitmap_from_video/tex-3d-rgba8-rgba-unsigned_byte.html": 0.4575,
-    "conformance2/textures/image_bitmap_from_video/tex-3d-rgba8ui-rgba_integer-unsigned_byte.html": 0.7303,
-    "conformance2/textures/image_bitmap_from_video/tex-3d-srgb8-rgb-unsigned_byte.html": 0.6153,
-    "conformance2/textures/image_bitmap_from_video/tex-3d-srgb8_alpha8-rgba-unsigned_byte.html": 0.4944,
-    "conformance2/textures/image_data/tex-2d-r11f_g11f_b10f-rgb-float.html": 0.5914,
-    "conformance2/textures/image_data/tex-2d-r11f_g11f_b10f-rgb-half_float.html": 0.8196,
-    "conformance2/textures/image_data/tex-2d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html": 0.5228,
-    "conformance2/textures/image_data/tex-2d-r16f-red-float.html": 0.6559,
-    "conformance2/textures/image_data/tex-2d-r16f-red-half_float.html": 0.771,
-    "conformance2/textures/image_data/tex-2d-r32f-red-float.html": 1.3795,
-    "conformance2/textures/image_data/tex-2d-r8-red-unsigned_byte.html": 0.6812,
-    "conformance2/textures/image_data/tex-2d-r8ui-red_integer-unsigned_byte.html": 0.667,
-    "conformance2/textures/image_data/tex-2d-rg16f-rg-float.html": 0.7635,
-    "conformance2/textures/image_data/tex-2d-rg16f-rg-half_float.html": 0.605,
-    "conformance2/textures/image_data/tex-2d-rg32f-rg-float.html": 1.0647,
-    "conformance2/textures/image_data/tex-2d-rg8-rg-unsigned_byte.html": 0.7378,
-    "conformance2/textures/image_data/tex-2d-rg8ui-rg_integer-unsigned_byte.html": 0.6151,
-    "conformance2/textures/image_data/tex-2d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html": 0.5893,
-    "conformance2/textures/image_data/tex-2d-rgb16f-rgb-float.html": 1.1358,
-    "conformance2/textures/image_data/tex-2d-rgb16f-rgb-half_float.html": 0.4962,
-    "conformance2/textures/image_data/tex-2d-rgb32f-rgb-float.html": 0.5535,
-    "conformance2/textures/image_data/tex-2d-rgb565-rgb-unsigned_byte.html": 0.7371,
-    "conformance2/textures/image_data/tex-2d-rgb565-rgb-unsigned_short_5_6_5.html": 0.8056,
-    "conformance2/textures/image_data/tex-2d-rgb5_a1-rgba-unsigned_byte.html": 0.5975,
-    "conformance2/textures/image_data/tex-2d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html": 0.8865,
-    "conformance2/textures/image_data/tex-2d-rgb8-rgb-unsigned_byte.html": 0.7247,
-    "conformance2/textures/image_data/tex-2d-rgb8ui-rgb_integer-unsigned_byte.html": 1.2612,
-    "conformance2/textures/image_data/tex-2d-rgb9_e5-rgb-float.html": 1.1209,
-    "conformance2/textures/image_data/tex-2d-rgb9_e5-rgb-half_float.html": 0.7376,
-    "conformance2/textures/image_data/tex-2d-rgba16f-rgba-float.html": 0.6857,
-    "conformance2/textures/image_data/tex-2d-rgba16f-rgba-half_float.html": 0.7049,
-    "conformance2/textures/image_data/tex-2d-rgba32f-rgba-float.html": 0.6315,
-    "conformance2/textures/image_data/tex-2d-rgba4-rgba-unsigned_byte.html": 0.5688,
-    "conformance2/textures/image_data/tex-2d-rgba4-rgba-unsigned_short_4_4_4_4.html": 0.7155,
-    "conformance2/textures/image_data/tex-2d-rgba8-rgba-unsigned_byte.html": 0.7315,
-    "conformance2/textures/image_data/tex-2d-rgba8ui-rgba_integer-unsigned_byte.html": 1.1473,
-    "conformance2/textures/image_data/tex-2d-srgb8-rgb-unsigned_byte.html": 0.751,
-    "conformance2/textures/image_data/tex-2d-srgb8_alpha8-rgba-unsigned_byte.html": 1.0689,
-    "conformance2/textures/image_data/tex-3d-r11f_g11f_b10f-rgb-float.html": 1.3822,
-    "conformance2/textures/image_data/tex-3d-r11f_g11f_b10f-rgb-half_float.html": 0.7147,
-    "conformance2/textures/image_data/tex-3d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html": 0.6883,
-    "conformance2/textures/image_data/tex-3d-r16f-red-float.html": 1.1882,
-    "conformance2/textures/image_data/tex-3d-r16f-red-half_float.html": 1.2871,
-    "conformance2/textures/image_data/tex-3d-r32f-red-float.html": 1.019,
-    "conformance2/textures/image_data/tex-3d-r8-red-unsigned_byte.html": 0.8264,
-    "conformance2/textures/image_data/tex-3d-r8ui-red_integer-unsigned_byte.html": 0.6153,
-    "conformance2/textures/image_data/tex-3d-rg16f-rg-float.html": 1.182,
-    "conformance2/textures/image_data/tex-3d-rg16f-rg-half_float.html": 1.1482,
-    "conformance2/textures/image_data/tex-3d-rg32f-rg-float.html": 0.6196,
-    "conformance2/textures/image_data/tex-3d-rg8-rg-unsigned_byte.html": 0.7481,
-    "conformance2/textures/image_data/tex-3d-rg8ui-rg_integer-unsigned_byte.html": 1.2527,
-    "conformance2/textures/image_data/tex-3d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html": 0.9564,
-    "conformance2/textures/image_data/tex-3d-rgb16f-rgb-float.html": 0.7789,
-    "conformance2/textures/image_data/tex-3d-rgb16f-rgb-half_float.html": 0.8558,
-    "conformance2/textures/image_data/tex-3d-rgb32f-rgb-float.html": 0.7004,
-    "conformance2/textures/image_data/tex-3d-rgb565-rgb-unsigned_byte.html": 0.7663,
-    "conformance2/textures/image_data/tex-3d-rgb565-rgb-unsigned_short_5_6_5.html": 1.0431,
-    "conformance2/textures/image_data/tex-3d-rgb5_a1-rgba-unsigned_byte.html": 0.7607,
-    "conformance2/textures/image_data/tex-3d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html": 0.6165,
-    "conformance2/textures/image_data/tex-3d-rgb8-rgb-unsigned_byte.html": 1.1461,
-    "conformance2/textures/image_data/tex-3d-rgb8ui-rgb_integer-unsigned_byte.html": 1.2387,
-    "conformance2/textures/image_data/tex-3d-rgb9_e5-rgb-float.html": 0.7174,
-    "conformance2/textures/image_data/tex-3d-rgb9_e5-rgb-half_float.html": 1.1173,
-    "conformance2/textures/image_data/tex-3d-rgba16f-rgba-float.html": 0.598,
-    "conformance2/textures/image_data/tex-3d-rgba16f-rgba-half_float.html": 0.605,
-    "conformance2/textures/image_data/tex-3d-rgba32f-rgba-float.html": 0.5946,
-    "conformance2/textures/image_data/tex-3d-rgba4-rgba-unsigned_byte.html": 0.5843,
-    "conformance2/textures/image_data/tex-3d-rgba4-rgba-unsigned_short_4_4_4_4.html": 0.5872,
-    "conformance2/textures/image_data/tex-3d-rgba8-rgba-unsigned_byte.html": 0.7433,
-    "conformance2/textures/image_data/tex-3d-rgba8ui-rgba_integer-unsigned_byte.html": 0.9057,
-    "conformance2/textures/image_data/tex-3d-srgb8-rgb-unsigned_byte.html": 0.5501,
-    "conformance2/textures/image_data/tex-3d-srgb8_alpha8-rgba-unsigned_byte.html": 0.9557,
-    "conformance2/textures/misc/active-3d-texture-bug.html": 0.2987,
-    "conformance2/textures/misc/angle-stuck-depth-textures.html": 0.3674,
-    "conformance2/textures/misc/canvas-remains-unchanged-after-used-in-webgl-texture.html": 0.3636,
-    "conformance2/textures/misc/compressed-tex-from-pbo-crash.html": 0.068,
-    "conformance2/textures/misc/copy-texture-cube-map-AMD-bug.html": 0.3831,
-    "conformance2/textures/misc/copy-texture-cube-map-bug.html": 0.2224,
-    "conformance2/textures/misc/copy-texture-image-luma-format.html": 9.4153,
-    "conformance2/textures/misc/copy-texture-image-same-texture.html": 0.4015,
-    "conformance2/textures/misc/copy-texture-image-webgl-specific.html": 0.216,
-    "conformance2/textures/misc/copy-texture-image.html": 0.4503,
-    "conformance2/textures/misc/generate-mipmap-with-large-base-level.html": 0.133,
-    "conformance2/textures/misc/gl-get-tex-parameter.html": 0.4291,
-    "conformance2/textures/misc/integer-cubemap-specification-order-bug.html": 1.4159,
-    "conformance2/textures/misc/integer-cubemap-texture-sampling.html": 1.4834,
-    "conformance2/textures/misc/mipmap-fbo.html": 0.2107,
-    "conformance2/textures/misc/npot-video-sizing.html": 0.2131,
-    "conformance2/textures/misc/origin-clean-conformance-offscreencanvas.html": 0.1708,
-    "conformance2/textures/misc/tex-3d-mipmap-levels-intel-bug.html": 0.1741,
-    "conformance2/textures/misc/tex-3d-size-limit.html": 0.3358,
-    "conformance2/textures/misc/tex-base-level-bug.html": 0.099,
-    "conformance2/textures/misc/tex-image-and-sub-image-with-array-buffer-view-sub-source.html": 0.2636,
-    "conformance2/textures/misc/tex-image-with-bad-args-from-dom-elements.html": 0.6089,
-    "conformance2/textures/misc/tex-image-with-bad-args.html": 0.1474,
-    "conformance2/textures/misc/tex-image-with-different-data-source.html": 0.2356,
-    "conformance2/textures/misc/tex-input-validation.html": 0.48,
-    "conformance2/textures/misc/tex-mipmap-levels.html": 0.2058,
-    "conformance2/textures/misc/tex-new-formats.html": 1.1755,
-    "conformance2/textures/misc/tex-srgb-mipmap.html": 0.5186,
-    "conformance2/textures/misc/tex-storage-2d.html": 0.5173,
-    "conformance2/textures/misc/tex-storage-and-subimage-3d.html": 0.1638,
-    "conformance2/textures/misc/tex-storage-compressed-formats.html": 0.1806,
-    "conformance2/textures/misc/tex-subimage3d-canvas-bug.html": 0.2243,
-    "conformance2/textures/misc/tex-subimage3d-pixel-buffer-bug.html": 0.1791,
-    "conformance2/textures/misc/tex-unpack-params-imagedata.html": 0.0898,
-    "conformance2/textures/misc/tex-unpack-params-with-flip-y-and-premultiply-alpha.html": 1.0028,
-    "conformance2/textures/misc/tex-unpack-params.html": 1.2336,
-    "conformance2/textures/misc/texel-fetch-undefined.html": 0.3797,
-    "conformance2/textures/misc/texture-npot.html": 0.2171,
-    "conformance2/textures/svg_image/tex-2d-r11f_g11f_b10f-rgb-float.html": 0.5432,
-    "conformance2/textures/svg_image/tex-2d-r11f_g11f_b10f-rgb-half_float.html": 0.2779,
-    "conformance2/textures/svg_image/tex-2d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html": 0.4053,
-    "conformance2/textures/svg_image/tex-2d-r16f-red-float.html": 0.3513,
-    "conformance2/textures/svg_image/tex-2d-r16f-red-half_float.html": 0.5003,
-    "conformance2/textures/svg_image/tex-2d-r32f-red-float.html": 0.3865,
-    "conformance2/textures/svg_image/tex-2d-r8-red-unsigned_byte.html": 0.2892,
-    "conformance2/textures/svg_image/tex-2d-r8ui-red_integer-unsigned_byte.html": 0.3857,
-    "conformance2/textures/svg_image/tex-2d-rg16f-rg-float.html": 0.4359,
-    "conformance2/textures/svg_image/tex-2d-rg16f-rg-half_float.html": 0.285,
-    "conformance2/textures/svg_image/tex-2d-rg32f-rg-float.html": 0.3516,
-    "conformance2/textures/svg_image/tex-2d-rg8-rg-unsigned_byte.html": 0.3989,
-    "conformance2/textures/svg_image/tex-2d-rg8ui-rg_integer-unsigned_byte.html": 0.3251,
-    "conformance2/textures/svg_image/tex-2d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html": 0.3541,
-    "conformance2/textures/svg_image/tex-2d-rgb16f-rgb-float.html": 0.3755,
-    "conformance2/textures/svg_image/tex-2d-rgb16f-rgb-half_float.html": 0.3427,
-    "conformance2/textures/svg_image/tex-2d-rgb32f-rgb-float.html": 0.2819,
-    "conformance2/textures/svg_image/tex-2d-rgb565-rgb-unsigned_byte.html": 0.7767,
-    "conformance2/textures/svg_image/tex-2d-rgb565-rgb-unsigned_short_5_6_5.html": 0.3443,
-    "conformance2/textures/svg_image/tex-2d-rgb5_a1-rgba-unsigned_byte.html": 0.3864,
-    "conformance2/textures/svg_image/tex-2d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html": 0.277,
-    "conformance2/textures/svg_image/tex-2d-rgb8-rgb-unsigned_byte.html": 0.3304,
-    "conformance2/textures/svg_image/tex-2d-rgb8ui-rgb_integer-unsigned_byte.html": 0.3142,
-    "conformance2/textures/svg_image/tex-2d-rgb9_e5-rgb-float.html": 0.5816,
-    "conformance2/textures/svg_image/tex-2d-rgb9_e5-rgb-half_float.html": 0.3064,
-    "conformance2/textures/svg_image/tex-2d-rgba16f-rgba-float.html": 0.4329,
-    "conformance2/textures/svg_image/tex-2d-rgba16f-rgba-half_float.html": 0.3288,
-    "conformance2/textures/svg_image/tex-2d-rgba32f-rgba-float.html": 0.235,
-    "conformance2/textures/svg_image/tex-2d-rgba4-rgba-unsigned_byte.html": 0.3003,
-    "conformance2/textures/svg_image/tex-2d-rgba4-rgba-unsigned_short_4_4_4_4.html": 0.4052,
-    "conformance2/textures/svg_image/tex-2d-rgba8-rgba-unsigned_byte.html": 0.316,
-    "conformance2/textures/svg_image/tex-2d-rgba8ui-rgba_integer-unsigned_byte.html": 0.2979,
-    "conformance2/textures/svg_image/tex-2d-srgb8-rgb-unsigned_byte.html": 0.3031,
-    "conformance2/textures/svg_image/tex-2d-srgb8_alpha8-rgba-unsigned_byte.html": 0.3114,
-    "conformance2/textures/svg_image/tex-3d-r11f_g11f_b10f-rgb-float.html": 0.1543,
-    "conformance2/textures/svg_image/tex-3d-r11f_g11f_b10f-rgb-half_float.html": 0.1718,
-    "conformance2/textures/svg_image/tex-3d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html": 0.2082,
-    "conformance2/textures/svg_image/tex-3d-r16f-red-float.html": 0.224,
-    "conformance2/textures/svg_image/tex-3d-r16f-red-half_float.html": 0.1656,
-    "conformance2/textures/svg_image/tex-3d-r32f-red-float.html": 0.2772,
-    "conformance2/textures/svg_image/tex-3d-r8-red-unsigned_byte.html": 0.1479,
-    "conformance2/textures/svg_image/tex-3d-r8ui-red_integer-unsigned_byte.html": 0.1796,
-    "conformance2/textures/svg_image/tex-3d-rg16f-rg-float.html": 0.1523,
-    "conformance2/textures/svg_image/tex-3d-rg16f-rg-half_float.html": 0.2504,
-    "conformance2/textures/svg_image/tex-3d-rg32f-rg-float.html": 0.1631,
-    "conformance2/textures/svg_image/tex-3d-rg8-rg-unsigned_byte.html": 0.1432,
-    "conformance2/textures/svg_image/tex-3d-rg8ui-rg_integer-unsigned_byte.html": 0.1675,
-    "conformance2/textures/svg_image/tex-3d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html": 0.1771,
-    "conformance2/textures/svg_image/tex-3d-rgb16f-rgb-float.html": 0.2978,
-    "conformance2/textures/svg_image/tex-3d-rgb16f-rgb-half_float.html": 0.2645,
-    "conformance2/textures/svg_image/tex-3d-rgb32f-rgb-float.html": 0.2858,
-    "conformance2/textures/svg_image/tex-3d-rgb565-rgb-unsigned_byte.html": 0.179,
-    "conformance2/textures/svg_image/tex-3d-rgb565-rgb-unsigned_short_5_6_5.html": 0.2622,
-    "conformance2/textures/svg_image/tex-3d-rgb5_a1-rgba-unsigned_byte.html": 0.2228,
-    "conformance2/textures/svg_image/tex-3d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html": 0.2234,
-    "conformance2/textures/svg_image/tex-3d-rgb8-rgb-unsigned_byte.html": 0.3155,
-    "conformance2/textures/svg_image/tex-3d-rgb8ui-rgb_integer-unsigned_byte.html": 0.2633,
-    "conformance2/textures/svg_image/tex-3d-rgb9_e5-rgb-float.html": 0.2021,
-    "conformance2/textures/svg_image/tex-3d-rgb9_e5-rgb-half_float.html": 0.2162,
-    "conformance2/textures/svg_image/tex-3d-rgba16f-rgba-float.html": 0.2236,
-    "conformance2/textures/svg_image/tex-3d-rgba16f-rgba-half_float.html": 0.2502,
-    "conformance2/textures/svg_image/tex-3d-rgba32f-rgba-float.html": 0.187,
-    "conformance2/textures/svg_image/tex-3d-rgba4-rgba-unsigned_byte.html": 0.1909,
-    "conformance2/textures/svg_image/tex-3d-rgba4-rgba-unsigned_short_4_4_4_4.html": 0.1763,
-    "conformance2/textures/svg_image/tex-3d-rgba8-rgba-unsigned_byte.html": 0.1953,
-    "conformance2/textures/svg_image/tex-3d-rgba8ui-rgba_integer-unsigned_byte.html": 0.2675,
-    "conformance2/textures/svg_image/tex-3d-srgb8-rgb-unsigned_byte.html": 0.2972,
-    "conformance2/textures/svg_image/tex-3d-srgb8_alpha8-rgba-unsigned_byte.html": 0.2874,
-    "conformance2/textures/video/tex-2d-r11f_g11f_b10f-rgb-float.html": 3.0534,
-    "conformance2/textures/video/tex-2d-r11f_g11f_b10f-rgb-half_float.html": 0.9546,
-    "conformance2/textures/video/tex-2d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html": 0.7341,
-    "conformance2/textures/video/tex-2d-r16f-red-float.html": 0.6977,
-    "conformance2/textures/video/tex-2d-r16f-red-half_float.html": 2.6978,
-    "conformance2/textures/video/tex-2d-r32f-red-float.html": 0.6317,
-    "conformance2/textures/video/tex-2d-r8-red-unsigned_byte.html": 0.6788,
-    "conformance2/textures/video/tex-2d-r8ui-red_integer-unsigned_byte.html": 0.7639,
-    "conformance2/textures/video/tex-2d-rg16f-rg-float.html": 0.7343,
-    "conformance2/textures/video/tex-2d-rg16f-rg-half_float.html": 0.634,
-    "conformance2/textures/video/tex-2d-rg32f-rg-float.html": 0.679,
-    "conformance2/textures/video/tex-2d-rg8-rg-unsigned_byte.html": 0.6155,
-    "conformance2/textures/video/tex-2d-rg8ui-rg_integer-unsigned_byte.html": 2.8739,
-    "conformance2/textures/video/tex-2d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html": 0.6369,
-    "conformance2/textures/video/tex-2d-rgb16f-rgb-float.html": 2.9946,
-    "conformance2/textures/video/tex-2d-rgb16f-rgb-half_float.html": 0.6651,
-    "conformance2/textures/video/tex-2d-rgb32f-rgb-float.html": 0.679,
-    "conformance2/textures/video/tex-2d-rgb565-rgb-unsigned_byte.html": 3.0286,
-    "conformance2/textures/video/tex-2d-rgb565-rgb-unsigned_short_5_6_5.html": 0.7797,
-    "conformance2/textures/video/tex-2d-rgb5_a1-rgba-unsigned_byte.html": 0.8309,
-    "conformance2/textures/video/tex-2d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html": 0.8473,
-    "conformance2/textures/video/tex-2d-rgb8-rgb-unsigned_byte.html": 0.7573,
-    "conformance2/textures/video/tex-2d-rgb8ui-rgb_integer-unsigned_byte.html": 0.716,
-    "conformance2/textures/video/tex-2d-rgb9_e5-rgb-float.html": 0.9717,
-    "conformance2/textures/video/tex-2d-rgb9_e5-rgb-half_float.html": 0.6437,
-    "conformance2/textures/video/tex-2d-rgba16f-rgba-float.html": 0.8063,
-    "conformance2/textures/video/tex-2d-rgba16f-rgba-half_float.html": 0.7183,
-    "conformance2/textures/video/tex-2d-rgba32f-rgba-float.html": 0.6979,
-    "conformance2/textures/video/tex-2d-rgba4-rgba-unsigned_byte.html": 0.7316,
-    "conformance2/textures/video/tex-2d-rgba4-rgba-unsigned_short_4_4_4_4.html": 0.6798,
-    "conformance2/textures/video/tex-2d-rgba8-rgba-unsigned_byte.html": 0.9234,
-    "conformance2/textures/video/tex-2d-rgba8ui-rgba_integer-unsigned_byte.html": 0.8679,
-    "conformance2/textures/video/tex-2d-srgb8-rgb-unsigned_byte.html": 0.7313,
-    "conformance2/textures/video/tex-2d-srgb8_alpha8-rgba-unsigned_byte.html": 0.6536,
-    "conformance2/textures/video/tex-3d-r11f_g11f_b10f-rgb-float.html": 0.9543,
-    "conformance2/textures/video/tex-3d-r11f_g11f_b10f-rgb-half_float.html": 1.1407,
-    "conformance2/textures/video/tex-3d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html": 1.0221,
-    "conformance2/textures/video/tex-3d-r16f-red-float.html": 0.8647,
-    "conformance2/textures/video/tex-3d-r16f-red-half_float.html": 1.0771,
-    "conformance2/textures/video/tex-3d-r32f-red-float.html": 0.9673,
-    "conformance2/textures/video/tex-3d-r8-red-unsigned_byte.html": 1.3061,
-    "conformance2/textures/video/tex-3d-r8ui-red_integer-unsigned_byte.html": 1.0046,
-    "conformance2/textures/video/tex-3d-rg16f-rg-float.html": 1.072,
-    "conformance2/textures/video/tex-3d-rg16f-rg-half_float.html": 0.8457,
-    "conformance2/textures/video/tex-3d-rg32f-rg-float.html": 0.8917,
-    "conformance2/textures/video/tex-3d-rg8-rg-unsigned_byte.html": 1.1966,
-    "conformance2/textures/video/tex-3d-rg8ui-rg_integer-unsigned_byte.html": 0.9039,
-    "conformance2/textures/video/tex-3d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html": 0.8796,
-    "conformance2/textures/video/tex-3d-rgb16f-rgb-float.html": 0.9812,
-    "conformance2/textures/video/tex-3d-rgb16f-rgb-half_float.html": 1.0458,
-    "conformance2/textures/video/tex-3d-rgb32f-rgb-float.html": 0.9201,
-    "conformance2/textures/video/tex-3d-rgb565-rgb-unsigned_byte.html": 0.8118,
-    "conformance2/textures/video/tex-3d-rgb565-rgb-unsigned_short_5_6_5.html": 0.7825,
-    "conformance2/textures/video/tex-3d-rgb5_a1-rgba-unsigned_byte.html": 0.9063,
-    "conformance2/textures/video/tex-3d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html": 0.8748,
-    "conformance2/textures/video/tex-3d-rgb8-rgb-unsigned_byte.html": 0.9769,
-    "conformance2/textures/video/tex-3d-rgb8ui-rgb_integer-unsigned_byte.html": 0.9462,
-    "conformance2/textures/video/tex-3d-rgb9_e5-rgb-float.html": 0.9264,
-    "conformance2/textures/video/tex-3d-rgb9_e5-rgb-half_float.html": 1.1702,
-    "conformance2/textures/video/tex-3d-rgba16f-rgba-float.html": 0.9321,
-    "conformance2/textures/video/tex-3d-rgba16f-rgba-half_float.html": 0.9256,
-    "conformance2/textures/video/tex-3d-rgba32f-rgba-float.html": 0.7958,
-    "conformance2/textures/video/tex-3d-rgba4-rgba-unsigned_byte.html": 0.8306,
-    "conformance2/textures/video/tex-3d-rgba4-rgba-unsigned_short_4_4_4_4.html": 0.9639,
-    "conformance2/textures/video/tex-3d-rgba8-rgba-unsigned_byte.html": 1.1243,
-    "conformance2/textures/video/tex-3d-rgba8ui-rgba_integer-unsigned_byte.html": 0.8056,
-    "conformance2/textures/video/tex-3d-srgb8-rgb-unsigned_byte.html": 0.8715,
-    "conformance2/textures/video/tex-3d-srgb8_alpha8-rgba-unsigned_byte.html": 1.1455,
-    "conformance2/textures/webgl_canvas/tex-2d-r11f_g11f_b10f-rgb-float.html": 0.8827,
-    "conformance2/textures/webgl_canvas/tex-2d-r11f_g11f_b10f-rgb-half_float.html": 1.2218,
-    "conformance2/textures/webgl_canvas/tex-2d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html": 1.1033,
-    "conformance2/textures/webgl_canvas/tex-2d-r16f-red-float.html": 0.8472,
-    "conformance2/textures/webgl_canvas/tex-2d-r16f-red-half_float.html": 1.0333,
-    "conformance2/textures/webgl_canvas/tex-2d-r32f-red-float.html": 0.8628,
-    "conformance2/textures/webgl_canvas/tex-2d-r8-red-unsigned_byte.html": 0.8557,
-    "conformance2/textures/webgl_canvas/tex-2d-r8ui-red_integer-unsigned_byte.html": 1.0666,
-    "conformance2/textures/webgl_canvas/tex-2d-rg16f-rg-float.html": 0.7137,
-    "conformance2/textures/webgl_canvas/tex-2d-rg16f-rg-half_float.html": 1.0097,
-    "conformance2/textures/webgl_canvas/tex-2d-rg32f-rg-float.html": 1.0719,
-    "conformance2/textures/webgl_canvas/tex-2d-rg8-rg-unsigned_byte.html": 0.9374,
-    "conformance2/textures/webgl_canvas/tex-2d-rg8ui-rg_integer-unsigned_byte.html": 0.8813,
-    "conformance2/textures/webgl_canvas/tex-2d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html": 1.1354,
-    "conformance2/textures/webgl_canvas/tex-2d-rgb16f-rgb-float.html": 0.8534,
-    "conformance2/textures/webgl_canvas/tex-2d-rgb16f-rgb-half_float.html": 1.1783,
-    "conformance2/textures/webgl_canvas/tex-2d-rgb32f-rgb-float.html": 0.866,
-    "conformance2/textures/webgl_canvas/tex-2d-rgb565-rgb-unsigned_byte.html": 0.8516,
-    "conformance2/textures/webgl_canvas/tex-2d-rgb565-rgb-unsigned_short_5_6_5.html": 1.078,
-    "conformance2/textures/webgl_canvas/tex-2d-rgb5_a1-rgba-unsigned_byte.html": 0.8779,
-    "conformance2/textures/webgl_canvas/tex-2d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html": 0.8639,
-    "conformance2/textures/webgl_canvas/tex-2d-rgb8-rgb-unsigned_byte.html": 0.8347,
-    "conformance2/textures/webgl_canvas/tex-2d-rgb8ui-rgb_integer-unsigned_byte.html": 1.5331,
-    "conformance2/textures/webgl_canvas/tex-2d-rgb9_e5-rgb-float.html": 1.0817,
-    "conformance2/textures/webgl_canvas/tex-2d-rgb9_e5-rgb-half_float.html": 0.8145,
-    "conformance2/textures/webgl_canvas/tex-2d-rgba16f-rgba-float.html": 1.1268,
-    "conformance2/textures/webgl_canvas/tex-2d-rgba16f-rgba-half_float.html": 1.0815,
-    "conformance2/textures/webgl_canvas/tex-2d-rgba32f-rgba-float.html": 0.7807,
-    "conformance2/textures/webgl_canvas/tex-2d-rgba4-rgba-unsigned_byte.html": 0.819,
-    "conformance2/textures/webgl_canvas/tex-2d-rgba4-rgba-unsigned_short_4_4_4_4.html": 0.8808,
-    "conformance2/textures/webgl_canvas/tex-2d-rgba8-rgba-unsigned_byte.html": 0.8312,
-    "conformance2/textures/webgl_canvas/tex-2d-rgba8ui-rgba_integer-unsigned_byte.html": 0.6822,
-    "conformance2/textures/webgl_canvas/tex-2d-srgb8-rgb-unsigned_byte.html": 0.9499,
-    "conformance2/textures/webgl_canvas/tex-2d-srgb8_alpha8-rgba-unsigned_byte.html": 0.5844,
-    "conformance2/textures/webgl_canvas/tex-3d-r11f_g11f_b10f-rgb-float.html": 5.4567,
-    "conformance2/textures/webgl_canvas/tex-3d-r11f_g11f_b10f-rgb-half_float.html": 5.4498,
-    "conformance2/textures/webgl_canvas/tex-3d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html": 5.6265,
-    "conformance2/textures/webgl_canvas/tex-3d-r16f-red-float.html": 5.3391,
-    "conformance2/textures/webgl_canvas/tex-3d-r16f-red-half_float.html": 5.4358,
-    "conformance2/textures/webgl_canvas/tex-3d-r32f-red-float.html": 5.4008,
-    "conformance2/textures/webgl_canvas/tex-3d-r8-red-unsigned_byte.html": 5.4001,
-    "conformance2/textures/webgl_canvas/tex-3d-r8ui-red_integer-unsigned_byte.html": 5.4849,
-    "conformance2/textures/webgl_canvas/tex-3d-rg16f-rg-float.html": 5.74,
-    "conformance2/textures/webgl_canvas/tex-3d-rg16f-rg-half_float.html": 5.4431,
-    "conformance2/textures/webgl_canvas/tex-3d-rg32f-rg-float.html": 5.4549,
-    "conformance2/textures/webgl_canvas/tex-3d-rg8-rg-unsigned_byte.html": 5.4756,
-    "conformance2/textures/webgl_canvas/tex-3d-rg8ui-rg_integer-unsigned_byte.html": 5.4783,
-    "conformance2/textures/webgl_canvas/tex-3d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html": 5.4588,
-    "conformance2/textures/webgl_canvas/tex-3d-rgb16f-rgb-float.html": 5.5572,
-    "conformance2/textures/webgl_canvas/tex-3d-rgb16f-rgb-half_float.html": 5.551,
-    "conformance2/textures/webgl_canvas/tex-3d-rgb32f-rgb-float.html": 5.5729,
-    "conformance2/textures/webgl_canvas/tex-3d-rgb565-rgb-unsigned_byte.html": 5.8358,
-    "conformance2/textures/webgl_canvas/tex-3d-rgb565-rgb-unsigned_short_5_6_5.html": 5.3762,
-    "conformance2/textures/webgl_canvas/tex-3d-rgb5_a1-rgba-unsigned_byte.html": 5.4578,
-    "conformance2/textures/webgl_canvas/tex-3d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html": 5.5401,
-    "conformance2/textures/webgl_canvas/tex-3d-rgb8-rgb-unsigned_byte.html": 5.5221,
-    "conformance2/textures/webgl_canvas/tex-3d-rgb8ui-rgb_integer-unsigned_byte.html": 5.3829,
-    "conformance2/textures/webgl_canvas/tex-3d-rgb9_e5-rgb-float.html": 5.4272,
-    "conformance2/textures/webgl_canvas/tex-3d-rgb9_e5-rgb-half_float.html": 5.4756,
-    "conformance2/textures/webgl_canvas/tex-3d-rgba16f-rgba-float.html": 5.3864,
-    "conformance2/textures/webgl_canvas/tex-3d-rgba16f-rgba-half_float.html": 5.6891,
-    "conformance2/textures/webgl_canvas/tex-3d-rgba32f-rgba-float.html": 5.5837,
-    "conformance2/textures/webgl_canvas/tex-3d-rgba4-rgba-unsigned_byte.html": 5.452,
-    "conformance2/textures/webgl_canvas/tex-3d-rgba4-rgba-unsigned_short_4_4_4_4.html": 5.833,
-    "conformance2/textures/webgl_canvas/tex-3d-rgba8-rgba-unsigned_byte.html": 5.6567,
-    "conformance2/textures/webgl_canvas/tex-3d-rgba8ui-rgba_integer-unsigned_byte.html": 5.4743,
-    "conformance2/textures/webgl_canvas/tex-3d-srgb8-rgb-unsigned_byte.html": 5.3576,
-    "conformance2/textures/webgl_canvas/tex-3d-srgb8_alpha8-rgba-unsigned_byte.html": 5.7833,
-    "conformance2/transform_feedback/default_transform_feedback.html": 0.1515,
-    "conformance2/transform_feedback/non-existent-varying.html": 0.1812,
-    "conformance2/transform_feedback/same-buffer-two-binding-points.html": 0.2247,
-    "conformance2/transform_feedback/simultaneous_binding.html": 0.3974,
-    "conformance2/transform_feedback/switching-objects.html": 0.3587,
-    "conformance2/transform_feedback/too-small-buffers.html": 0.5047,
-    "conformance2/transform_feedback/transform_feedback.html": 1.8648,
-    "conformance2/transform_feedback/two-unreferenced-varyings.html": 0.1966,
-    "conformance2/transform_feedback/unwritten-output-defaults-to-zero.html": 0.1513,
-    "conformance2/uniforms/dependent-buffer-change.html": 0.2637,
-    "conformance2/uniforms/draw-with-uniform-blocks.html": 0.2071,
-    "conformance2/uniforms/gl-uniform-arrays-sub-source.html": 1.54,
-    "conformance2/uniforms/incompatible-texture-type-for-sampler.html": 8.7779,
-    "conformance2/uniforms/large-uniform-buffers.html": 0.2808,
-    "conformance2/uniforms/query-uniform-blocks-after-shader-detach.html": 0.2816,
-    "conformance2/uniforms/simple-buffer-change.html": 0.2085,
-    "conformance2/uniforms/uniform-blocks-with-arrays.html": 0.5436,
-    "conformance2/vertex_arrays/vertex-array-object-and-disabled-attributes.html": 0.3599,
-    "conformance2/vertex_arrays/vertex-array-object.html": 0.4316,
-    "deqp/data/gles3/shaders/arrays.html": 5.2678,
-    "deqp/data/gles3/shaders/conditionals.html": 1.8181,
-    "deqp/data/gles3/shaders/constant_expressions.html": 2.1041,
-    "deqp/data/gles3/shaders/constants.html": 5.1188,
-    "deqp/data/gles3/shaders/conversions.html": 78.1311,
-    "deqp/data/gles3/shaders/declarations.html": 1.8217,
-    "deqp/data/gles3/shaders/fragdata.html": 0.4652,
-    "deqp/data/gles3/shaders/functions.html": 10.884,
-    "deqp/data/gles3/shaders/invalid_texture_functions.html": 2.8492,
-    "deqp/data/gles3/shaders/keywords.html": 7.5556,
-    "deqp/data/gles3/shaders/linkage.html": 5.2112,
-    "deqp/data/gles3/shaders/negative.html": 0.7726,
-    "deqp/data/gles3/shaders/preprocessor.html": 15.5632,
-    "deqp/data/gles3/shaders/qualification_order.html": 2.5125,
-    "deqp/data/gles3/shaders/scoping.html": 3.3059,
-    "deqp/data/gles3/shaders/switch.html": 1.4202,
-    "deqp/data/gles3/shaders/swizzles.html": 33.9185,
-    "deqp/framework/opengl/simplereference/referencecontext.html": 4.354,
-    "deqp/functional/gles3/attriblocation.html": 6.5417,
-    "deqp/functional/gles3/booleanstatequery.html": 0.619,
-    "deqp/functional/gles3/buffercopy.html": 8.4643,
-    "deqp/functional/gles3/bufferobjectquery.html": 0.5391,
-    "deqp/functional/gles3/clipping.html": 21.8743,
-    "deqp/functional/gles3/defaultvertexattribute.html": 11.6838,
-    "deqp/functional/gles3/draw/draw_arrays.html": 17.9223,
-    "deqp/functional/gles3/draw/draw_arrays_instanced.html": 19.7748,
-    "deqp/functional/gles3/draw/draw_elements.html": 15.7541,
-    "deqp/functional/gles3/draw/draw_elements_instanced.html": 18.2232,
-    "deqp/functional/gles3/draw/draw_range_elements.html": 12.3409,
-    "deqp/functional/gles3/draw/instancing.html": 1.7466,
-    "deqp/functional/gles3/draw/random.html": 19.0798,
-    "deqp/functional/gles3/fbocolorbuffer/blend.html": 17.7692,
-    "deqp/functional/gles3/fbocolorbuffer/clear.html": 9.3948,
-    "deqp/functional/gles3/fbocolorbuffer/tex2d_00.html": 19.4148,
-    "deqp/functional/gles3/fbocolorbuffer/tex2d_01.html": 18.0478,
-    "deqp/functional/gles3/fbocolorbuffer/tex2d_02.html": 18.7647,
-    "deqp/functional/gles3/fbocolorbuffer/tex2d_03.html": 17.8818,
-    "deqp/functional/gles3/fbocolorbuffer/tex2d_04.html": 18.0543,
-    "deqp/functional/gles3/fbocolorbuffer/tex2d_05.html": 14.5803,
-    "deqp/functional/gles3/fbocolorbuffer/tex2darray_00.html": 17.2299,
-    "deqp/functional/gles3/fbocolorbuffer/tex2darray_01.html": 16.2613,
-    "deqp/functional/gles3/fbocolorbuffer/tex2darray_02.html": 16.3167,
-    "deqp/functional/gles3/fbocolorbuffer/tex2darray_03.html": 16.6831,
-    "deqp/functional/gles3/fbocolorbuffer/tex2darray_04.html": 15.8277,
-    "deqp/functional/gles3/fbocolorbuffer/tex2darray_05.html": 12.9674,
-    "deqp/functional/gles3/fbocolorbuffer/tex3d_00.html": 16.0612,
-    "deqp/functional/gles3/fbocolorbuffer/tex3d_01.html": 14.6752,
-    "deqp/functional/gles3/fbocolorbuffer/tex3d_02.html": 15.0615,
-    "deqp/functional/gles3/fbocolorbuffer/tex3d_03.html": 14.1247,
-    "deqp/functional/gles3/fbocolorbuffer/tex3d_04.html": 15.633,
-    "deqp/functional/gles3/fbocolorbuffer/tex3d_05.html": 14.3607,
-    "deqp/functional/gles3/fbocolorbuffer/texcube_00.html": 22.8642,
-    "deqp/functional/gles3/fbocolorbuffer/texcube_01.html": 22.1713,
-    "deqp/functional/gles3/fbocolorbuffer/texcube_02.html": 21.9135,
-    "deqp/functional/gles3/fbocolorbuffer/texcube_03.html": 18.7393,
-    "deqp/functional/gles3/fbocolorbuffer/texcube_04.html": 22.4355,
-    "deqp/functional/gles3/fbocolorbuffer/texcube_05.html": 19.2314,
-    "deqp/functional/gles3/fbocompleteness.html": 5.0641,
-    "deqp/functional/gles3/fbodepthbuffer.html": 18.345,
-    "deqp/functional/gles3/fboinvalidate/default.html": 43.3513,
-    "deqp/functional/gles3/fboinvalidate/format_00.html": 18.9922,
-    "deqp/functional/gles3/fboinvalidate/format_01.html": 19.5078,
-    "deqp/functional/gles3/fboinvalidate/format_02.html": 17.6474,
-    "deqp/functional/gles3/fboinvalidate/sub.html": 31.812,
-    "deqp/functional/gles3/fboinvalidate/target.html": 44.7988,
-    "deqp/functional/gles3/fboinvalidate/whole.html": 32.1415,
-    "deqp/functional/gles3/fbomultisample.2_samples.html": 34.4611,
-    "deqp/functional/gles3/fbomultisample.4_samples.html": 34.2754,
-    "deqp/functional/gles3/fbomultisample.8_samples.html": 32.976,
-    "deqp/functional/gles3/fborender/recreate_color_00.html": 19.7862,
-    "deqp/functional/gles3/fborender/recreate_color_01.html": 19.1305,
-    "deqp/functional/gles3/fborender/recreate_color_02.html": 20.8136,
-    "deqp/functional/gles3/fborender/recreate_color_03.html": 20.3767,
-    "deqp/functional/gles3/fborender/recreate_color_04.html": 18.934,
-    "deqp/functional/gles3/fborender/recreate_color_05.html": 19.2991,
-    "deqp/functional/gles3/fborender/recreate_color_06.html": 20.5599,
-    "deqp/functional/gles3/fborender/recreate_depth_stencil.html": 18.0161,
-    "deqp/functional/gles3/fborender/resize_00.html": 16.8552,
-    "deqp/functional/gles3/fborender/resize_01.html": 16.3348,
-    "deqp/functional/gles3/fborender/resize_02.html": 16.4757,
-    "deqp/functional/gles3/fborender/resize_03.html": 27.4005,
-    "deqp/functional/gles3/fborender/shared_colorbuffer_00.html": 22.2984,
-    "deqp/functional/gles3/fborender/shared_colorbuffer_01.html": 27.9256,
-    "deqp/functional/gles3/fborender/shared_colorbuffer_02.html": 34.0232,
-    "deqp/functional/gles3/fborender/shared_colorbuffer_clear.html": 9.0206,
-    "deqp/functional/gles3/fborender/shared_depth_stencil.html": 16.9643,
-    "deqp/functional/gles3/fborender/stencil_clear.html": 7.8826,
-    "deqp/functional/gles3/fbostatequery.html": 0.5206,
-    "deqp/functional/gles3/fbostencilbuffer.html": 18.9761,
-    "deqp/functional/gles3/floatstatequery.html": 1.1087,
-    "deqp/functional/gles3/fragdepth.html": 9.1644,
-    "deqp/functional/gles3/fragmentoutput/array.fixed.html": 8.6803,
-    "deqp/functional/gles3/fragmentoutput/array.float.html": 11.9044,
-    "deqp/functional/gles3/fragmentoutput/array.int.html": 12.427,
-    "deqp/functional/gles3/fragmentoutput/array.uint.html": 12.6902,
-    "deqp/functional/gles3/fragmentoutput/basic.fixed.html": 5.7673,
-    "deqp/functional/gles3/fragmentoutput/basic.float.html": 7.7741,
-    "deqp/functional/gles3/fragmentoutput/basic.int.html": 6.7161,
-    "deqp/functional/gles3/fragmentoutput/basic.uint.html": 7.3128,
-    "deqp/functional/gles3/fragmentoutput/random_00.html": 14.1606,
-    "deqp/functional/gles3/fragmentoutput/random_01.html": 15.2663,
-    "deqp/functional/gles3/fragmentoutput/random_02.html": 15.6771,
-    "deqp/functional/gles3/framebufferblit/conversion_00.html": 8.0115,
-    "deqp/functional/gles3/framebufferblit/conversion_01.html": 8.6256,
-    "deqp/functional/gles3/framebufferblit/conversion_02.html": 8.6176,
-    "deqp/functional/gles3/framebufferblit/conversion_03.html": 8.2927,
-    "deqp/functional/gles3/framebufferblit/conversion_04.html": 11.8882,
-    "deqp/functional/gles3/framebufferblit/conversion_05.html": 8.6547,
-    "deqp/functional/gles3/framebufferblit/conversion_06.html": 9.545,
-    "deqp/functional/gles3/framebufferblit/conversion_07.html": 12.4355,
-    "deqp/functional/gles3/framebufferblit/conversion_08.html": 12.8623,
-    "deqp/functional/gles3/framebufferblit/conversion_09.html": 9.3546,
-    "deqp/functional/gles3/framebufferblit/conversion_10.html": 12.7246,
-    "deqp/functional/gles3/framebufferblit/conversion_11.html": 13.4707,
-    "deqp/functional/gles3/framebufferblit/conversion_12.html": 11.655,
-    "deqp/functional/gles3/framebufferblit/conversion_13.html": 12.8678,
-    "deqp/functional/gles3/framebufferblit/conversion_14.html": 8.201,
-    "deqp/functional/gles3/framebufferblit/conversion_15.html": 8.8065,
-    "deqp/functional/gles3/framebufferblit/conversion_16.html": 8.6155,
-    "deqp/functional/gles3/framebufferblit/conversion_17.html": 8.6553,
-    "deqp/functional/gles3/framebufferblit/conversion_18.html": 13.0204,
-    "deqp/functional/gles3/framebufferblit/conversion_19.html": 8.6296,
-    "deqp/functional/gles3/framebufferblit/conversion_20.html": 8.6421,
-    "deqp/functional/gles3/framebufferblit/conversion_21.html": 8.501,
-    "deqp/functional/gles3/framebufferblit/conversion_22.html": 9.0364,
-    "deqp/functional/gles3/framebufferblit/conversion_23.html": 8.6365,
-    "deqp/functional/gles3/framebufferblit/conversion_24.html": 8.5377,
-    "deqp/functional/gles3/framebufferblit/conversion_25.html": 12.8909,
-    "deqp/functional/gles3/framebufferblit/conversion_26.html": 7.9638,
-    "deqp/functional/gles3/framebufferblit/conversion_27.html": 9.5503,
-    "deqp/functional/gles3/framebufferblit/conversion_28.html": 12.2677,
-    "deqp/functional/gles3/framebufferblit/conversion_29.html": 13.1199,
-    "deqp/functional/gles3/framebufferblit/conversion_30.html": 13.3625,
-    "deqp/functional/gles3/framebufferblit/conversion_31.html": 13.5509,
-    "deqp/functional/gles3/framebufferblit/conversion_32.html": 13.7542,
-    "deqp/functional/gles3/framebufferblit/conversion_33.html": 12.3406,
-    "deqp/functional/gles3/framebufferblit/conversion_34.html": 13.1682,
-    "deqp/functional/gles3/framebufferblit/default_framebuffer_00.html": 16.0333,
-    "deqp/functional/gles3/framebufferblit/default_framebuffer_01.html": 17.2553,
-    "deqp/functional/gles3/framebufferblit/default_framebuffer_02.html": 13.4326,
-    "deqp/functional/gles3/framebufferblit/default_framebuffer_03.html": 17.8962,
-    "deqp/functional/gles3/framebufferblit/default_framebuffer_04.html": 29.47,
-    "deqp/functional/gles3/framebufferblit/default_framebuffer_05.html": 16.4796,
-    "deqp/functional/gles3/framebufferblit/default_framebuffer_06.html": 19.2537,
-    "deqp/functional/gles3/framebufferblit/depth_stencil.html": 30.7654,
-    "deqp/functional/gles3/framebufferblit/rect_00.html": 10.3233,
-    "deqp/functional/gles3/framebufferblit/rect_01.html": 9.8416,
-    "deqp/functional/gles3/framebufferblit/rect_02.html": 8.4729,
-    "deqp/functional/gles3/framebufferblit/rect_03.html": 5.9387,
-    "deqp/functional/gles3/framebufferblit/rect_04.html": 5.5668,
-    "deqp/functional/gles3/framebufferblit/rect_05.html": 0.5814,
-    "deqp/functional/gles3/framebufferblit/rect_06.html": 0.6734,
-    "deqp/functional/gles3/indexedstatequery.html": 0.4073,
-    "deqp/functional/gles3/instancedrendering.html": 28.4928,
-    "deqp/functional/gles3/integerstatequery.html": 1.9463,
-    "deqp/functional/gles3/internalformatquery.html": 0.5679,
-    "deqp/functional/gles3/lifetime.html": 1.4069,
-    "deqp/functional/gles3/multisample.html": 69.5919,
-    "deqp/functional/gles3/negativebufferapi.html": 0.5977,
-    "deqp/functional/gles3/negativefragmentapi.html": 0.5411,
-    "deqp/functional/gles3/negativeshaderapi.html": 0.8005,
-    "deqp/functional/gles3/negativestateapi.html": 0.8794,
-    "deqp/functional/gles3/negativetextureapi.html": 1.1425,
-    "deqp/functional/gles3/negativevertexarrayapi.html": 0.7149,
-    "deqp/functional/gles3/occlusionquery_conservative.html": 24.13,
-    "deqp/functional/gles3/occlusionquery_strict.html": 23.7092,
-    "deqp/functional/gles3/pixelbufferobject.html": 6.2706,
-    "deqp/functional/gles3/primitiverestart/00.html": 7.4737,
-    "deqp/functional/gles3/primitiverestart/01.html": 7.6212,
-    "deqp/functional/gles3/primitiverestart/02.html": 7.2267,
-    "deqp/functional/gles3/primitiverestart/03.html": 7.0609,
-    "deqp/functional/gles3/primitiverestart/04.html": 7.3713,
-    "deqp/functional/gles3/primitiverestart/05.html": 7.0186,
-    "deqp/functional/gles3/primitiverestart/06.html": 7.287,
-    "deqp/functional/gles3/primitiverestart/07.html": 7.3728,
-    "deqp/functional/gles3/rasterizerdiscard.html": 10.0541,
-    "deqp/functional/gles3/rbostatequery.html": 0.4251,
-    "deqp/functional/gles3/readpixel.html": 2.1412,
-    "deqp/functional/gles3/samplerobject.html": 5.6014,
-    "deqp/functional/gles3/samplerstatequery.html": 0.6092,
-    "deqp/functional/gles3/shaderapi.html": 0.7249,
-    "deqp/functional/gles3/shaderbuiltinvar.html": 8.442,
-    "deqp/functional/gles3/shadercommonfunction.html": 16.2826,
-    "deqp/functional/gles3/shaderderivate_dfdx.html": 13.9277,
-    "deqp/functional/gles3/shaderderivate_dfdy.html": 13.5305,
-    "deqp/functional/gles3/shaderderivate_fwidth.html": 14.3719,
-    "deqp/functional/gles3/shaderindexing/mat_00.html": 34.2979,
-    "deqp/functional/gles3/shaderindexing/mat_01.html": 35.0138,
-    "deqp/functional/gles3/shaderindexing/mat_02.html": 38.2681,
-    "deqp/functional/gles3/shaderindexing/tmp.html": 45.2051,
-    "deqp/functional/gles3/shaderindexing/uniform.html": 14.3379,
-    "deqp/functional/gles3/shaderindexing/varying.html": 28.477,
-    "deqp/functional/gles3/shaderindexing/vec2.html": 26.5214,
-    "deqp/functional/gles3/shaderindexing/vec3.html": 28.5999,
-    "deqp/functional/gles3/shaderindexing/vec4.html": 29.2089,
-    "deqp/functional/gles3/shaderloop_do_while.html": 67.4197,
-    "deqp/functional/gles3/shaderloop_for.html": 65.2928,
-    "deqp/functional/gles3/shaderloop_while.html": 65.6417,
-    "deqp/functional/gles3/shadermatrix/add_assign.html": 42.5816,
-    "deqp/functional/gles3/shadermatrix/add_const.html": 68.5179,
-    "deqp/functional/gles3/shadermatrix/add_dynamic.html": 68.7433,
-    "deqp/functional/gles3/shadermatrix/add_uniform.html": 67.0647,
-    "deqp/functional/gles3/shadermatrix/determinant.html": 15.0411,
-    "deqp/functional/gles3/shadermatrix/div_assign.html": 39.5174,
-    "deqp/functional/gles3/shadermatrix/div_const.html": 68.3799,
-    "deqp/functional/gles3/shadermatrix/div_dynamic.html": 88.3403,
-    "deqp/functional/gles3/shadermatrix/div_uniform.html": 63.8996,
-    "deqp/functional/gles3/shadermatrix/inverse.html": 31.9382,
-    "deqp/functional/gles3/shadermatrix/matrixcompmult.html": 40.1703,
-    "deqp/functional/gles3/shadermatrix/mul_assign.html": 16.9121,
-    "deqp/functional/gles3/shadermatrix/mul_const_highp.html": 66.6531,
-    "deqp/functional/gles3/shadermatrix/mul_const_lowp.html": 63.7331,
-    "deqp/functional/gles3/shadermatrix/mul_const_mediump.html": 64.5694,
-    "deqp/functional/gles3/shadermatrix/mul_dynamic_highp.html": 65.4017,
-    "deqp/functional/gles3/shadermatrix/mul_dynamic_lowp.html": 66.5392,
-    "deqp/functional/gles3/shadermatrix/mul_dynamic_mediump.html": 63.9398,
-    "deqp/functional/gles3/shadermatrix/mul_uniform_highp.html": 63.2443,
-    "deqp/functional/gles3/shadermatrix/mul_uniform_lowp.html": 64.6045,
-    "deqp/functional/gles3/shadermatrix/mul_uniform_mediump.html": 66.3312,
-    "deqp/functional/gles3/shadermatrix/negation.html": 35.4085,
-    "deqp/functional/gles3/shadermatrix/outerproduct.html": 39.3077,
-    "deqp/functional/gles3/shadermatrix/post_decrement.html": 36.0789,
-    "deqp/functional/gles3/shadermatrix/post_increment.html": 35.8198,
-    "deqp/functional/gles3/shadermatrix/pre_decrement.html": 42.8961,
-    "deqp/functional/gles3/shadermatrix/pre_increment.html": 43.8321,
-    "deqp/functional/gles3/shadermatrix/sub_assign.html": 38.3038,
-    "deqp/functional/gles3/shadermatrix/sub_const.html": 67.2747,
-    "deqp/functional/gles3/shadermatrix/sub_dynamic.html": 68.903,
-    "deqp/functional/gles3/shadermatrix/sub_uniform.html": 69.6091,
-    "deqp/functional/gles3/shadermatrix/transpose.html": 37.1009,
-    "deqp/functional/gles3/shadermatrix/unary_addition.html": 29.2776,
-    "deqp/functional/gles3/shaderoperator/angle_and_trigonometry_00.html": 40.4036,
-    "deqp/functional/gles3/shaderoperator/angle_and_trigonometry_01.html": 26.2876,
-    "deqp/functional/gles3/shaderoperator/angle_and_trigonometry_02.html": 28.5418,
-    "deqp/functional/gles3/shaderoperator/angle_and_trigonometry_03.html": 21.785,
-    "deqp/functional/gles3/shaderoperator/binary_operator_00.html": 110.1404,
-    "deqp/functional/gles3/shaderoperator/binary_operator_01.html": 102.4677,
-    "deqp/functional/gles3/shaderoperator/binary_operator_02.html": 66.2557,
-    "deqp/functional/gles3/shaderoperator/binary_operator_03.html": 66.4469,
-    "deqp/functional/gles3/shaderoperator/binary_operator_04.html": 81.1529,
-    "deqp/functional/gles3/shaderoperator/binary_operator_05.html": 74.4877,
-    "deqp/functional/gles3/shaderoperator/binary_operator_06.html": 75.5041,
-    "deqp/functional/gles3/shaderoperator/binary_operator_07.html": 45.2467,
-    "deqp/functional/gles3/shaderoperator/binary_operator_08.html": 47.8241,
-    "deqp/functional/gles3/shaderoperator/binary_operator_09.html": 82.5641,
-    "deqp/functional/gles3/shaderoperator/binary_operator_10.html": 78.9465,
-    "deqp/functional/gles3/shaderoperator/binary_operator_11.html": 72.3889,
-    "deqp/functional/gles3/shaderoperator/binary_operator_12.html": 46.1278,
-    "deqp/functional/gles3/shaderoperator/binary_operator_13.html": 45.0741,
-    "deqp/functional/gles3/shaderoperator/binary_operator_14.html": 87.9061,
-    "deqp/functional/gles3/shaderoperator/binary_operator_15.html": 85.9811,
-    "deqp/functional/gles3/shaderoperator/bool_compare.html": 16.1464,
-    "deqp/functional/gles3/shaderoperator/common_functions_00.html": 44.4745,
-    "deqp/functional/gles3/shaderoperator/common_functions_01.html": 55.7797,
-    "deqp/functional/gles3/shaderoperator/common_functions_02.html": 42.8124,
-    "deqp/functional/gles3/shaderoperator/common_functions_03.html": 61.4007,
-    "deqp/functional/gles3/shaderoperator/common_functions_04.html": 45.2278,
-    "deqp/functional/gles3/shaderoperator/common_functions_05.html": 43.7365,
-    "deqp/functional/gles3/shaderoperator/common_functions_06.html": 34.053,
-    "deqp/functional/gles3/shaderoperator/exponential.html": 49.2678,
-    "deqp/functional/gles3/shaderoperator/float_compare.html": 77.7679,
-    "deqp/functional/gles3/shaderoperator/geometric.html": 45.7637,
-    "deqp/functional/gles3/shaderoperator/int_compare.html": 48.9679,
-    "deqp/functional/gles3/shaderoperator/selection.html": 35.2079,
-    "deqp/functional/gles3/shaderoperator/sequence.html": 23.6388,
-    "deqp/functional/gles3/shaderoperator/unary_operator_00.html": 61.4003,
-    "deqp/functional/gles3/shaderoperator/unary_operator_01.html": 102.8134,
-    "deqp/functional/gles3/shaderoperator/unary_operator_02.html": 111.0542,
-    "deqp/functional/gles3/shaderpackingfunction.html": 1.6592,
-    "deqp/functional/gles3/shaderprecision_float.html": 18.8929,
-    "deqp/functional/gles3/shaderprecision_int.html": 17.8698,
-    "deqp/functional/gles3/shaderprecision_uint.html": 18.1683,
-    "deqp/functional/gles3/shaderstatequery.html": 1.2548,
-    "deqp/functional/gles3/shaderstruct.html": 36.494,
-    "deqp/functional/gles3/shaderswitch.html": 42.2961,
-    "deqp/functional/gles3/shadertexturefunction/texelfetch.html": 15.0449,
-    "deqp/functional/gles3/shadertexturefunction/texelfetchoffset.html": 16.4018,
-    "deqp/functional/gles3/shadertexturefunction/texture.html": 33.3507,
-    "deqp/functional/gles3/shadertexturefunction/texturegrad.html": 24.154,
-    "deqp/functional/gles3/shadertexturefunction/texturegradoffset.html": 17.5513,
-    "deqp/functional/gles3/shadertexturefunction/texturelod.html": 21.7584,
-    "deqp/functional/gles3/shadertexturefunction/texturelodoffset.html": 15.1833,
-    "deqp/functional/gles3/shadertexturefunction/textureoffset.html": 20.8607,
-    "deqp/functional/gles3/shadertexturefunction/textureproj.html": 22.5937,
-    "deqp/functional/gles3/shadertexturefunction/textureprojgrad.html": 17.6683,
-    "deqp/functional/gles3/shadertexturefunction/textureprojgradoffset.html": 17.0529,
-    "deqp/functional/gles3/shadertexturefunction/textureprojlod.html": 15.5976,
-    "deqp/functional/gles3/shadertexturefunction/textureprojlodoffset.html": 15.3998,
-    "deqp/functional/gles3/shadertexturefunction/textureprojoffset.html": 20.3365,
-    "deqp/functional/gles3/shadertexturefunction/texturesize.html": 17.9611,
-    "deqp/functional/gles3/stringquery.html": 0.4505,
-    "deqp/functional/gles3/sync.html": 4.1434,
-    "deqp/functional/gles3/texturefiltering/2d_array_combinations_00.html": 9.2149,
-    "deqp/functional/gles3/texturefiltering/2d_array_combinations_01.html": 8.7938,
-    "deqp/functional/gles3/texturefiltering/2d_array_combinations_02.html": 9.4262,
-    "deqp/functional/gles3/texturefiltering/2d_array_combinations_03.html": 9.83,
-    "deqp/functional/gles3/texturefiltering/2d_array_combinations_04.html": 9.6641,
-    "deqp/functional/gles3/texturefiltering/2d_array_combinations_05.html": 10.4189,
-    "deqp/functional/gles3/texturefiltering/2d_array_formats_00.html": 5.8574,
-    "deqp/functional/gles3/texturefiltering/2d_array_formats_01.html": 5.4001,
-    "deqp/functional/gles3/texturefiltering/2d_array_formats_02.html": 5.3124,
-    "deqp/functional/gles3/texturefiltering/2d_array_formats_03.html": 4.6545,
-    "deqp/functional/gles3/texturefiltering/2d_array_formats_04.html": 5.0764,
-    "deqp/functional/gles3/texturefiltering/2d_array_formats_05.html": 4.7899,
-    "deqp/functional/gles3/texturefiltering/2d_array_formats_06.html": 4.5402,
-    "deqp/functional/gles3/texturefiltering/2d_array_formats_07.html": 4.5244,
-    "deqp/functional/gles3/texturefiltering/2d_array_formats_08.html": 5.1943,
-    "deqp/functional/gles3/texturefiltering/2d_array_formats_09.html": 5.2494,
-    "deqp/functional/gles3/texturefiltering/2d_array_sizes_00.html": 4.1964,
-    "deqp/functional/gles3/texturefiltering/2d_array_sizes_01.html": 4.4162,
-    "deqp/functional/gles3/texturefiltering/2d_array_sizes_02.html": 5.798,
-    "deqp/functional/gles3/texturefiltering/2d_array_sizes_03.html": 4.3385,
-    "deqp/functional/gles3/texturefiltering/2d_array_sizes_04.html": 11.0526,
-    "deqp/functional/gles3/texturefiltering/2d_combinations_00.html": 4.8331,
-    "deqp/functional/gles3/texturefiltering/2d_combinations_01.html": 4.6477,
-    "deqp/functional/gles3/texturefiltering/2d_combinations_02.html": 5.016,
-    "deqp/functional/gles3/texturefiltering/2d_combinations_03.html": 4.3725,
-    "deqp/functional/gles3/texturefiltering/2d_combinations_04.html": 4.9294,
-    "deqp/functional/gles3/texturefiltering/2d_combinations_05.html": 4.7973,
-    "deqp/functional/gles3/texturefiltering/2d_formats_00.html": 4.2315,
-    "deqp/functional/gles3/texturefiltering/2d_formats_01.html": 3.8517,
-    "deqp/functional/gles3/texturefiltering/2d_formats_02.html": 3.083,
-    "deqp/functional/gles3/texturefiltering/2d_formats_03.html": 2.8856,
-    "deqp/functional/gles3/texturefiltering/2d_formats_04.html": 3.0759,
-    "deqp/functional/gles3/texturefiltering/2d_formats_05.html": 2.8678,
-    "deqp/functional/gles3/texturefiltering/2d_formats_06.html": 3.3559,
-    "deqp/functional/gles3/texturefiltering/2d_formats_07.html": 3.2251,
-    "deqp/functional/gles3/texturefiltering/2d_formats_08.html": 3.1849,
-    "deqp/functional/gles3/texturefiltering/2d_formats_09.html": 3.3988,
-    "deqp/functional/gles3/texturefiltering/2d_sizes_00.html": 2.8819,
-    "deqp/functional/gles3/texturefiltering/2d_sizes_01.html": 3.2244,
-    "deqp/functional/gles3/texturefiltering/2d_sizes_02.html": 3.1457,
-    "deqp/functional/gles3/texturefiltering/2d_sizes_03.html": 3.1494,
-    "deqp/functional/gles3/texturefiltering/2d_sizes_04.html": 3.1462,
-    "deqp/functional/gles3/texturefiltering/2d_sizes_05.html": 3.2655,
-    "deqp/functional/gles3/texturefiltering/3d_combinations_00.html": 4.693,
-    "deqp/functional/gles3/texturefiltering/3d_combinations_01.html": 4.8055,
-    "deqp/functional/gles3/texturefiltering/3d_combinations_02.html": 4.8452,
-    "deqp/functional/gles3/texturefiltering/3d_combinations_03.html": 5.0821,
-    "deqp/functional/gles3/texturefiltering/3d_combinations_04.html": 4.9439,
-    "deqp/functional/gles3/texturefiltering/3d_combinations_05.html": 4.8859,
-    "deqp/functional/gles3/texturefiltering/3d_combinations_06.html": 4.9469,
-    "deqp/functional/gles3/texturefiltering/3d_combinations_07.html": 5.2659,
-    "deqp/functional/gles3/texturefiltering/3d_combinations_08.html": 4.58,
-    "deqp/functional/gles3/texturefiltering/3d_combinations_09.html": 4.957,
-    "deqp/functional/gles3/texturefiltering/3d_combinations_10.html": 4.626,
-    "deqp/functional/gles3/texturefiltering/3d_combinations_11.html": 5.1183,
-    "deqp/functional/gles3/texturefiltering/3d_combinations_12.html": 4.7218,
-    "deqp/functional/gles3/texturefiltering/3d_combinations_13.html": 4.7432,
-    "deqp/functional/gles3/texturefiltering/3d_combinations_14.html": 4.369,
-    "deqp/functional/gles3/texturefiltering/3d_combinations_15.html": 4.9823,
-    "deqp/functional/gles3/texturefiltering/3d_combinations_16.html": 5.416,
-    "deqp/functional/gles3/texturefiltering/3d_combinations_17.html": 4.7369,
-    "deqp/functional/gles3/texturefiltering/3d_combinations_18.html": 4.6431,
-    "deqp/functional/gles3/texturefiltering/3d_combinations_19.html": 4.6012,
-    "deqp/functional/gles3/texturefiltering/3d_combinations_20.html": 4.8106,
-    "deqp/functional/gles3/texturefiltering/3d_combinations_21.html": 4.6833,
-    "deqp/functional/gles3/texturefiltering/3d_combinations_22.html": 4.9645,
-    "deqp/functional/gles3/texturefiltering/3d_combinations_23.html": 4.7691,
-    "deqp/functional/gles3/texturefiltering/3d_combinations_24.html": 18.7763,
-    "deqp/functional/gles3/texturefiltering/3d_combinations_25.html": 18.2796,
-    "deqp/functional/gles3/texturefiltering/3d_combinations_26.html": 18.6038,
-    "deqp/functional/gles3/texturefiltering/3d_combinations_27.html": 18.7556,
-    "deqp/functional/gles3/texturefiltering/3d_combinations_28.html": 18.8638,
-    "deqp/functional/gles3/texturefiltering/3d_combinations_29.html": 18.5861,
-    "deqp/functional/gles3/texturefiltering/3d_combinations_30.html": 19.5671,
-    "deqp/functional/gles3/texturefiltering/3d_combinations_31.html": 19.6733,
-    "deqp/functional/gles3/texturefiltering/3d_combinations_32.html": 20.2635,
-    "deqp/functional/gles3/texturefiltering/3d_combinations_33.html": 19.8281,
-    "deqp/functional/gles3/texturefiltering/3d_combinations_34.html": 19.5866,
-    "deqp/functional/gles3/texturefiltering/3d_combinations_35.html": 20.2449,
-    "deqp/functional/gles3/texturefiltering/3d_formats_00.html": 11.9227,
-    "deqp/functional/gles3/texturefiltering/3d_formats_01.html": 12.5257,
-    "deqp/functional/gles3/texturefiltering/3d_formats_02.html": 10.3233,
-    "deqp/functional/gles3/texturefiltering/3d_formats_03.html": 9.9843,
-    "deqp/functional/gles3/texturefiltering/3d_formats_04.html": 10.8728,
-    "deqp/functional/gles3/texturefiltering/3d_formats_05.html": 9.7742,
-    "deqp/functional/gles3/texturefiltering/3d_formats_06.html": 10.4808,
-    "deqp/functional/gles3/texturefiltering/3d_formats_07.html": 9.5904,
-    "deqp/functional/gles3/texturefiltering/3d_formats_08.html": 11.31,
-    "deqp/functional/gles3/texturefiltering/3d_formats_09.html": 9.2947,
-    "deqp/functional/gles3/texturefiltering/3d_sizes_00.html": 10.6551,
-    "deqp/functional/gles3/texturefiltering/3d_sizes_01.html": 9.9074,
-    "deqp/functional/gles3/texturefiltering/3d_sizes_02.html": 11.4131,
-    "deqp/functional/gles3/texturefiltering/3d_sizes_03.html": 8.9871,
-    "deqp/functional/gles3/texturefiltering/3d_sizes_04.html": 10.5536,
-    "deqp/functional/gles3/texturefiltering/cube_combinations_00.html": 12.052,
-    "deqp/functional/gles3/texturefiltering/cube_combinations_01.html": 13.4696,
-    "deqp/functional/gles3/texturefiltering/cube_combinations_02.html": 20.7644,
-    "deqp/functional/gles3/texturefiltering/cube_combinations_03.html": 18.4919,
-    "deqp/functional/gles3/texturefiltering/cube_combinations_04.html": 23.6347,
-    "deqp/functional/gles3/texturefiltering/cube_combinations_05.html": 30.9313,
-    "deqp/functional/gles3/texturefiltering/cube_formats_00.html": 12.2339,
-    "deqp/functional/gles3/texturefiltering/cube_formats_01.html": 11.2254,
-    "deqp/functional/gles3/texturefiltering/cube_formats_02.html": 10.8152,
-    "deqp/functional/gles3/texturefiltering/cube_formats_03.html": 10.5788,
-    "deqp/functional/gles3/texturefiltering/cube_formats_04.html": 10.9015,
-    "deqp/functional/gles3/texturefiltering/cube_formats_05.html": 10.408,
-    "deqp/functional/gles3/texturefiltering/cube_formats_06.html": 10.4827,
-    "deqp/functional/gles3/texturefiltering/cube_formats_07.html": 10.1756,
-    "deqp/functional/gles3/texturefiltering/cube_formats_08.html": 10.8552,
-    "deqp/functional/gles3/texturefiltering/cube_formats_09.html": 10.5421,
-    "deqp/functional/gles3/texturefiltering/cube_no_edges_visible.html": 5.3194,
-    "deqp/functional/gles3/texturefiltering/cube_sizes_00.html": 6.1976,
-    "deqp/functional/gles3/texturefiltering/cube_sizes_01.html": 10.9043,
-    "deqp/functional/gles3/texturefiltering/cube_sizes_02.html": 11.6362,
-    "deqp/functional/gles3/texturefiltering/cube_sizes_03.html": 6.3725,
-    "deqp/functional/gles3/texturefiltering/cube_sizes_04.html": 10.4368,
-    "deqp/functional/gles3/textureformat/compressed_2d.html": 0.263,
-    "deqp/functional/gles3/textureformat/compressed_cube.html": 0.4675,
-    "deqp/functional/gles3/textureformat/sized_color_2d_array_npot_00.html": 7.4033,
-    "deqp/functional/gles3/textureformat/sized_color_2d_array_npot_01.html": 6.7226,
-    "deqp/functional/gles3/textureformat/sized_color_2d_array_npot_02.html": 7.0192,
-    "deqp/functional/gles3/textureformat/sized_color_2d_array_npot_03.html": 7.7302,
-    "deqp/functional/gles3/textureformat/sized_color_2d_array_pot_00.html": 7.7763,
-    "deqp/functional/gles3/textureformat/sized_color_2d_array_pot_01.html": 7.3367,
-    "deqp/functional/gles3/textureformat/sized_color_2d_array_pot_02.html": 7.5613,
-    "deqp/functional/gles3/textureformat/sized_color_2d_array_pot_03.html": 8.3642,
-    "deqp/functional/gles3/textureformat/sized_color_2d_npot_00.html": 3.7313,
-    "deqp/functional/gles3/textureformat/sized_color_2d_npot_01.html": 4.1135,
-    "deqp/functional/gles3/textureformat/sized_color_2d_npot_02.html": 4.2343,
-    "deqp/functional/gles3/textureformat/sized_color_2d_npot_03.html": 4.2649,
-    "deqp/functional/gles3/textureformat/sized_color_2d_pot_00.html": 4.6188,
-    "deqp/functional/gles3/textureformat/sized_color_2d_pot_01.html": 4.8445,
-    "deqp/functional/gles3/textureformat/sized_color_2d_pot_02.html": 4.6368,
-    "deqp/functional/gles3/textureformat/sized_color_2d_pot_03.html": 4.9105,
-    "deqp/functional/gles3/textureformat/sized_color_3d_npot_00.html": 5.5398,
-    "deqp/functional/gles3/textureformat/sized_color_3d_npot_01.html": 5.2716,
-    "deqp/functional/gles3/textureformat/sized_color_3d_npot_02.html": 4.8285,
-    "deqp/functional/gles3/textureformat/sized_color_3d_npot_03.html": 5.2624,
-    "deqp/functional/gles3/textureformat/sized_color_3d_pot_00.html": 9.0812,
-    "deqp/functional/gles3/textureformat/sized_color_3d_pot_01.html": 8.8925,
-    "deqp/functional/gles3/textureformat/sized_color_3d_pot_02.html": 8.1466,
-    "deqp/functional/gles3/textureformat/sized_color_3d_pot_03.html": 8.5246,
-    "deqp/functional/gles3/textureformat/sized_color_cube_npot_00.html": 7.7328,
-    "deqp/functional/gles3/textureformat/sized_color_cube_npot_01.html": 7.3356,
-    "deqp/functional/gles3/textureformat/sized_color_cube_npot_02.html": 7.0816,
-    "deqp/functional/gles3/textureformat/sized_color_cube_npot_03.html": 7.0071,
-    "deqp/functional/gles3/textureformat/sized_color_cube_pot_00.html": 8.2952,
-    "deqp/functional/gles3/textureformat/sized_color_cube_pot_01.html": 8.3526,
-    "deqp/functional/gles3/textureformat/sized_color_cube_pot_02.html": 7.089,
-    "deqp/functional/gles3/textureformat/sized_color_cube_pot_03.html": 8.6374,
-    "deqp/functional/gles3/textureformat/sized_depth_stencil.html": 7.8124,
-    "deqp/functional/gles3/textureformat/unsized_2d.html": 8.9751,
-    "deqp/functional/gles3/textureformat/unsized_2d_array.html": 8.2076,
-    "deqp/functional/gles3/textureformat/unsized_3d.html": 8.349,
-    "deqp/functional/gles3/textureshadow/2d_array_linear_always.html": 3.6616,
-    "deqp/functional/gles3/textureshadow/2d_array_linear_equal.html": 6.9527,
-    "deqp/functional/gles3/textureshadow/2d_array_linear_greater.html": 6.3486,
-    "deqp/functional/gles3/textureshadow/2d_array_linear_greater_or_equal.html": 6.3701,
-    "deqp/functional/gles3/textureshadow/2d_array_linear_less.html": 6.5172,
-    "deqp/functional/gles3/textureshadow/2d_array_linear_less_or_equal.html": 6.2626,
-    "deqp/functional/gles3/textureshadow/2d_array_linear_mipmap_linear_always.html": 3.8505,
-    "deqp/functional/gles3/textureshadow/2d_array_linear_mipmap_linear_equal.html": 6.8691,
-    "deqp/functional/gles3/textureshadow/2d_array_linear_mipmap_linear_greater.html": 8.34,
-    "deqp/functional/gles3/textureshadow/2d_array_linear_mipmap_linear_greater_or_equal.html": 8.1483,
-    "deqp/functional/gles3/textureshadow/2d_array_linear_mipmap_linear_less.html": 8.5191,
-    "deqp/functional/gles3/textureshadow/2d_array_linear_mipmap_linear_less_or_equal.html": 8.1166,
-    "deqp/functional/gles3/textureshadow/2d_array_linear_mipmap_linear_never.html": 3.7036,
-    "deqp/functional/gles3/textureshadow/2d_array_linear_mipmap_linear_not_equal.html": 7.0663,
-    "deqp/functional/gles3/textureshadow/2d_array_linear_mipmap_nearest_always.html": 3.9573,
-    "deqp/functional/gles3/textureshadow/2d_array_linear_mipmap_nearest_equal.html": 6.3256,
-    "deqp/functional/gles3/textureshadow/2d_array_linear_mipmap_nearest_greater.html": 7.0079,
-    "deqp/functional/gles3/textureshadow/2d_array_linear_mipmap_nearest_greater_or_equal.html": 6.3525,
-    "deqp/functional/gles3/textureshadow/2d_array_linear_mipmap_nearest_less.html": 5.9967,
-    "deqp/functional/gles3/textureshadow/2d_array_linear_mipmap_nearest_less_or_equal.html": 6.7216,
-    "deqp/functional/gles3/textureshadow/2d_array_linear_mipmap_nearest_never.html": 3.9428,
-    "deqp/functional/gles3/textureshadow/2d_array_linear_mipmap_nearest_not_equal.html": 5.9375,
-    "deqp/functional/gles3/textureshadow/2d_array_linear_never.html": 3.6617,
-    "deqp/functional/gles3/textureshadow/2d_array_linear_not_equal.html": 6.5504,
-    "deqp/functional/gles3/textureshadow/2d_array_nearest_always.html": 3.8491,
-    "deqp/functional/gles3/textureshadow/2d_array_nearest_equal.html": 3.6602,
-    "deqp/functional/gles3/textureshadow/2d_array_nearest_greater.html": 3.9067,
-    "deqp/functional/gles3/textureshadow/2d_array_nearest_greater_or_equal.html": 3.7432,
-    "deqp/functional/gles3/textureshadow/2d_array_nearest_less.html": 3.8737,
-    "deqp/functional/gles3/textureshadow/2d_array_nearest_less_or_equal.html": 3.8987,
-    "deqp/functional/gles3/textureshadow/2d_array_nearest_mipmap_linear_always.html": 3.9938,
-    "deqp/functional/gles3/textureshadow/2d_array_nearest_mipmap_linear_equal.html": 5.9163,
-    "deqp/functional/gles3/textureshadow/2d_array_nearest_mipmap_linear_greater.html": 5.7403,
-    "deqp/functional/gles3/textureshadow/2d_array_nearest_mipmap_linear_greater_or_equal.html": 5.4443,
-    "deqp/functional/gles3/textureshadow/2d_array_nearest_mipmap_linear_less.html": 5.378,
-    "deqp/functional/gles3/textureshadow/2d_array_nearest_mipmap_linear_less_or_equal.html": 5.6533,
-    "deqp/functional/gles3/textureshadow/2d_array_nearest_mipmap_linear_never.html": 3.5766,
-    "deqp/functional/gles3/textureshadow/2d_array_nearest_mipmap_linear_not_equal.html": 5.5057,
-    "deqp/functional/gles3/textureshadow/2d_array_nearest_mipmap_nearest_always.html": 4.0326,
-    "deqp/functional/gles3/textureshadow/2d_array_nearest_mipmap_nearest_equal.html": 5.8656,
-    "deqp/functional/gles3/textureshadow/2d_array_nearest_mipmap_nearest_greater.html": 6.0277,
-    "deqp/functional/gles3/textureshadow/2d_array_nearest_mipmap_nearest_greater_or_equal.html": 5.4573,
-    "deqp/functional/gles3/textureshadow/2d_array_nearest_mipmap_nearest_less.html": 5.6472,
-    "deqp/functional/gles3/textureshadow/2d_array_nearest_mipmap_nearest_less_or_equal.html": 5.9061,
-    "deqp/functional/gles3/textureshadow/2d_array_nearest_mipmap_nearest_never.html": 3.6901,
-    "deqp/functional/gles3/textureshadow/2d_array_nearest_mipmap_nearest_not_equal.html": 5.6573,
-    "deqp/functional/gles3/textureshadow/2d_array_nearest_never.html": 4.1853,
-    "deqp/functional/gles3/textureshadow/2d_array_nearest_not_equal.html": 3.9428,
-    "deqp/functional/gles3/textureshadow/2d_linear_always.html": 3.2569,
-    "deqp/functional/gles3/textureshadow/2d_linear_equal.html": 5.8481,
-    "deqp/functional/gles3/textureshadow/2d_linear_greater.html": 5.4111,
-    "deqp/functional/gles3/textureshadow/2d_linear_greater_or_equal.html": 5.549,
-    "deqp/functional/gles3/textureshadow/2d_linear_less.html": 5.6216,
-    "deqp/functional/gles3/textureshadow/2d_linear_less_or_equal.html": 5.765,
-    "deqp/functional/gles3/textureshadow/2d_linear_mipmap_linear_always.html": 3.5478,
-    "deqp/functional/gles3/textureshadow/2d_linear_mipmap_linear_equal.html": 7.7554,
-    "deqp/functional/gles3/textureshadow/2d_linear_mipmap_linear_greater.html": 7.2493,
-    "deqp/functional/gles3/textureshadow/2d_linear_mipmap_linear_greater_or_equal.html": 7.9919,
-    "deqp/functional/gles3/textureshadow/2d_linear_mipmap_linear_less.html": 8.2383,
-    "deqp/functional/gles3/textureshadow/2d_linear_mipmap_linear_less_or_equal.html": 7.3297,
-    "deqp/functional/gles3/textureshadow/2d_linear_mipmap_linear_never.html": 3.3783,
-    "deqp/functional/gles3/textureshadow/2d_linear_mipmap_linear_not_equal.html": 7.9479,
-    "deqp/functional/gles3/textureshadow/2d_linear_mipmap_nearest_always.html": 3.7798,
-    "deqp/functional/gles3/textureshadow/2d_linear_mipmap_nearest_equal.html": 6.0335,
-    "deqp/functional/gles3/textureshadow/2d_linear_mipmap_nearest_greater.html": 6.3982,
-    "deqp/functional/gles3/textureshadow/2d_linear_mipmap_nearest_greater_or_equal.html": 5.8141,
-    "deqp/functional/gles3/textureshadow/2d_linear_mipmap_nearest_less.html": 5.6288,
-    "deqp/functional/gles3/textureshadow/2d_linear_mipmap_nearest_less_or_equal.html": 5.8832,
-    "deqp/functional/gles3/textureshadow/2d_linear_mipmap_nearest_never.html": 3.4992,
-    "deqp/functional/gles3/textureshadow/2d_linear_mipmap_nearest_not_equal.html": 5.9241,
-    "deqp/functional/gles3/textureshadow/2d_linear_never.html": 3.5081,
-    "deqp/functional/gles3/textureshadow/2d_linear_not_equal.html": 6.0524,
-    "deqp/functional/gles3/textureshadow/2d_nearest_always.html": 3.2877,
-    "deqp/functional/gles3/textureshadow/2d_nearest_equal.html": 3.467,
-    "deqp/functional/gles3/textureshadow/2d_nearest_greater.html": 3.5353,
-    "deqp/functional/gles3/textureshadow/2d_nearest_greater_or_equal.html": 3.5748,
-    "deqp/functional/gles3/textureshadow/2d_nearest_less.html": 3.3902,
-    "deqp/functional/gles3/textureshadow/2d_nearest_less_or_equal.html": 3.4932,
-    "deqp/functional/gles3/textureshadow/2d_nearest_mipmap_linear_always.html": 3.4163,
-    "deqp/functional/gles3/textureshadow/2d_nearest_mipmap_linear_equal.html": 6.7517,
-    "deqp/functional/gles3/textureshadow/2d_nearest_mipmap_linear_greater.html": 5.036,
-    "deqp/functional/gles3/textureshadow/2d_nearest_mipmap_linear_greater_or_equal.html": 5.9398,
-    "deqp/functional/gles3/textureshadow/2d_nearest_mipmap_linear_less.html": 5.9224,
-    "deqp/functional/gles3/textureshadow/2d_nearest_mipmap_linear_less_or_equal.html": 5.0764,
-    "deqp/functional/gles3/textureshadow/2d_nearest_mipmap_linear_never.html": 3.424,
-    "deqp/functional/gles3/textureshadow/2d_nearest_mipmap_linear_not_equal.html": 6.9957,
-    "deqp/functional/gles3/textureshadow/2d_nearest_mipmap_nearest_always.html": 3.6452,
-    "deqp/functional/gles3/textureshadow/2d_nearest_mipmap_nearest_equal.html": 5.7118,
-    "deqp/functional/gles3/textureshadow/2d_nearest_mipmap_nearest_greater.html": 5.3102,
-    "deqp/functional/gles3/textureshadow/2d_nearest_mipmap_nearest_greater_or_equal.html": 4.9531,
-    "deqp/functional/gles3/textureshadow/2d_nearest_mipmap_nearest_less.html": 5.1364,
-    "deqp/functional/gles3/textureshadow/2d_nearest_mipmap_nearest_less_or_equal.html": 5.3696,
-    "deqp/functional/gles3/textureshadow/2d_nearest_mipmap_nearest_never.html": 3.5012,
-    "deqp/functional/gles3/textureshadow/2d_nearest_mipmap_nearest_not_equal.html": 5.0793,
-    "deqp/functional/gles3/textureshadow/2d_nearest_never.html": 3.505,
-    "deqp/functional/gles3/textureshadow/2d_nearest_not_equal.html": 3.5801,
-    "deqp/functional/gles3/textureshadow/cube_linear_always.html": 6.0837,
-    "deqp/functional/gles3/textureshadow/cube_linear_equal.html": 9.0531,
-    "deqp/functional/gles3/textureshadow/cube_linear_greater.html": 7.9959,
-    "deqp/functional/gles3/textureshadow/cube_linear_greater_or_equal.html": 8.9346,
-    "deqp/functional/gles3/textureshadow/cube_linear_less.html": 9.0037,
-    "deqp/functional/gles3/textureshadow/cube_linear_less_or_equal.html": 8.5905,
-    "deqp/functional/gles3/textureshadow/cube_linear_mipmap_linear_always.html": 6.3285,
-    "deqp/functional/gles3/textureshadow/cube_linear_mipmap_linear_equal.html": 12.019,
-    "deqp/functional/gles3/textureshadow/cube_linear_mipmap_linear_greater.html": 11.0812,
-    "deqp/functional/gles3/textureshadow/cube_linear_mipmap_linear_greater_or_equal.html": 11.3749,
-    "deqp/functional/gles3/textureshadow/cube_linear_mipmap_linear_less.html": 11.2672,
-    "deqp/functional/gles3/textureshadow/cube_linear_mipmap_linear_less_or_equal.html": 11.1786,
-    "deqp/functional/gles3/textureshadow/cube_linear_mipmap_linear_never.html": 6.0759,
-    "deqp/functional/gles3/textureshadow/cube_linear_mipmap_linear_not_equal.html": 11.7461,
-    "deqp/functional/gles3/textureshadow/cube_linear_mipmap_nearest_always.html": 5.9016,
-    "deqp/functional/gles3/textureshadow/cube_linear_mipmap_nearest_equal.html": 8.8732,
-    "deqp/functional/gles3/textureshadow/cube_linear_mipmap_nearest_greater.html": 8.6498,
-    "deqp/functional/gles3/textureshadow/cube_linear_mipmap_nearest_greater_or_equal.html": 9.6442,
-    "deqp/functional/gles3/textureshadow/cube_linear_mipmap_nearest_less.html": 9.4173,
-    "deqp/functional/gles3/textureshadow/cube_linear_mipmap_nearest_less_or_equal.html": 8.7536,
-    "deqp/functional/gles3/textureshadow/cube_linear_mipmap_nearest_never.html": 6.16,
-    "deqp/functional/gles3/textureshadow/cube_linear_mipmap_nearest_not_equal.html": 8.9735,
-    "deqp/functional/gles3/textureshadow/cube_linear_never.html": 6.2774,
-    "deqp/functional/gles3/textureshadow/cube_linear_not_equal.html": 9.0813,
-    "deqp/functional/gles3/textureshadow/cube_nearest_always.html": 6.3809,
-    "deqp/functional/gles3/textureshadow/cube_nearest_equal.html": 6.7126,
-    "deqp/functional/gles3/textureshadow/cube_nearest_greater.html": 6.3345,
-    "deqp/functional/gles3/textureshadow/cube_nearest_greater_or_equal.html": 7.0126,
-    "deqp/functional/gles3/textureshadow/cube_nearest_less.html": 7.3983,
-    "deqp/functional/gles3/textureshadow/cube_nearest_less_or_equal.html": 6.8851,
-    "deqp/functional/gles3/textureshadow/cube_nearest_mipmap_linear_always.html": 7.0638,
-    "deqp/functional/gles3/textureshadow/cube_nearest_mipmap_linear_equal.html": 11.7497,
-    "deqp/functional/gles3/textureshadow/cube_nearest_mipmap_linear_greater.html": 10.1966,
-    "deqp/functional/gles3/textureshadow/cube_nearest_mipmap_linear_greater_or_equal.html": 11.4066,
-    "deqp/functional/gles3/textureshadow/cube_nearest_mipmap_linear_less.html": 10.6583,
-    "deqp/functional/gles3/textureshadow/cube_nearest_mipmap_linear_less_or_equal.html": 10.2248,
-    "deqp/functional/gles3/textureshadow/cube_nearest_mipmap_linear_never.html": 7.6774,
-    "deqp/functional/gles3/textureshadow/cube_nearest_mipmap_linear_not_equal.html": 11.7511,
-    "deqp/functional/gles3/textureshadow/cube_nearest_mipmap_nearest_always.html": 6.7204,
-    "deqp/functional/gles3/textureshadow/cube_nearest_mipmap_nearest_equal.html": 9.4859,
-    "deqp/functional/gles3/textureshadow/cube_nearest_mipmap_nearest_greater.html": 8.7226,
-    "deqp/functional/gles3/textureshadow/cube_nearest_mipmap_nearest_greater_or_equal.html": 9.1155,
-    "deqp/functional/gles3/textureshadow/cube_nearest_mipmap_nearest_less.html": 8.6817,
-    "deqp/functional/gles3/textureshadow/cube_nearest_mipmap_nearest_less_or_equal.html": 9.0143,
-    "deqp/functional/gles3/textureshadow/cube_nearest_mipmap_nearest_never.html": 6.7792,
-    "deqp/functional/gles3/textureshadow/cube_nearest_mipmap_nearest_not_equal.html": 8.7925,
-    "deqp/functional/gles3/textureshadow/cube_nearest_never.html": 6.607,
-    "deqp/functional/gles3/textureshadow/cube_nearest_not_equal.html": 7.3469,
-    "deqp/functional/gles3/texturespecification/basic_copyteximage2d.html": 23.6959,
-    "deqp/functional/gles3/texturespecification/basic_copytexsubimage2d.html": 27.6927,
-    "deqp/functional/gles3/texturespecification/basic_teximage2d_2d_00.html": 10.968,
-    "deqp/functional/gles3/texturespecification/basic_teximage2d_2d_01.html": 11.5943,
-    "deqp/functional/gles3/texturespecification/basic_teximage2d_cube_00.html": 18.1346,
-    "deqp/functional/gles3/texturespecification/basic_teximage2d_cube_01.html": 18.9737,
-    "deqp/functional/gles3/texturespecification/basic_teximage2d_cube_02.html": 18.1651,
-    "deqp/functional/gles3/texturespecification/basic_teximage2d_cube_03.html": 18.0981,
-    "deqp/functional/gles3/texturespecification/basic_teximage2d_cube_04.html": 16.5845,
-    "deqp/functional/gles3/texturespecification/basic_teximage3d_2d_array_00.html": 11.9715,
-    "deqp/functional/gles3/texturespecification/basic_teximage3d_2d_array_01.html": 9.9251,
-    "deqp/functional/gles3/texturespecification/basic_teximage3d_2d_array_02.html": 8.9965,
-    "deqp/functional/gles3/texturespecification/basic_teximage3d_3d_00.html": 8.0289,
-    "deqp/functional/gles3/texturespecification/basic_teximage3d_3d_01.html": 8.4538,
-    "deqp/functional/gles3/texturespecification/basic_teximage3d_3d_02.html": 7.8327,
-    "deqp/functional/gles3/texturespecification/basic_teximage3d_3d_03.html": 7.4702,
-    "deqp/functional/gles3/texturespecification/basic_teximage3d_3d_04.html": 6.8062,
-    "deqp/functional/gles3/texturespecification/basic_texsubimage2d_2d_00.html": 12.6637,
-    "deqp/functional/gles3/texturespecification/basic_texsubimage2d_2d_01.html": 10.0255,
-    "deqp/functional/gles3/texturespecification/basic_texsubimage2d_2d_02.html": 9.5875,
-    "deqp/functional/gles3/texturespecification/basic_texsubimage2d_cube_00.html": 18.7329,
-    "deqp/functional/gles3/texturespecification/basic_texsubimage2d_cube_01.html": 18.2992,
-    "deqp/functional/gles3/texturespecification/basic_texsubimage2d_cube_02.html": 19.6675,
-    "deqp/functional/gles3/texturespecification/basic_texsubimage2d_cube_03.html": 18.0736,
-    "deqp/functional/gles3/texturespecification/basic_texsubimage2d_cube_04.html": 17.4456,
-    "deqp/functional/gles3/texturespecification/basic_texsubimage3d_00.html": 9.6385,
-    "deqp/functional/gles3/texturespecification/basic_texsubimage3d_01.html": 9.0589,
-    "deqp/functional/gles3/texturespecification/basic_texsubimage3d_02.html": 9.1824,
-    "deqp/functional/gles3/texturespecification/basic_texsubimage3d_03.html": 8.8887,
-    "deqp/functional/gles3/texturespecification/basic_texsubimage3d_04.html": 8.3982,
-    "deqp/functional/gles3/texturespecification/random_teximage2d_2d.html": 8.5195,
-    "deqp/functional/gles3/texturespecification/random_teximage2d_cube.html": 23.7382,
-    "deqp/functional/gles3/texturespecification/teximage2d_align.html": 22.1716,
-    "deqp/functional/gles3/texturespecification/teximage2d_depth.html": 4.5176,
-    "deqp/functional/gles3/texturespecification/teximage2d_depth_pbo.html": 6.0367,
-    "deqp/functional/gles3/texturespecification/teximage2d_pbo_2d_00.html": 7.0703,
-    "deqp/functional/gles3/texturespecification/teximage2d_pbo_2d_01.html": 7.0003,
-    "deqp/functional/gles3/texturespecification/teximage2d_pbo_cube_00.html": 13.8986,
-    "deqp/functional/gles3/texturespecification/teximage2d_pbo_cube_01.html": 14.8779,
-    "deqp/functional/gles3/texturespecification/teximage2d_pbo_cube_02.html": 14.2376,
-    "deqp/functional/gles3/texturespecification/teximage2d_pbo_cube_03.html": 13.3954,
-    "deqp/functional/gles3/texturespecification/teximage2d_pbo_cube_04.html": 12.1325,
-    "deqp/functional/gles3/texturespecification/teximage2d_pbo_params.html": 4.5128,
-    "deqp/functional/gles3/texturespecification/teximage2d_unpack_params.html": 4.4955,
-    "deqp/functional/gles3/texturespecification/teximage3d_depth.html": 5.1318,
-    "deqp/functional/gles3/texturespecification/teximage3d_depth_pbo.html": 4.4973,
-    "deqp/functional/gles3/texturespecification/teximage3d_pbo_2d_array_00.html": 6.7067,
-    "deqp/functional/gles3/texturespecification/teximage3d_pbo_2d_array_01.html": 6.9087,
-    "deqp/functional/gles3/texturespecification/teximage3d_pbo_3d_00.html": 6.3123,
-    "deqp/functional/gles3/texturespecification/teximage3d_pbo_3d_01.html": 6.8592,
-    "deqp/functional/gles3/texturespecification/teximage3d_pbo_params.html": 3.8794,
-    "deqp/functional/gles3/texturespecification/teximage3d_unpack_params.html": 4.4343,
-    "deqp/functional/gles3/texturespecification/texstorage2d_format_2d_00.html": 11.7628,
-    "deqp/functional/gles3/texturespecification/texstorage2d_format_2d_01.html": 9.6308,
-    "deqp/functional/gles3/texturespecification/texstorage2d_format_2d_02.html": 9.3176,
-    "deqp/functional/gles3/texturespecification/texstorage2d_format_cube_00.html": 15.1389,
-    "deqp/functional/gles3/texturespecification/texstorage2d_format_cube_01.html": 15.4439,
-    "deqp/functional/gles3/texturespecification/texstorage2d_format_cube_02.html": 15.1531,
-    "deqp/functional/gles3/texturespecification/texstorage2d_format_cube_03.html": 15.4984,
-    "deqp/functional/gles3/texturespecification/texstorage2d_format_cube_04.html": 14.5734,
-    "deqp/functional/gles3/texturespecification/texstorage2d_format_depth_stencil.html": 13.1436,
-    "deqp/functional/gles3/texturespecification/texstorage2d_format_size.html": 10.739,
-    "deqp/functional/gles3/texturespecification/texstorage3d_format_2d_array_00.html": 8.8392,
-    "deqp/functional/gles3/texturespecification/texstorage3d_format_2d_array_01.html": 6.8917,
-    "deqp/functional/gles3/texturespecification/texstorage3d_format_2d_array_02.html": 6.9894,
-    "deqp/functional/gles3/texturespecification/texstorage3d_format_3d_00.html": 10.7551,
-    "deqp/functional/gles3/texturespecification/texstorage3d_format_3d_01.html": 10.3939,
-    "deqp/functional/gles3/texturespecification/texstorage3d_format_3d_02.html": 9.5833,
-    "deqp/functional/gles3/texturespecification/texstorage3d_format_3d_03.html": 10.1304,
-    "deqp/functional/gles3/texturespecification/texstorage3d_format_depth_stencil.html": 3.4928,
-    "deqp/functional/gles3/texturespecification/texstorage3d_format_size.html": 6.0413,
-    "deqp/functional/gles3/texturespecification/texsubimage2d_align.html": 30.659,
-    "deqp/functional/gles3/texturespecification/texsubimage2d_depth.html": 4.1328,
-    "deqp/functional/gles3/texturespecification/texsubimage2d_empty_tex.html": 10.0029,
-    "deqp/functional/gles3/texturespecification/texsubimage2d_pbo_2d_00.html": 8.5048,
-    "deqp/functional/gles3/texturespecification/texsubimage2d_pbo_2d_01.html": 8.5244,
-    "deqp/functional/gles3/texturespecification/texsubimage2d_pbo_cube_00.html": 14.4371,
-    "deqp/functional/gles3/texturespecification/texsubimage2d_pbo_cube_01.html": 15.4871,
-    "deqp/functional/gles3/texturespecification/texsubimage2d_pbo_cube_02.html": 14.5579,
-    "deqp/functional/gles3/texturespecification/texsubimage2d_pbo_cube_03.html": 14.1502,
-    "deqp/functional/gles3/texturespecification/texsubimage2d_pbo_cube_04.html": 13.6171,
-    "deqp/functional/gles3/texturespecification/texsubimage2d_pbo_params.html": 8.8333,
-    "deqp/functional/gles3/texturespecification/texsubimage2d_unpack_params.html": 5.2723,
-    "deqp/functional/gles3/texturespecification/texsubimage3d_depth.html": 6.0821,
-    "deqp/functional/gles3/texturespecification/texsubimage3d_pbo_2d_array_00.html": 8.949,
-    "deqp/functional/gles3/texturespecification/texsubimage3d_pbo_2d_array_01.html": 9.7701,
-    "deqp/functional/gles3/texturespecification/texsubimage3d_pbo_3d_00.html": 10.3844,
-    "deqp/functional/gles3/texturespecification/texsubimage3d_pbo_3d_01.html": 10.9455,
-    "deqp/functional/gles3/texturespecification/texsubimage3d_pbo_params.html": 3.958,
-    "deqp/functional/gles3/texturespecification/texsubimage3d_unpack_params.html": 5.2929,
-    "deqp/functional/gles3/texturestatequery.html": 1.9613,
-    "deqp/functional/gles3/texturewrap/eac_r11_npot.html": 0.4875,
-    "deqp/functional/gles3/texturewrap/eac_r11_pot.html": 0.2811,
-    "deqp/functional/gles3/texturewrap/eac_rg11_npot.html": 0.3292,
-    "deqp/functional/gles3/texturewrap/eac_rg11_pot.html": 0.2644,
-    "deqp/functional/gles3/texturewrap/eac_signed_r11_npot.html": 0.5027,
-    "deqp/functional/gles3/texturewrap/eac_signed_r11_pot.html": 0.2739,
-    "deqp/functional/gles3/texturewrap/eac_signed_rg11_npot.html": 0.286,
-    "deqp/functional/gles3/texturewrap/eac_signed_rg11_pot.html": 0.298,
-    "deqp/functional/gles3/texturewrap/etc2_eac_rgba8_npot.html": 0.3261,
-    "deqp/functional/gles3/texturewrap/etc2_eac_rgba8_pot.html": 0.2719,
-    "deqp/functional/gles3/texturewrap/etc2_eac_srgb8_alpha8_npot.html": 0.4094,
-    "deqp/functional/gles3/texturewrap/etc2_eac_srgb8_alpha8_pot.html": 0.2541,
-    "deqp/functional/gles3/texturewrap/etc2_rgb8_npot.html": 0.5336,
-    "deqp/functional/gles3/texturewrap/etc2_rgb8_pot.html": 0.2441,
-    "deqp/functional/gles3/texturewrap/etc2_rgb8_punchthrough_alpha1_npot.html": 0.2863,
-    "deqp/functional/gles3/texturewrap/etc2_rgb8_punchthrough_alpha1_pot.html": 0.3221,
-    "deqp/functional/gles3/texturewrap/etc2_srgb8_npot.html": 0.2913,
-    "deqp/functional/gles3/texturewrap/etc2_srgb8_pot.html": 0.5506,
-    "deqp/functional/gles3/texturewrap/etc2_srgb8_punchthrough_alpha1_npot.html": 0.2461,
-    "deqp/functional/gles3/texturewrap/etc2_srgb8_punchthrough_alpha1_pot.html": 0.3147,
-    "deqp/functional/gles3/texturewrap/rgba8_npot.html": 9.0674,
-    "deqp/functional/gles3/texturewrap/rgba8_pot.html": 9.2815,
-    "deqp/functional/gles3/transformfeedback/array_element_interleaved_lines.html": 2.7585,
-    "deqp/functional/gles3/transformfeedback/array_element_interleaved_points.html": 2.703,
-    "deqp/functional/gles3/transformfeedback/array_element_interleaved_triangles.html": 2.7147,
-    "deqp/functional/gles3/transformfeedback/array_element_separate_lines.html": 2.527,
-    "deqp/functional/gles3/transformfeedback/array_element_separate_points.html": 2.9079,
-    "deqp/functional/gles3/transformfeedback/array_element_separate_triangles.html": 2.7916,
-    "deqp/functional/gles3/transformfeedback/array_interleaved_lines.html": 2.2577,
-    "deqp/functional/gles3/transformfeedback/array_interleaved_points.html": 2.6116,
-    "deqp/functional/gles3/transformfeedback/array_interleaved_triangles.html": 2.7204,
-    "deqp/functional/gles3/transformfeedback/array_separate_lines.html": 2.3911,
-    "deqp/functional/gles3/transformfeedback/array_separate_points.html": 2.4056,
-    "deqp/functional/gles3/transformfeedback/array_separate_triangles.html": 2.4052,
-    "deqp/functional/gles3/transformfeedback/basic_types_interleaved_lines.html": 32.6476,
-    "deqp/functional/gles3/transformfeedback/basic_types_interleaved_points.html": 36.3894,
-    "deqp/functional/gles3/transformfeedback/basic_types_interleaved_triangles.html": 35.329,
-    "deqp/functional/gles3/transformfeedback/basic_types_separate_lines.html": 22.6206,
-    "deqp/functional/gles3/transformfeedback/basic_types_separate_points.html": 21.6512,
-    "deqp/functional/gles3/transformfeedback/basic_types_separate_triangles.html": 17.2972,
-    "deqp/functional/gles3/transformfeedback/interpolation_centroid.html": 10.5775,
-    "deqp/functional/gles3/transformfeedback/interpolation_flat.html": 11.0834,
-    "deqp/functional/gles3/transformfeedback/interpolation_smooth.html": 10.5096,
-    "deqp/functional/gles3/transformfeedback/point_size.html": 4.2655,
-    "deqp/functional/gles3/transformfeedback/position.html": 4.3178,
-    "deqp/functional/gles3/transformfeedback/random_interleaved_lines.html": 6.2282,
-    "deqp/functional/gles3/transformfeedback/random_interleaved_points.html": 6.4195,
-    "deqp/functional/gles3/transformfeedback/random_interleaved_triangles.html": 6.5453,
-    "deqp/functional/gles3/transformfeedback/random_separate_lines.html": 6.8673,
-    "deqp/functional/gles3/transformfeedback/random_separate_points.html": 6.2369,
-    "deqp/functional/gles3/transformfeedback/random_separate_triangles.html": 6.2288,
-    "deqp/functional/gles3/uniformapi/info_query.html": 16.8526,
-    "deqp/functional/gles3/uniformapi/random.html": 8.0805,
-    "deqp/functional/gles3/uniformapi/value_assigned.html": 41.4929,
-    "deqp/functional/gles3/uniformapi/value_initial.html": 20.6221,
-    "deqp/functional/gles3/uniformbuffers/instance_array_basic_type.html": 7.8472,
-    "deqp/functional/gles3/uniformbuffers/multi_basic_types.html": 1.4903,
-    "deqp/functional/gles3/uniformbuffers/multi_nested_struct.html": 2.0776,
-    "deqp/functional/gles3/uniformbuffers/random.html": 25.1802,
-    "deqp/functional/gles3/uniformbuffers/single_basic_array.html": 8.1519,
-    "deqp/functional/gles3/uniformbuffers/single_basic_type.html": 16.3579,
-    "deqp/functional/gles3/uniformbuffers/single_nested_struct.html": 2.4284,
-    "deqp/functional/gles3/uniformbuffers/single_nested_struct_array.html": 2.1242,
-    "deqp/functional/gles3/uniformbuffers/single_struct.html": 1.415,
-    "deqp/functional/gles3/uniformbuffers/single_struct_array.html": 3.7346,
-    "deqp/functional/gles3/vertexarrayobject.html": 2.6975,
-    "deqp/functional/gles3/vertexarrays/multiple_attributes.count.html": 16.8019,
-    "deqp/functional/gles3/vertexarrays/multiple_attributes.output.html": 66.6121,
-    "deqp/functional/gles3/vertexarrays/multiple_attributes.storage.html": 5.1929,
-    "deqp/functional/gles3/vertexarrays/multiple_attributes.stride.html": 66.4387,
-    "deqp/functional/gles3/vertexarrays/single_attribute.first.html": 51.8196,
-    "deqp/functional/gles3/vertexarrays/single_attribute.normalize.html": 40.7775,
-    "deqp/functional/gles3/vertexarrays/single_attribute.offset.html": 41.5117,
-    "deqp/functional/gles3/vertexarrays/single_attribute.output_type.byte.html": 26.9584,
-    "deqp/functional/gles3/vertexarrays/single_attribute.output_type.float.html": 19.4649,
-    "deqp/functional/gles3/vertexarrays/single_attribute.output_type.half.html": 22.657,
-    "deqp/functional/gles3/vertexarrays/single_attribute.output_type.int.html": 26.5127,
-    "deqp/functional/gles3/vertexarrays/single_attribute.output_type.int_2_10_10_10.html": 11.4605,
-    "deqp/functional/gles3/vertexarrays/single_attribute.output_type.short.html": 29.7359,
-    "deqp/functional/gles3/vertexarrays/single_attribute.output_type.unsigned_byte.html": 26.9378,
-    "deqp/functional/gles3/vertexarrays/single_attribute.output_type.unsigned_int.html": 29.5714,
-    "deqp/functional/gles3/vertexarrays/single_attribute.output_type.unsigned_int_2_10_10_10.html": 8.6912,
-    "deqp/functional/gles3/vertexarrays/single_attribute.output_type.unsigned_short.html": 28.714,
-    "deqp/functional/gles3/vertexarrays/single_attribute.stride.html": 35.682,
-    "deqp/functional/gles3/vertexarrays/single_attribute.usage.dynamic_copy.html": 19.1419,
-    "deqp/functional/gles3/vertexarrays/single_attribute.usage.dynamic_draw.html": 19.8923,
-    "deqp/functional/gles3/vertexarrays/single_attribute.usage.dynamic_read.html": 20.7081,
-    "deqp/functional/gles3/vertexarrays/single_attribute.usage.static_copy.html": 20.8676,
-    "deqp/functional/gles3/vertexarrays/single_attribute.usage.static_draw.html": 20.2987,
-    "deqp/functional/gles3/vertexarrays/single_attribute.usage.static_read.html": 21.3239,
-    "deqp/functional/gles3/vertexarrays/single_attribute.usage.stream_copy.html": 20.4969,
-    "deqp/functional/gles3/vertexarrays/single_attribute.usage.stream_draw.html": 21.7477,
-    "deqp/functional/gles3/vertexarrays/single_attribute.usage.stream_read.html": 21.2668
+    "conformance2/rendering/uniform-block-buffer-size.html": 0.4152,
+    "conformance2/rendering/vertex-id.html": 0.4436,
+    "conformance2/samplers/multi-context-sampler-test.html": 0.2857,
+    "conformance2/samplers/sampler-drawing-test.html": 0.3815,
+    "conformance2/samplers/samplers.html": 0.4774,
+    "conformance2/state/gl-enum-tests.html": 0.2563,
+    "conformance2/state/gl-get-calls.html": 0.3113,
+    "conformance2/state/gl-getstring.html": 0.2255,
+    "conformance2/state/gl-object-get-calls.html": 16.3843,
+    "conformance2/sync/sync-webgl-specific.html": 23.1643,
+    "conformance2/textures/canvas/tex-2d-r11f_g11f_b10f-rgb-float.html": 1.2813,
+    "conformance2/textures/canvas/tex-2d-r11f_g11f_b10f-rgb-half_float.html": 1.5635,
+    "conformance2/textures/canvas/tex-2d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html": 0.9323,
+    "conformance2/textures/canvas/tex-2d-r16f-red-float.html": 1.657,
+    "conformance2/textures/canvas/tex-2d-r16f-red-half_float.html": 1.452,
+    "conformance2/textures/canvas/tex-2d-r32f-red-float.html": 1.1352,
+    "conformance2/textures/canvas/tex-2d-r8-red-unsigned_byte.html": 1.6673,
+    "conformance2/textures/canvas/tex-2d-r8ui-red_integer-unsigned_byte.html": 1.9966,
+    "conformance2/textures/canvas/tex-2d-rg16f-rg-float.html": 1.4202,
+    "conformance2/textures/canvas/tex-2d-rg16f-rg-half_float.html": 1.3841,
+    "conformance2/textures/canvas/tex-2d-rg32f-rg-float.html": 1.0508,
+    "conformance2/textures/canvas/tex-2d-rg8-rg-unsigned_byte.html": 1.2845,
+    "conformance2/textures/canvas/tex-2d-rg8ui-rg_integer-unsigned_byte.html": 1.4452,
+    "conformance2/textures/canvas/tex-2d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html": 1.3854,
+    "conformance2/textures/canvas/tex-2d-rgb16f-rgb-float.html": 1.4447,
+    "conformance2/textures/canvas/tex-2d-rgb16f-rgb-half_float.html": 1.1358,
+    "conformance2/textures/canvas/tex-2d-rgb32f-rgb-float.html": 1.6026,
+    "conformance2/textures/canvas/tex-2d-rgb565-rgb-unsigned_byte.html": 1.7655,
+    "conformance2/textures/canvas/tex-2d-rgb565-rgb-unsigned_short_5_6_5.html": 1.1165,
+    "conformance2/textures/canvas/tex-2d-rgb5_a1-rgba-unsigned_byte.html": 2.1894,
+    "conformance2/textures/canvas/tex-2d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html": 1.097,
+    "conformance2/textures/canvas/tex-2d-rgb8-rgb-unsigned_byte.html": 1.4629,
+    "conformance2/textures/canvas/tex-2d-rgb8ui-rgb_integer-unsigned_byte.html": 1.7236,
+    "conformance2/textures/canvas/tex-2d-rgb9_e5-rgb-float.html": 1.5263,
+    "conformance2/textures/canvas/tex-2d-rgb9_e5-rgb-half_float.html": 1.7806,
+    "conformance2/textures/canvas/tex-2d-rgba16f-rgba-float.html": 1.5318,
+    "conformance2/textures/canvas/tex-2d-rgba16f-rgba-half_float.html": 1.4868,
+    "conformance2/textures/canvas/tex-2d-rgba32f-rgba-float.html": 1.7554,
+    "conformance2/textures/canvas/tex-2d-rgba4-rgba-unsigned_byte.html": 1.4471,
+    "conformance2/textures/canvas/tex-2d-rgba4-rgba-unsigned_short_4_4_4_4.html": 1.0097,
+    "conformance2/textures/canvas/tex-2d-rgba8-rgba-unsigned_byte.html": 1.5278,
+    "conformance2/textures/canvas/tex-2d-rgba8ui-rgba_integer-unsigned_byte.html": 1.3039,
+    "conformance2/textures/canvas/tex-2d-srgb8-rgb-unsigned_byte.html": 1.4522,
+    "conformance2/textures/canvas/tex-2d-srgb8_alpha8-rgba-unsigned_byte.html": 1.5371,
+    "conformance2/textures/canvas/tex-3d-r11f_g11f_b10f-rgb-float.html": 5.8411,
+    "conformance2/textures/canvas/tex-3d-r11f_g11f_b10f-rgb-half_float.html": 5.8969,
+    "conformance2/textures/canvas/tex-3d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html": 5.6245,
+    "conformance2/textures/canvas/tex-3d-r16f-red-float.html": 5.6296,
+    "conformance2/textures/canvas/tex-3d-r16f-red-half_float.html": 5.737,
+    "conformance2/textures/canvas/tex-3d-r32f-red-float.html": 7.3679,
+    "conformance2/textures/canvas/tex-3d-r8-red-unsigned_byte.html": 5.4286,
+    "conformance2/textures/canvas/tex-3d-r8ui-red_integer-unsigned_byte.html": 5.9279,
+    "conformance2/textures/canvas/tex-3d-rg16f-rg-float.html": 5.9073,
+    "conformance2/textures/canvas/tex-3d-rg16f-rg-half_float.html": 5.4323,
+    "conformance2/textures/canvas/tex-3d-rg32f-rg-float.html": 5.845,
+    "conformance2/textures/canvas/tex-3d-rg8-rg-unsigned_byte.html": 5.98,
+    "conformance2/textures/canvas/tex-3d-rg8ui-rg_integer-unsigned_byte.html": 5.4712,
+    "conformance2/textures/canvas/tex-3d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html": 5.4847,
+    "conformance2/textures/canvas/tex-3d-rgb16f-rgb-float.html": 5.6118,
+    "conformance2/textures/canvas/tex-3d-rgb16f-rgb-half_float.html": 6.0393,
+    "conformance2/textures/canvas/tex-3d-rgb32f-rgb-float.html": 5.8583,
+    "conformance2/textures/canvas/tex-3d-rgb565-rgb-unsigned_byte.html": 5.5456,
+    "conformance2/textures/canvas/tex-3d-rgb565-rgb-unsigned_short_5_6_5.html": 6.0045,
+    "conformance2/textures/canvas/tex-3d-rgb5_a1-rgba-unsigned_byte.html": 5.8877,
+    "conformance2/textures/canvas/tex-3d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html": 5.4563,
+    "conformance2/textures/canvas/tex-3d-rgb8-rgb-unsigned_byte.html": 6.0692,
+    "conformance2/textures/canvas/tex-3d-rgb8ui-rgb_integer-unsigned_byte.html": 5.9428,
+    "conformance2/textures/canvas/tex-3d-rgb9_e5-rgb-float.html": 5.905,
+    "conformance2/textures/canvas/tex-3d-rgb9_e5-rgb-half_float.html": 5.9819,
+    "conformance2/textures/canvas/tex-3d-rgba16f-rgba-float.html": 5.4939,
+    "conformance2/textures/canvas/tex-3d-rgba16f-rgba-half_float.html": 5.3238,
+    "conformance2/textures/canvas/tex-3d-rgba32f-rgba-float.html": 5.7412,
+    "conformance2/textures/canvas/tex-3d-rgba4-rgba-unsigned_byte.html": 5.579,
+    "conformance2/textures/canvas/tex-3d-rgba4-rgba-unsigned_short_4_4_4_4.html": 5.5909,
+    "conformance2/textures/canvas/tex-3d-rgba8-rgba-unsigned_byte.html": 5.5784,
+    "conformance2/textures/canvas/tex-3d-rgba8ui-rgba_integer-unsigned_byte.html": 5.7007,
+    "conformance2/textures/canvas/tex-3d-srgb8-rgb-unsigned_byte.html": 5.7369,
+    "conformance2/textures/canvas/tex-3d-srgb8_alpha8-rgba-unsigned_byte.html": 5.611,
+    "conformance2/textures/canvas_sub_rectangle/tex-2d-r11f_g11f_b10f-rgb-float.html": 1.5115,
+    "conformance2/textures/canvas_sub_rectangle/tex-2d-r11f_g11f_b10f-rgb-half_float.html": 1.5505,
+    "conformance2/textures/canvas_sub_rectangle/tex-2d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html": 1.0607,
+    "conformance2/textures/canvas_sub_rectangle/tex-2d-r16f-red-float.html": 2.3934,
+    "conformance2/textures/canvas_sub_rectangle/tex-2d-r16f-red-half_float.html": 1.2673,
+    "conformance2/textures/canvas_sub_rectangle/tex-2d-r32f-red-float.html": 1.1373,
+    "conformance2/textures/canvas_sub_rectangle/tex-2d-r8-red-unsigned_byte.html": 1.5795,
+    "conformance2/textures/canvas_sub_rectangle/tex-2d-r8ui-red_integer-unsigned_byte.html": 2.676,
+    "conformance2/textures/canvas_sub_rectangle/tex-2d-rg16f-rg-float.html": 1.9324,
+    "conformance2/textures/canvas_sub_rectangle/tex-2d-rg16f-rg-half_float.html": 1.8467,
+    "conformance2/textures/canvas_sub_rectangle/tex-2d-rg32f-rg-float.html": 1.5616,
+    "conformance2/textures/canvas_sub_rectangle/tex-2d-rg8-rg-unsigned_byte.html": 1.4224,
+    "conformance2/textures/canvas_sub_rectangle/tex-2d-rg8ui-rg_integer-unsigned_byte.html": 1.3379,
+    "conformance2/textures/canvas_sub_rectangle/tex-2d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html": 1.2912,
+    "conformance2/textures/canvas_sub_rectangle/tex-2d-rgb16f-rgb-float.html": 1.4586,
+    "conformance2/textures/canvas_sub_rectangle/tex-2d-rgb16f-rgb-half_float.html": 1.4236,
+    "conformance2/textures/canvas_sub_rectangle/tex-2d-rgb32f-rgb-float.html": 1.3043,
+    "conformance2/textures/canvas_sub_rectangle/tex-2d-rgb565-rgb-unsigned_byte.html": 2.101,
+    "conformance2/textures/canvas_sub_rectangle/tex-2d-rgb565-rgb-unsigned_short_5_6_5.html": 1.857,
+    "conformance2/textures/canvas_sub_rectangle/tex-2d-rgb5_a1-rgba-unsigned_byte.html": 2.2486,
+    "conformance2/textures/canvas_sub_rectangle/tex-2d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html": 2.1424,
+    "conformance2/textures/canvas_sub_rectangle/tex-2d-rgb8-rgb-unsigned_byte.html": 2.0904,
+    "conformance2/textures/canvas_sub_rectangle/tex-2d-rgb8ui-rgb_integer-unsigned_byte.html": 1.6081,
+    "conformance2/textures/canvas_sub_rectangle/tex-2d-rgb9_e5-rgb-float.html": 1.5442,
+    "conformance2/textures/canvas_sub_rectangle/tex-2d-rgb9_e5-rgb-half_float.html": 2.2974,
+    "conformance2/textures/canvas_sub_rectangle/tex-2d-rgba16f-rgba-float.html": 1.9912,
+    "conformance2/textures/canvas_sub_rectangle/tex-2d-rgba16f-rgba-half_float.html": 2.1919,
+    "conformance2/textures/canvas_sub_rectangle/tex-2d-rgba32f-rgba-float.html": 2.043,
+    "conformance2/textures/canvas_sub_rectangle/tex-2d-rgba4-rgba-unsigned_byte.html": 1.4822,
+    "conformance2/textures/canvas_sub_rectangle/tex-2d-rgba4-rgba-unsigned_short_4_4_4_4.html": 1.4564,
+    "conformance2/textures/canvas_sub_rectangle/tex-2d-rgba8-rgba-unsigned_byte.html": 1.0509,
+    "conformance2/textures/canvas_sub_rectangle/tex-2d-rgba8ui-rgba_integer-unsigned_byte.html": 1.8427,
+    "conformance2/textures/canvas_sub_rectangle/tex-2d-srgb8-rgb-unsigned_byte.html": 1.2084,
+    "conformance2/textures/canvas_sub_rectangle/tex-2d-srgb8_alpha8-rgba-unsigned_byte.html": 1.3454,
+    "conformance2/textures/canvas_sub_rectangle/tex-3d-r11f_g11f_b10f-rgb-float.html": 2.0239,
+    "conformance2/textures/canvas_sub_rectangle/tex-3d-r11f_g11f_b10f-rgb-half_float.html": 1.9917,
+    "conformance2/textures/canvas_sub_rectangle/tex-3d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html": 2.3111,
+    "conformance2/textures/canvas_sub_rectangle/tex-3d-r16f-red-float.html": 1.8697,
+    "conformance2/textures/canvas_sub_rectangle/tex-3d-r16f-red-half_float.html": 1.9271,
+    "conformance2/textures/canvas_sub_rectangle/tex-3d-r32f-red-float.html": 1.8967,
+    "conformance2/textures/canvas_sub_rectangle/tex-3d-r8-red-unsigned_byte.html": 2.0967,
+    "conformance2/textures/canvas_sub_rectangle/tex-3d-r8ui-red_integer-unsigned_byte.html": 2.3902,
+    "conformance2/textures/canvas_sub_rectangle/tex-3d-rg16f-rg-float.html": 2.4559,
+    "conformance2/textures/canvas_sub_rectangle/tex-3d-rg16f-rg-half_float.html": 1.9061,
+    "conformance2/textures/canvas_sub_rectangle/tex-3d-rg32f-rg-float.html": 2.5055,
+    "conformance2/textures/canvas_sub_rectangle/tex-3d-rg8-rg-unsigned_byte.html": 3.0251,
+    "conformance2/textures/canvas_sub_rectangle/tex-3d-rg8ui-rg_integer-unsigned_byte.html": 1.5665,
+    "conformance2/textures/canvas_sub_rectangle/tex-3d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html": 2.3068,
+    "conformance2/textures/canvas_sub_rectangle/tex-3d-rgb16f-rgb-float.html": 3.5728,
+    "conformance2/textures/canvas_sub_rectangle/tex-3d-rgb16f-rgb-half_float.html": 3.0682,
+    "conformance2/textures/canvas_sub_rectangle/tex-3d-rgb32f-rgb-float.html": 3.2446,
+    "conformance2/textures/canvas_sub_rectangle/tex-3d-rgb565-rgb-unsigned_byte.html": 1.8298,
+    "conformance2/textures/canvas_sub_rectangle/tex-3d-rgb565-rgb-unsigned_short_5_6_5.html": 1.8083,
+    "conformance2/textures/canvas_sub_rectangle/tex-3d-rgb5_a1-rgba-unsigned_byte.html": 1.9769,
+    "conformance2/textures/canvas_sub_rectangle/tex-3d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html": 1.7183,
+    "conformance2/textures/canvas_sub_rectangle/tex-3d-rgb8-rgb-unsigned_byte.html": 1.661,
+    "conformance2/textures/canvas_sub_rectangle/tex-3d-rgb8ui-rgb_integer-unsigned_byte.html": 2.1955,
+    "conformance2/textures/canvas_sub_rectangle/tex-3d-rgb9_e5-rgb-float.html": 2.4035,
+    "conformance2/textures/canvas_sub_rectangle/tex-3d-rgb9_e5-rgb-half_float.html": 2.2879,
+    "conformance2/textures/canvas_sub_rectangle/tex-3d-rgba16f-rgba-float.html": 2.6312,
+    "conformance2/textures/canvas_sub_rectangle/tex-3d-rgba16f-rgba-half_float.html": 2.9764,
+    "conformance2/textures/canvas_sub_rectangle/tex-3d-rgba32f-rgba-float.html": 2.289,
+    "conformance2/textures/canvas_sub_rectangle/tex-3d-rgba4-rgba-unsigned_byte.html": 2.1396,
+    "conformance2/textures/canvas_sub_rectangle/tex-3d-rgba4-rgba-unsigned_short_4_4_4_4.html": 2.1046,
+    "conformance2/textures/canvas_sub_rectangle/tex-3d-rgba8-rgba-unsigned_byte.html": 2.0423,
+    "conformance2/textures/canvas_sub_rectangle/tex-3d-rgba8ui-rgba_integer-unsigned_byte.html": 2.3977,
+    "conformance2/textures/canvas_sub_rectangle/tex-3d-srgb8-rgb-unsigned_byte.html": 1.934,
+    "conformance2/textures/canvas_sub_rectangle/tex-3d-srgb8_alpha8-rgba-unsigned_byte.html": 1.5079,
+    "conformance2/textures/image/tex-2d-r11f_g11f_b10f-rgb-float.html": 0.566,
+    "conformance2/textures/image/tex-2d-r11f_g11f_b10f-rgb-half_float.html": 0.6032,
+    "conformance2/textures/image/tex-2d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html": 0.4327,
+    "conformance2/textures/image/tex-2d-r16f-red-float.html": 0.553,
+    "conformance2/textures/image/tex-2d-r16f-red-half_float.html": 0.632,
+    "conformance2/textures/image/tex-2d-r32f-red-float.html": 0.5485,
+    "conformance2/textures/image/tex-2d-r8-red-unsigned_byte.html": 0.8017,
+    "conformance2/textures/image/tex-2d-r8ui-red_integer-unsigned_byte.html": 0.5089,
+    "conformance2/textures/image/tex-2d-rg16f-rg-float.html": 0.6456,
+    "conformance2/textures/image/tex-2d-rg16f-rg-half_float.html": 0.394,
+    "conformance2/textures/image/tex-2d-rg32f-rg-float.html": 0.626,
+    "conformance2/textures/image/tex-2d-rg8-rg-unsigned_byte.html": 0.5885,
+    "conformance2/textures/image/tex-2d-rg8ui-rg_integer-unsigned_byte.html": 0.7348,
+    "conformance2/textures/image/tex-2d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html": 0.6304,
+    "conformance2/textures/image/tex-2d-rgb16f-rgb-float.html": 0.5143,
+    "conformance2/textures/image/tex-2d-rgb16f-rgb-half_float.html": 0.5109,
+    "conformance2/textures/image/tex-2d-rgb32f-rgb-float.html": 0.7487,
+    "conformance2/textures/image/tex-2d-rgb565-rgb-unsigned_byte.html": 0.6263,
+    "conformance2/textures/image/tex-2d-rgb565-rgb-unsigned_short_5_6_5.html": 0.4634,
+    "conformance2/textures/image/tex-2d-rgb5_a1-rgba-unsigned_byte.html": 0.5739,
+    "conformance2/textures/image/tex-2d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html": 0.6388,
+    "conformance2/textures/image/tex-2d-rgb8-rgb-unsigned_byte.html": 0.4393,
+    "conformance2/textures/image/tex-2d-rgb8ui-rgb_integer-unsigned_byte.html": 0.5452,
+    "conformance2/textures/image/tex-2d-rgb9_e5-rgb-float.html": 0.5496,
+    "conformance2/textures/image/tex-2d-rgb9_e5-rgb-half_float.html": 0.6205,
+    "conformance2/textures/image/tex-2d-rgba16f-rgba-float.html": 0.5647,
+    "conformance2/textures/image/tex-2d-rgba16f-rgba-half_float.html": 0.5975,
+    "conformance2/textures/image/tex-2d-rgba32f-rgba-float.html": 0.6035,
+    "conformance2/textures/image/tex-2d-rgba4-rgba-unsigned_byte.html": 0.7384,
+    "conformance2/textures/image/tex-2d-rgba4-rgba-unsigned_short_4_4_4_4.html": 0.5344,
+    "conformance2/textures/image/tex-2d-rgba8-rgba-unsigned_byte.html": 0.3661,
+    "conformance2/textures/image/tex-2d-rgba8ui-rgba_integer-unsigned_byte.html": 0.6451,
+    "conformance2/textures/image/tex-2d-srgb8-rgb-unsigned_byte.html": 0.5573,
+    "conformance2/textures/image/tex-2d-srgb8_alpha8-rgba-unsigned_byte.html": 0.7768,
+    "conformance2/textures/image/tex-3d-r11f_g11f_b10f-rgb-float.html": 0.5002,
+    "conformance2/textures/image/tex-3d-r11f_g11f_b10f-rgb-half_float.html": 0.5536,
+    "conformance2/textures/image/tex-3d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html": 0.5632,
+    "conformance2/textures/image/tex-3d-r16f-red-float.html": 0.7404,
+    "conformance2/textures/image/tex-3d-r16f-red-half_float.html": 0.5447,
+    "conformance2/textures/image/tex-3d-r32f-red-float.html": 0.5512,
+    "conformance2/textures/image/tex-3d-r8-red-unsigned_byte.html": 0.5286,
+    "conformance2/textures/image/tex-3d-r8ui-red_integer-unsigned_byte.html": 0.5707,
+    "conformance2/textures/image/tex-3d-rg16f-rg-float.html": 0.48,
+    "conformance2/textures/image/tex-3d-rg16f-rg-half_float.html": 0.4719,
+    "conformance2/textures/image/tex-3d-rg32f-rg-float.html": 0.5104,
+    "conformance2/textures/image/tex-3d-rg8-rg-unsigned_byte.html": 0.4954,
+    "conformance2/textures/image/tex-3d-rg8ui-rg_integer-unsigned_byte.html": 0.5055,
+    "conformance2/textures/image/tex-3d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html": 0.7105,
+    "conformance2/textures/image/tex-3d-rgb16f-rgb-float.html": 0.5572,
+    "conformance2/textures/image/tex-3d-rgb16f-rgb-half_float.html": 0.562,
+    "conformance2/textures/image/tex-3d-rgb32f-rgb-float.html": 0.6128,
+    "conformance2/textures/image/tex-3d-rgb565-rgb-unsigned_byte.html": 0.4908,
+    "conformance2/textures/image/tex-3d-rgb565-rgb-unsigned_short_5_6_5.html": 0.6384,
+    "conformance2/textures/image/tex-3d-rgb5_a1-rgba-unsigned_byte.html": 0.5225,
+    "conformance2/textures/image/tex-3d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html": 0.7209,
+    "conformance2/textures/image/tex-3d-rgb8-rgb-unsigned_byte.html": 0.4627,
+    "conformance2/textures/image/tex-3d-rgb8ui-rgb_integer-unsigned_byte.html": 0.7603,
+    "conformance2/textures/image/tex-3d-rgb9_e5-rgb-float.html": 0.4391,
+    "conformance2/textures/image/tex-3d-rgb9_e5-rgb-half_float.html": 0.494,
+    "conformance2/textures/image/tex-3d-rgba16f-rgba-float.html": 0.5092,
+    "conformance2/textures/image/tex-3d-rgba16f-rgba-half_float.html": 0.5203,
+    "conformance2/textures/image/tex-3d-rgba32f-rgba-float.html": 0.4949,
+    "conformance2/textures/image/tex-3d-rgba4-rgba-unsigned_byte.html": 0.5565,
+    "conformance2/textures/image/tex-3d-rgba4-rgba-unsigned_short_4_4_4_4.html": 0.6024,
+    "conformance2/textures/image/tex-3d-rgba8-rgba-unsigned_byte.html": 0.4708,
+    "conformance2/textures/image/tex-3d-rgba8ui-rgba_integer-unsigned_byte.html": 0.5119,
+    "conformance2/textures/image/tex-3d-srgb8-rgb-unsigned_byte.html": 0.5124,
+    "conformance2/textures/image/tex-3d-srgb8_alpha8-rgba-unsigned_byte.html": 0.6944,
+    "conformance2/textures/image_bitmap_from_blob/tex-2d-r11f_g11f_b10f-rgb-float.html": 0.6608,
+    "conformance2/textures/image_bitmap_from_blob/tex-2d-r11f_g11f_b10f-rgb-half_float.html": 0.721,
+    "conformance2/textures/image_bitmap_from_blob/tex-2d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html": 0.71,
+    "conformance2/textures/image_bitmap_from_blob/tex-2d-r16f-red-float.html": 0.6693,
+    "conformance2/textures/image_bitmap_from_blob/tex-2d-r16f-red-half_float.html": 0.7495,
+    "conformance2/textures/image_bitmap_from_blob/tex-2d-r32f-red-float.html": 0.6843,
+    "conformance2/textures/image_bitmap_from_blob/tex-2d-r8-red-unsigned_byte.html": 0.6605,
+    "conformance2/textures/image_bitmap_from_blob/tex-2d-r8ui-red_integer-unsigned_byte.html": 0.698,
+    "conformance2/textures/image_bitmap_from_blob/tex-2d-rg16f-rg-float.html": 0.7012,
+    "conformance2/textures/image_bitmap_from_blob/tex-2d-rg16f-rg-half_float.html": 0.6485,
+    "conformance2/textures/image_bitmap_from_blob/tex-2d-rg32f-rg-float.html": 0.6936,
+    "conformance2/textures/image_bitmap_from_blob/tex-2d-rg8-rg-unsigned_byte.html": 0.6852,
+    "conformance2/textures/image_bitmap_from_blob/tex-2d-rg8ui-rg_integer-unsigned_byte.html": 0.6646,
+    "conformance2/textures/image_bitmap_from_blob/tex-2d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html": 0.7427,
+    "conformance2/textures/image_bitmap_from_blob/tex-2d-rgb16f-rgb-float.html": 1.0919,
+    "conformance2/textures/image_bitmap_from_blob/tex-2d-rgb16f-rgb-half_float.html": 0.6752,
+    "conformance2/textures/image_bitmap_from_blob/tex-2d-rgb32f-rgb-float.html": 0.678,
+    "conformance2/textures/image_bitmap_from_blob/tex-2d-rgb565-rgb-unsigned_byte.html": 0.7818,
+    "conformance2/textures/image_bitmap_from_blob/tex-2d-rgb565-rgb-unsigned_short_5_6_5.html": 0.6959,
+    "conformance2/textures/image_bitmap_from_blob/tex-2d-rgb5_a1-rgba-unsigned_byte.html": 0.7426,
+    "conformance2/textures/image_bitmap_from_blob/tex-2d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html": 0.6888,
+    "conformance2/textures/image_bitmap_from_blob/tex-2d-rgb8-rgb-unsigned_byte.html": 0.734,
+    "conformance2/textures/image_bitmap_from_blob/tex-2d-rgb8ui-rgb_integer-unsigned_byte.html": 0.6742,
+    "conformance2/textures/image_bitmap_from_blob/tex-2d-rgb9_e5-rgb-float.html": 0.6757,
+    "conformance2/textures/image_bitmap_from_blob/tex-2d-rgb9_e5-rgb-half_float.html": 0.6818,
+    "conformance2/textures/image_bitmap_from_blob/tex-2d-rgba16f-rgba-float.html": 0.6934,
+    "conformance2/textures/image_bitmap_from_blob/tex-2d-rgba16f-rgba-half_float.html": 0.5877,
+    "conformance2/textures/image_bitmap_from_blob/tex-2d-rgba32f-rgba-float.html": 0.6998,
+    "conformance2/textures/image_bitmap_from_blob/tex-2d-rgba4-rgba-unsigned_byte.html": 0.7057,
+    "conformance2/textures/image_bitmap_from_blob/tex-2d-rgba4-rgba-unsigned_short_4_4_4_4.html": 0.5334,
+    "conformance2/textures/image_bitmap_from_blob/tex-2d-rgba8-rgba-unsigned_byte.html": 0.7138,
+    "conformance2/textures/image_bitmap_from_blob/tex-2d-rgba8ui-rgba_integer-unsigned_byte.html": 0.6147,
+    "conformance2/textures/image_bitmap_from_blob/tex-2d-srgb8-rgb-unsigned_byte.html": 0.7013,
+    "conformance2/textures/image_bitmap_from_blob/tex-2d-srgb8_alpha8-rgba-unsigned_byte.html": 0.7149,
+    "conformance2/textures/image_bitmap_from_blob/tex-3d-r11f_g11f_b10f-rgb-float.html": 0.3839,
+    "conformance2/textures/image_bitmap_from_blob/tex-3d-r11f_g11f_b10f-rgb-half_float.html": 0.3499,
+    "conformance2/textures/image_bitmap_from_blob/tex-3d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html": 0.3529,
+    "conformance2/textures/image_bitmap_from_blob/tex-3d-r16f-red-float.html": 0.3436,
+    "conformance2/textures/image_bitmap_from_blob/tex-3d-r16f-red-half_float.html": 0.3784,
+    "conformance2/textures/image_bitmap_from_blob/tex-3d-r32f-red-float.html": 0.3682,
+    "conformance2/textures/image_bitmap_from_blob/tex-3d-r8-red-unsigned_byte.html": 0.3447,
+    "conformance2/textures/image_bitmap_from_blob/tex-3d-r8ui-red_integer-unsigned_byte.html": 0.3543,
+    "conformance2/textures/image_bitmap_from_blob/tex-3d-rg16f-rg-float.html": 0.3552,
+    "conformance2/textures/image_bitmap_from_blob/tex-3d-rg16f-rg-half_float.html": 0.3253,
+    "conformance2/textures/image_bitmap_from_blob/tex-3d-rg32f-rg-float.html": 0.339,
+    "conformance2/textures/image_bitmap_from_blob/tex-3d-rg8-rg-unsigned_byte.html": 0.3734,
+    "conformance2/textures/image_bitmap_from_blob/tex-3d-rg8ui-rg_integer-unsigned_byte.html": 0.3377,
+    "conformance2/textures/image_bitmap_from_blob/tex-3d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html": 0.3177,
+    "conformance2/textures/image_bitmap_from_blob/tex-3d-rgb16f-rgb-float.html": 0.3584,
+    "conformance2/textures/image_bitmap_from_blob/tex-3d-rgb16f-rgb-half_float.html": 0.3462,
+    "conformance2/textures/image_bitmap_from_blob/tex-3d-rgb32f-rgb-float.html": 0.3283,
+    "conformance2/textures/image_bitmap_from_blob/tex-3d-rgb565-rgb-unsigned_byte.html": 0.201,
+    "conformance2/textures/image_bitmap_from_blob/tex-3d-rgb565-rgb-unsigned_short_5_6_5.html": 0.3254,
+    "conformance2/textures/image_bitmap_from_blob/tex-3d-rgb5_a1-rgba-unsigned_byte.html": 0.3179,
+    "conformance2/textures/image_bitmap_from_blob/tex-3d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html": 0.3435,
+    "conformance2/textures/image_bitmap_from_blob/tex-3d-rgb8-rgb-unsigned_byte.html": 0.3384,
+    "conformance2/textures/image_bitmap_from_blob/tex-3d-rgb8ui-rgb_integer-unsigned_byte.html": 0.4484,
+    "conformance2/textures/image_bitmap_from_blob/tex-3d-rgb9_e5-rgb-float.html": 0.3301,
+    "conformance2/textures/image_bitmap_from_blob/tex-3d-rgb9_e5-rgb-half_float.html": 0.3313,
+    "conformance2/textures/image_bitmap_from_blob/tex-3d-rgba16f-rgba-float.html": 0.3324,
+    "conformance2/textures/image_bitmap_from_blob/tex-3d-rgba16f-rgba-half_float.html": 0.3616,
+    "conformance2/textures/image_bitmap_from_blob/tex-3d-rgba32f-rgba-float.html": 0.2423,
+    "conformance2/textures/image_bitmap_from_blob/tex-3d-rgba4-rgba-unsigned_byte.html": 0.3437,
+    "conformance2/textures/image_bitmap_from_blob/tex-3d-rgba4-rgba-unsigned_short_4_4_4_4.html": 0.3733,
+    "conformance2/textures/image_bitmap_from_blob/tex-3d-rgba8-rgba-unsigned_byte.html": 0.2267,
+    "conformance2/textures/image_bitmap_from_blob/tex-3d-rgba8ui-rgba_integer-unsigned_byte.html": 0.4342,
+    "conformance2/textures/image_bitmap_from_blob/tex-3d-srgb8-rgb-unsigned_byte.html": 0.3216,
+    "conformance2/textures/image_bitmap_from_blob/tex-3d-srgb8_alpha8-rgba-unsigned_byte.html": 0.3147,
+    "conformance2/textures/image_bitmap_from_canvas/tex-2d-r11f_g11f_b10f-rgb-float.html": 1.0671,
+    "conformance2/textures/image_bitmap_from_canvas/tex-2d-r11f_g11f_b10f-rgb-half_float.html": 1.6581,
+    "conformance2/textures/image_bitmap_from_canvas/tex-2d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html": 1.3091,
+    "conformance2/textures/image_bitmap_from_canvas/tex-2d-r16f-red-float.html": 1.659,
+    "conformance2/textures/image_bitmap_from_canvas/tex-2d-r16f-red-half_float.html": 1.1743,
+    "conformance2/textures/image_bitmap_from_canvas/tex-2d-r32f-red-float.html": 1.44,
+    "conformance2/textures/image_bitmap_from_canvas/tex-2d-r8-red-unsigned_byte.html": 1.0208,
+    "conformance2/textures/image_bitmap_from_canvas/tex-2d-r8ui-red_integer-unsigned_byte.html": 0.9613,
+    "conformance2/textures/image_bitmap_from_canvas/tex-2d-rg16f-rg-float.html": 1.288,
+    "conformance2/textures/image_bitmap_from_canvas/tex-2d-rg16f-rg-half_float.html": 1.4098,
+    "conformance2/textures/image_bitmap_from_canvas/tex-2d-rg32f-rg-float.html": 0.9305,
+    "conformance2/textures/image_bitmap_from_canvas/tex-2d-rg8-rg-unsigned_byte.html": 0.9395,
+    "conformance2/textures/image_bitmap_from_canvas/tex-2d-rg8ui-rg_integer-unsigned_byte.html": 1.3978,
+    "conformance2/textures/image_bitmap_from_canvas/tex-2d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html": 1.1049,
+    "conformance2/textures/image_bitmap_from_canvas/tex-2d-rgb16f-rgb-float.html": 1.25,
+    "conformance2/textures/image_bitmap_from_canvas/tex-2d-rgb16f-rgb-half_float.html": 0.9793,
+    "conformance2/textures/image_bitmap_from_canvas/tex-2d-rgb32f-rgb-float.html": 1.0622,
+    "conformance2/textures/image_bitmap_from_canvas/tex-2d-rgb565-rgb-unsigned_byte.html": 1.0592,
+    "conformance2/textures/image_bitmap_from_canvas/tex-2d-rgb565-rgb-unsigned_short_5_6_5.html": 0.7963,
+    "conformance2/textures/image_bitmap_from_canvas/tex-2d-rgb5_a1-rgba-unsigned_byte.html": 0.952,
+    "conformance2/textures/image_bitmap_from_canvas/tex-2d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html": 0.9633,
+    "conformance2/textures/image_bitmap_from_canvas/tex-2d-rgb8-rgb-unsigned_byte.html": 0.903,
+    "conformance2/textures/image_bitmap_from_canvas/tex-2d-rgb8ui-rgb_integer-unsigned_byte.html": 0.9765,
+    "conformance2/textures/image_bitmap_from_canvas/tex-2d-rgb9_e5-rgb-float.html": 1.1893,
+    "conformance2/textures/image_bitmap_from_canvas/tex-2d-rgb9_e5-rgb-half_float.html": 1.4362,
+    "conformance2/textures/image_bitmap_from_canvas/tex-2d-rgba16f-rgba-float.html": 0.8779,
+    "conformance2/textures/image_bitmap_from_canvas/tex-2d-rgba16f-rgba-half_float.html": 1.1633,
+    "conformance2/textures/image_bitmap_from_canvas/tex-2d-rgba32f-rgba-float.html": 1.1474,
+    "conformance2/textures/image_bitmap_from_canvas/tex-2d-rgba4-rgba-unsigned_byte.html": 1.0294,
+    "conformance2/textures/image_bitmap_from_canvas/tex-2d-rgba4-rgba-unsigned_short_4_4_4_4.html": 0.8651,
+    "conformance2/textures/image_bitmap_from_canvas/tex-2d-rgba8-rgba-unsigned_byte.html": 1.375,
+    "conformance2/textures/image_bitmap_from_canvas/tex-2d-rgba8ui-rgba_integer-unsigned_byte.html": 0.9552,
+    "conformance2/textures/image_bitmap_from_canvas/tex-2d-srgb8-rgb-unsigned_byte.html": 1.2549,
+    "conformance2/textures/image_bitmap_from_canvas/tex-2d-srgb8_alpha8-rgba-unsigned_byte.html": 0.9349,
+    "conformance2/textures/image_bitmap_from_canvas/tex-3d-r11f_g11f_b10f-rgb-float.html": 0.5725,
+    "conformance2/textures/image_bitmap_from_canvas/tex-3d-r11f_g11f_b10f-rgb-half_float.html": 0.5774,
+    "conformance2/textures/image_bitmap_from_canvas/tex-3d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html": 0.6307,
+    "conformance2/textures/image_bitmap_from_canvas/tex-3d-r16f-red-float.html": 0.5892,
+    "conformance2/textures/image_bitmap_from_canvas/tex-3d-r16f-red-half_float.html": 0.4724,
+    "conformance2/textures/image_bitmap_from_canvas/tex-3d-r32f-red-float.html": 0.61,
+    "conformance2/textures/image_bitmap_from_canvas/tex-3d-r8-red-unsigned_byte.html": 0.7879,
+    "conformance2/textures/image_bitmap_from_canvas/tex-3d-r8ui-red_integer-unsigned_byte.html": 0.4496,
+    "conformance2/textures/image_bitmap_from_canvas/tex-3d-rg16f-rg-float.html": 0.6403,
+    "conformance2/textures/image_bitmap_from_canvas/tex-3d-rg16f-rg-half_float.html": 0.5537,
+    "conformance2/textures/image_bitmap_from_canvas/tex-3d-rg32f-rg-float.html": 0.5353,
+    "conformance2/textures/image_bitmap_from_canvas/tex-3d-rg8-rg-unsigned_byte.html": 0.7654,
+    "conformance2/textures/image_bitmap_from_canvas/tex-3d-rg8ui-rg_integer-unsigned_byte.html": 0.6295,
+    "conformance2/textures/image_bitmap_from_canvas/tex-3d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html": 0.6385,
+    "conformance2/textures/image_bitmap_from_canvas/tex-3d-rgb16f-rgb-float.html": 0.6168,
+    "conformance2/textures/image_bitmap_from_canvas/tex-3d-rgb16f-rgb-half_float.html": 1.0349,
+    "conformance2/textures/image_bitmap_from_canvas/tex-3d-rgb32f-rgb-float.html": 0.6248,
+    "conformance2/textures/image_bitmap_from_canvas/tex-3d-rgb565-rgb-unsigned_byte.html": 0.8637,
+    "conformance2/textures/image_bitmap_from_canvas/tex-3d-rgb565-rgb-unsigned_short_5_6_5.html": 0.4872,
+    "conformance2/textures/image_bitmap_from_canvas/tex-3d-rgb5_a1-rgba-unsigned_byte.html": 0.5334,
+    "conformance2/textures/image_bitmap_from_canvas/tex-3d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html": 0.5002,
+    "conformance2/textures/image_bitmap_from_canvas/tex-3d-rgb8-rgb-unsigned_byte.html": 0.6175,
+    "conformance2/textures/image_bitmap_from_canvas/tex-3d-rgb8ui-rgb_integer-unsigned_byte.html": 0.6024,
+    "conformance2/textures/image_bitmap_from_canvas/tex-3d-rgb9_e5-rgb-float.html": 0.5766,
+    "conformance2/textures/image_bitmap_from_canvas/tex-3d-rgb9_e5-rgb-half_float.html": 0.6215,
+    "conformance2/textures/image_bitmap_from_canvas/tex-3d-rgba16f-rgba-float.html": 0.66,
+    "conformance2/textures/image_bitmap_from_canvas/tex-3d-rgba16f-rgba-half_float.html": 0.5925,
+    "conformance2/textures/image_bitmap_from_canvas/tex-3d-rgba32f-rgba-float.html": 0.7305,
+    "conformance2/textures/image_bitmap_from_canvas/tex-3d-rgba4-rgba-unsigned_byte.html": 0.6921,
+    "conformance2/textures/image_bitmap_from_canvas/tex-3d-rgba4-rgba-unsigned_short_4_4_4_4.html": 0.6071,
+    "conformance2/textures/image_bitmap_from_canvas/tex-3d-rgba8-rgba-unsigned_byte.html": 0.5106,
+    "conformance2/textures/image_bitmap_from_canvas/tex-3d-rgba8ui-rgba_integer-unsigned_byte.html": 0.5476,
+    "conformance2/textures/image_bitmap_from_canvas/tex-3d-srgb8-rgb-unsigned_byte.html": 0.558,
+    "conformance2/textures/image_bitmap_from_canvas/tex-3d-srgb8_alpha8-rgba-unsigned_byte.html": 0.5728,
+    "conformance2/textures/image_bitmap_from_image/tex-2d-r11f_g11f_b10f-rgb-float.html": 0.7548,
+    "conformance2/textures/image_bitmap_from_image/tex-2d-r11f_g11f_b10f-rgb-half_float.html": 0.6228,
+    "conformance2/textures/image_bitmap_from_image/tex-2d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html": 0.5886,
+    "conformance2/textures/image_bitmap_from_image/tex-2d-r16f-red-float.html": 0.7281,
+    "conformance2/textures/image_bitmap_from_image/tex-2d-r16f-red-half_float.html": 0.5425,
+    "conformance2/textures/image_bitmap_from_image/tex-2d-r32f-red-float.html": 0.6451,
+    "conformance2/textures/image_bitmap_from_image/tex-2d-r8-red-unsigned_byte.html": 0.6208,
+    "conformance2/textures/image_bitmap_from_image/tex-2d-r8ui-red_integer-unsigned_byte.html": 0.6233,
+    "conformance2/textures/image_bitmap_from_image/tex-2d-rg16f-rg-float.html": 0.4823,
+    "conformance2/textures/image_bitmap_from_image/tex-2d-rg16f-rg-half_float.html": 0.5628,
+    "conformance2/textures/image_bitmap_from_image/tex-2d-rg32f-rg-float.html": 0.8121,
+    "conformance2/textures/image_bitmap_from_image/tex-2d-rg8-rg-unsigned_byte.html": 0.5367,
+    "conformance2/textures/image_bitmap_from_image/tex-2d-rg8ui-rg_integer-unsigned_byte.html": 0.7387,
+    "conformance2/textures/image_bitmap_from_image/tex-2d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html": 0.4613,
+    "conformance2/textures/image_bitmap_from_image/tex-2d-rgb16f-rgb-float.html": 0.7591,
+    "conformance2/textures/image_bitmap_from_image/tex-2d-rgb16f-rgb-half_float.html": 0.8379,
+    "conformance2/textures/image_bitmap_from_image/tex-2d-rgb32f-rgb-float.html": 0.5003,
+    "conformance2/textures/image_bitmap_from_image/tex-2d-rgb565-rgb-unsigned_byte.html": 0.5787,
+    "conformance2/textures/image_bitmap_from_image/tex-2d-rgb565-rgb-unsigned_short_5_6_5.html": 0.8097,
+    "conformance2/textures/image_bitmap_from_image/tex-2d-rgb5_a1-rgba-unsigned_byte.html": 0.6473,
+    "conformance2/textures/image_bitmap_from_image/tex-2d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html": 0.5775,
+    "conformance2/textures/image_bitmap_from_image/tex-2d-rgb8-rgb-unsigned_byte.html": 0.7478,
+    "conformance2/textures/image_bitmap_from_image/tex-2d-rgb8ui-rgb_integer-unsigned_byte.html": 0.5518,
+    "conformance2/textures/image_bitmap_from_image/tex-2d-rgb9_e5-rgb-float.html": 0.4934,
+    "conformance2/textures/image_bitmap_from_image/tex-2d-rgb9_e5-rgb-half_float.html": 0.4767,
+    "conformance2/textures/image_bitmap_from_image/tex-2d-rgba16f-rgba-float.html": 0.5465,
+    "conformance2/textures/image_bitmap_from_image/tex-2d-rgba16f-rgba-half_float.html": 0.5559,
+    "conformance2/textures/image_bitmap_from_image/tex-2d-rgba32f-rgba-float.html": 0.5446,
+    "conformance2/textures/image_bitmap_from_image/tex-2d-rgba4-rgba-unsigned_byte.html": 0.585,
+    "conformance2/textures/image_bitmap_from_image/tex-2d-rgba4-rgba-unsigned_short_4_4_4_4.html": 0.9892,
+    "conformance2/textures/image_bitmap_from_image/tex-2d-rgba8-rgba-unsigned_byte.html": 0.4329,
+    "conformance2/textures/image_bitmap_from_image/tex-2d-rgba8ui-rgba_integer-unsigned_byte.html": 0.5083,
+    "conformance2/textures/image_bitmap_from_image/tex-2d-srgb8-rgb-unsigned_byte.html": 0.7907,
+    "conformance2/textures/image_bitmap_from_image/tex-2d-srgb8_alpha8-rgba-unsigned_byte.html": 0.5227,
+    "conformance2/textures/image_bitmap_from_image/tex-3d-r11f_g11f_b10f-rgb-float.html": 0.3534,
+    "conformance2/textures/image_bitmap_from_image/tex-3d-r11f_g11f_b10f-rgb-half_float.html": 0.6151,
+    "conformance2/textures/image_bitmap_from_image/tex-3d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html": 0.3377,
+    "conformance2/textures/image_bitmap_from_image/tex-3d-r16f-red-float.html": 0.5949,
+    "conformance2/textures/image_bitmap_from_image/tex-3d-r16f-red-half_float.html": 0.4298,
+    "conformance2/textures/image_bitmap_from_image/tex-3d-r32f-red-float.html": 0.4418,
+    "conformance2/textures/image_bitmap_from_image/tex-3d-r8-red-unsigned_byte.html": 0.5005,
+    "conformance2/textures/image_bitmap_from_image/tex-3d-r8ui-red_integer-unsigned_byte.html": 0.4104,
+    "conformance2/textures/image_bitmap_from_image/tex-3d-rg16f-rg-float.html": 0.3424,
+    "conformance2/textures/image_bitmap_from_image/tex-3d-rg16f-rg-half_float.html": 0.4383,
+    "conformance2/textures/image_bitmap_from_image/tex-3d-rg32f-rg-float.html": 0.3772,
+    "conformance2/textures/image_bitmap_from_image/tex-3d-rg8-rg-unsigned_byte.html": 0.4693,
+    "conformance2/textures/image_bitmap_from_image/tex-3d-rg8ui-rg_integer-unsigned_byte.html": 0.4004,
+    "conformance2/textures/image_bitmap_from_image/tex-3d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html": 0.4281,
+    "conformance2/textures/image_bitmap_from_image/tex-3d-rgb16f-rgb-float.html": 0.466,
+    "conformance2/textures/image_bitmap_from_image/tex-3d-rgb16f-rgb-half_float.html": 0.4759,
+    "conformance2/textures/image_bitmap_from_image/tex-3d-rgb32f-rgb-float.html": 0.5218,
+    "conformance2/textures/image_bitmap_from_image/tex-3d-rgb565-rgb-unsigned_byte.html": 0.5622,
+    "conformance2/textures/image_bitmap_from_image/tex-3d-rgb565-rgb-unsigned_short_5_6_5.html": 0.4294,
+    "conformance2/textures/image_bitmap_from_image/tex-3d-rgb5_a1-rgba-unsigned_byte.html": 0.3772,
+    "conformance2/textures/image_bitmap_from_image/tex-3d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html": 0.3965,
+    "conformance2/textures/image_bitmap_from_image/tex-3d-rgb8-rgb-unsigned_byte.html": 0.4076,
+    "conformance2/textures/image_bitmap_from_image/tex-3d-rgb8ui-rgb_integer-unsigned_byte.html": 0.479,
+    "conformance2/textures/image_bitmap_from_image/tex-3d-rgb9_e5-rgb-float.html": 0.4389,
+    "conformance2/textures/image_bitmap_from_image/tex-3d-rgb9_e5-rgb-half_float.html": 0.4252,
+    "conformance2/textures/image_bitmap_from_image/tex-3d-rgba16f-rgba-float.html": 0.4326,
+    "conformance2/textures/image_bitmap_from_image/tex-3d-rgba16f-rgba-half_float.html": 0.4071,
+    "conformance2/textures/image_bitmap_from_image/tex-3d-rgba32f-rgba-float.html": 0.4149,
+    "conformance2/textures/image_bitmap_from_image/tex-3d-rgba4-rgba-unsigned_byte.html": 0.395,
+    "conformance2/textures/image_bitmap_from_image/tex-3d-rgba4-rgba-unsigned_short_4_4_4_4.html": 0.3706,
+    "conformance2/textures/image_bitmap_from_image/tex-3d-rgba8-rgba-unsigned_byte.html": 0.3773,
+    "conformance2/textures/image_bitmap_from_image/tex-3d-rgba8ui-rgba_integer-unsigned_byte.html": 0.3945,
+    "conformance2/textures/image_bitmap_from_image/tex-3d-srgb8-rgb-unsigned_byte.html": 0.4478,
+    "conformance2/textures/image_bitmap_from_image/tex-3d-srgb8_alpha8-rgba-unsigned_byte.html": 0.4046,
+    "conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-r11f_g11f_b10f-rgb-float.html": 0.608,
+    "conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-r11f_g11f_b10f-rgb-half_float.html": 0.5388,
+    "conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html": 0.7605,
+    "conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-r16f-red-float.html": 0.5832,
+    "conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-r16f-red-half_float.html": 0.5446,
+    "conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-r32f-red-float.html": 0.5918,
+    "conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-r8-red-unsigned_byte.html": 0.7085,
+    "conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-r8ui-red_integer-unsigned_byte.html": 0.5227,
+    "conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-rg16f-rg-float.html": 0.7693,
+    "conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-rg16f-rg-half_float.html": 0.4915,
+    "conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-rg32f-rg-float.html": 0.6253,
+    "conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-rg8-rg-unsigned_byte.html": 0.5781,
+    "conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-rg8ui-rg_integer-unsigned_byte.html": 0.5246,
+    "conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html": 0.528,
+    "conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-rgb16f-rgb-float.html": 0.5491,
+    "conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-rgb16f-rgb-half_float.html": 0.5785,
+    "conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-rgb32f-rgb-float.html": 0.3536,
+    "conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-rgb565-rgb-unsigned_byte.html": 0.4886,
+    "conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-rgb565-rgb-unsigned_short_5_6_5.html": 0.5224,
+    "conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-rgb5_a1-rgba-unsigned_byte.html": 0.73,
+    "conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html": 0.4476,
+    "conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-rgb8-rgb-unsigned_byte.html": 0.7688,
+    "conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-rgb8ui-rgb_integer-unsigned_byte.html": 0.3935,
+    "conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-rgb9_e5-rgb-float.html": 0.7573,
+    "conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-rgb9_e5-rgb-half_float.html": 0.5379,
+    "conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-rgba16f-rgba-float.html": 0.5322,
+    "conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-rgba16f-rgba-half_float.html": 0.4868,
+    "conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-rgba32f-rgba-float.html": 0.5992,
+    "conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-rgba4-rgba-unsigned_byte.html": 0.5347,
+    "conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-rgba4-rgba-unsigned_short_4_4_4_4.html": 0.3583,
+    "conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-rgba8-rgba-unsigned_byte.html": 0.5206,
+    "conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-rgba8ui-rgba_integer-unsigned_byte.html": 0.494,
+    "conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-srgb8-rgb-unsigned_byte.html": 0.518,
+    "conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-srgb8_alpha8-rgba-unsigned_byte.html": 0.5268,
+    "conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-r11f_g11f_b10f-rgb-float.html": 0.3301,
+    "conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-r11f_g11f_b10f-rgb-half_float.html": 0.3994,
+    "conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html": 0.339,
+    "conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-r16f-red-float.html": 0.4015,
+    "conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-r16f-red-half_float.html": 0.3681,
+    "conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-r32f-red-float.html": 0.3092,
+    "conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-r8-red-unsigned_byte.html": 0.3701,
+    "conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-r8ui-red_integer-unsigned_byte.html": 0.4489,
+    "conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-rg16f-rg-float.html": 0.3129,
+    "conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-rg16f-rg-half_float.html": 0.2255,
+    "conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-rg32f-rg-float.html": 0.1916,
+    "conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-rg8-rg-unsigned_byte.html": 0.385,
+    "conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-rg8ui-rg_integer-unsigned_byte.html": 0.4107,
+    "conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html": 0.4886,
+    "conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-rgb16f-rgb-float.html": 0.3799,
+    "conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-rgb16f-rgb-half_float.html": 0.3722,
+    "conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-rgb32f-rgb-float.html": 0.3106,
+    "conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-rgb565-rgb-unsigned_byte.html": 0.4995,
+    "conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-rgb565-rgb-unsigned_short_5_6_5.html": 0.2152,
+    "conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-rgb5_a1-rgba-unsigned_byte.html": 0.2241,
+    "conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html": 0.4966,
+    "conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-rgb8-rgb-unsigned_byte.html": 0.3352,
+    "conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-rgb8ui-rgb_integer-unsigned_byte.html": 0.3334,
+    "conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-rgb9_e5-rgb-float.html": 0.3713,
+    "conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-rgb9_e5-rgb-half_float.html": 0.4161,
+    "conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-rgba16f-rgba-float.html": 0.2662,
+    "conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-rgba16f-rgba-half_float.html": 0.3625,
+    "conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-rgba32f-rgba-float.html": 0.3699,
+    "conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-rgba4-rgba-unsigned_byte.html": 0.4329,
+    "conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-rgba4-rgba-unsigned_short_4_4_4_4.html": 0.4074,
+    "conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-rgba8-rgba-unsigned_byte.html": 0.202,
+    "conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-rgba8ui-rgba_integer-unsigned_byte.html": 0.4234,
+    "conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-srgb8-rgb-unsigned_byte.html": 0.2295,
+    "conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-srgb8_alpha8-rgba-unsigned_byte.html": 0.3995,
+    "conformance2/textures/image_bitmap_from_image_data/tex-2d-r11f_g11f_b10f-rgb-float.html": 0.5033,
+    "conformance2/textures/image_bitmap_from_image_data/tex-2d-r11f_g11f_b10f-rgb-half_float.html": 0.5418,
+    "conformance2/textures/image_bitmap_from_image_data/tex-2d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html": 0.7653,
+    "conformance2/textures/image_bitmap_from_image_data/tex-2d-r16f-red-float.html": 0.533,
+    "conformance2/textures/image_bitmap_from_image_data/tex-2d-r16f-red-half_float.html": 0.5222,
+    "conformance2/textures/image_bitmap_from_image_data/tex-2d-r32f-red-float.html": 0.6477,
+    "conformance2/textures/image_bitmap_from_image_data/tex-2d-r8-red-unsigned_byte.html": 0.4228,
+    "conformance2/textures/image_bitmap_from_image_data/tex-2d-r8ui-red_integer-unsigned_byte.html": 0.7526,
+    "conformance2/textures/image_bitmap_from_image_data/tex-2d-rg16f-rg-float.html": 0.5536,
+    "conformance2/textures/image_bitmap_from_image_data/tex-2d-rg16f-rg-half_float.html": 0.5488,
+    "conformance2/textures/image_bitmap_from_image_data/tex-2d-rg32f-rg-float.html": 0.4974,
+    "conformance2/textures/image_bitmap_from_image_data/tex-2d-rg8-rg-unsigned_byte.html": 0.4776,
+    "conformance2/textures/image_bitmap_from_image_data/tex-2d-rg8ui-rg_integer-unsigned_byte.html": 0.5608,
+    "conformance2/textures/image_bitmap_from_image_data/tex-2d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html": 0.6825,
+    "conformance2/textures/image_bitmap_from_image_data/tex-2d-rgb16f-rgb-float.html": 0.5352,
+    "conformance2/textures/image_bitmap_from_image_data/tex-2d-rgb16f-rgb-half_float.html": 0.7434,
+    "conformance2/textures/image_bitmap_from_image_data/tex-2d-rgb32f-rgb-float.html": 0.5905,
+    "conformance2/textures/image_bitmap_from_image_data/tex-2d-rgb565-rgb-unsigned_byte.html": 0.5782,
+    "conformance2/textures/image_bitmap_from_image_data/tex-2d-rgb565-rgb-unsigned_short_5_6_5.html": 0.5034,
+    "conformance2/textures/image_bitmap_from_image_data/tex-2d-rgb5_a1-rgba-unsigned_byte.html": 0.5936,
+    "conformance2/textures/image_bitmap_from_image_data/tex-2d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html": 0.5469,
+    "conformance2/textures/image_bitmap_from_image_data/tex-2d-rgb8-rgb-unsigned_byte.html": 0.6149,
+    "conformance2/textures/image_bitmap_from_image_data/tex-2d-rgb8ui-rgb_integer-unsigned_byte.html": 0.4942,
+    "conformance2/textures/image_bitmap_from_image_data/tex-2d-rgb9_e5-rgb-float.html": 0.562,
+    "conformance2/textures/image_bitmap_from_image_data/tex-2d-rgb9_e5-rgb-half_float.html": 0.6529,
+    "conformance2/textures/image_bitmap_from_image_data/tex-2d-rgba16f-rgba-float.html": 0.478,
+    "conformance2/textures/image_bitmap_from_image_data/tex-2d-rgba16f-rgba-half_float.html": 0.5724,
+    "conformance2/textures/image_bitmap_from_image_data/tex-2d-rgba32f-rgba-float.html": 0.4659,
+    "conformance2/textures/image_bitmap_from_image_data/tex-2d-rgba4-rgba-unsigned_byte.html": 0.6601,
+    "conformance2/textures/image_bitmap_from_image_data/tex-2d-rgba4-rgba-unsigned_short_4_4_4_4.html": 0.3942,
+    "conformance2/textures/image_bitmap_from_image_data/tex-2d-rgba8-rgba-unsigned_byte.html": 0.4433,
+    "conformance2/textures/image_bitmap_from_image_data/tex-2d-rgba8ui-rgba_integer-unsigned_byte.html": 0.6057,
+    "conformance2/textures/image_bitmap_from_image_data/tex-2d-srgb8-rgb-unsigned_byte.html": 0.7864,
+    "conformance2/textures/image_bitmap_from_image_data/tex-2d-srgb8_alpha8-rgba-unsigned_byte.html": 0.5056,
+    "conformance2/textures/image_bitmap_from_image_data/tex-3d-r11f_g11f_b10f-rgb-float.html": 0.3093,
+    "conformance2/textures/image_bitmap_from_image_data/tex-3d-r11f_g11f_b10f-rgb-half_float.html": 0.3376,
+    "conformance2/textures/image_bitmap_from_image_data/tex-3d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html": 0.6389,
+    "conformance2/textures/image_bitmap_from_image_data/tex-3d-r16f-red-float.html": 0.3342,
+    "conformance2/textures/image_bitmap_from_image_data/tex-3d-r16f-red-half_float.html": 0.3763,
+    "conformance2/textures/image_bitmap_from_image_data/tex-3d-r32f-red-float.html": 0.3673,
+    "conformance2/textures/image_bitmap_from_image_data/tex-3d-r8-red-unsigned_byte.html": 0.3728,
+    "conformance2/textures/image_bitmap_from_image_data/tex-3d-r8ui-red_integer-unsigned_byte.html": 0.4077,
+    "conformance2/textures/image_bitmap_from_image_data/tex-3d-rg16f-rg-float.html": 0.3069,
+    "conformance2/textures/image_bitmap_from_image_data/tex-3d-rg16f-rg-half_float.html": 0.4054,
+    "conformance2/textures/image_bitmap_from_image_data/tex-3d-rg32f-rg-float.html": 0.2396,
+    "conformance2/textures/image_bitmap_from_image_data/tex-3d-rg8-rg-unsigned_byte.html": 0.3904,
+    "conformance2/textures/image_bitmap_from_image_data/tex-3d-rg8ui-rg_integer-unsigned_byte.html": 0.3987,
+    "conformance2/textures/image_bitmap_from_image_data/tex-3d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html": 0.4081,
+    "conformance2/textures/image_bitmap_from_image_data/tex-3d-rgb16f-rgb-float.html": 0.4193,
+    "conformance2/textures/image_bitmap_from_image_data/tex-3d-rgb16f-rgb-half_float.html": 0.4126,
+    "conformance2/textures/image_bitmap_from_image_data/tex-3d-rgb32f-rgb-float.html": 0.3164,
+    "conformance2/textures/image_bitmap_from_image_data/tex-3d-rgb565-rgb-unsigned_byte.html": 0.3606,
+    "conformance2/textures/image_bitmap_from_image_data/tex-3d-rgb565-rgb-unsigned_short_5_6_5.html": 0.5014,
+    "conformance2/textures/image_bitmap_from_image_data/tex-3d-rgb5_a1-rgba-unsigned_byte.html": 0.3406,
+    "conformance2/textures/image_bitmap_from_image_data/tex-3d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html": 0.2697,
+    "conformance2/textures/image_bitmap_from_image_data/tex-3d-rgb8-rgb-unsigned_byte.html": 0.5428,
+    "conformance2/textures/image_bitmap_from_image_data/tex-3d-rgb8ui-rgb_integer-unsigned_byte.html": 0.4221,
+    "conformance2/textures/image_bitmap_from_image_data/tex-3d-rgb9_e5-rgb-float.html": 0.3639,
+    "conformance2/textures/image_bitmap_from_image_data/tex-3d-rgb9_e5-rgb-half_float.html": 0.2557,
+    "conformance2/textures/image_bitmap_from_image_data/tex-3d-rgba16f-rgba-float.html": 0.4655,
+    "conformance2/textures/image_bitmap_from_image_data/tex-3d-rgba16f-rgba-half_float.html": 0.2847,
+    "conformance2/textures/image_bitmap_from_image_data/tex-3d-rgba32f-rgba-float.html": 0.4168,
+    "conformance2/textures/image_bitmap_from_image_data/tex-3d-rgba4-rgba-unsigned_byte.html": 0.3639,
+    "conformance2/textures/image_bitmap_from_image_data/tex-3d-rgba4-rgba-unsigned_short_4_4_4_4.html": 0.7402,
+    "conformance2/textures/image_bitmap_from_image_data/tex-3d-rgba8-rgba-unsigned_byte.html": 0.3685,
+    "conformance2/textures/image_bitmap_from_image_data/tex-3d-rgba8ui-rgba_integer-unsigned_byte.html": 0.4856,
+    "conformance2/textures/image_bitmap_from_image_data/tex-3d-srgb8-rgb-unsigned_byte.html": 0.4601,
+    "conformance2/textures/image_bitmap_from_image_data/tex-3d-srgb8_alpha8-rgba-unsigned_byte.html": 0.4833,
+    "conformance2/textures/image_bitmap_from_video/tex-2d-r11f_g11f_b10f-rgb-float.html": 0.6066,
+    "conformance2/textures/image_bitmap_from_video/tex-2d-r11f_g11f_b10f-rgb-half_float.html": 0.6981,
+    "conformance2/textures/image_bitmap_from_video/tex-2d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html": 0.6309,
+    "conformance2/textures/image_bitmap_from_video/tex-2d-r16f-red-float.html": 0.602,
+    "conformance2/textures/image_bitmap_from_video/tex-2d-r16f-red-half_float.html": 0.6454,
+    "conformance2/textures/image_bitmap_from_video/tex-2d-r32f-red-float.html": 0.5375,
+    "conformance2/textures/image_bitmap_from_video/tex-2d-r8-red-unsigned_byte.html": 0.5893,
+    "conformance2/textures/image_bitmap_from_video/tex-2d-r8ui-red_integer-unsigned_byte.html": 0.5087,
+    "conformance2/textures/image_bitmap_from_video/tex-2d-rg16f-rg-float.html": 0.7772,
+    "conformance2/textures/image_bitmap_from_video/tex-2d-rg16f-rg-half_float.html": 0.5706,
+    "conformance2/textures/image_bitmap_from_video/tex-2d-rg32f-rg-float.html": 0.7644,
+    "conformance2/textures/image_bitmap_from_video/tex-2d-rg8-rg-unsigned_byte.html": 0.6013,
+    "conformance2/textures/image_bitmap_from_video/tex-2d-rg8ui-rg_integer-unsigned_byte.html": 0.5559,
+    "conformance2/textures/image_bitmap_from_video/tex-2d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html": 0.5659,
+    "conformance2/textures/image_bitmap_from_video/tex-2d-rgb16f-rgb-float.html": 0.6808,
+    "conformance2/textures/image_bitmap_from_video/tex-2d-rgb16f-rgb-half_float.html": 0.7664,
+    "conformance2/textures/image_bitmap_from_video/tex-2d-rgb32f-rgb-float.html": 0.5502,
+    "conformance2/textures/image_bitmap_from_video/tex-2d-rgb565-rgb-unsigned_byte.html": 0.7845,
+    "conformance2/textures/image_bitmap_from_video/tex-2d-rgb565-rgb-unsigned_short_5_6_5.html": 0.522,
+    "conformance2/textures/image_bitmap_from_video/tex-2d-rgb5_a1-rgba-unsigned_byte.html": 0.4674,
+    "conformance2/textures/image_bitmap_from_video/tex-2d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html": 0.5623,
+    "conformance2/textures/image_bitmap_from_video/tex-2d-rgb8-rgb-unsigned_byte.html": 0.5326,
+    "conformance2/textures/image_bitmap_from_video/tex-2d-rgb8ui-rgb_integer-unsigned_byte.html": 0.5468,
+    "conformance2/textures/image_bitmap_from_video/tex-2d-rgb9_e5-rgb-float.html": 0.5942,
+    "conformance2/textures/image_bitmap_from_video/tex-2d-rgb9_e5-rgb-half_float.html": 0.5724,
+    "conformance2/textures/image_bitmap_from_video/tex-2d-rgba16f-rgba-float.html": 0.701,
+    "conformance2/textures/image_bitmap_from_video/tex-2d-rgba16f-rgba-half_float.html": 0.5899,
+    "conformance2/textures/image_bitmap_from_video/tex-2d-rgba32f-rgba-float.html": 0.5469,
+    "conformance2/textures/image_bitmap_from_video/tex-2d-rgba4-rgba-unsigned_byte.html": 0.5446,
+    "conformance2/textures/image_bitmap_from_video/tex-2d-rgba4-rgba-unsigned_short_4_4_4_4.html": 0.513,
+    "conformance2/textures/image_bitmap_from_video/tex-2d-rgba8-rgba-unsigned_byte.html": 0.5527,
+    "conformance2/textures/image_bitmap_from_video/tex-2d-rgba8ui-rgba_integer-unsigned_byte.html": 0.6155,
+    "conformance2/textures/image_bitmap_from_video/tex-2d-srgb8-rgb-unsigned_byte.html": 0.544,
+    "conformance2/textures/image_bitmap_from_video/tex-2d-srgb8_alpha8-rgba-unsigned_byte.html": 0.6719,
+    "conformance2/textures/image_bitmap_from_video/tex-3d-r11f_g11f_b10f-rgb-float.html": 0.5625,
+    "conformance2/textures/image_bitmap_from_video/tex-3d-r11f_g11f_b10f-rgb-half_float.html": 0.5617,
+    "conformance2/textures/image_bitmap_from_video/tex-3d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html": 0.4874,
+    "conformance2/textures/image_bitmap_from_video/tex-3d-r16f-red-float.html": 0.5907,
+    "conformance2/textures/image_bitmap_from_video/tex-3d-r16f-red-half_float.html": 0.6838,
+    "conformance2/textures/image_bitmap_from_video/tex-3d-r32f-red-float.html": 0.543,
+    "conformance2/textures/image_bitmap_from_video/tex-3d-r8-red-unsigned_byte.html": 0.5967,
+    "conformance2/textures/image_bitmap_from_video/tex-3d-r8ui-red_integer-unsigned_byte.html": 0.7182,
+    "conformance2/textures/image_bitmap_from_video/tex-3d-rg16f-rg-float.html": 0.5569,
+    "conformance2/textures/image_bitmap_from_video/tex-3d-rg16f-rg-half_float.html": 0.6873,
+    "conformance2/textures/image_bitmap_from_video/tex-3d-rg32f-rg-float.html": 0.7784,
+    "conformance2/textures/image_bitmap_from_video/tex-3d-rg8-rg-unsigned_byte.html": 0.669,
+    "conformance2/textures/image_bitmap_from_video/tex-3d-rg8ui-rg_integer-unsigned_byte.html": 0.6877,
+    "conformance2/textures/image_bitmap_from_video/tex-3d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html": 0.9584,
+    "conformance2/textures/image_bitmap_from_video/tex-3d-rgb16f-rgb-float.html": 0.5884,
+    "conformance2/textures/image_bitmap_from_video/tex-3d-rgb16f-rgb-half_float.html": 0.5425,
+    "conformance2/textures/image_bitmap_from_video/tex-3d-rgb32f-rgb-float.html": 0.5775,
+    "conformance2/textures/image_bitmap_from_video/tex-3d-rgb565-rgb-unsigned_byte.html": 0.5666,
+    "conformance2/textures/image_bitmap_from_video/tex-3d-rgb565-rgb-unsigned_short_5_6_5.html": 0.5407,
+    "conformance2/textures/image_bitmap_from_video/tex-3d-rgb5_a1-rgba-unsigned_byte.html": 0.4975,
+    "conformance2/textures/image_bitmap_from_video/tex-3d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html": 0.5218,
+    "conformance2/textures/image_bitmap_from_video/tex-3d-rgb8-rgb-unsigned_byte.html": 0.443,
+    "conformance2/textures/image_bitmap_from_video/tex-3d-rgb8ui-rgb_integer-unsigned_byte.html": 0.5418,
+    "conformance2/textures/image_bitmap_from_video/tex-3d-rgb9_e5-rgb-float.html": 0.5928,
+    "conformance2/textures/image_bitmap_from_video/tex-3d-rgb9_e5-rgb-half_float.html": 0.5188,
+    "conformance2/textures/image_bitmap_from_video/tex-3d-rgba16f-rgba-float.html": 0.5822,
+    "conformance2/textures/image_bitmap_from_video/tex-3d-rgba16f-rgba-half_float.html": 0.5612,
+    "conformance2/textures/image_bitmap_from_video/tex-3d-rgba32f-rgba-float.html": 0.542,
+    "conformance2/textures/image_bitmap_from_video/tex-3d-rgba4-rgba-unsigned_byte.html": 0.5597,
+    "conformance2/textures/image_bitmap_from_video/tex-3d-rgba4-rgba-unsigned_short_4_4_4_4.html": 0.5034,
+    "conformance2/textures/image_bitmap_from_video/tex-3d-rgba8-rgba-unsigned_byte.html": 0.6512,
+    "conformance2/textures/image_bitmap_from_video/tex-3d-rgba8ui-rgba_integer-unsigned_byte.html": 0.566,
+    "conformance2/textures/image_bitmap_from_video/tex-3d-srgb8-rgb-unsigned_byte.html": 0.6401,
+    "conformance2/textures/image_bitmap_from_video/tex-3d-srgb8_alpha8-rgba-unsigned_byte.html": 0.5852,
+    "conformance2/textures/image_data/tex-2d-r11f_g11f_b10f-rgb-float.html": 1.024,
+    "conformance2/textures/image_data/tex-2d-r11f_g11f_b10f-rgb-half_float.html": 1.1333,
+    "conformance2/textures/image_data/tex-2d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html": 0.9425,
+    "conformance2/textures/image_data/tex-2d-r16f-red-float.html": 1.4094,
+    "conformance2/textures/image_data/tex-2d-r16f-red-half_float.html": 0.8945,
+    "conformance2/textures/image_data/tex-2d-r32f-red-float.html": 0.8862,
+    "conformance2/textures/image_data/tex-2d-r8-red-unsigned_byte.html": 0.8822,
+    "conformance2/textures/image_data/tex-2d-r8ui-red_integer-unsigned_byte.html": 1.3839,
+    "conformance2/textures/image_data/tex-2d-rg16f-rg-float.html": 1.1229,
+    "conformance2/textures/image_data/tex-2d-rg16f-rg-half_float.html": 1.0591,
+    "conformance2/textures/image_data/tex-2d-rg32f-rg-float.html": 1.0879,
+    "conformance2/textures/image_data/tex-2d-rg8-rg-unsigned_byte.html": 0.8172,
+    "conformance2/textures/image_data/tex-2d-rg8ui-rg_integer-unsigned_byte.html": 0.9097,
+    "conformance2/textures/image_data/tex-2d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html": 0.9594,
+    "conformance2/textures/image_data/tex-2d-rgb16f-rgb-float.html": 0.8031,
+    "conformance2/textures/image_data/tex-2d-rgb16f-rgb-half_float.html": 0.9324,
+    "conformance2/textures/image_data/tex-2d-rgb32f-rgb-float.html": 0.7619,
+    "conformance2/textures/image_data/tex-2d-rgb565-rgb-unsigned_byte.html": 0.9643,
+    "conformance2/textures/image_data/tex-2d-rgb565-rgb-unsigned_short_5_6_5.html": 0.8854,
+    "conformance2/textures/image_data/tex-2d-rgb5_a1-rgba-unsigned_byte.html": 1.3531,
+    "conformance2/textures/image_data/tex-2d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html": 0.8347,
+    "conformance2/textures/image_data/tex-2d-rgb8-rgb-unsigned_byte.html": 1.0343,
+    "conformance2/textures/image_data/tex-2d-rgb8ui-rgb_integer-unsigned_byte.html": 0.8097,
+    "conformance2/textures/image_data/tex-2d-rgb9_e5-rgb-float.html": 0.8727,
+    "conformance2/textures/image_data/tex-2d-rgb9_e5-rgb-half_float.html": 0.7303,
+    "conformance2/textures/image_data/tex-2d-rgba16f-rgba-float.html": 0.8745,
+    "conformance2/textures/image_data/tex-2d-rgba16f-rgba-half_float.html": 1.1883,
+    "conformance2/textures/image_data/tex-2d-rgba32f-rgba-float.html": 0.9422,
+    "conformance2/textures/image_data/tex-2d-rgba4-rgba-unsigned_byte.html": 0.9718,
+    "conformance2/textures/image_data/tex-2d-rgba4-rgba-unsigned_short_4_4_4_4.html": 1.2357,
+    "conformance2/textures/image_data/tex-2d-rgba8-rgba-unsigned_byte.html": 0.9307,
+    "conformance2/textures/image_data/tex-2d-rgba8ui-rgba_integer-unsigned_byte.html": 0.8057,
+    "conformance2/textures/image_data/tex-2d-srgb8-rgb-unsigned_byte.html": 0.8949,
+    "conformance2/textures/image_data/tex-2d-srgb8_alpha8-rgba-unsigned_byte.html": 0.8817,
+    "conformance2/textures/image_data/tex-3d-r11f_g11f_b10f-rgb-float.html": 0.8564,
+    "conformance2/textures/image_data/tex-3d-r11f_g11f_b10f-rgb-half_float.html": 0.7863,
+    "conformance2/textures/image_data/tex-3d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html": 1.0044,
+    "conformance2/textures/image_data/tex-3d-r16f-red-float.html": 0.8081,
+    "conformance2/textures/image_data/tex-3d-r16f-red-half_float.html": 0.9375,
+    "conformance2/textures/image_data/tex-3d-r32f-red-float.html": 1.1863,
+    "conformance2/textures/image_data/tex-3d-r8-red-unsigned_byte.html": 0.775,
+    "conformance2/textures/image_data/tex-3d-r8ui-red_integer-unsigned_byte.html": 0.802,
+    "conformance2/textures/image_data/tex-3d-rg16f-rg-float.html": 1.1784,
+    "conformance2/textures/image_data/tex-3d-rg16f-rg-half_float.html": 1.0668,
+    "conformance2/textures/image_data/tex-3d-rg32f-rg-float.html": 1.0747,
+    "conformance2/textures/image_data/tex-3d-rg8-rg-unsigned_byte.html": 1.1015,
+    "conformance2/textures/image_data/tex-3d-rg8ui-rg_integer-unsigned_byte.html": 1.2657,
+    "conformance2/textures/image_data/tex-3d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html": 0.9207,
+    "conformance2/textures/image_data/tex-3d-rgb16f-rgb-float.html": 0.7078,
+    "conformance2/textures/image_data/tex-3d-rgb16f-rgb-half_float.html": 0.736,
+    "conformance2/textures/image_data/tex-3d-rgb32f-rgb-float.html": 0.8162,
+    "conformance2/textures/image_data/tex-3d-rgb565-rgb-unsigned_byte.html": 0.8444,
+    "conformance2/textures/image_data/tex-3d-rgb565-rgb-unsigned_short_5_6_5.html": 0.8859,
+    "conformance2/textures/image_data/tex-3d-rgb5_a1-rgba-unsigned_byte.html": 0.9869,
+    "conformance2/textures/image_data/tex-3d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html": 0.655,
+    "conformance2/textures/image_data/tex-3d-rgb8-rgb-unsigned_byte.html": 0.9324,
+    "conformance2/textures/image_data/tex-3d-rgb8ui-rgb_integer-unsigned_byte.html": 0.6492,
+    "conformance2/textures/image_data/tex-3d-rgb9_e5-rgb-float.html": 0.7506,
+    "conformance2/textures/image_data/tex-3d-rgb9_e5-rgb-half_float.html": 0.6679,
+    "conformance2/textures/image_data/tex-3d-rgba16f-rgba-float.html": 0.8879,
+    "conformance2/textures/image_data/tex-3d-rgba16f-rgba-half_float.html": 0.7438,
+    "conformance2/textures/image_data/tex-3d-rgba32f-rgba-float.html": 0.7939,
+    "conformance2/textures/image_data/tex-3d-rgba4-rgba-unsigned_byte.html": 1.3664,
+    "conformance2/textures/image_data/tex-3d-rgba4-rgba-unsigned_short_4_4_4_4.html": 0.6492,
+    "conformance2/textures/image_data/tex-3d-rgba8-rgba-unsigned_byte.html": 0.9925,
+    "conformance2/textures/image_data/tex-3d-rgba8ui-rgba_integer-unsigned_byte.html": 1.2631,
+    "conformance2/textures/image_data/tex-3d-srgb8-rgb-unsigned_byte.html": 1.1432,
+    "conformance2/textures/image_data/tex-3d-srgb8_alpha8-rgba-unsigned_byte.html": 0.8995,
+    "conformance2/textures/misc/active-3d-texture-bug.html": 0.3479,
+    "conformance2/textures/misc/angle-stuck-depth-textures.html": 0.2961,
+    "conformance2/textures/misc/canvas-remains-unchanged-after-used-in-webgl-texture.html": 0.2153,
+    "conformance2/textures/misc/compressed-tex-from-pbo-crash.html": 0.1728,
+    "conformance2/textures/misc/compressed-tex-image.html": 0.2087,
+    "conformance2/textures/misc/copy-texture-cube-map-AMD-bug.html": 0.2676,
+    "conformance2/textures/misc/copy-texture-cube-map-bug.html": 0.1238,
+    "conformance2/textures/misc/copy-texture-image-luma-format.html": 5.2303,
+    "conformance2/textures/misc/copy-texture-image-same-texture.html": 0.4701,
+    "conformance2/textures/misc/copy-texture-image-webgl-specific.html": 0.174,
+    "conformance2/textures/misc/copy-texture-image.html": 0.3414,
+    "conformance2/textures/misc/generate-mipmap-with-large-base-level.html": 0.1679,
+    "conformance2/textures/misc/gl-get-tex-parameter.html": 0.3247,
+    "conformance2/textures/misc/integer-cubemap-specification-order-bug.html": 0.8789,
+    "conformance2/textures/misc/integer-cubemap-texture-sampling.html": 1.8262,
+    "conformance2/textures/misc/mipmap-fbo.html": 0.1463,
+    "conformance2/textures/misc/npot-video-sizing.html": 0.2012,
+    "conformance2/textures/misc/origin-clean-conformance-offscreencanvas.html": 0.2176,
+    "conformance2/textures/misc/tex-3d-mipmap-levels-intel-bug.html": 0.1354,
+    "conformance2/textures/misc/tex-3d-size-limit.html": 0.1497,
+    "conformance2/textures/misc/tex-base-level-bug.html": 0.3366,
+    "conformance2/textures/misc/tex-image-and-sub-image-with-array-buffer-view-sub-source.html": 0.7423,
+    "conformance2/textures/misc/tex-image-with-bad-args-from-dom-elements.html": 0.2021,
+    "conformance2/textures/misc/tex-image-with-bad-args.html": 0.307,
+    "conformance2/textures/misc/tex-image-with-different-data-source.html": 0.302,
+    "conformance2/textures/misc/tex-input-validation.html": 0.2467,
+    "conformance2/textures/misc/tex-mipmap-levels.html": 0.3703,
+    "conformance2/textures/misc/tex-new-formats.html": 0.7535,
+    "conformance2/textures/misc/tex-srgb-mipmap.html": 0.4628,
+    "conformance2/textures/misc/tex-storage-2d.html": 0.7276,
+    "conformance2/textures/misc/tex-storage-and-subimage-3d.html": 0.1825,
+    "conformance2/textures/misc/tex-storage-compressed-formats.html": 0.1996,
+    "conformance2/textures/misc/tex-subimage3d-canvas-bug.html": 0.3285,
+    "conformance2/textures/misc/tex-subimage3d-pixel-buffer-bug.html": 0.2199,
+    "conformance2/textures/misc/tex-unpack-params-imagedata.html": 0.1119,
+    "conformance2/textures/misc/tex-unpack-params-with-flip-y-and-premultiply-alpha.html": 1.2721,
+    "conformance2/textures/misc/tex-unpack-params.html": 1.9597,
+    "conformance2/textures/misc/texel-fetch-undefined.html": 0.5037,
+    "conformance2/textures/misc/texture-npot.html": 0.3489,
+    "conformance2/textures/svg_image/tex-2d-r11f_g11f_b10f-rgb-float.html": 0.2853,
+    "conformance2/textures/svg_image/tex-2d-r11f_g11f_b10f-rgb-half_float.html": 0.388,
+    "conformance2/textures/svg_image/tex-2d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html": 0.5467,
+    "conformance2/textures/svg_image/tex-2d-r16f-red-float.html": 0.4303,
+    "conformance2/textures/svg_image/tex-2d-r16f-red-half_float.html": 0.3198,
+    "conformance2/textures/svg_image/tex-2d-r32f-red-float.html": 0.5594,
+    "conformance2/textures/svg_image/tex-2d-r8-red-unsigned_byte.html": 0.419,
+    "conformance2/textures/svg_image/tex-2d-r8ui-red_integer-unsigned_byte.html": 0.4232,
+    "conformance2/textures/svg_image/tex-2d-rg16f-rg-float.html": 0.5069,
+    "conformance2/textures/svg_image/tex-2d-rg16f-rg-half_float.html": 0.3671,
+    "conformance2/textures/svg_image/tex-2d-rg32f-rg-float.html": 0.3987,
+    "conformance2/textures/svg_image/tex-2d-rg8-rg-unsigned_byte.html": 0.4087,
+    "conformance2/textures/svg_image/tex-2d-rg8ui-rg_integer-unsigned_byte.html": 0.4392,
+    "conformance2/textures/svg_image/tex-2d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html": 0.3853,
+    "conformance2/textures/svg_image/tex-2d-rgb16f-rgb-float.html": 0.3364,
+    "conformance2/textures/svg_image/tex-2d-rgb16f-rgb-half_float.html": 0.3581,
+    "conformance2/textures/svg_image/tex-2d-rgb32f-rgb-float.html": 0.4824,
+    "conformance2/textures/svg_image/tex-2d-rgb565-rgb-unsigned_byte.html": 0.4513,
+    "conformance2/textures/svg_image/tex-2d-rgb565-rgb-unsigned_short_5_6_5.html": 0.4428,
+    "conformance2/textures/svg_image/tex-2d-rgb5_a1-rgba-unsigned_byte.html": 0.2223,
+    "conformance2/textures/svg_image/tex-2d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html": 0.3862,
+    "conformance2/textures/svg_image/tex-2d-rgb8-rgb-unsigned_byte.html": 0.3748,
+    "conformance2/textures/svg_image/tex-2d-rgb8ui-rgb_integer-unsigned_byte.html": 0.425,
+    "conformance2/textures/svg_image/tex-2d-rgb9_e5-rgb-float.html": 0.3541,
+    "conformance2/textures/svg_image/tex-2d-rgb9_e5-rgb-half_float.html": 0.3219,
+    "conformance2/textures/svg_image/tex-2d-rgba16f-rgba-float.html": 0.3951,
+    "conformance2/textures/svg_image/tex-2d-rgba16f-rgba-half_float.html": 0.5686,
+    "conformance2/textures/svg_image/tex-2d-rgba32f-rgba-float.html": 0.3974,
+    "conformance2/textures/svg_image/tex-2d-rgba4-rgba-unsigned_byte.html": 0.5008,
+    "conformance2/textures/svg_image/tex-2d-rgba4-rgba-unsigned_short_4_4_4_4.html": 0.3356,
+    "conformance2/textures/svg_image/tex-2d-rgba8-rgba-unsigned_byte.html": 0.3005,
+    "conformance2/textures/svg_image/tex-2d-rgba8ui-rgba_integer-unsigned_byte.html": 0.3863,
+    "conformance2/textures/svg_image/tex-2d-srgb8-rgb-unsigned_byte.html": 0.3886,
+    "conformance2/textures/svg_image/tex-2d-srgb8_alpha8-rgba-unsigned_byte.html": 0.4215,
+    "conformance2/textures/svg_image/tex-3d-r11f_g11f_b10f-rgb-float.html": 0.3386,
+    "conformance2/textures/svg_image/tex-3d-r11f_g11f_b10f-rgb-half_float.html": 0.3401,
+    "conformance2/textures/svg_image/tex-3d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html": 0.2773,
+    "conformance2/textures/svg_image/tex-3d-r16f-red-float.html": 0.366,
+    "conformance2/textures/svg_image/tex-3d-r16f-red-half_float.html": 0.1652,
+    "conformance2/textures/svg_image/tex-3d-r32f-red-float.html": 0.1912,
+    "conformance2/textures/svg_image/tex-3d-r8-red-unsigned_byte.html": 0.3238,
+    "conformance2/textures/svg_image/tex-3d-r8ui-red_integer-unsigned_byte.html": 0.3219,
+    "conformance2/textures/svg_image/tex-3d-rg16f-rg-float.html": 0.2118,
+    "conformance2/textures/svg_image/tex-3d-rg16f-rg-half_float.html": 0.335,
+    "conformance2/textures/svg_image/tex-3d-rg32f-rg-float.html": 0.2532,
+    "conformance2/textures/svg_image/tex-3d-rg8-rg-unsigned_byte.html": 0.3177,
+    "conformance2/textures/svg_image/tex-3d-rg8ui-rg_integer-unsigned_byte.html": 0.3256,
+    "conformance2/textures/svg_image/tex-3d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html": 0.1729,
+    "conformance2/textures/svg_image/tex-3d-rgb16f-rgb-float.html": 0.3186,
+    "conformance2/textures/svg_image/tex-3d-rgb16f-rgb-half_float.html": 0.3046,
+    "conformance2/textures/svg_image/tex-3d-rgb32f-rgb-float.html": 0.1654,
+    "conformance2/textures/svg_image/tex-3d-rgb565-rgb-unsigned_byte.html": 0.3754,
+    "conformance2/textures/svg_image/tex-3d-rgb565-rgb-unsigned_short_5_6_5.html": 0.2096,
+    "conformance2/textures/svg_image/tex-3d-rgb5_a1-rgba-unsigned_byte.html": 0.2024,
+    "conformance2/textures/svg_image/tex-3d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html": 0.2793,
+    "conformance2/textures/svg_image/tex-3d-rgb8-rgb-unsigned_byte.html": 0.2972,
+    "conformance2/textures/svg_image/tex-3d-rgb8ui-rgb_integer-unsigned_byte.html": 0.2463,
+    "conformance2/textures/svg_image/tex-3d-rgb9_e5-rgb-float.html": 0.4776,
+    "conformance2/textures/svg_image/tex-3d-rgb9_e5-rgb-half_float.html": 0.2977,
+    "conformance2/textures/svg_image/tex-3d-rgba16f-rgba-float.html": 0.2081,
+    "conformance2/textures/svg_image/tex-3d-rgba16f-rgba-half_float.html": 0.2512,
+    "conformance2/textures/svg_image/tex-3d-rgba32f-rgba-float.html": 0.2719,
+    "conformance2/textures/svg_image/tex-3d-rgba4-rgba-unsigned_byte.html": 0.3055,
+    "conformance2/textures/svg_image/tex-3d-rgba4-rgba-unsigned_short_4_4_4_4.html": 0.2041,
+    "conformance2/textures/svg_image/tex-3d-rgba8-rgba-unsigned_byte.html": 0.2378,
+    "conformance2/textures/svg_image/tex-3d-rgba8ui-rgba_integer-unsigned_byte.html": 0.4453,
+    "conformance2/textures/svg_image/tex-3d-srgb8-rgb-unsigned_byte.html": 0.3243,
+    "conformance2/textures/svg_image/tex-3d-srgb8_alpha8-rgba-unsigned_byte.html": 0.1832,
+    "conformance2/textures/video/tex-2d-r11f_g11f_b10f-rgb-float.html": 0.5468,
+    "conformance2/textures/video/tex-2d-r11f_g11f_b10f-rgb-half_float.html": 0.6192,
+    "conformance2/textures/video/tex-2d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html": 0.7602,
+    "conformance2/textures/video/tex-2d-r16f-red-float.html": 0.7329,
+    "conformance2/textures/video/tex-2d-r16f-red-half_float.html": 0.9183,
+    "conformance2/textures/video/tex-2d-r32f-red-float.html": 0.7575,
+    "conformance2/textures/video/tex-2d-r8-red-unsigned_byte.html": 0.695,
+    "conformance2/textures/video/tex-2d-r8ui-red_integer-unsigned_byte.html": 0.7561,
+    "conformance2/textures/video/tex-2d-rg16f-rg-float.html": 0.7418,
+    "conformance2/textures/video/tex-2d-rg16f-rg-half_float.html": 0.6759,
+    "conformance2/textures/video/tex-2d-rg32f-rg-float.html": 0.7666,
+    "conformance2/textures/video/tex-2d-rg8-rg-unsigned_byte.html": 0.6911,
+    "conformance2/textures/video/tex-2d-rg8ui-rg_integer-unsigned_byte.html": 0.7132,
+    "conformance2/textures/video/tex-2d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html": 0.5436,
+    "conformance2/textures/video/tex-2d-rgb16f-rgb-float.html": 0.8752,
+    "conformance2/textures/video/tex-2d-rgb16f-rgb-half_float.html": 0.5339,
+    "conformance2/textures/video/tex-2d-rgb32f-rgb-float.html": 0.7535,
+    "conformance2/textures/video/tex-2d-rgb565-rgb-unsigned_byte.html": 0.8516,
+    "conformance2/textures/video/tex-2d-rgb565-rgb-unsigned_short_5_6_5.html": 0.7313,
+    "conformance2/textures/video/tex-2d-rgb5_a1-rgba-unsigned_byte.html": 1.0432,
+    "conformance2/textures/video/tex-2d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html": 0.8432,
+    "conformance2/textures/video/tex-2d-rgb8-rgb-unsigned_byte.html": 1.0175,
+    "conformance2/textures/video/tex-2d-rgb8ui-rgb_integer-unsigned_byte.html": 0.5916,
+    "conformance2/textures/video/tex-2d-rgb9_e5-rgb-float.html": 0.734,
+    "conformance2/textures/video/tex-2d-rgb9_e5-rgb-half_float.html": 0.4868,
+    "conformance2/textures/video/tex-2d-rgba16f-rgba-float.html": 0.8134,
+    "conformance2/textures/video/tex-2d-rgba16f-rgba-half_float.html": 0.5861,
+    "conformance2/textures/video/tex-2d-rgba32f-rgba-float.html": 0.9958,
+    "conformance2/textures/video/tex-2d-rgba4-rgba-unsigned_byte.html": 0.7184,
+    "conformance2/textures/video/tex-2d-rgba4-rgba-unsigned_short_4_4_4_4.html": 0.731,
+    "conformance2/textures/video/tex-2d-rgba8-rgba-unsigned_byte.html": 0.7293,
+    "conformance2/textures/video/tex-2d-rgba8ui-rgba_integer-unsigned_byte.html": 0.6152,
+    "conformance2/textures/video/tex-2d-srgb8-rgb-unsigned_byte.html": 0.5606,
+    "conformance2/textures/video/tex-2d-srgb8_alpha8-rgba-unsigned_byte.html": 0.6635,
+    "conformance2/textures/video/tex-3d-r11f_g11f_b10f-rgb-float.html": 0.8797,
+    "conformance2/textures/video/tex-3d-r11f_g11f_b10f-rgb-half_float.html": 1.152,
+    "conformance2/textures/video/tex-3d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html": 1.0132,
+    "conformance2/textures/video/tex-3d-r16f-red-float.html": 1.2302,
+    "conformance2/textures/video/tex-3d-r16f-red-half_float.html": 1.059,
+    "conformance2/textures/video/tex-3d-r32f-red-float.html": 0.94,
+    "conformance2/textures/video/tex-3d-r8-red-unsigned_byte.html": 0.9438,
+    "conformance2/textures/video/tex-3d-r8ui-red_integer-unsigned_byte.html": 0.8502,
+    "conformance2/textures/video/tex-3d-rg16f-rg-float.html": 0.9116,
+    "conformance2/textures/video/tex-3d-rg16f-rg-half_float.html": 1.0499,
+    "conformance2/textures/video/tex-3d-rg32f-rg-float.html": 0.9176,
+    "conformance2/textures/video/tex-3d-rg8-rg-unsigned_byte.html": 0.8577,
+    "conformance2/textures/video/tex-3d-rg8ui-rg_integer-unsigned_byte.html": 0.9489,
+    "conformance2/textures/video/tex-3d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html": 0.7154,
+    "conformance2/textures/video/tex-3d-rgb16f-rgb-float.html": 0.9042,
+    "conformance2/textures/video/tex-3d-rgb16f-rgb-half_float.html": 0.7134,
+    "conformance2/textures/video/tex-3d-rgb32f-rgb-float.html": 0.9176,
+    "conformance2/textures/video/tex-3d-rgb565-rgb-unsigned_byte.html": 0.8013,
+    "conformance2/textures/video/tex-3d-rgb565-rgb-unsigned_short_5_6_5.html": 1.0297,
+    "conformance2/textures/video/tex-3d-rgb5_a1-rgba-unsigned_byte.html": 1.1738,
+    "conformance2/textures/video/tex-3d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html": 0.9288,
+    "conformance2/textures/video/tex-3d-rgb8-rgb-unsigned_byte.html": 0.8691,
+    "conformance2/textures/video/tex-3d-rgb8ui-rgb_integer-unsigned_byte.html": 0.9278,
+    "conformance2/textures/video/tex-3d-rgb9_e5-rgb-float.html": 0.9033,
+    "conformance2/textures/video/tex-3d-rgb9_e5-rgb-half_float.html": 1.2131,
+    "conformance2/textures/video/tex-3d-rgba16f-rgba-float.html": 0.8637,
+    "conformance2/textures/video/tex-3d-rgba16f-rgba-half_float.html": 1.1175,
+    "conformance2/textures/video/tex-3d-rgba32f-rgba-float.html": 0.903,
+    "conformance2/textures/video/tex-3d-rgba4-rgba-unsigned_byte.html": 0.9912,
+    "conformance2/textures/video/tex-3d-rgba4-rgba-unsigned_short_4_4_4_4.html": 0.7335,
+    "conformance2/textures/video/tex-3d-rgba8-rgba-unsigned_byte.html": 0.7262,
+    "conformance2/textures/video/tex-3d-rgba8ui-rgba_integer-unsigned_byte.html": 1.0748,
+    "conformance2/textures/video/tex-3d-srgb8-rgb-unsigned_byte.html": 1.032,
+    "conformance2/textures/video/tex-3d-srgb8_alpha8-rgba-unsigned_byte.html": 0.9275,
+    "conformance2/textures/webgl_canvas/tex-2d-r11f_g11f_b10f-rgb-float.html": 1.9371,
+    "conformance2/textures/webgl_canvas/tex-2d-r11f_g11f_b10f-rgb-half_float.html": 2.0092,
+    "conformance2/textures/webgl_canvas/tex-2d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html": 1.887,
+    "conformance2/textures/webgl_canvas/tex-2d-r16f-red-float.html": 1.5584,
+    "conformance2/textures/webgl_canvas/tex-2d-r16f-red-half_float.html": 1.6418,
+    "conformance2/textures/webgl_canvas/tex-2d-r32f-red-float.html": 1.8789,
+    "conformance2/textures/webgl_canvas/tex-2d-r8-red-unsigned_byte.html": 1.3247,
+    "conformance2/textures/webgl_canvas/tex-2d-r8ui-red_integer-unsigned_byte.html": 1.4249,
+    "conformance2/textures/webgl_canvas/tex-2d-rg16f-rg-float.html": 1.7632,
+    "conformance2/textures/webgl_canvas/tex-2d-rg16f-rg-half_float.html": 1.6324,
+    "conformance2/textures/webgl_canvas/tex-2d-rg32f-rg-float.html": 1.9121,
+    "conformance2/textures/webgl_canvas/tex-2d-rg8-rg-unsigned_byte.html": 1.9035,
+    "conformance2/textures/webgl_canvas/tex-2d-rg8ui-rg_integer-unsigned_byte.html": 1.9031,
+    "conformance2/textures/webgl_canvas/tex-2d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html": 1.6477,
+    "conformance2/textures/webgl_canvas/tex-2d-rgb16f-rgb-float.html": 1.8634,
+    "conformance2/textures/webgl_canvas/tex-2d-rgb16f-rgb-half_float.html": 1.7342,
+    "conformance2/textures/webgl_canvas/tex-2d-rgb32f-rgb-float.html": 1.8971,
+    "conformance2/textures/webgl_canvas/tex-2d-rgb565-rgb-unsigned_byte.html": 1.4328,
+    "conformance2/textures/webgl_canvas/tex-2d-rgb565-rgb-unsigned_short_5_6_5.html": 1.3983,
+    "conformance2/textures/webgl_canvas/tex-2d-rgb5_a1-rgba-unsigned_byte.html": 1.7364,
+    "conformance2/textures/webgl_canvas/tex-2d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html": 1.5786,
+    "conformance2/textures/webgl_canvas/tex-2d-rgb8-rgb-unsigned_byte.html": 1.847,
+    "conformance2/textures/webgl_canvas/tex-2d-rgb8ui-rgb_integer-unsigned_byte.html": 1.6319,
+    "conformance2/textures/webgl_canvas/tex-2d-rgb9_e5-rgb-float.html": 1.7326,
+    "conformance2/textures/webgl_canvas/tex-2d-rgb9_e5-rgb-half_float.html": 1.8312,
+    "conformance2/textures/webgl_canvas/tex-2d-rgba16f-rgba-float.html": 1.8505,
+    "conformance2/textures/webgl_canvas/tex-2d-rgba16f-rgba-half_float.html": 1.6606,
+    "conformance2/textures/webgl_canvas/tex-2d-rgba32f-rgba-float.html": 1.6933,
+    "conformance2/textures/webgl_canvas/tex-2d-rgba4-rgba-unsigned_byte.html": 1.6648,
+    "conformance2/textures/webgl_canvas/tex-2d-rgba4-rgba-unsigned_short_4_4_4_4.html": 1.6907,
+    "conformance2/textures/webgl_canvas/tex-2d-rgba8-rgba-unsigned_byte.html": 1.8493,
+    "conformance2/textures/webgl_canvas/tex-2d-rgba8ui-rgba_integer-unsigned_byte.html": 1.4914,
+    "conformance2/textures/webgl_canvas/tex-2d-srgb8-rgb-unsigned_byte.html": 1.3173,
+    "conformance2/textures/webgl_canvas/tex-2d-srgb8_alpha8-rgba-unsigned_byte.html": 1.8785,
+    "conformance2/textures/webgl_canvas/tex-3d-r11f_g11f_b10f-rgb-float.html": 5.8507,
+    "conformance2/textures/webgl_canvas/tex-3d-r11f_g11f_b10f-rgb-half_float.html": 5.8079,
+    "conformance2/textures/webgl_canvas/tex-3d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html": 5.5266,
+    "conformance2/textures/webgl_canvas/tex-3d-r16f-red-float.html": 5.5222,
+    "conformance2/textures/webgl_canvas/tex-3d-r16f-red-half_float.html": 5.5788,
+    "conformance2/textures/webgl_canvas/tex-3d-r32f-red-float.html": 5.5206,
+    "conformance2/textures/webgl_canvas/tex-3d-r8-red-unsigned_byte.html": 5.4929,
+    "conformance2/textures/webgl_canvas/tex-3d-r8ui-red_integer-unsigned_byte.html": 5.5198,
+    "conformance2/textures/webgl_canvas/tex-3d-rg16f-rg-float.html": 5.9102,
+    "conformance2/textures/webgl_canvas/tex-3d-rg16f-rg-half_float.html": 5.5407,
+    "conformance2/textures/webgl_canvas/tex-3d-rg32f-rg-float.html": 5.7505,
+    "conformance2/textures/webgl_canvas/tex-3d-rg8-rg-unsigned_byte.html": 5.6491,
+    "conformance2/textures/webgl_canvas/tex-3d-rg8ui-rg_integer-unsigned_byte.html": 5.4964,
+    "conformance2/textures/webgl_canvas/tex-3d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html": 5.5039,
+    "conformance2/textures/webgl_canvas/tex-3d-rgb16f-rgb-float.html": 5.5007,
+    "conformance2/textures/webgl_canvas/tex-3d-rgb16f-rgb-half_float.html": 5.6694,
+    "conformance2/textures/webgl_canvas/tex-3d-rgb32f-rgb-float.html": 5.9995,
+    "conformance2/textures/webgl_canvas/tex-3d-rgb565-rgb-unsigned_byte.html": 5.7181,
+    "conformance2/textures/webgl_canvas/tex-3d-rgb565-rgb-unsigned_short_5_6_5.html": 5.8418,
+    "conformance2/textures/webgl_canvas/tex-3d-rgb5_a1-rgba-unsigned_byte.html": 5.4312,
+    "conformance2/textures/webgl_canvas/tex-3d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html": 5.4962,
+    "conformance2/textures/webgl_canvas/tex-3d-rgb8-rgb-unsigned_byte.html": 5.5367,
+    "conformance2/textures/webgl_canvas/tex-3d-rgb8ui-rgb_integer-unsigned_byte.html": 5.7875,
+    "conformance2/textures/webgl_canvas/tex-3d-rgb9_e5-rgb-float.html": 5.5009,
+    "conformance2/textures/webgl_canvas/tex-3d-rgb9_e5-rgb-half_float.html": 5.7735,
+    "conformance2/textures/webgl_canvas/tex-3d-rgba16f-rgba-float.html": 6.1147,
+    "conformance2/textures/webgl_canvas/tex-3d-rgba16f-rgba-half_float.html": 5.4097,
+    "conformance2/textures/webgl_canvas/tex-3d-rgba32f-rgba-float.html": 5.5841,
+    "conformance2/textures/webgl_canvas/tex-3d-rgba4-rgba-unsigned_byte.html": 5.4089,
+    "conformance2/textures/webgl_canvas/tex-3d-rgba4-rgba-unsigned_short_4_4_4_4.html": 5.4493,
+    "conformance2/textures/webgl_canvas/tex-3d-rgba8-rgba-unsigned_byte.html": 5.791,
+    "conformance2/textures/webgl_canvas/tex-3d-rgba8ui-rgba_integer-unsigned_byte.html": 5.6329,
+    "conformance2/textures/webgl_canvas/tex-3d-srgb8-rgb-unsigned_byte.html": 5.8329,
+    "conformance2/textures/webgl_canvas/tex-3d-srgb8_alpha8-rgba-unsigned_byte.html": 5.7867,
+    "conformance2/transform_feedback/default_transform_feedback.html": 0.1927,
+    "conformance2/transform_feedback/non-existent-varying.html": 0.2208,
+    "conformance2/transform_feedback/same-buffer-two-binding-points.html": 0.195,
+    "conformance2/transform_feedback/simultaneous_binding.html": 0.2963,
+    "conformance2/transform_feedback/switching-objects.html": 0.4884,
+    "conformance2/transform_feedback/too-small-buffers.html": 0.3821,
+    "conformance2/transform_feedback/transform_feedback.html": 1.7058,
+    "conformance2/transform_feedback/two-unreferenced-varyings.html": 0.1291,
+    "conformance2/transform_feedback/unwritten-output-defaults-to-zero.html": 0.2266,
+    "conformance2/uniforms/dependent-buffer-change.html": 0.3887,
+    "conformance2/uniforms/draw-with-uniform-blocks.html": 0.2287,
+    "conformance2/uniforms/gl-uniform-arrays-sub-source.html": 1.1589,
+    "conformance2/uniforms/incompatible-texture-type-for-sampler.html": 6.2317,
+    "conformance2/uniforms/large-uniform-buffers.html": 0.4367,
+    "conformance2/uniforms/query-uniform-blocks-after-shader-detach.html": 0.4111,
+    "conformance2/uniforms/simple-buffer-change.html": 0.2327,
+    "conformance2/uniforms/uniform-blocks-with-arrays.html": 0.3635,
+    "conformance2/vertex_arrays/vertex-array-object-and-disabled-attributes.html": 0.5086,
+    "conformance2/vertex_arrays/vertex-array-object.html": 0.5197,
+    "deqp/data/gles3/shaders/arrays.html": 5.4927,
+    "deqp/data/gles3/shaders/conditionals.html": 1.9135,
+    "deqp/data/gles3/shaders/constant_expressions.html": 2.2888,
+    "deqp/data/gles3/shaders/constants.html": 4.5781,
+    "deqp/data/gles3/shaders/conversions.html": 76.9115,
+    "deqp/data/gles3/shaders/declarations.html": 1.2863,
+    "deqp/data/gles3/shaders/fragdata.html": 0.4611,
+    "deqp/data/gles3/shaders/functions.html": 13.0018,
+    "deqp/data/gles3/shaders/invalid_texture_functions.html": 2.4362,
+    "deqp/data/gles3/shaders/keywords.html": 5.0786,
+    "deqp/data/gles3/shaders/linkage.html": 5.3696,
+    "deqp/data/gles3/shaders/negative.html": 0.7784,
+    "deqp/data/gles3/shaders/preprocessor.html": 16.3259,
+    "deqp/data/gles3/shaders/qualification_order.html": 2.1285,
+    "deqp/data/gles3/shaders/scoping.html": 2.4766,
+    "deqp/data/gles3/shaders/switch.html": 1.4503,
+    "deqp/data/gles3/shaders/swizzles.html": 38.9969,
+    "deqp/framework/opengl/simplereference/referencecontext.html": 4.5305,
+    "deqp/functional/gles3/attriblocation.html": 6.795,
+    "deqp/functional/gles3/booleanstatequery.html": 0.6217,
+    "deqp/functional/gles3/buffercopy.html": 8.0987,
+    "deqp/functional/gles3/bufferobjectquery.html": 0.4522,
+    "deqp/functional/gles3/clipping.html": 28.5123,
+    "deqp/functional/gles3/defaultvertexattribute.html": 11.0768,
+    "deqp/functional/gles3/draw/draw_arrays.html": 17.9266,
+    "deqp/functional/gles3/draw/draw_arrays_instanced.html": 21.656,
+    "deqp/functional/gles3/draw/draw_elements.html": 15.7873,
+    "deqp/functional/gles3/draw/draw_elements_instanced.html": 19.2682,
+    "deqp/functional/gles3/draw/draw_range_elements.html": 10.8046,
+    "deqp/functional/gles3/draw/instancing.html": 1.4597,
+    "deqp/functional/gles3/draw/random.html": 16.6638,
+    "deqp/functional/gles3/fbocolorbuffer/blend.html": 17.9141,
+    "deqp/functional/gles3/fbocolorbuffer/clear.html": 10.8813,
+    "deqp/functional/gles3/fbocolorbuffer/tex2d_00.html": 19.0756,
+    "deqp/functional/gles3/fbocolorbuffer/tex2d_01.html": 17.4809,
+    "deqp/functional/gles3/fbocolorbuffer/tex2d_02.html": 19.5968,
+    "deqp/functional/gles3/fbocolorbuffer/tex2d_03.html": 15.915,
+    "deqp/functional/gles3/fbocolorbuffer/tex2d_04.html": 18.5513,
+    "deqp/functional/gles3/fbocolorbuffer/tex2d_05.html": 16.1648,
+    "deqp/functional/gles3/fbocolorbuffer/tex2darray_00.html": 18.0498,
+    "deqp/functional/gles3/fbocolorbuffer/tex2darray_01.html": 15.6474,
+    "deqp/functional/gles3/fbocolorbuffer/tex2darray_02.html": 16.7224,
+    "deqp/functional/gles3/fbocolorbuffer/tex2darray_03.html": 16.0242,
+    "deqp/functional/gles3/fbocolorbuffer/tex2darray_04.html": 16.4917,
+    "deqp/functional/gles3/fbocolorbuffer/tex2darray_05.html": 14.0216,
+    "deqp/functional/gles3/fbocolorbuffer/tex3d_00.html": 15.8808,
+    "deqp/functional/gles3/fbocolorbuffer/tex3d_01.html": 16.4243,
+    "deqp/functional/gles3/fbocolorbuffer/tex3d_02.html": 15.4028,
+    "deqp/functional/gles3/fbocolorbuffer/tex3d_03.html": 15.7178,
+    "deqp/functional/gles3/fbocolorbuffer/tex3d_04.html": 17.011,
+    "deqp/functional/gles3/fbocolorbuffer/tex3d_05.html": 13.7105,
+    "deqp/functional/gles3/fbocolorbuffer/texcube_00.html": 24.1638,
+    "deqp/functional/gles3/fbocolorbuffer/texcube_01.html": 22.5316,
+    "deqp/functional/gles3/fbocolorbuffer/texcube_02.html": 25.5942,
+    "deqp/functional/gles3/fbocolorbuffer/texcube_03.html": 20.566,
+    "deqp/functional/gles3/fbocolorbuffer/texcube_04.html": 24.7419,
+    "deqp/functional/gles3/fbocolorbuffer/texcube_05.html": 20.6543,
+    "deqp/functional/gles3/fbocompleteness.html": 4.9495,
+    "deqp/functional/gles3/fbodepthbuffer.html": 25.2687,
+    "deqp/functional/gles3/fboinvalidate/default.html": 50.388,
+    "deqp/functional/gles3/fboinvalidate/format_00.html": 19.0347,
+    "deqp/functional/gles3/fboinvalidate/format_01.html": 18.8165,
+    "deqp/functional/gles3/fboinvalidate/format_02.html": 17.7652,
+    "deqp/functional/gles3/fboinvalidate/sub.html": 37.4744,
+    "deqp/functional/gles3/fboinvalidate/target.html": 44.0602,
+    "deqp/functional/gles3/fboinvalidate/whole.html": 40.1843,
+    "deqp/functional/gles3/fbomultisample.2_samples.html": 35.658,
+    "deqp/functional/gles3/fbomultisample.4_samples.html": 35.0021,
+    "deqp/functional/gles3/fbomultisample.8_samples.html": 37.8935,
+    "deqp/functional/gles3/fborender/recreate_color_00.html": 18.6776,
+    "deqp/functional/gles3/fborender/recreate_color_01.html": 17.5506,
+    "deqp/functional/gles3/fborender/recreate_color_02.html": 19.7001,
+    "deqp/functional/gles3/fborender/recreate_color_03.html": 18.7946,
+    "deqp/functional/gles3/fborender/recreate_color_04.html": 18.7604,
+    "deqp/functional/gles3/fborender/recreate_color_05.html": 17.2652,
+    "deqp/functional/gles3/fborender/recreate_color_06.html": 19.1802,
+    "deqp/functional/gles3/fborender/recreate_depth_stencil.html": 16.4255,
+    "deqp/functional/gles3/fborender/resize_00.html": 17.6163,
+    "deqp/functional/gles3/fborender/resize_01.html": 18.2086,
+    "deqp/functional/gles3/fborender/resize_02.html": 15.2165,
+    "deqp/functional/gles3/fborender/resize_03.html": 24.5897,
+    "deqp/functional/gles3/fborender/shared_colorbuffer_00.html": 27.6068,
+    "deqp/functional/gles3/fborender/shared_colorbuffer_01.html": 27.6173,
+    "deqp/functional/gles3/fborender/shared_colorbuffer_02.html": 31.9987,
+    "deqp/functional/gles3/fborender/shared_colorbuffer_clear.html": 9.7986,
+    "deqp/functional/gles3/fborender/shared_depth_stencil.html": 17.2185,
+    "deqp/functional/gles3/fborender/stencil_clear.html": 7.4134,
+    "deqp/functional/gles3/fbostatequery.html": 0.6883,
+    "deqp/functional/gles3/fbostencilbuffer.html": 19.7051,
+    "deqp/functional/gles3/floatstatequery.html": 0.9683,
+    "deqp/functional/gles3/fragdepth.html": 11.5636,
+    "deqp/functional/gles3/fragmentoutput/array.fixed.html": 8.2541,
+    "deqp/functional/gles3/fragmentoutput/array.float.html": 11.161,
+    "deqp/functional/gles3/fragmentoutput/array.int.html": 9.8795,
+    "deqp/functional/gles3/fragmentoutput/array.uint.html": 11.9009,
+    "deqp/functional/gles3/fragmentoutput/basic.fixed.html": 5.5374,
+    "deqp/functional/gles3/fragmentoutput/basic.float.html": 7.3116,
+    "deqp/functional/gles3/fragmentoutput/basic.int.html": 5.9783,
+    "deqp/functional/gles3/fragmentoutput/basic.uint.html": 6.5468,
+    "deqp/functional/gles3/fragmentoutput/random_00.html": 14.4779,
+    "deqp/functional/gles3/fragmentoutput/random_01.html": 14.8818,
+    "deqp/functional/gles3/fragmentoutput/random_02.html": 14.4162,
+    "deqp/functional/gles3/framebufferblit/conversion_00.html": 8.7919,
+    "deqp/functional/gles3/framebufferblit/conversion_01.html": 8.4789,
+    "deqp/functional/gles3/framebufferblit/conversion_02.html": 8.8428,
+    "deqp/functional/gles3/framebufferblit/conversion_03.html": 9.2038,
+    "deqp/functional/gles3/framebufferblit/conversion_04.html": 14.3149,
+    "deqp/functional/gles3/framebufferblit/conversion_05.html": 7.4194,
+    "deqp/functional/gles3/framebufferblit/conversion_06.html": 9.0632,
+    "deqp/functional/gles3/framebufferblit/conversion_07.html": 13.6706,
+    "deqp/functional/gles3/framebufferblit/conversion_08.html": 12.9684,
+    "deqp/functional/gles3/framebufferblit/conversion_09.html": 8.9008,
+    "deqp/functional/gles3/framebufferblit/conversion_10.html": 15.1128,
+    "deqp/functional/gles3/framebufferblit/conversion_11.html": 13.675,
+    "deqp/functional/gles3/framebufferblit/conversion_12.html": 13.2814,
+    "deqp/functional/gles3/framebufferblit/conversion_13.html": 12.9482,
+    "deqp/functional/gles3/framebufferblit/conversion_14.html": 9.1919,
+    "deqp/functional/gles3/framebufferblit/conversion_15.html": 9.7015,
+    "deqp/functional/gles3/framebufferblit/conversion_16.html": 7.9373,
+    "deqp/functional/gles3/framebufferblit/conversion_17.html": 8.7763,
+    "deqp/functional/gles3/framebufferblit/conversion_18.html": 14.1758,
+    "deqp/functional/gles3/framebufferblit/conversion_19.html": 8.492,
+    "deqp/functional/gles3/framebufferblit/conversion_20.html": 8.759,
+    "deqp/functional/gles3/framebufferblit/conversion_21.html": 8.0001,
+    "deqp/functional/gles3/framebufferblit/conversion_22.html": 8.6829,
+    "deqp/functional/gles3/framebufferblit/conversion_23.html": 8.0737,
+    "deqp/functional/gles3/framebufferblit/conversion_24.html": 8.5056,
+    "deqp/functional/gles3/framebufferblit/conversion_25.html": 14.5723,
+    "deqp/functional/gles3/framebufferblit/conversion_26.html": 8.6924,
+    "deqp/functional/gles3/framebufferblit/conversion_27.html": 9.6397,
+    "deqp/functional/gles3/framebufferblit/conversion_28.html": 14.798,
+    "deqp/functional/gles3/framebufferblit/conversion_29.html": 13.6466,
+    "deqp/functional/gles3/framebufferblit/conversion_30.html": 13.2891,
+    "deqp/functional/gles3/framebufferblit/conversion_31.html": 13.7105,
+    "deqp/functional/gles3/framebufferblit/conversion_32.html": 13.2879,
+    "deqp/functional/gles3/framebufferblit/conversion_33.html": 12.8226,
+    "deqp/functional/gles3/framebufferblit/conversion_34.html": 13.5944,
+    "deqp/functional/gles3/framebufferblit/default_framebuffer_00.html": 17.5814,
+    "deqp/functional/gles3/framebufferblit/default_framebuffer_01.html": 17.847,
+    "deqp/functional/gles3/framebufferblit/default_framebuffer_02.html": 13.8203,
+    "deqp/functional/gles3/framebufferblit/default_framebuffer_03.html": 19.0266,
+    "deqp/functional/gles3/framebufferblit/default_framebuffer_04.html": 31.903,
+    "deqp/functional/gles3/framebufferblit/default_framebuffer_05.html": 16.622,
+    "deqp/functional/gles3/framebufferblit/default_framebuffer_06.html": 20.7838,
+    "deqp/functional/gles3/framebufferblit/depth_stencil.html": 33.8569,
+    "deqp/functional/gles3/framebufferblit/rect_00.html": 9.9852,
+    "deqp/functional/gles3/framebufferblit/rect_01.html": 10.5017,
+    "deqp/functional/gles3/framebufferblit/rect_02.html": 8.0013,
+    "deqp/functional/gles3/framebufferblit/rect_03.html": 5.6803,
+    "deqp/functional/gles3/framebufferblit/rect_04.html": 5.3912,
+    "deqp/functional/gles3/framebufferblit/rect_05.html": 0.6351,
+    "deqp/functional/gles3/framebufferblit/rect_06.html": 0.6364,
+    "deqp/functional/gles3/indexedstatequery.html": 0.314,
+    "deqp/functional/gles3/instancedrendering.html": 33.277,
+    "deqp/functional/gles3/integerstatequery.html": 1.8028,
+    "deqp/functional/gles3/internalformatquery.html": 0.5024,
+    "deqp/functional/gles3/lifetime.html": 1.5059,
+    "deqp/functional/gles3/multisample.html": 124.583,
+    "deqp/functional/gles3/negativebufferapi.html": 0.6649,
+    "deqp/functional/gles3/negativefragmentapi.html": 0.4248,
+    "deqp/functional/gles3/negativeshaderapi.html": 0.8676,
+    "deqp/functional/gles3/negativestateapi.html": 0.6304,
+    "deqp/functional/gles3/negativetextureapi.html": 1.0559,
+    "deqp/functional/gles3/negativevertexarrayapi.html": 0.9471,
+    "deqp/functional/gles3/occlusionquery_conservative.html": 19.5033,
+    "deqp/functional/gles3/occlusionquery_strict.html": 18.5944,
+    "deqp/functional/gles3/pixelbufferobject.html": 7.0603,
+    "deqp/functional/gles3/primitiverestart/00.html": 6.0853,
+    "deqp/functional/gles3/primitiverestart/01.html": 6.7324,
+    "deqp/functional/gles3/primitiverestart/02.html": 6.7785,
+    "deqp/functional/gles3/primitiverestart/03.html": 6.7211,
+    "deqp/functional/gles3/primitiverestart/04.html": 6.2866,
+    "deqp/functional/gles3/primitiverestart/05.html": 6.8685,
+    "deqp/functional/gles3/primitiverestart/06.html": 5.8894,
+    "deqp/functional/gles3/primitiverestart/07.html": 6.3586,
+    "deqp/functional/gles3/rasterizerdiscard.html": 8.5007,
+    "deqp/functional/gles3/rbostatequery.html": 0.3948,
+    "deqp/functional/gles3/readpixel.html": 2.2063,
+    "deqp/functional/gles3/samplerobject.html": 5.1514,
+    "deqp/functional/gles3/samplerstatequery.html": 0.6203,
+    "deqp/functional/gles3/shaderapi.html": 0.8315,
+    "deqp/functional/gles3/shaderbuiltinvar.html": 9.6097,
+    "deqp/functional/gles3/shadercommonfunction.html": 14.0613,
+    "deqp/functional/gles3/shaderderivate_dfdx.html": 12.4368,
+    "deqp/functional/gles3/shaderderivate_dfdy.html": 13.0936,
+    "deqp/functional/gles3/shaderderivate_fwidth.html": 12.8459,
+    "deqp/functional/gles3/shaderindexing/mat_00.html": 49.4006,
+    "deqp/functional/gles3/shaderindexing/mat_01.html": 49.196,
+    "deqp/functional/gles3/shaderindexing/mat_02.html": 64.6569,
+    "deqp/functional/gles3/shaderindexing/tmp.html": 61.8934,
+    "deqp/functional/gles3/shaderindexing/uniform.html": 17.0099,
+    "deqp/functional/gles3/shaderindexing/varying.html": 31.7124,
+    "deqp/functional/gles3/shaderindexing/vec2.html": 38.0852,
+    "deqp/functional/gles3/shaderindexing/vec3.html": 34.9643,
+    "deqp/functional/gles3/shaderindexing/vec4.html": 35.7014,
+    "deqp/functional/gles3/shaderloop_do_while.html": 85.9848,
+    "deqp/functional/gles3/shaderloop_for.html": 84.5642,
+    "deqp/functional/gles3/shaderloop_while.html": 89.8627,
+    "deqp/functional/gles3/shadermatrix/add_assign.html": 49.7048,
+    "deqp/functional/gles3/shadermatrix/add_const.html": 78.6233,
+    "deqp/functional/gles3/shadermatrix/add_dynamic.html": 79.9774,
+    "deqp/functional/gles3/shadermatrix/add_uniform.html": 77.2481,
+    "deqp/functional/gles3/shadermatrix/determinant.html": 14.73,
+    "deqp/functional/gles3/shadermatrix/div_assign.html": 44.0458,
+    "deqp/functional/gles3/shadermatrix/div_const.html": 79.1737,
+    "deqp/functional/gles3/shadermatrix/div_dynamic.html": 103.3187,
+    "deqp/functional/gles3/shadermatrix/div_uniform.html": 79.5751,
+    "deqp/functional/gles3/shadermatrix/inverse.html": 31.2532,
+    "deqp/functional/gles3/shadermatrix/matrixcompmult.html": 41.4608,
+    "deqp/functional/gles3/shadermatrix/mul_assign.html": 18.7602,
+    "deqp/functional/gles3/shadermatrix/mul_const_highp.html": 74.5858,
+    "deqp/functional/gles3/shadermatrix/mul_const_lowp.html": 77.8448,
+    "deqp/functional/gles3/shadermatrix/mul_const_mediump.html": 75.1778,
+    "deqp/functional/gles3/shadermatrix/mul_dynamic_highp.html": 79.1787,
+    "deqp/functional/gles3/shadermatrix/mul_dynamic_lowp.html": 76.6234,
+    "deqp/functional/gles3/shadermatrix/mul_dynamic_mediump.html": 79.1611,
+    "deqp/functional/gles3/shadermatrix/mul_uniform_highp.html": 76.3603,
+    "deqp/functional/gles3/shadermatrix/mul_uniform_lowp.html": 79.7511,
+    "deqp/functional/gles3/shadermatrix/mul_uniform_mediump.html": 83.8969,
+    "deqp/functional/gles3/shadermatrix/negation.html": 43.5772,
+    "deqp/functional/gles3/shadermatrix/outerproduct.html": 46.6459,
+    "deqp/functional/gles3/shadermatrix/post_decrement.html": 41.9801,
+    "deqp/functional/gles3/shadermatrix/post_increment.html": 40.4847,
+    "deqp/functional/gles3/shadermatrix/pre_decrement.html": 51.4306,
+    "deqp/functional/gles3/shadermatrix/pre_increment.html": 50.498,
+    "deqp/functional/gles3/shadermatrix/sub_assign.html": 45.8503,
+    "deqp/functional/gles3/shadermatrix/sub_const.html": 79.7309,
+    "deqp/functional/gles3/shadermatrix/sub_dynamic.html": 80.5905,
+    "deqp/functional/gles3/shadermatrix/sub_uniform.html": 81.0267,
+    "deqp/functional/gles3/shadermatrix/transpose.html": 52.799,
+    "deqp/functional/gles3/shadermatrix/unary_addition.html": 36.4138,
+    "deqp/functional/gles3/shaderoperator/angle_and_trigonometry_00.html": 59.3128,
+    "deqp/functional/gles3/shaderoperator/angle_and_trigonometry_01.html": 34.0124,
+    "deqp/functional/gles3/shaderoperator/angle_and_trigonometry_02.html": 36.9459,
+    "deqp/functional/gles3/shaderoperator/angle_and_trigonometry_03.html": 28.6354,
+    "deqp/functional/gles3/shaderoperator/binary_operator_00.html": 136.6353,
+    "deqp/functional/gles3/shaderoperator/binary_operator_01.html": 135.2298,
+    "deqp/functional/gles3/shaderoperator/binary_operator_02.html": 83.5236,
+    "deqp/functional/gles3/shaderoperator/binary_operator_03.html": 88.5133,
+    "deqp/functional/gles3/shaderoperator/binary_operator_04.html": 113.9627,
+    "deqp/functional/gles3/shaderoperator/binary_operator_05.html": 97.1943,
+    "deqp/functional/gles3/shaderoperator/binary_operator_06.html": 96.2103,
+    "deqp/functional/gles3/shaderoperator/binary_operator_07.html": 65.625,
+    "deqp/functional/gles3/shaderoperator/binary_operator_08.html": 62.5231,
+    "deqp/functional/gles3/shaderoperator/binary_operator_09.html": 108.295,
+    "deqp/functional/gles3/shaderoperator/binary_operator_10.html": 95.5139,
+    "deqp/functional/gles3/shaderoperator/binary_operator_11.html": 96.7594,
+    "deqp/functional/gles3/shaderoperator/binary_operator_12.html": 65.0465,
+    "deqp/functional/gles3/shaderoperator/binary_operator_13.html": 63.3077,
+    "deqp/functional/gles3/shaderoperator/binary_operator_14.html": 106.8526,
+    "deqp/functional/gles3/shaderoperator/binary_operator_15.html": 110.7028,
+    "deqp/functional/gles3/shaderoperator/bool_compare.html": 20.2399,
+    "deqp/functional/gles3/shaderoperator/common_functions_00.html": 61.3537,
+    "deqp/functional/gles3/shaderoperator/common_functions_01.html": 64.3813,
+    "deqp/functional/gles3/shaderoperator/common_functions_02.html": 60.0378,
+    "deqp/functional/gles3/shaderoperator/common_functions_03.html": 72.9309,
+    "deqp/functional/gles3/shaderoperator/common_functions_04.html": 59.2245,
+    "deqp/functional/gles3/shaderoperator/common_functions_05.html": 57.8672,
+    "deqp/functional/gles3/shaderoperator/common_functions_06.html": 47.6832,
+    "deqp/functional/gles3/shaderoperator/exponential.html": 55.5937,
+    "deqp/functional/gles3/shaderoperator/float_compare.html": 74.2315,
+    "deqp/functional/gles3/shaderoperator/geometric.html": 58.638,
+    "deqp/functional/gles3/shaderoperator/int_compare.html": 56.4135,
+    "deqp/functional/gles3/shaderoperator/selection.html": 45.3551,
+    "deqp/functional/gles3/shaderoperator/sequence.html": 32.8332,
+    "deqp/functional/gles3/shaderoperator/unary_operator_00.html": 79.4715,
+    "deqp/functional/gles3/shaderoperator/unary_operator_01.html": 135.5306,
+    "deqp/functional/gles3/shaderoperator/unary_operator_02.html": 146.889,
+    "deqp/functional/gles3/shaderpackingfunction.html": 1.6265,
+    "deqp/functional/gles3/shaderprecision_float.html": 18.4849,
+    "deqp/functional/gles3/shaderprecision_int.html": 16.3971,
+    "deqp/functional/gles3/shaderprecision_uint.html": 17.625,
+    "deqp/functional/gles3/shaderstatequery.html": 1.2495,
+    "deqp/functional/gles3/shaderstruct.html": 47.5794,
+    "deqp/functional/gles3/shaderswitch.html": 53.5557,
+    "deqp/functional/gles3/shadertexturefunction/texelfetch.html": 22.0863,
+    "deqp/functional/gles3/shadertexturefunction/texelfetchoffset.html": 18.6804,
+    "deqp/functional/gles3/shadertexturefunction/texture.html": 36.3278,
+    "deqp/functional/gles3/shadertexturefunction/texturegrad.html": 24.878,
+    "deqp/functional/gles3/shadertexturefunction/texturegradoffset.html": 18.2487,
+    "deqp/functional/gles3/shadertexturefunction/texturelod.html": 24.4717,
+    "deqp/functional/gles3/shadertexturefunction/texturelodoffset.html": 17.7382,
+    "deqp/functional/gles3/shadertexturefunction/textureoffset.html": 23.4754,
+    "deqp/functional/gles3/shadertexturefunction/textureproj.html": 28.0846,
+    "deqp/functional/gles3/shadertexturefunction/textureprojgrad.html": 18.1498,
+    "deqp/functional/gles3/shadertexturefunction/textureprojgradoffset.html": 17.9773,
+    "deqp/functional/gles3/shadertexturefunction/textureprojlod.html": 17.7233,
+    "deqp/functional/gles3/shadertexturefunction/textureprojlodoffset.html": 17.3851,
+    "deqp/functional/gles3/shadertexturefunction/textureprojoffset.html": 24.0382,
+    "deqp/functional/gles3/shadertexturefunction/texturesize.html": 26.6967,
+    "deqp/functional/gles3/stringquery.html": 0.3897,
+    "deqp/functional/gles3/sync.html": 4.1107,
+    "deqp/functional/gles3/texturefiltering/2d_array_combinations_00.html": 8.5834,
+    "deqp/functional/gles3/texturefiltering/2d_array_combinations_01.html": 9.1263,
+    "deqp/functional/gles3/texturefiltering/2d_array_combinations_02.html": 8.9467,
+    "deqp/functional/gles3/texturefiltering/2d_array_combinations_03.html": 8.6149,
+    "deqp/functional/gles3/texturefiltering/2d_array_combinations_04.html": 9.1643,
+    "deqp/functional/gles3/texturefiltering/2d_array_combinations_05.html": 10.0702,
+    "deqp/functional/gles3/texturefiltering/2d_array_formats_00.html": 6.4877,
+    "deqp/functional/gles3/texturefiltering/2d_array_formats_01.html": 5.8089,
+    "deqp/functional/gles3/texturefiltering/2d_array_formats_02.html": 5.4398,
+    "deqp/functional/gles3/texturefiltering/2d_array_formats_03.html": 5.322,
+    "deqp/functional/gles3/texturefiltering/2d_array_formats_04.html": 5.0164,
+    "deqp/functional/gles3/texturefiltering/2d_array_formats_05.html": 5.4166,
+    "deqp/functional/gles3/texturefiltering/2d_array_formats_06.html": 4.8317,
+    "deqp/functional/gles3/texturefiltering/2d_array_formats_07.html": 4.7443,
+    "deqp/functional/gles3/texturefiltering/2d_array_formats_08.html": 5.3703,
+    "deqp/functional/gles3/texturefiltering/2d_array_formats_09.html": 5.009,
+    "deqp/functional/gles3/texturefiltering/2d_array_sizes_00.html": 4.5537,
+    "deqp/functional/gles3/texturefiltering/2d_array_sizes_01.html": 4.394,
+    "deqp/functional/gles3/texturefiltering/2d_array_sizes_02.html": 5.4652,
+    "deqp/functional/gles3/texturefiltering/2d_array_sizes_03.html": 4.702,
+    "deqp/functional/gles3/texturefiltering/2d_array_sizes_04.html": 11.6098,
+    "deqp/functional/gles3/texturefiltering/2d_combinations_00.html": 5.0141,
+    "deqp/functional/gles3/texturefiltering/2d_combinations_01.html": 4.5311,
+    "deqp/functional/gles3/texturefiltering/2d_combinations_02.html": 5.3016,
+    "deqp/functional/gles3/texturefiltering/2d_combinations_03.html": 4.7318,
+    "deqp/functional/gles3/texturefiltering/2d_combinations_04.html": 4.6039,
+    "deqp/functional/gles3/texturefiltering/2d_combinations_05.html": 4.8183,
+    "deqp/functional/gles3/texturefiltering/2d_formats_00.html": 3.6842,
+    "deqp/functional/gles3/texturefiltering/2d_formats_01.html": 3.6888,
+    "deqp/functional/gles3/texturefiltering/2d_formats_02.html": 3.3238,
+    "deqp/functional/gles3/texturefiltering/2d_formats_03.html": 3.1258,
+    "deqp/functional/gles3/texturefiltering/2d_formats_04.html": 3.3602,
+    "deqp/functional/gles3/texturefiltering/2d_formats_05.html": 3.0803,
+    "deqp/functional/gles3/texturefiltering/2d_formats_06.html": 3.5269,
+    "deqp/functional/gles3/texturefiltering/2d_formats_07.html": 2.7984,
+    "deqp/functional/gles3/texturefiltering/2d_formats_08.html": 3.0363,
+    "deqp/functional/gles3/texturefiltering/2d_formats_09.html": 3.3043,
+    "deqp/functional/gles3/texturefiltering/2d_sizes_00.html": 2.7906,
+    "deqp/functional/gles3/texturefiltering/2d_sizes_01.html": 2.7475,
+    "deqp/functional/gles3/texturefiltering/2d_sizes_02.html": 3.1445,
+    "deqp/functional/gles3/texturefiltering/2d_sizes_03.html": 2.8623,
+    "deqp/functional/gles3/texturefiltering/2d_sizes_04.html": 3.4561,
+    "deqp/functional/gles3/texturefiltering/2d_sizes_05.html": 2.9431,
+    "deqp/functional/gles3/texturefiltering/3d_combinations_00.html": 5.2043,
+    "deqp/functional/gles3/texturefiltering/3d_combinations_01.html": 5.1744,
+    "deqp/functional/gles3/texturefiltering/3d_combinations_02.html": 4.3593,
+    "deqp/functional/gles3/texturefiltering/3d_combinations_03.html": 5.8217,
+    "deqp/functional/gles3/texturefiltering/3d_combinations_04.html": 5.6526,
+    "deqp/functional/gles3/texturefiltering/3d_combinations_05.html": 5.1207,
+    "deqp/functional/gles3/texturefiltering/3d_combinations_06.html": 5.107,
+    "deqp/functional/gles3/texturefiltering/3d_combinations_07.html": 5.2652,
+    "deqp/functional/gles3/texturefiltering/3d_combinations_08.html": 5.1948,
+    "deqp/functional/gles3/texturefiltering/3d_combinations_09.html": 5.1084,
+    "deqp/functional/gles3/texturefiltering/3d_combinations_10.html": 5.3732,
+    "deqp/functional/gles3/texturefiltering/3d_combinations_11.html": 5.0923,
+    "deqp/functional/gles3/texturefiltering/3d_combinations_12.html": 5.424,
+    "deqp/functional/gles3/texturefiltering/3d_combinations_13.html": 4.6909,
+    "deqp/functional/gles3/texturefiltering/3d_combinations_14.html": 4.6595,
+    "deqp/functional/gles3/texturefiltering/3d_combinations_15.html": 5.5386,
+    "deqp/functional/gles3/texturefiltering/3d_combinations_16.html": 5.185,
+    "deqp/functional/gles3/texturefiltering/3d_combinations_17.html": 5.3338,
+    "deqp/functional/gles3/texturefiltering/3d_combinations_18.html": 5.4961,
+    "deqp/functional/gles3/texturefiltering/3d_combinations_19.html": 5.2288,
+    "deqp/functional/gles3/texturefiltering/3d_combinations_20.html": 5.5089,
+    "deqp/functional/gles3/texturefiltering/3d_combinations_21.html": 5.031,
+    "deqp/functional/gles3/texturefiltering/3d_combinations_22.html": 5.0257,
+    "deqp/functional/gles3/texturefiltering/3d_combinations_23.html": 5.1342,
+    "deqp/functional/gles3/texturefiltering/3d_combinations_24.html": 17.8891,
+    "deqp/functional/gles3/texturefiltering/3d_combinations_25.html": 17.8943,
+    "deqp/functional/gles3/texturefiltering/3d_combinations_26.html": 17.8644,
+    "deqp/functional/gles3/texturefiltering/3d_combinations_27.html": 19.0879,
+    "deqp/functional/gles3/texturefiltering/3d_combinations_28.html": 16.5173,
+    "deqp/functional/gles3/texturefiltering/3d_combinations_29.html": 17.9685,
+    "deqp/functional/gles3/texturefiltering/3d_combinations_30.html": 17.6767,
+    "deqp/functional/gles3/texturefiltering/3d_combinations_31.html": 18.2394,
+    "deqp/functional/gles3/texturefiltering/3d_combinations_32.html": 19.3553,
+    "deqp/functional/gles3/texturefiltering/3d_combinations_33.html": 17.8837,
+    "deqp/functional/gles3/texturefiltering/3d_combinations_34.html": 17.6733,
+    "deqp/functional/gles3/texturefiltering/3d_combinations_35.html": 21.0721,
+    "deqp/functional/gles3/texturefiltering/3d_formats_00.html": 11.8232,
+    "deqp/functional/gles3/texturefiltering/3d_formats_01.html": 11.207,
+    "deqp/functional/gles3/texturefiltering/3d_formats_02.html": 10.3023,
+    "deqp/functional/gles3/texturefiltering/3d_formats_03.html": 10.3933,
+    "deqp/functional/gles3/texturefiltering/3d_formats_04.html": 11.2353,
+    "deqp/functional/gles3/texturefiltering/3d_formats_05.html": 9.7258,
+    "deqp/functional/gles3/texturefiltering/3d_formats_06.html": 10.1946,
+    "deqp/functional/gles3/texturefiltering/3d_formats_07.html": 10.3245,
+    "deqp/functional/gles3/texturefiltering/3d_formats_08.html": 10.2871,
+    "deqp/functional/gles3/texturefiltering/3d_formats_09.html": 10.7378,
+    "deqp/functional/gles3/texturefiltering/3d_sizes_00.html": 11.2046,
+    "deqp/functional/gles3/texturefiltering/3d_sizes_01.html": 9.9377,
+    "deqp/functional/gles3/texturefiltering/3d_sizes_02.html": 10.9346,
+    "deqp/functional/gles3/texturefiltering/3d_sizes_03.html": 8.7039,
+    "deqp/functional/gles3/texturefiltering/3d_sizes_04.html": 10.5352,
+    "deqp/functional/gles3/texturefiltering/cube_combinations_00.html": 12.5676,
+    "deqp/functional/gles3/texturefiltering/cube_combinations_01.html": 14.5286,
+    "deqp/functional/gles3/texturefiltering/cube_combinations_02.html": 18.0429,
+    "deqp/functional/gles3/texturefiltering/cube_combinations_03.html": 17.9496,
+    "deqp/functional/gles3/texturefiltering/cube_combinations_04.html": 21.2414,
+    "deqp/functional/gles3/texturefiltering/cube_combinations_05.html": 30.1802,
+    "deqp/functional/gles3/texturefiltering/cube_formats_00.html": 11.5897,
+    "deqp/functional/gles3/texturefiltering/cube_formats_01.html": 11.3714,
+    "deqp/functional/gles3/texturefiltering/cube_formats_02.html": 10.8074,
+    "deqp/functional/gles3/texturefiltering/cube_formats_03.html": 10.2115,
+    "deqp/functional/gles3/texturefiltering/cube_formats_04.html": 10.3566,
+    "deqp/functional/gles3/texturefiltering/cube_formats_05.html": 10.5751,
+    "deqp/functional/gles3/texturefiltering/cube_formats_06.html": 10.1203,
+    "deqp/functional/gles3/texturefiltering/cube_formats_07.html": 9.6884,
+    "deqp/functional/gles3/texturefiltering/cube_formats_08.html": 10.4015,
+    "deqp/functional/gles3/texturefiltering/cube_formats_09.html": 10.545,
+    "deqp/functional/gles3/texturefiltering/cube_no_edges_visible.html": 5.0039,
+    "deqp/functional/gles3/texturefiltering/cube_sizes_00.html": 6.2294,
+    "deqp/functional/gles3/texturefiltering/cube_sizes_01.html": 10.6372,
+    "deqp/functional/gles3/texturefiltering/cube_sizes_02.html": 10.714,
+    "deqp/functional/gles3/texturefiltering/cube_sizes_03.html": 6.4021,
+    "deqp/functional/gles3/texturefiltering/cube_sizes_04.html": 9.5121,
+    "deqp/functional/gles3/textureformat/compressed_2d.html": 0.2955,
+    "deqp/functional/gles3/textureformat/compressed_cube.html": 0.4107,
+    "deqp/functional/gles3/textureformat/sized_color_2d_array_npot_00.html": 7.0192,
+    "deqp/functional/gles3/textureformat/sized_color_2d_array_npot_01.html": 7.1213,
+    "deqp/functional/gles3/textureformat/sized_color_2d_array_npot_02.html": 7.2762,
+    "deqp/functional/gles3/textureformat/sized_color_2d_array_npot_03.html": 7.1596,
+    "deqp/functional/gles3/textureformat/sized_color_2d_array_pot_00.html": 7.7528,
+    "deqp/functional/gles3/textureformat/sized_color_2d_array_pot_01.html": 7.9818,
+    "deqp/functional/gles3/textureformat/sized_color_2d_array_pot_02.html": 8.0483,
+    "deqp/functional/gles3/textureformat/sized_color_2d_array_pot_03.html": 8.1379,
+    "deqp/functional/gles3/textureformat/sized_color_2d_npot_00.html": 3.9409,
+    "deqp/functional/gles3/textureformat/sized_color_2d_npot_01.html": 4.0437,
+    "deqp/functional/gles3/textureformat/sized_color_2d_npot_02.html": 3.7625,
+    "deqp/functional/gles3/textureformat/sized_color_2d_npot_03.html": 3.9912,
+    "deqp/functional/gles3/textureformat/sized_color_2d_pot_00.html": 4.4982,
+    "deqp/functional/gles3/textureformat/sized_color_2d_pot_01.html": 4.7777,
+    "deqp/functional/gles3/textureformat/sized_color_2d_pot_02.html": 4.3043,
+    "deqp/functional/gles3/textureformat/sized_color_2d_pot_03.html": 4.4934,
+    "deqp/functional/gles3/textureformat/sized_color_3d_npot_00.html": 5.4088,
+    "deqp/functional/gles3/textureformat/sized_color_3d_npot_01.html": 5.2636,
+    "deqp/functional/gles3/textureformat/sized_color_3d_npot_02.html": 5.3548,
+    "deqp/functional/gles3/textureformat/sized_color_3d_npot_03.html": 5.0417,
+    "deqp/functional/gles3/textureformat/sized_color_3d_pot_00.html": 8.5549,
+    "deqp/functional/gles3/textureformat/sized_color_3d_pot_01.html": 9.0955,
+    "deqp/functional/gles3/textureformat/sized_color_3d_pot_02.html": 8.578,
+    "deqp/functional/gles3/textureformat/sized_color_3d_pot_03.html": 7.7276,
+    "deqp/functional/gles3/textureformat/sized_color_cube_npot_00.html": 7.481,
+    "deqp/functional/gles3/textureformat/sized_color_cube_npot_01.html": 7.0738,
+    "deqp/functional/gles3/textureformat/sized_color_cube_npot_02.html": 6.6389,
+    "deqp/functional/gles3/textureformat/sized_color_cube_npot_03.html": 6.9461,
+    "deqp/functional/gles3/textureformat/sized_color_cube_pot_00.html": 7.8896,
+    "deqp/functional/gles3/textureformat/sized_color_cube_pot_01.html": 7.1927,
+    "deqp/functional/gles3/textureformat/sized_color_cube_pot_02.html": 6.887,
+    "deqp/functional/gles3/textureformat/sized_color_cube_pot_03.html": 7.1318,
+    "deqp/functional/gles3/textureformat/sized_depth_stencil.html": 8.2313,
+    "deqp/functional/gles3/textureformat/unsized_2d.html": 8.3554,
+    "deqp/functional/gles3/textureformat/unsized_2d_array.html": 7.4249,
+    "deqp/functional/gles3/textureformat/unsized_3d.html": 8.348,
+    "deqp/functional/gles3/textureshadow/2d_array_linear_always.html": 3.9449,
+    "deqp/functional/gles3/textureshadow/2d_array_linear_equal.html": 6.091,
+    "deqp/functional/gles3/textureshadow/2d_array_linear_greater.html": 5.8138,
+    "deqp/functional/gles3/textureshadow/2d_array_linear_greater_or_equal.html": 5.9025,
+    "deqp/functional/gles3/textureshadow/2d_array_linear_less.html": 6.2214,
+    "deqp/functional/gles3/textureshadow/2d_array_linear_less_or_equal.html": 5.6489,
+    "deqp/functional/gles3/textureshadow/2d_array_linear_mipmap_linear_always.html": 3.9133,
+    "deqp/functional/gles3/textureshadow/2d_array_linear_mipmap_linear_equal.html": 6.2243,
+    "deqp/functional/gles3/textureshadow/2d_array_linear_mipmap_linear_greater.html": 7.6809,
+    "deqp/functional/gles3/textureshadow/2d_array_linear_mipmap_linear_greater_or_equal.html": 7.8445,
+    "deqp/functional/gles3/textureshadow/2d_array_linear_mipmap_linear_less.html": 7.6333,
+    "deqp/functional/gles3/textureshadow/2d_array_linear_mipmap_linear_less_or_equal.html": 7.9095,
+    "deqp/functional/gles3/textureshadow/2d_array_linear_mipmap_linear_never.html": 3.9598,
+    "deqp/functional/gles3/textureshadow/2d_array_linear_mipmap_linear_not_equal.html": 6.5712,
+    "deqp/functional/gles3/textureshadow/2d_array_linear_mipmap_nearest_always.html": 3.6855,
+    "deqp/functional/gles3/textureshadow/2d_array_linear_mipmap_nearest_equal.html": 6.0514,
+    "deqp/functional/gles3/textureshadow/2d_array_linear_mipmap_nearest_greater.html": 5.9761,
+    "deqp/functional/gles3/textureshadow/2d_array_linear_mipmap_nearest_greater_or_equal.html": 5.9189,
+    "deqp/functional/gles3/textureshadow/2d_array_linear_mipmap_nearest_less.html": 6.0687,
+    "deqp/functional/gles3/textureshadow/2d_array_linear_mipmap_nearest_less_or_equal.html": 6.2073,
+    "deqp/functional/gles3/textureshadow/2d_array_linear_mipmap_nearest_never.html": 3.6778,
+    "deqp/functional/gles3/textureshadow/2d_array_linear_mipmap_nearest_not_equal.html": 5.8374,
+    "deqp/functional/gles3/textureshadow/2d_array_linear_never.html": 3.8011,
+    "deqp/functional/gles3/textureshadow/2d_array_linear_not_equal.html": 6.1843,
+    "deqp/functional/gles3/textureshadow/2d_array_nearest_always.html": 3.8806,
+    "deqp/functional/gles3/textureshadow/2d_array_nearest_equal.html": 3.6448,
+    "deqp/functional/gles3/textureshadow/2d_array_nearest_greater.html": 3.8739,
+    "deqp/functional/gles3/textureshadow/2d_array_nearest_greater_or_equal.html": 3.5777,
+    "deqp/functional/gles3/textureshadow/2d_array_nearest_less.html": 3.7137,
+    "deqp/functional/gles3/textureshadow/2d_array_nearest_less_or_equal.html": 3.762,
+    "deqp/functional/gles3/textureshadow/2d_array_nearest_mipmap_linear_always.html": 3.7378,
+    "deqp/functional/gles3/textureshadow/2d_array_nearest_mipmap_linear_equal.html": 5.5599,
+    "deqp/functional/gles3/textureshadow/2d_array_nearest_mipmap_linear_greater.html": 5.4236,
+    "deqp/functional/gles3/textureshadow/2d_array_nearest_mipmap_linear_greater_or_equal.html": 5.0052,
+    "deqp/functional/gles3/textureshadow/2d_array_nearest_mipmap_linear_less.html": 5.1198,
+    "deqp/functional/gles3/textureshadow/2d_array_nearest_mipmap_linear_less_or_equal.html": 5.1839,
+    "deqp/functional/gles3/textureshadow/2d_array_nearest_mipmap_linear_never.html": 3.7029,
+    "deqp/functional/gles3/textureshadow/2d_array_nearest_mipmap_linear_not_equal.html": 5.699,
+    "deqp/functional/gles3/textureshadow/2d_array_nearest_mipmap_nearest_always.html": 3.9615,
+    "deqp/functional/gles3/textureshadow/2d_array_nearest_mipmap_nearest_equal.html": 5.5891,
+    "deqp/functional/gles3/textureshadow/2d_array_nearest_mipmap_nearest_greater.html": 5.4922,
+    "deqp/functional/gles3/textureshadow/2d_array_nearest_mipmap_nearest_greater_or_equal.html": 5.2629,
+    "deqp/functional/gles3/textureshadow/2d_array_nearest_mipmap_nearest_less.html": 5.3344,
+    "deqp/functional/gles3/textureshadow/2d_array_nearest_mipmap_nearest_less_or_equal.html": 5.6799,
+    "deqp/functional/gles3/textureshadow/2d_array_nearest_mipmap_nearest_never.html": 4.0206,
+    "deqp/functional/gles3/textureshadow/2d_array_nearest_mipmap_nearest_not_equal.html": 5.6047,
+    "deqp/functional/gles3/textureshadow/2d_array_nearest_never.html": 3.6358,
+    "deqp/functional/gles3/textureshadow/2d_array_nearest_not_equal.html": 3.6196,
+    "deqp/functional/gles3/textureshadow/2d_linear_always.html": 3.7865,
+    "deqp/functional/gles3/textureshadow/2d_linear_equal.html": 5.7318,
+    "deqp/functional/gles3/textureshadow/2d_linear_greater.html": 5.4551,
+    "deqp/functional/gles3/textureshadow/2d_linear_greater_or_equal.html": 5.3471,
+    "deqp/functional/gles3/textureshadow/2d_linear_less.html": 5.7111,
+    "deqp/functional/gles3/textureshadow/2d_linear_less_or_equal.html": 5.5004,
+    "deqp/functional/gles3/textureshadow/2d_linear_mipmap_linear_always.html": 3.5964,
+    "deqp/functional/gles3/textureshadow/2d_linear_mipmap_linear_equal.html": 6.9353,
+    "deqp/functional/gles3/textureshadow/2d_linear_mipmap_linear_greater.html": 6.9942,
+    "deqp/functional/gles3/textureshadow/2d_linear_mipmap_linear_greater_or_equal.html": 7.7348,
+    "deqp/functional/gles3/textureshadow/2d_linear_mipmap_linear_less.html": 7.3648,
+    "deqp/functional/gles3/textureshadow/2d_linear_mipmap_linear_less_or_equal.html": 7.1089,
+    "deqp/functional/gles3/textureshadow/2d_linear_mipmap_linear_never.html": 3.481,
+    "deqp/functional/gles3/textureshadow/2d_linear_mipmap_linear_not_equal.html": 7.2594,
+    "deqp/functional/gles3/textureshadow/2d_linear_mipmap_nearest_always.html": 3.1999,
+    "deqp/functional/gles3/textureshadow/2d_linear_mipmap_nearest_equal.html": 5.7794,
+    "deqp/functional/gles3/textureshadow/2d_linear_mipmap_nearest_greater.html": 5.5348,
+    "deqp/functional/gles3/textureshadow/2d_linear_mipmap_nearest_greater_or_equal.html": 5.1075,
+    "deqp/functional/gles3/textureshadow/2d_linear_mipmap_nearest_less.html": 5.595,
+    "deqp/functional/gles3/textureshadow/2d_linear_mipmap_nearest_less_or_equal.html": 5.6685,
+    "deqp/functional/gles3/textureshadow/2d_linear_mipmap_nearest_never.html": 3.4772,
+    "deqp/functional/gles3/textureshadow/2d_linear_mipmap_nearest_not_equal.html": 5.4298,
+    "deqp/functional/gles3/textureshadow/2d_linear_never.html": 3.259,
+    "deqp/functional/gles3/textureshadow/2d_linear_not_equal.html": 5.778,
+    "deqp/functional/gles3/textureshadow/2d_nearest_always.html": 3.3017,
+    "deqp/functional/gles3/textureshadow/2d_nearest_equal.html": 3.6071,
+    "deqp/functional/gles3/textureshadow/2d_nearest_greater.html": 3.236,
+    "deqp/functional/gles3/textureshadow/2d_nearest_greater_or_equal.html": 3.2892,
+    "deqp/functional/gles3/textureshadow/2d_nearest_less.html": 3.5107,
+    "deqp/functional/gles3/textureshadow/2d_nearest_less_or_equal.html": 3.3408,
+    "deqp/functional/gles3/textureshadow/2d_nearest_mipmap_linear_always.html": 3.6836,
+    "deqp/functional/gles3/textureshadow/2d_nearest_mipmap_linear_equal.html": 6.0373,
+    "deqp/functional/gles3/textureshadow/2d_nearest_mipmap_linear_greater.html": 4.9147,
+    "deqp/functional/gles3/textureshadow/2d_nearest_mipmap_linear_greater_or_equal.html": 5.7789,
+    "deqp/functional/gles3/textureshadow/2d_nearest_mipmap_linear_less.html": 5.9373,
+    "deqp/functional/gles3/textureshadow/2d_nearest_mipmap_linear_less_or_equal.html": 5.1398,
+    "deqp/functional/gles3/textureshadow/2d_nearest_mipmap_linear_never.html": 3.4318,
+    "deqp/functional/gles3/textureshadow/2d_nearest_mipmap_linear_not_equal.html": 5.9988,
+    "deqp/functional/gles3/textureshadow/2d_nearest_mipmap_nearest_always.html": 3.547,
+    "deqp/functional/gles3/textureshadow/2d_nearest_mipmap_nearest_equal.html": 5.2248,
+    "deqp/functional/gles3/textureshadow/2d_nearest_mipmap_nearest_greater.html": 5.1707,
+    "deqp/functional/gles3/textureshadow/2d_nearest_mipmap_nearest_greater_or_equal.html": 4.5961,
+    "deqp/functional/gles3/textureshadow/2d_nearest_mipmap_nearest_less.html": 4.7484,
+    "deqp/functional/gles3/textureshadow/2d_nearest_mipmap_nearest_less_or_equal.html": 5.2838,
+    "deqp/functional/gles3/textureshadow/2d_nearest_mipmap_nearest_never.html": 3.5632,
+    "deqp/functional/gles3/textureshadow/2d_nearest_mipmap_nearest_not_equal.html": 5.1316,
+    "deqp/functional/gles3/textureshadow/2d_nearest_never.html": 3.1541,
+    "deqp/functional/gles3/textureshadow/2d_nearest_not_equal.html": 3.3208,
+    "deqp/functional/gles3/textureshadow/cube_linear_always.html": 6.1478,
+    "deqp/functional/gles3/textureshadow/cube_linear_equal.html": 8.2039,
+    "deqp/functional/gles3/textureshadow/cube_linear_greater.html": 7.9345,
+    "deqp/functional/gles3/textureshadow/cube_linear_greater_or_equal.html": 9.4329,
+    "deqp/functional/gles3/textureshadow/cube_linear_less.html": 9.1556,
+    "deqp/functional/gles3/textureshadow/cube_linear_less_or_equal.html": 8.1812,
+    "deqp/functional/gles3/textureshadow/cube_linear_mipmap_linear_always.html": 6.4151,
+    "deqp/functional/gles3/textureshadow/cube_linear_mipmap_linear_equal.html": 10.9826,
+    "deqp/functional/gles3/textureshadow/cube_linear_mipmap_linear_greater.html": 10.6756,
+    "deqp/functional/gles3/textureshadow/cube_linear_mipmap_linear_greater_or_equal.html": 10.73,
+    "deqp/functional/gles3/textureshadow/cube_linear_mipmap_linear_less.html": 10.8095,
+    "deqp/functional/gles3/textureshadow/cube_linear_mipmap_linear_less_or_equal.html": 10.8706,
+    "deqp/functional/gles3/textureshadow/cube_linear_mipmap_linear_never.html": 6.3635,
+    "deqp/functional/gles3/textureshadow/cube_linear_mipmap_linear_not_equal.html": 10.872,
+    "deqp/functional/gles3/textureshadow/cube_linear_mipmap_nearest_always.html": 6.1382,
+    "deqp/functional/gles3/textureshadow/cube_linear_mipmap_nearest_equal.html": 8.7132,
+    "deqp/functional/gles3/textureshadow/cube_linear_mipmap_nearest_greater.html": 8.7623,
+    "deqp/functional/gles3/textureshadow/cube_linear_mipmap_nearest_greater_or_equal.html": 9.6489,
+    "deqp/functional/gles3/textureshadow/cube_linear_mipmap_nearest_less.html": 9.1515,
+    "deqp/functional/gles3/textureshadow/cube_linear_mipmap_nearest_less_or_equal.html": 9.5091,
+    "deqp/functional/gles3/textureshadow/cube_linear_mipmap_nearest_never.html": 6.0431,
+    "deqp/functional/gles3/textureshadow/cube_linear_mipmap_nearest_not_equal.html": 8.8329,
+    "deqp/functional/gles3/textureshadow/cube_linear_never.html": 6.2148,
+    "deqp/functional/gles3/textureshadow/cube_linear_not_equal.html": 8.8146,
+    "deqp/functional/gles3/textureshadow/cube_nearest_always.html": 6.1353,
+    "deqp/functional/gles3/textureshadow/cube_nearest_equal.html": 6.8405,
+    "deqp/functional/gles3/textureshadow/cube_nearest_greater.html": 6.5643,
+    "deqp/functional/gles3/textureshadow/cube_nearest_greater_or_equal.html": 7.1791,
+    "deqp/functional/gles3/textureshadow/cube_nearest_less.html": 7.7329,
+    "deqp/functional/gles3/textureshadow/cube_nearest_less_or_equal.html": 7.1486,
+    "deqp/functional/gles3/textureshadow/cube_nearest_mipmap_linear_always.html": 7.0025,
+    "deqp/functional/gles3/textureshadow/cube_nearest_mipmap_linear_equal.html": 11.555,
+    "deqp/functional/gles3/textureshadow/cube_nearest_mipmap_linear_greater.html": 9.5731,
+    "deqp/functional/gles3/textureshadow/cube_nearest_mipmap_linear_greater_or_equal.html": 10.0319,
+    "deqp/functional/gles3/textureshadow/cube_nearest_mipmap_linear_less.html": 9.955,
+    "deqp/functional/gles3/textureshadow/cube_nearest_mipmap_linear_less_or_equal.html": 9.9701,
+    "deqp/functional/gles3/textureshadow/cube_nearest_mipmap_linear_never.html": 6.8861,
+    "deqp/functional/gles3/textureshadow/cube_nearest_mipmap_linear_not_equal.html": 10.786,
+    "deqp/functional/gles3/textureshadow/cube_nearest_mipmap_nearest_always.html": 6.5262,
+    "deqp/functional/gles3/textureshadow/cube_nearest_mipmap_nearest_equal.html": 8.7924,
+    "deqp/functional/gles3/textureshadow/cube_nearest_mipmap_nearest_greater.html": 8.8138,
+    "deqp/functional/gles3/textureshadow/cube_nearest_mipmap_nearest_greater_or_equal.html": 9.3621,
+    "deqp/functional/gles3/textureshadow/cube_nearest_mipmap_nearest_less.html": 8.7568,
+    "deqp/functional/gles3/textureshadow/cube_nearest_mipmap_nearest_less_or_equal.html": 8.5149,
+    "deqp/functional/gles3/textureshadow/cube_nearest_mipmap_nearest_never.html": 6.7117,
+    "deqp/functional/gles3/textureshadow/cube_nearest_mipmap_nearest_not_equal.html": 8.8778,
+    "deqp/functional/gles3/textureshadow/cube_nearest_never.html": 6.2355,
+    "deqp/functional/gles3/textureshadow/cube_nearest_not_equal.html": 7.4378,
+    "deqp/functional/gles3/texturespecification/basic_copyteximage2d.html": 30.372,
+    "deqp/functional/gles3/texturespecification/basic_copytexsubimage2d.html": 31.2791,
+    "deqp/functional/gles3/texturespecification/basic_teximage2d_2d_00.html": 11.2391,
+    "deqp/functional/gles3/texturespecification/basic_teximage2d_2d_01.html": 11.968,
+    "deqp/functional/gles3/texturespecification/basic_teximage2d_cube_00.html": 21.9158,
+    "deqp/functional/gles3/texturespecification/basic_teximage2d_cube_01.html": 20.903,
+    "deqp/functional/gles3/texturespecification/basic_teximage2d_cube_02.html": 21.9492,
+    "deqp/functional/gles3/texturespecification/basic_teximage2d_cube_03.html": 22.2901,
+    "deqp/functional/gles3/texturespecification/basic_teximage2d_cube_04.html": 19.0708,
+    "deqp/functional/gles3/texturespecification/basic_teximage3d_2d_array_00.html": 11.9435,
+    "deqp/functional/gles3/texturespecification/basic_teximage3d_2d_array_01.html": 9.7265,
+    "deqp/functional/gles3/texturespecification/basic_teximage3d_2d_array_02.html": 9.4667,
+    "deqp/functional/gles3/texturespecification/basic_teximage3d_3d_00.html": 8.5368,
+    "deqp/functional/gles3/texturespecification/basic_teximage3d_3d_01.html": 8.2829,
+    "deqp/functional/gles3/texturespecification/basic_teximage3d_3d_02.html": 7.7255,
+    "deqp/functional/gles3/texturespecification/basic_teximage3d_3d_03.html": 7.5678,
+    "deqp/functional/gles3/texturespecification/basic_teximage3d_3d_04.html": 7.2318,
+    "deqp/functional/gles3/texturespecification/basic_texsubimage2d_2d_00.html": 11.9923,
+    "deqp/functional/gles3/texturespecification/basic_texsubimage2d_2d_01.html": 10.272,
+    "deqp/functional/gles3/texturespecification/basic_texsubimage2d_2d_02.html": 9.7785,
+    "deqp/functional/gles3/texturespecification/basic_texsubimage2d_cube_00.html": 21.9277,
+    "deqp/functional/gles3/texturespecification/basic_texsubimage2d_cube_01.html": 21.0692,
+    "deqp/functional/gles3/texturespecification/basic_texsubimage2d_cube_02.html": 21.917,
+    "deqp/functional/gles3/texturespecification/basic_texsubimage2d_cube_03.html": 22.5583,
+    "deqp/functional/gles3/texturespecification/basic_texsubimage2d_cube_04.html": 18.266,
+    "deqp/functional/gles3/texturespecification/basic_texsubimage3d_00.html": 10.2702,
+    "deqp/functional/gles3/texturespecification/basic_texsubimage3d_01.html": 8.9075,
+    "deqp/functional/gles3/texturespecification/basic_texsubimage3d_02.html": 9.7994,
+    "deqp/functional/gles3/texturespecification/basic_texsubimage3d_03.html": 8.549,
+    "deqp/functional/gles3/texturespecification/basic_texsubimage3d_04.html": 8.2435,
+    "deqp/functional/gles3/texturespecification/random_teximage2d_2d.html": 7.744,
+    "deqp/functional/gles3/texturespecification/random_teximage2d_cube.html": 29.9238,
+    "deqp/functional/gles3/texturespecification/teximage2d_align.html": 24.1882,
+    "deqp/functional/gles3/texturespecification/teximage2d_depth.html": 4.5094,
+    "deqp/functional/gles3/texturespecification/teximage2d_depth_pbo.html": 5.4586,
+    "deqp/functional/gles3/texturespecification/teximage2d_pbo_2d_00.html": 6.5144,
+    "deqp/functional/gles3/texturespecification/teximage2d_pbo_2d_01.html": 7.2888,
+    "deqp/functional/gles3/texturespecification/teximage2d_pbo_cube_00.html": 15.4128,
+    "deqp/functional/gles3/texturespecification/teximage2d_pbo_cube_01.html": 17.7247,
+    "deqp/functional/gles3/texturespecification/teximage2d_pbo_cube_02.html": 15.6067,
+    "deqp/functional/gles3/texturespecification/teximage2d_pbo_cube_03.html": 15.8486,
+    "deqp/functional/gles3/texturespecification/teximage2d_pbo_cube_04.html": 16.7187,
+    "deqp/functional/gles3/texturespecification/teximage2d_pbo_params.html": 6.1065,
+    "deqp/functional/gles3/texturespecification/teximage2d_unpack_params.html": 3.8678,
+    "deqp/functional/gles3/texturespecification/teximage3d_depth.html": 5.3977,
+    "deqp/functional/gles3/texturespecification/teximage3d_depth_pbo.html": 4.7055,
+    "deqp/functional/gles3/texturespecification/teximage3d_pbo_2d_array_00.html": 6.5899,
+    "deqp/functional/gles3/texturespecification/teximage3d_pbo_2d_array_01.html": 7.4512,
+    "deqp/functional/gles3/texturespecification/teximage3d_pbo_3d_00.html": 6.2602,
+    "deqp/functional/gles3/texturespecification/teximage3d_pbo_3d_01.html": 7.2646,
+    "deqp/functional/gles3/texturespecification/teximage3d_pbo_params.html": 4.2194,
+    "deqp/functional/gles3/texturespecification/teximage3d_unpack_params.html": 4.6177,
+    "deqp/functional/gles3/texturespecification/texstorage2d_format_2d_00.html": 10.5246,
+    "deqp/functional/gles3/texturespecification/texstorage2d_format_2d_01.html": 9.0155,
+    "deqp/functional/gles3/texturespecification/texstorage2d_format_2d_02.html": 9.8367,
+    "deqp/functional/gles3/texturespecification/texstorage2d_format_cube_00.html": 18.3651,
+    "deqp/functional/gles3/texturespecification/texstorage2d_format_cube_01.html": 19.3377,
+    "deqp/functional/gles3/texturespecification/texstorage2d_format_cube_02.html": 17.3963,
+    "deqp/functional/gles3/texturespecification/texstorage2d_format_cube_03.html": 18.3248,
+    "deqp/functional/gles3/texturespecification/texstorage2d_format_cube_04.html": 17.0192,
+    "deqp/functional/gles3/texturespecification/texstorage2d_format_depth_stencil.html": 15.1049,
+    "deqp/functional/gles3/texturespecification/texstorage2d_format_size.html": 14.8131,
+    "deqp/functional/gles3/texturespecification/texstorage3d_format_2d_array_00.html": 8.7266,
+    "deqp/functional/gles3/texturespecification/texstorage3d_format_2d_array_01.html": 6.9242,
+    "deqp/functional/gles3/texturespecification/texstorage3d_format_2d_array_02.html": 6.651,
+    "deqp/functional/gles3/texturespecification/texstorage3d_format_3d_00.html": 10.1953,
+    "deqp/functional/gles3/texturespecification/texstorage3d_format_3d_01.html": 9.8527,
+    "deqp/functional/gles3/texturespecification/texstorage3d_format_3d_02.html": 10.9833,
+    "deqp/functional/gles3/texturespecification/texstorage3d_format_3d_03.html": 10.6222,
+    "deqp/functional/gles3/texturespecification/texstorage3d_format_depth_stencil.html": 3.8225,
+    "deqp/functional/gles3/texturespecification/texstorage3d_format_size.html": 6.3556,
+    "deqp/functional/gles3/texturespecification/texsubimage2d_align.html": 40.4617,
+    "deqp/functional/gles3/texturespecification/texsubimage2d_depth.html": 3.7857,
+    "deqp/functional/gles3/texturespecification/texsubimage2d_empty_tex.html": 11.2365,
+    "deqp/functional/gles3/texturespecification/texsubimage2d_pbo_2d_00.html": 8.2379,
+    "deqp/functional/gles3/texturespecification/texsubimage2d_pbo_2d_01.html": 7.9177,
+    "deqp/functional/gles3/texturespecification/texsubimage2d_pbo_cube_00.html": 17.1927,
+    "deqp/functional/gles3/texturespecification/texsubimage2d_pbo_cube_01.html": 17.251,
+    "deqp/functional/gles3/texturespecification/texsubimage2d_pbo_cube_02.html": 19.0907,
+    "deqp/functional/gles3/texturespecification/texsubimage2d_pbo_cube_03.html": 17.4239,
+    "deqp/functional/gles3/texturespecification/texsubimage2d_pbo_cube_04.html": 17.0116,
+    "deqp/functional/gles3/texturespecification/texsubimage2d_pbo_params.html": 10.8445,
+    "deqp/functional/gles3/texturespecification/texsubimage2d_unpack_params.html": 5.5711,
+    "deqp/functional/gles3/texturespecification/texsubimage3d_depth.html": 5.6469,
+    "deqp/functional/gles3/texturespecification/texsubimage3d_pbo_2d_array_00.html": 9.146,
+    "deqp/functional/gles3/texturespecification/texsubimage3d_pbo_2d_array_01.html": 9.6661,
+    "deqp/functional/gles3/texturespecification/texsubimage3d_pbo_3d_00.html": 10.6188,
+    "deqp/functional/gles3/texturespecification/texsubimage3d_pbo_3d_01.html": 11.5742,
+    "deqp/functional/gles3/texturespecification/texsubimage3d_pbo_params.html": 4.215,
+    "deqp/functional/gles3/texturespecification/texsubimage3d_unpack_params.html": 5.4319,
+    "deqp/functional/gles3/texturestatequery.html": 2.0966,
+    "deqp/functional/gles3/texturewrap/eac_r11_npot.html": 0.3073,
+    "deqp/functional/gles3/texturewrap/eac_r11_pot.html": 0.3193,
+    "deqp/functional/gles3/texturewrap/eac_rg11_npot.html": 0.2999,
+    "deqp/functional/gles3/texturewrap/eac_rg11_pot.html": 0.3101,
+    "deqp/functional/gles3/texturewrap/eac_signed_r11_npot.html": 0.2643,
+    "deqp/functional/gles3/texturewrap/eac_signed_r11_pot.html": 0.341,
+    "deqp/functional/gles3/texturewrap/eac_signed_rg11_npot.html": 0.282,
+    "deqp/functional/gles3/texturewrap/eac_signed_rg11_pot.html": 0.3605,
+    "deqp/functional/gles3/texturewrap/etc2_eac_rgba8_npot.html": 0.4081,
+    "deqp/functional/gles3/texturewrap/etc2_eac_rgba8_pot.html": 0.2934,
+    "deqp/functional/gles3/texturewrap/etc2_eac_srgb8_alpha8_npot.html": 0.2731,
+    "deqp/functional/gles3/texturewrap/etc2_eac_srgb8_alpha8_pot.html": 0.2536,
+    "deqp/functional/gles3/texturewrap/etc2_rgb8_npot.html": 0.3028,
+    "deqp/functional/gles3/texturewrap/etc2_rgb8_pot.html": 0.3057,
+    "deqp/functional/gles3/texturewrap/etc2_rgb8_punchthrough_alpha1_npot.html": 0.3136,
+    "deqp/functional/gles3/texturewrap/etc2_rgb8_punchthrough_alpha1_pot.html": 0.5252,
+    "deqp/functional/gles3/texturewrap/etc2_srgb8_npot.html": 0.2592,
+    "deqp/functional/gles3/texturewrap/etc2_srgb8_pot.html": 0.2931,
+    "deqp/functional/gles3/texturewrap/etc2_srgb8_punchthrough_alpha1_npot.html": 0.2835,
+    "deqp/functional/gles3/texturewrap/etc2_srgb8_punchthrough_alpha1_pot.html": 0.2692,
+    "deqp/functional/gles3/texturewrap/rgba8_npot.html": 9.9138,
+    "deqp/functional/gles3/texturewrap/rgba8_pot.html": 9.7601,
+    "deqp/functional/gles3/transformfeedback/array_element_interleaved_lines.html": 2.0453,
+    "deqp/functional/gles3/transformfeedback/array_element_interleaved_points.html": 2.1438,
+    "deqp/functional/gles3/transformfeedback/array_element_interleaved_triangles.html": 2.7311,
+    "deqp/functional/gles3/transformfeedback/array_element_separate_lines.html": 2.0179,
+    "deqp/functional/gles3/transformfeedback/array_element_separate_points.html": 2.5684,
+    "deqp/functional/gles3/transformfeedback/array_element_separate_triangles.html": 2.1849,
+    "deqp/functional/gles3/transformfeedback/array_interleaved_lines.html": 2.2803,
+    "deqp/functional/gles3/transformfeedback/array_interleaved_points.html": 2.9673,
+    "deqp/functional/gles3/transformfeedback/array_interleaved_triangles.html": 2.5862,
+    "deqp/functional/gles3/transformfeedback/array_separate_lines.html": 2.0994,
+    "deqp/functional/gles3/transformfeedback/array_separate_points.html": 2.3726,
+    "deqp/functional/gles3/transformfeedback/array_separate_triangles.html": 2.6257,
+    "deqp/functional/gles3/transformfeedback/basic_types_interleaved_lines.html": 35.3355,
+    "deqp/functional/gles3/transformfeedback/basic_types_interleaved_points.html": 33.2702,
+    "deqp/functional/gles3/transformfeedback/basic_types_interleaved_triangles.html": 34.3474,
+    "deqp/functional/gles3/transformfeedback/basic_types_separate_lines.html": 21.4536,
+    "deqp/functional/gles3/transformfeedback/basic_types_separate_points.html": 22.8867,
+    "deqp/functional/gles3/transformfeedback/basic_types_separate_triangles.html": 22.3308,
+    "deqp/functional/gles3/transformfeedback/interpolation_centroid.html": 10.6019,
+    "deqp/functional/gles3/transformfeedback/interpolation_flat.html": 11.6008,
+    "deqp/functional/gles3/transformfeedback/interpolation_smooth.html": 10.9689,
+    "deqp/functional/gles3/transformfeedback/point_size.html": 4.1158,
+    "deqp/functional/gles3/transformfeedback/position.html": 4.2093,
+    "deqp/functional/gles3/transformfeedback/random_interleaved_lines.html": 6.5097,
+    "deqp/functional/gles3/transformfeedback/random_interleaved_points.html": 6.3677,
+    "deqp/functional/gles3/transformfeedback/random_interleaved_triangles.html": 5.4392,
+    "deqp/functional/gles3/transformfeedback/random_separate_lines.html": 6.3537,
+    "deqp/functional/gles3/transformfeedback/random_separate_points.html": 6.7831,
+    "deqp/functional/gles3/transformfeedback/random_separate_triangles.html": 6.3406,
+    "deqp/functional/gles3/uniformapi/info_query.html": 15.116,
+    "deqp/functional/gles3/uniformapi/random.html": 6.9361,
+    "deqp/functional/gles3/uniformapi/value_assigned.html": 38.1869,
+    "deqp/functional/gles3/uniformapi/value_initial.html": 16.0341,
+    "deqp/functional/gles3/uniformbuffers/instance_array_basic_type.html": 6.4611,
+    "deqp/functional/gles3/uniformbuffers/multi_basic_types.html": 1.4128,
+    "deqp/functional/gles3/uniformbuffers/multi_nested_struct.html": 2.0127,
+    "deqp/functional/gles3/uniformbuffers/random.html": 20.022,
+    "deqp/functional/gles3/uniformbuffers/single_basic_array.html": 6.9601,
+    "deqp/functional/gles3/uniformbuffers/single_basic_type.html": 15.4633,
+    "deqp/functional/gles3/uniformbuffers/single_nested_struct.html": 1.9016,
+    "deqp/functional/gles3/uniformbuffers/single_nested_struct_array.html": 1.9859,
+    "deqp/functional/gles3/uniformbuffers/single_struct.html": 1.3369,
+    "deqp/functional/gles3/uniformbuffers/single_struct_array.html": 3.2203,
+    "deqp/functional/gles3/vertexarrayobject.html": 2.4155,
+    "deqp/functional/gles3/vertexarrays/multiple_attributes.count.html": 20.3589,
+    "deqp/functional/gles3/vertexarrays/multiple_attributes.output.html": 57.9566,
+    "deqp/functional/gles3/vertexarrays/multiple_attributes.storage.html": 5.0709,
+    "deqp/functional/gles3/vertexarrays/multiple_attributes.stride.html": 46.0135,
+    "deqp/functional/gles3/vertexarrays/single_attribute.first.html": 54.381,
+    "deqp/functional/gles3/vertexarrays/single_attribute.normalize.html": 36.0473,
+    "deqp/functional/gles3/vertexarrays/single_attribute.offset.html": 40.3913,
+    "deqp/functional/gles3/vertexarrays/single_attribute.output_type.byte.html": 27.5109,
+    "deqp/functional/gles3/vertexarrays/single_attribute.output_type.float.html": 18.266,
+    "deqp/functional/gles3/vertexarrays/single_attribute.output_type.half.html": 20.1996,
+    "deqp/functional/gles3/vertexarrays/single_attribute.output_type.int.html": 25.683,
+    "deqp/functional/gles3/vertexarrays/single_attribute.output_type.int_2_10_10_10.html": 11.3981,
+    "deqp/functional/gles3/vertexarrays/single_attribute.output_type.short.html": 25.7891,
+    "deqp/functional/gles3/vertexarrays/single_attribute.output_type.unsigned_byte.html": 25.8998,
+    "deqp/functional/gles3/vertexarrays/single_attribute.output_type.unsigned_int.html": 25.4544,
+    "deqp/functional/gles3/vertexarrays/single_attribute.output_type.unsigned_int_2_10_10_10.html": 8.2816,
+    "deqp/functional/gles3/vertexarrays/single_attribute.output_type.unsigned_short.html": 27.3873,
+    "deqp/functional/gles3/vertexarrays/single_attribute.stride.html": 30.5422,
+    "deqp/functional/gles3/vertexarrays/single_attribute.usage.dynamic_copy.html": 18.9174,
+    "deqp/functional/gles3/vertexarrays/single_attribute.usage.dynamic_draw.html": 19.8194,
+    "deqp/functional/gles3/vertexarrays/single_attribute.usage.dynamic_read.html": 19.6885,
+    "deqp/functional/gles3/vertexarrays/single_attribute.usage.static_copy.html": 19.6368,
+    "deqp/functional/gles3/vertexarrays/single_attribute.usage.static_draw.html": 20.4549,
+    "deqp/functional/gles3/vertexarrays/single_attribute.usage.static_read.html": 22.1891,
+    "deqp/functional/gles3/vertexarrays/single_attribute.usage.stream_copy.html": 20.9253,
+    "deqp/functional/gles3/vertexarrays/single_attribute.usage.stream_draw.html": 20.0795,
+    "deqp/functional/gles3/vertexarrays/single_attribute.usage.stream_read.html": 19.8545
   }
 }
\ No newline at end of file
diff --git a/content/test/data/gpu/webgl_conformance_tests_output.json b/content/test/data/gpu/webgl_conformance_tests_output.json
index a5da7910f..44a2ff2 100644
--- a/content/test/data/gpu/webgl_conformance_tests_output.json
+++ b/content/test/data/gpu/webgl_conformance_tests_output.json
@@ -1,950 +1,964 @@
 {
   "times": {
-    "WebglExtension_ANGLE_instanced_arrays": 0.0811,
-    "WebglExtension_EXT_blend_minmax": 0.5485,
-    "WebglExtension_EXT_color_buffer_half_float": 0.4396,
-    "WebglExtension_EXT_disjoint_timer_query": 0.4694,
-    "WebglExtension_EXT_float_blend": 0.0869,
-    "WebglExtension_EXT_frag_depth": 0.0593,
-    "WebglExtension_EXT_sRGB": 0.0498,
-    "WebglExtension_EXT_shader_texture_lod": 0.0587,
-    "WebglExtension_EXT_texture_filter_anisotropic": 0.0505,
-    "WebglExtension_KHR_parallel_shader_compile": 0.0489,
-    "WebglExtension_OES_element_index_uint": 0.0533,
-    "WebglExtension_OES_fbo_render_mipmap": 0.0581,
-    "WebglExtension_OES_standard_derivatives": 0.0509,
-    "WebglExtension_OES_texture_float": 0.053,
-    "WebglExtension_OES_texture_float_linear": 0.0503,
-    "WebglExtension_OES_texture_half_float": 0.0516,
-    "WebglExtension_OES_texture_half_float_linear": 0.0491,
-    "WebglExtension_OES_vertex_array_object": 0.0498,
-    "WebglExtension_TestCoverage": 0.0486,
-    "WebglExtension_WEBGL_color_buffer_float": 0.0535,
+    "WebglExtension_ANGLE_instanced_arrays": 0.2108,
+    "WebglExtension_EXT_blend_minmax": 0.1965,
+    "WebglExtension_EXT_color_buffer_half_float": 0.1634,
+    "WebglExtension_EXT_disjoint_timer_query": 0.0684,
+    "WebglExtension_EXT_float_blend": 0.1687,
+    "WebglExtension_EXT_frag_depth": 0.2377,
+    "WebglExtension_EXT_sRGB": 0.1739,
+    "WebglExtension_EXT_shader_texture_lod": 0.1956,
+    "WebglExtension_EXT_texture_compression_bptc": 0.0821,
+    "WebglExtension_EXT_texture_compression_rgtc": 0.0771,
+    "WebglExtension_EXT_texture_filter_anisotropic": 0.1892,
+    "WebglExtension_KHR_parallel_shader_compile": 0.4924,
+    "WebglExtension_OES_element_index_uint": 0.218,
+    "WebglExtension_OES_fbo_render_mipmap": 0.7368,
+    "WebglExtension_OES_standard_derivatives": 0.1756,
+    "WebglExtension_OES_texture_float": 0.0761,
+    "WebglExtension_OES_texture_float_linear": 0.4093,
+    "WebglExtension_OES_texture_half_float": 0.2881,
+    "WebglExtension_OES_texture_half_float_linear": 0.068,
+    "WebglExtension_OES_vertex_array_object": 0.321,
+    "WebglExtension_TestCoverage": 0.1716,
+    "WebglExtension_WEBGL_color_buffer_float": 0.2936,
     "WebglExtension_WEBGL_compressed_texture_astc": 0.0,
     "WebglExtension_WEBGL_compressed_texture_etc": 0.0,
     "WebglExtension_WEBGL_compressed_texture_etc1": 0.0,
     "WebglExtension_WEBGL_compressed_texture_pvrtc": 0.0,
-    "WebglExtension_WEBGL_compressed_texture_s3tc": 0.0479,
+    "WebglExtension_WEBGL_compressed_texture_s3tc": 0.2856,
     "WebglExtension_WEBGL_compressed_texture_s3tc_srgb": 0.0,
-    "WebglExtension_WEBGL_debug_renderer_info": 0.0488,
-    "WebglExtension_WEBGL_debug_shaders": 0.0491,
-    "WebglExtension_WEBGL_depth_texture": 0.0493,
-    "WebglExtension_WEBGL_draw_buffers": 0.0742,
-    "WebglExtension_WEBGL_lose_context": 0.0494,
-    "WebglExtension_WEBGL_multi_draw": 0.0665,
-    "WebglExtension_WEBGL_video_texture": 0.0504,
-    "conformance/attribs/gl-bindAttribLocation-aliasing.html": 0.2837,
-    "conformance/attribs/gl-bindAttribLocation-matrix.html": 0.3872,
-    "conformance/attribs/gl-bindAttribLocation-nonexistent-attribute.html": 0.0736,
-    "conformance/attribs/gl-bindAttribLocation-repeated.html": 0.3004,
-    "conformance/attribs/gl-disabled-vertex-attrib-update.html": 0.4446,
-    "conformance/attribs/gl-disabled-vertex-attrib.html": 0.9998,
-    "conformance/attribs/gl-enable-vertex-attrib.html": 0.2817,
-    "conformance/attribs/gl-matrix-attributes.html": 0.9868,
-    "conformance/attribs/gl-vertex-attrib-context-switch.html": 0.6031,
-    "conformance/attribs/gl-vertex-attrib-render.html": 0.2792,
-    "conformance/attribs/gl-vertex-attrib-unconsumed-out-of-bounds.html": 0.1969,
-    "conformance/attribs/gl-vertex-attrib-zero-issues.html": 0.5157,
-    "conformance/attribs/gl-vertex-attrib.html": 0.7572,
-    "conformance/attribs/gl-vertexattribpointer-offsets.html": 0.3664,
-    "conformance/attribs/gl-vertexattribpointer.html": 1.0057,
-    "conformance/buffers/buffer-bind-test.html": 0.1671,
-    "conformance/buffers/buffer-data-and-buffer-sub-data.html": 0.1031,
-    "conformance/buffers/buffer-data-array-buffer-delete.html": 2.0837,
-    "conformance/buffers/buffer-data-dynamic-delay.html": 0.3275,
-    "conformance/buffers/buffer-uninitialized.html": 0.1811,
-    "conformance/buffers/element-array-buffer-delete-recreate.html": 0.2705,
-    "conformance/buffers/index-validation-copies-indices.html": 0.253,
-    "conformance/buffers/index-validation-crash-with-buffer-sub-data.html": 0.0688,
-    "conformance/buffers/index-validation-large-buffer.html": 0.2793,
-    "conformance/buffers/index-validation-verifies-too-many-indices.html": 0.1835,
-    "conformance/buffers/index-validation-with-resized-buffer.html": 0.081,
-    "conformance/buffers/index-validation.html": 0.2964,
-    "conformance/buffers/vertex-buffer-updated-after-draw.html": 0.3732,
-    "conformance/canvas/buffer-offscreen-test.html": 0.1818,
-    "conformance/canvas/buffer-preserve-test.html": 0.1673,
-    "conformance/canvas/canvas-test.html": 0.4942,
-    "conformance/canvas/canvas-zero-size.html": 0.0743,
-    "conformance/canvas/draw-static-webgl-to-multiple-canvas-test.html": 0.8454,
-    "conformance/canvas/draw-webgl-to-canvas-test.html": 0.8012,
-    "conformance/canvas/drawingbuffer-hd-dpi-test.html": 0.9349,
-    "conformance/canvas/drawingbuffer-static-canvas-test.html": 0.4336,
-    "conformance/canvas/drawingbuffer-test.html": 0.1496,
-    "conformance/canvas/framebuffer-bindings-affected-by-to-data-url.html": 0.369,
-    "conformance/canvas/framebuffer-bindings-unaffected-on-resize.html": 0.1946,
-    "conformance/canvas/rapid-resizing.html": 2.8456,
-    "conformance/canvas/render-after-resize-test.html": 0.2988,
-    "conformance/canvas/texture-bindings-unaffected-on-resize.html": 0.1779,
-    "conformance/canvas/to-data-url-test.html": 0.7962,
-    "conformance/canvas/viewport-unchanged-upon-resize.html": 0.0919,
-    "conformance/context/constants-and-properties.html": 0.1887,
-    "conformance/context/context-attribute-preserve-drawing-buffer.html": 0.4034,
-    "conformance/context/context-attributes-alpha-depth-stencil-antialias.html": 0.6869,
-    "conformance/context/context-creation-and-destruction.html": 0.814,
-    "conformance/context/context-creation.html": 1.1428,
-    "conformance/context/context-eviction-with-garbage-collection.html": 0.9342,
-    "conformance/context/context-hidden-alpha.html": 0.277,
-    "conformance/context/context-lost-restored.html": 0.1951,
-    "conformance/context/context-lost.html": 0.3182,
-    "conformance/context/context-no-alpha-fbo-with-alpha.html": 0.182,
-    "conformance/context/context-release-upon-reload.html": 2.3358,
-    "conformance/context/context-release-with-workers.html": 3.1468,
-    "conformance/context/context-size-change.html": 0.1859,
-    "conformance/context/context-type-test.html": 0.1467,
-    "conformance/context/incorrect-context-object-behaviour.html": 0.1676,
-    "conformance/context/methods.html": 0.1252,
-    "conformance/context/premultiplyalpha-test.html": 0.6517,
-    "conformance/context/user-defined-properties-on-context.html": 0.1403,
-    "conformance/extensions/angle-instanced-arrays-out-of-bounds.html": 0.9838,
-    "conformance/extensions/angle-instanced-arrays.html": 0.5319,
-    "conformance/extensions/ext-blend-minmax.html": 0.5332,
-    "conformance/extensions/ext-disjoint-timer-query.html": 8.5883,
-    "conformance/extensions/ext-float-blend.html": 0.3852,
-    "conformance/extensions/ext-frag-depth.html": 0.6227,
-    "conformance/extensions/ext-sRGB.html": 0.4072,
-    "conformance/extensions/ext-shader-texture-lod.html": 1.1368,
-    "conformance/extensions/ext-texture-compression-bptc.html": 0.1773,
-    "conformance/extensions/ext-texture-compression-rgtc.html": 0.2254,
-    "conformance/extensions/ext-texture-filter-anisotropic.html": 0.2658,
-    "conformance/extensions/get-extension.html": 0.4461,
-    "conformance/extensions/oes-element-index-uint.html": 0.5422,
-    "conformance/extensions/oes-fbo-render-mipmap.html": 0.1233,
-    "conformance/extensions/oes-standard-derivatives.html": 0.5345,
-    "conformance/extensions/oes-texture-float-linear.html": 0.9727,
-    "conformance/extensions/oes-texture-float-with-canvas.html": 1.357,
-    "conformance/extensions/oes-texture-float-with-image-data.html": 0.8988,
-    "conformance/extensions/oes-texture-float-with-image.html": 0.5421,
-    "conformance/extensions/oes-texture-float-with-video.html": 3.6372,
-    "conformance/extensions/oes-texture-float.html": 0.766,
-    "conformance/extensions/oes-texture-half-float-linear.html": 0.9558,
-    "conformance/extensions/oes-texture-half-float-with-canvas.html": 1.5804,
-    "conformance/extensions/oes-texture-half-float-with-image-data.html": 0.405,
-    "conformance/extensions/oes-texture-half-float-with-image.html": 0.264,
-    "conformance/extensions/oes-texture-half-float-with-video.html": 2.2716,
-    "conformance/extensions/oes-texture-half-float.html": 0.4554,
-    "conformance/extensions/oes-vertex-array-object-bufferData.html": 0.3058,
-    "conformance/extensions/oes-vertex-array-object.html": 0.3467,
-    "conformance/extensions/webgl-compressed-texture-astc.html": 0.4543,
-    "conformance/extensions/webgl-compressed-texture-etc.html": 0.1471,
-    "conformance/extensions/webgl-compressed-texture-etc1.html": 0.0996,
-    "conformance/extensions/webgl-compressed-texture-pvrtc.html": 0.2746,
-    "conformance/extensions/webgl-compressed-texture-s3tc-srgb.html": 0.0809,
-    "conformance/extensions/webgl-compressed-texture-s3tc.html": 0.7964,
-    "conformance/extensions/webgl-compressed-texture-size-limit.html": 4.6437,
-    "conformance/extensions/webgl-debug-renderer-info.html": 0.0915,
-    "conformance/extensions/webgl-debug-shaders.html": 0.1857,
-    "conformance/extensions/webgl-depth-texture.html": 0.2754,
-    "conformance/extensions/webgl-draw-buffers-broadcast-return.html": 0.6904,
-    "conformance/extensions/webgl-draw-buffers-framebuffer-unsupported.html": 0.3175,
-    "conformance/extensions/webgl-draw-buffers-max-draw-buffers.html": 0.4777,
-    "conformance/extensions/webgl-draw-buffers.html": 1.0769,
-    "conformance/extensions/webgl-multi-draw.html": 1.0079,
-    "conformance/glsl/bugs/angle-ambiguous-function-call.html": 0.1925,
-    "conformance/glsl/bugs/angle-constructor-invalid-parameters.html": 0.3209,
-    "conformance/glsl/bugs/angle-d3d11-compiler-error.html": 0.2344,
-    "conformance/glsl/bugs/angle-dx-variable-bug.html": 0.1393,
-    "conformance/glsl/bugs/array-of-struct-with-int-first-position.html": 0.4603,
-    "conformance/glsl/bugs/assign-to-swizzled-twice-in-function.html": 0.3443,
-    "conformance/glsl/bugs/bool-type-cast-bug-int-float.html": 0.3972,
-    "conformance/glsl/bugs/compare-loop-index-to-uniform.html": 0.2638,
-    "conformance/glsl/bugs/complex-glsl-does-not-crash.html": 3.1247,
-    "conformance/glsl/bugs/compound-assignment-type-combination.html": 2.2814,
-    "conformance/glsl/bugs/conditional-discard-in-loop.html": 0.3407,
-    "conformance/glsl/bugs/conditional-discard-optimization.html": 0.6279,
-    "conformance/glsl/bugs/conditional-texture-fetch.html": 0.367,
-    "conformance/glsl/bugs/constant-precision-qualifier.html": 0.5562,
-    "conformance/glsl/bugs/essl3-shaders-with-webgl1.html": 0.4169,
-    "conformance/glsl/bugs/floor-div-cos-should-not-truncate.html": 0.598,
-    "conformance/glsl/bugs/floored-division-accuracy.html": 0.1053,
-    "conformance/glsl/bugs/fragcoord-linking-bug.html": 0.3275,
-    "conformance/glsl/bugs/gl-fragcoord-multisampling-bug.html": 0.7048,
-    "conformance/glsl/bugs/global-invariant-does-not-leak-across-shaders.html": 0.4094,
-    "conformance/glsl/bugs/if-return-and-elseif.html": 0.2413,
-    "conformance/glsl/bugs/in-parameter-passed-as-inout-argument-and-global.html": 0.4113,
-    "conformance/glsl/bugs/init-array-with-loop.html": 0.4036,
-    "conformance/glsl/bugs/invariant-does-not-leak-across-shaders.html": 0.3094,
-    "conformance/glsl/bugs/logic-inside-block-without-braces.html": 0.3933,
-    "conformance/glsl/bugs/long-expressions-should-not-crash.html": 1.2039,
-    "conformance/glsl/bugs/loop-if-loop-gradient.html": 0.3759,
-    "conformance/glsl/bugs/modulo-arithmetic-accuracy.html": 0.3753,
-    "conformance/glsl/bugs/multiplication-assignment.html": 0.26,
-    "conformance/glsl/bugs/nested-functions-should-not-crash.html": 0.5544,
-    "conformance/glsl/bugs/nested-loops-with-break-and-continue.html": 0.4891,
-    "conformance/glsl/bugs/nested-sequence-operator.html": 0.4006,
-    "conformance/glsl/bugs/pow-of-small-constant-in-user-defined-function.html": 0.3445,
-    "conformance/glsl/bugs/pow-with-constant-exponent-should-not-crash.html": 0.4644,
-    "conformance/glsl/bugs/qualcomm-crash.html": 0.372,
-    "conformance/glsl/bugs/qualcomm-loop-with-continue-crash.html": 0.3896,
-    "conformance/glsl/bugs/sampler-array-struct-function-arg.html": 0.4019,
-    "conformance/glsl/bugs/sampler-array-using-loop-index.html": 0.383,
-    "conformance/glsl/bugs/sampler-struct-function-arg.html": 0.2464,
-    "conformance/glsl/bugs/sequence-operator-evaluation-order.html": 0.3901,
-    "conformance/glsl/bugs/sketchfab-lighting-shader-crash.html": 0.3719,
-    "conformance/glsl/bugs/struct-constructor-highp-bug.html": 0.2379,
-    "conformance/glsl/bugs/struct-with-single-member-constructor.html": 0.3399,
-    "conformance/glsl/bugs/temp-expressions-should-not-crash.html": 1.564,
-    "conformance/glsl/bugs/unary-minus-operator-float-bug.html": 0.3184,
-    "conformance/glsl/bugs/undefined-index-should-not-crash.html": 0.3747,
-    "conformance/glsl/bugs/uniforms-should-not-lose-values.html": 0.3632,
-    "conformance/glsl/bugs/varying-arrays-should-not-be-reversed.html": 0.2767,
-    "conformance/glsl/bugs/vector-scalar-arithmetic-inside-loop-complex.html": 0.3681,
-    "conformance/glsl/bugs/vector-scalar-arithmetic-inside-loop.html": 0.4745,
-    "conformance/glsl/constructors/glsl-construct-bvec2.html": 0.7066,
-    "conformance/glsl/constructors/glsl-construct-bvec3.html": 1.2259,
-    "conformance/glsl/constructors/glsl-construct-bvec4.html": 1.0729,
-    "conformance/glsl/constructors/glsl-construct-ivec2.html": 0.8775,
-    "conformance/glsl/constructors/glsl-construct-ivec3.html": 0.9843,
-    "conformance/glsl/constructors/glsl-construct-ivec4.html": 1.2314,
-    "conformance/glsl/constructors/glsl-construct-mat2.html": 1.0314,
-    "conformance/glsl/constructors/glsl-construct-mat3.html": 0.7633,
-    "conformance/glsl/constructors/glsl-construct-mat4.html": 0.7596,
-    "conformance/glsl/constructors/glsl-construct-vec-mat-corner-cases.html": 0.5321,
-    "conformance/glsl/constructors/glsl-construct-vec-mat-index.html": 0.4238,
-    "conformance/glsl/constructors/glsl-construct-vec2.html": 0.9701,
-    "conformance/glsl/constructors/glsl-construct-vec3.html": 0.753,
-    "conformance/glsl/constructors/glsl-construct-vec4.html": 1.2109,
-    "conformance/glsl/functions/glsl-function-abs.html": 0.6747,
-    "conformance/glsl/functions/glsl-function-acos.html": 0.7841,
-    "conformance/glsl/functions/glsl-function-asin.html": 0.8999,
-    "conformance/glsl/functions/glsl-function-atan-xy.html": 1.527,
-    "conformance/glsl/functions/glsl-function-atan.html": 0.9456,
-    "conformance/glsl/functions/glsl-function-ceil.html": 0.9201,
-    "conformance/glsl/functions/glsl-function-clamp-float.html": 0.7804,
-    "conformance/glsl/functions/glsl-function-clamp-gentype.html": 0.8856,
-    "conformance/glsl/functions/glsl-function-cos.html": 0.8458,
-    "conformance/glsl/functions/glsl-function-cross.html": 0.5993,
-    "conformance/glsl/functions/glsl-function-distance.html": 0.8088,
-    "conformance/glsl/functions/glsl-function-dot.html": 0.8535,
-    "conformance/glsl/functions/glsl-function-faceforward.html": 0.8612,
-    "conformance/glsl/functions/glsl-function-floor.html": 1.027,
-    "conformance/glsl/functions/glsl-function-fract.html": 0.8458,
-    "conformance/glsl/functions/glsl-function-length.html": 1.0468,
-    "conformance/glsl/functions/glsl-function-max-float.html": 0.8278,
-    "conformance/glsl/functions/glsl-function-max-gentype.html": 1.094,
-    "conformance/glsl/functions/glsl-function-min-float.html": 0.8649,
-    "conformance/glsl/functions/glsl-function-min-gentype.html": 0.9395,
-    "conformance/glsl/functions/glsl-function-mix-float.html": 0.6635,
-    "conformance/glsl/functions/glsl-function-mix-gentype.html": 1.0082,
-    "conformance/glsl/functions/glsl-function-mod-float.html": 0.6471,
-    "conformance/glsl/functions/glsl-function-mod-gentype.html": 1.0423,
-    "conformance/glsl/functions/glsl-function-normalize.html": 0.6192,
-    "conformance/glsl/functions/glsl-function-reflect.html": 1.0164,
-    "conformance/glsl/functions/glsl-function-sign.html": 0.823,
-    "conformance/glsl/functions/glsl-function-sin.html": 1.0975,
-    "conformance/glsl/functions/glsl-function-smoothstep-float.html": 0.9668,
-    "conformance/glsl/functions/glsl-function-smoothstep-gentype.html": 1.0915,
-    "conformance/glsl/functions/glsl-function-step-float.html": 0.8944,
-    "conformance/glsl/functions/glsl-function-step-gentype.html": 1.0216,
-    "conformance/glsl/functions/glsl-function.html": 0.7662,
-    "conformance/glsl/implicit/add_int_float.vert.html": 0.3246,
-    "conformance/glsl/implicit/add_int_mat2.vert.html": 0.3495,
-    "conformance/glsl/implicit/add_int_mat3.vert.html": 0.0927,
-    "conformance/glsl/implicit/add_int_mat4.vert.html": 0.1243,
-    "conformance/glsl/implicit/add_int_vec2.vert.html": 0.0849,
-    "conformance/glsl/implicit/add_int_vec3.vert.html": 0.0879,
-    "conformance/glsl/implicit/add_int_vec4.vert.html": 0.0819,
-    "conformance/glsl/implicit/add_ivec2_vec2.vert.html": 0.082,
-    "conformance/glsl/implicit/add_ivec3_vec3.vert.html": 0.1779,
-    "conformance/glsl/implicit/add_ivec4_vec4.vert.html": 0.0838,
-    "conformance/glsl/implicit/assign_int_to_float.vert.html": 0.1406,
-    "conformance/glsl/implicit/assign_ivec2_to_vec2.vert.html": 0.0846,
-    "conformance/glsl/implicit/assign_ivec3_to_vec3.vert.html": 0.1156,
-    "conformance/glsl/implicit/assign_ivec4_to_vec4.vert.html": 0.0815,
-    "conformance/glsl/implicit/construct_struct.vert.html": 0.2641,
-    "conformance/glsl/implicit/divide_int_float.vert.html": 0.0838,
-    "conformance/glsl/implicit/divide_int_mat2.vert.html": 0.1558,
-    "conformance/glsl/implicit/divide_int_mat3.vert.html": 0.085,
-    "conformance/glsl/implicit/divide_int_mat4.vert.html": 0.1108,
-    "conformance/glsl/implicit/divide_int_vec2.vert.html": 0.0991,
-    "conformance/glsl/implicit/divide_int_vec3.vert.html": 0.1708,
-    "conformance/glsl/implicit/divide_int_vec4.vert.html": 0.0818,
-    "conformance/glsl/implicit/divide_ivec2_vec2.vert.html": 0.1949,
-    "conformance/glsl/implicit/divide_ivec3_vec3.vert.html": 0.0941,
-    "conformance/glsl/implicit/divide_ivec4_vec4.vert.html": 0.2415,
-    "conformance/glsl/implicit/equal_int_float.vert.html": 0.0997,
-    "conformance/glsl/implicit/equal_ivec2_vec2.vert.html": 0.172,
-    "conformance/glsl/implicit/equal_ivec3_vec3.vert.html": 0.0871,
-    "conformance/glsl/implicit/equal_ivec4_vec4.vert.html": 0.0904,
-    "conformance/glsl/implicit/function_int_float.vert.html": 0.1154,
-    "conformance/glsl/implicit/function_ivec2_vec2.vert.html": 0.08,
-    "conformance/glsl/implicit/function_ivec3_vec3.vert.html": 0.1195,
-    "conformance/glsl/implicit/function_ivec4_vec4.vert.html": 0.0839,
-    "conformance/glsl/implicit/greater_than.vert.html": 0.0851,
-    "conformance/glsl/implicit/greater_than_equal.vert.html": 0.4512,
-    "conformance/glsl/implicit/less_than.vert.html": 0.1121,
-    "conformance/glsl/implicit/less_than_equal.vert.html": 0.1629,
-    "conformance/glsl/implicit/multiply_int_float.vert.html": 0.1212,
-    "conformance/glsl/implicit/multiply_int_mat2.vert.html": 0.1249,
-    "conformance/glsl/implicit/multiply_int_mat3.vert.html": 0.0817,
-    "conformance/glsl/implicit/multiply_int_mat4.vert.html": 0.1032,
-    "conformance/glsl/implicit/multiply_int_vec2.vert.html": 0.2286,
-    "conformance/glsl/implicit/multiply_int_vec3.vert.html": 0.1083,
-    "conformance/glsl/implicit/multiply_int_vec4.vert.html": 0.1507,
-    "conformance/glsl/implicit/multiply_ivec2_vec2.vert.html": 0.1667,
-    "conformance/glsl/implicit/multiply_ivec3_vec3.vert.html": 0.099,
-    "conformance/glsl/implicit/multiply_ivec4_vec4.vert.html": 0.1287,
-    "conformance/glsl/implicit/not_equal_int_float.vert.html": 0.09,
-    "conformance/glsl/implicit/not_equal_ivec2_vec2.vert.html": 0.1242,
-    "conformance/glsl/implicit/not_equal_ivec3_vec3.vert.html": 0.0978,
-    "conformance/glsl/implicit/not_equal_ivec4_vec4.vert.html": 0.2102,
-    "conformance/glsl/implicit/subtract_int_float.vert.html": 0.0833,
-    "conformance/glsl/implicit/subtract_int_mat2.vert.html": 0.1401,
-    "conformance/glsl/implicit/subtract_int_mat3.vert.html": 0.0839,
-    "conformance/glsl/implicit/subtract_int_mat4.vert.html": 0.1108,
-    "conformance/glsl/implicit/subtract_int_vec2.vert.html": 0.0945,
-    "conformance/glsl/implicit/subtract_int_vec3.vert.html": 0.117,
-    "conformance/glsl/implicit/subtract_int_vec4.vert.html": 0.1789,
-    "conformance/glsl/implicit/subtract_ivec2_vec2.vert.html": 0.259,
-    "conformance/glsl/implicit/subtract_ivec3_vec3.vert.html": 0.1228,
-    "conformance/glsl/implicit/subtract_ivec4_vec4.vert.html": 0.1368,
-    "conformance/glsl/implicit/ternary_int_float.vert.html": 0.0858,
-    "conformance/glsl/implicit/ternary_ivec2_vec2.vert.html": 0.1245,
-    "conformance/glsl/implicit/ternary_ivec3_vec3.vert.html": 0.0848,
-    "conformance/glsl/implicit/ternary_ivec4_vec4.vert.html": 0.0949,
-    "conformance/glsl/literals/float_literal.vert.html": 0.084,
-    "conformance/glsl/literals/literal_precision.html": 0.0998,
-    "conformance/glsl/literals/overflow_leak.vert.html": 0.2749,
-    "conformance/glsl/matrices/glsl-mat3-construction.html": 0.4692,
-    "conformance/glsl/matrices/glsl-mat4-to-mat3.html": 0.5293,
-    "conformance/glsl/matrices/matrix-compound-multiply.html": 0.659,
-    "conformance/glsl/misc/attrib-location-length-limits.html": 0.374,
-    "conformance/glsl/misc/boolean_precision.html": 0.4527,
-    "conformance/glsl/misc/const-variable-initialization.html": 2.1488,
-    "conformance/glsl/misc/embedded-struct-definitions-forbidden.html": 0.1046,
-    "conformance/glsl/misc/empty-declaration.html": 0.4105,
-    "conformance/glsl/misc/empty_main.vert.html": 0.1692,
-    "conformance/glsl/misc/expression-list-in-declarator-initializer.html": 0.8546,
-    "conformance/glsl/misc/fragcolor-fragdata-invariant.html": 0.3585,
-    "conformance/glsl/misc/gl_position_unset.vert.html": 0.367,
-    "conformance/glsl/misc/global-variable-init.html": 0.7653,
-    "conformance/glsl/misc/glsl-function-nodes.html": 0.7842,
-    "conformance/glsl/misc/glsl-long-variable-names.html": 0.3923,
-    "conformance/glsl/misc/glsl-vertex-branch.html": 0.7092,
-    "conformance/glsl/misc/large-loop-compile.html": 0.8656,
-    "conformance/glsl/misc/local-variable-shadowing-outer-function.html": 0.3779,
-    "conformance/glsl/misc/non-ascii-comments.vert.html": 0.3757,
-    "conformance/glsl/misc/non-ascii.vert.html": 0.3164,
-    "conformance/glsl/misc/re-compile-re-link.html": 0.686,
-    "conformance/glsl/misc/sampler-operand.html": 0.1472,
-    "conformance/glsl/misc/sequence-operator-returns-constant.html": 0.319,
-    "conformance/glsl/misc/shader-precision-format-obeyed.html": 0.127,
-    "conformance/glsl/misc/shader-struct-scope.html": 0.333,
-    "conformance/glsl/misc/shader-uniform-packing-restrictions.html": 3.807,
-    "conformance/glsl/misc/shader-varying-packing-restrictions.html": 0.9696,
-    "conformance/glsl/misc/shader-with-256-character-define.html": 0.2704,
-    "conformance/glsl/misc/shader-with-256-character-identifier.frag.html": 0.3908,
-    "conformance/glsl/misc/shader-with-257-character-define.html": 0.341,
-    "conformance/glsl/misc/shader-with-257-character-identifier.frag.html": 0.2182,
-    "conformance/glsl/misc/shader-with-_webgl-identifier.vert.html": 0.1153,
-    "conformance/glsl/misc/shader-with-arbitrary-indexing.frag.html": 0.1333,
-    "conformance/glsl/misc/shader-with-arbitrary-indexing.vert.html": 0.1062,
-    "conformance/glsl/misc/shader-with-array-of-structs-containing-arrays.html": 0.3904,
-    "conformance/glsl/misc/shader-with-array-of-structs-uniform.html": 0.4444,
-    "conformance/glsl/misc/shader-with-attrib-array.vert.html": 0.49,
-    "conformance/glsl/misc/shader-with-attrib-struct.vert.html": 0.2369,
-    "conformance/glsl/misc/shader-with-clipvertex.vert.html": 0.1623,
-    "conformance/glsl/misc/shader-with-comma-assignment.html": 0.1275,
-    "conformance/glsl/misc/shader-with-comma-conditional-assignment.html": 0.4441,
-    "conformance/glsl/misc/shader-with-comma-separated-variable-declarations.html": 0.3459,
-    "conformance/glsl/misc/shader-with-conditional-scoping-negative.html": 0.361,
-    "conformance/glsl/misc/shader-with-conditional-scoping.html": 0.3573,
-    "conformance/glsl/misc/shader-with-default-precision.frag.html": 0.1574,
-    "conformance/glsl/misc/shader-with-default-precision.vert.html": 0.29,
-    "conformance/glsl/misc/shader-with-define-line-continuation.frag.html": 0.3076,
-    "conformance/glsl/misc/shader-with-dfdx-no-ext.frag.html": 0.2081,
-    "conformance/glsl/misc/shader-with-dfdx.frag.html": 0.1892,
-    "conformance/glsl/misc/shader-with-do-loop.html": 0.1513,
-    "conformance/glsl/misc/shader-with-error-directive.html": 0.1461,
-    "conformance/glsl/misc/shader-with-explicit-int-cast.vert.html": 0.1168,
-    "conformance/glsl/misc/shader-with-float-return-value.frag.html": 0.2166,
-    "conformance/glsl/misc/shader-with-for-loop.html": 0.3262,
-    "conformance/glsl/misc/shader-with-for-scoping.html": 0.368,
-    "conformance/glsl/misc/shader-with-frag-depth.frag.html": 0.504,
-    "conformance/glsl/misc/shader-with-function-recursion.frag.html": 0.1466,
-    "conformance/glsl/misc/shader-with-function-scoped-struct.html": 0.1505,
-    "conformance/glsl/misc/shader-with-functional-scoping.html": 0.1221,
-    "conformance/glsl/misc/shader-with-glcolor.vert.html": 0.0893,
-    "conformance/glsl/misc/shader-with-gles-1.frag.html": 0.131,
-    "conformance/glsl/misc/shader-with-gles-symbol.frag.html": 0.0916,
-    "conformance/glsl/misc/shader-with-global-variable-precision-mismatch.html": 0.3138,
-    "conformance/glsl/misc/shader-with-glprojectionmatrix.vert.html": 0.2872,
-    "conformance/glsl/misc/shader-with-hex-int-constant-macro.html": 0.1011,
-    "conformance/glsl/misc/shader-with-implicit-vec3-to-vec4-cast.vert.html": 0.0949,
-    "conformance/glsl/misc/shader-with-include.vert.html": 0.2491,
-    "conformance/glsl/misc/shader-with-int-return-value.frag.html": 0.1196,
-    "conformance/glsl/misc/shader-with-invalid-identifier.frag.html": 0.1015,
-    "conformance/glsl/misc/shader-with-ivec2-return-value.frag.html": 0.2706,
-    "conformance/glsl/misc/shader-with-ivec3-return-value.frag.html": 0.1368,
-    "conformance/glsl/misc/shader-with-ivec4-return-value.frag.html": 0.2865,
-    "conformance/glsl/misc/shader-with-limited-indexing.frag.html": 0.2814,
-    "conformance/glsl/misc/shader-with-long-line.html": 0.348,
-    "conformance/glsl/misc/shader-with-non-ascii-error.frag.html": 0.2977,
-    "conformance/glsl/misc/shader-with-non-reserved-words.html": 28.2993,
-    "conformance/glsl/misc/shader-with-precision.frag.html": 0.2351,
-    "conformance/glsl/misc/shader-with-preprocessor-whitespace.html": 0.5565,
-    "conformance/glsl/misc/shader-with-quoted-error.frag.html": 0.3677,
-    "conformance/glsl/misc/shader-with-reserved-words.html": 4.2819,
-    "conformance/glsl/misc/shader-with-short-circuiting-operators.html": 0.8196,
-    "conformance/glsl/misc/shader-with-similar-uniform-array-names.html": 0.3269,
-    "conformance/glsl/misc/shader-with-too-many-uniforms.html": 0.9033,
-    "conformance/glsl/misc/shader-with-two-initializer-types.html": 0.3817,
-    "conformance/glsl/misc/shader-with-undefined-preprocessor-symbol.frag.html": 0.2925,
-    "conformance/glsl/misc/shader-with-uniform-in-loop-condition.vert.html": 0.1992,
-    "conformance/glsl/misc/shader-with-vec2-return-value.frag.html": 0.2402,
-    "conformance/glsl/misc/shader-with-vec3-return-value.frag.html": 0.0821,
-    "conformance/glsl/misc/shader-with-vec4-return-value.frag.html": 0.3706,
-    "conformance/glsl/misc/shader-with-vec4-vec3-vec4-conditional.html": 0.293,
-    "conformance/glsl/misc/shader-with-version-100.frag.html": 0.2703,
-    "conformance/glsl/misc/shader-with-version-100.vert.html": 0.2457,
-    "conformance/glsl/misc/shader-with-version-120.vert.html": 0.2646,
-    "conformance/glsl/misc/shader-with-version-130.vert.html": 0.2516,
-    "conformance/glsl/misc/shader-with-webgl-identifier.vert.html": 0.188,
-    "conformance/glsl/misc/shader-with-while-loop.html": 0.118,
-    "conformance/glsl/misc/shader-without-precision.frag.html": 0.0978,
-    "conformance/glsl/misc/shaders-with-constant-expression-loop-conditions.html": 0.0967,
-    "conformance/glsl/misc/shaders-with-invariance.html": 0.3466,
-    "conformance/glsl/misc/shaders-with-mis-matching-uniforms.html": 0.5176,
-    "conformance/glsl/misc/shaders-with-mis-matching-varyings.html": 0.4249,
-    "conformance/glsl/misc/shaders-with-missing-varyings.html": 0.1449,
-    "conformance/glsl/misc/shaders-with-name-conflicts.html": 0.2004,
-    "conformance/glsl/misc/shaders-with-uniform-structs.html": 0.1369,
-    "conformance/glsl/misc/shaders-with-varyings.html": 0.1759,
-    "conformance/glsl/misc/shared.html": 0.3199,
-    "conformance/glsl/misc/struct-as-inout-parameter.html": 0.3522,
-    "conformance/glsl/misc/struct-as-out-parameter.html": 0.3607,
-    "conformance/glsl/misc/struct-assign.html": 0.4943,
-    "conformance/glsl/misc/struct-equals.html": 0.4014,
-    "conformance/glsl/misc/struct-mixed-array-declarators.html": 1.1757,
-    "conformance/glsl/misc/struct-nesting-exceeds-maximum.html": 0.2285,
-    "conformance/glsl/misc/struct-nesting-of-variable-names.html": 3.1717,
-    "conformance/glsl/misc/struct-nesting-under-maximum.html": 0.1033,
-    "conformance/glsl/misc/struct-specifiers-in-uniforms.html": 0.5165,
-    "conformance/glsl/misc/struct-unary-operators.html": 0.4376,
-    "conformance/glsl/misc/ternary-operator-on-arrays.html": 0.325,
-    "conformance/glsl/misc/ternary-operators-in-global-initializers.html": 0.3296,
-    "conformance/glsl/misc/ternary-operators-in-initializers.html": 0.6444,
-    "conformance/glsl/misc/uniform-location-length-limits.html": 0.2983,
-    "conformance/glsl/misc/uninitialized-local-global-variables.html": 1.048,
-    "conformance/glsl/preprocessor/macro-expansion-tricky.html": 0.284,
-    "conformance/glsl/reserved/_webgl_field.vert.html": 0.4316,
-    "conformance/glsl/reserved/_webgl_function.vert.html": 0.2595,
-    "conformance/glsl/reserved/_webgl_struct.vert.html": 0.2598,
-    "conformance/glsl/reserved/_webgl_variable.vert.html": 0.0933,
-    "conformance/glsl/reserved/webgl_field.vert.html": 0.1365,
-    "conformance/glsl/reserved/webgl_function.vert.html": 0.0863,
-    "conformance/glsl/reserved/webgl_struct.vert.html": 0.09,
-    "conformance/glsl/reserved/webgl_variable.vert.html": 0.0996,
-    "conformance/glsl/samplers/glsl-function-texture2d-bias.html": 0.4559,
-    "conformance/glsl/samplers/glsl-function-texture2dlod.html": 0.3922,
-    "conformance/glsl/samplers/glsl-function-texture2dproj.html": 0.6041,
-    "conformance/glsl/samplers/glsl-function-texture2dprojlod.html": 1.4049,
-    "conformance/glsl/variables/gl-fragcoord-xy-values.html": 0.4937,
-    "conformance/glsl/variables/gl-fragcoord.html": 0.2155,
-    "conformance/glsl/variables/gl-fragdata-and-fragcolor.html": 0.4102,
-    "conformance/glsl/variables/gl-frontfacing.html": 0.2463,
-    "conformance/glsl/variables/gl-pointcoord.html": 0.3116,
-    "conformance/glsl/variables/glsl-built-ins.html": 0.4659,
-    "conformance/limits/gl-line-width.html": 0.3159,
-    "conformance/limits/gl-max-texture-dimensions.html": 0.4036,
-    "conformance/limits/gl-min-attribs.html": 0.1354,
-    "conformance/limits/gl-min-textures.html": 0.3133,
-    "conformance/limits/gl-min-uniforms.html": 0.3492,
-    "conformance/misc/bad-arguments-test.html": 0.3316,
-    "conformance/misc/boolean-argument-conversion.html": 0.2494,
-    "conformance/misc/delayed-drawing.html": 1.2052,
-    "conformance/misc/error-reporting.html": 0.2882,
-    "conformance/misc/expando-loss.html": 0.3642,
-    "conformance/misc/functions-returning-strings.html": 0.123,
-    "conformance/misc/instanceof-test.html": 0.3487,
-    "conformance/misc/invalid-passed-params.html": 0.4383,
-    "conformance/misc/is-object.html": 0.2529,
-    "conformance/misc/null-object-behaviour.html": 0.2442,
-    "conformance/misc/object-deletion-behaviour.html": 0.3779,
-    "conformance/misc/shader-precision-format.html": 0.1118,
-    "conformance/misc/type-conversion-test.html": 0.2715,
-    "conformance/misc/uninitialized-test.html": 0.5341,
-    "conformance/misc/webgl-specific-stencil-settings.html": 0.7361,
-    "conformance/misc/webgl-specific.html": 0.1928,
-    "conformance/more/conformance/constants.html": 0.1624,
-    "conformance/more/conformance/getContext.html": 0.1449,
-    "conformance/more/conformance/methods.html": 0.1159,
-    "conformance/more/conformance/quickCheckAPI-A.html": 0.2416,
-    "conformance/more/conformance/quickCheckAPI-B1.html": 0.3658,
-    "conformance/more/conformance/quickCheckAPI-B2.html": 0.2994,
-    "conformance/more/conformance/quickCheckAPI-B3.html": 0.3823,
-    "conformance/more/conformance/quickCheckAPI-B4.html": 0.2517,
-    "conformance/more/conformance/quickCheckAPI-C.html": 0.2151,
-    "conformance/more/conformance/quickCheckAPI-D_G.html": 0.369,
-    "conformance/more/conformance/quickCheckAPI-G_I.html": 0.3865,
-    "conformance/more/conformance/quickCheckAPI-L_S.html": 0.309,
-    "conformance/more/conformance/quickCheckAPI-S_V.html": 0.331,
-    "conformance/more/conformance/webGLArrays.html": 0.2156,
-    "conformance/more/functions/bindBuffer.html": 0.1537,
-    "conformance/more/functions/bindBufferBadArgs.html": 0.3758,
-    "conformance/more/functions/bindFramebufferLeaveNonZero.html": 0.125,
-    "conformance/more/functions/bufferData.html": 0.1748,
-    "conformance/more/functions/bufferDataBadArgs.html": 0.1854,
-    "conformance/more/functions/bufferSubData.html": 0.2231,
-    "conformance/more/functions/bufferSubDataBadArgs.html": 0.1644,
-    "conformance/more/functions/copyTexImage2D.html": 0.1989,
-    "conformance/more/functions/copyTexImage2DBadArgs.html": 0.1294,
-    "conformance/more/functions/copyTexSubImage2D.html": 0.4121,
-    "conformance/more/functions/copyTexSubImage2DBadArgs.html": 0.1336,
-    "conformance/more/functions/deleteBufferBadArgs.html": 0.2091,
-    "conformance/more/functions/drawArrays.html": 0.2289,
-    "conformance/more/functions/drawElements.html": 0.2807,
-    "conformance/more/functions/isTests.html": 0.3296,
-    "conformance/more/functions/isTestsBadArgs.html": 0.2629,
-    "conformance/more/functions/readPixels.html": 0.1403,
-    "conformance/more/functions/readPixelsBadArgs.html": 0.2437,
-    "conformance/more/functions/texImage2D.html": 0.1433,
-    "conformance/more/functions/texImage2DBadArgs.html": 0.1814,
-    "conformance/more/functions/texImage2DHTML.html": 0.2565,
-    "conformance/more/functions/texImage2DHTMLBadArgs.html": 0.1847,
-    "conformance/more/functions/texSubImage2D.html": 0.3869,
-    "conformance/more/functions/texSubImage2DBadArgs.html": 0.1275,
-    "conformance/more/functions/texSubImage2DHTML.html": 0.2932,
-    "conformance/more/functions/texSubImage2DHTMLBadArgs.html": 0.183,
-    "conformance/more/functions/uniformMatrix.html": 0.1791,
-    "conformance/more/functions/uniformMatrixBadArgs.html": 0.3468,
-    "conformance/more/functions/uniformf.html": 0.3657,
-    "conformance/more/functions/uniformfArrayLen1.html": 0.3193,
-    "conformance/more/functions/uniformfBadArgs.html": 0.4016,
-    "conformance/more/functions/uniformi.html": 0.4033,
-    "conformance/more/functions/uniformiBadArgs.html": 0.3933,
-    "conformance/more/functions/vertexAttrib.html": 0.4253,
-    "conformance/more/functions/vertexAttribBadArgs.html": 0.3329,
-    "conformance/more/functions/vertexAttribPointer.html": 0.2403,
-    "conformance/more/functions/vertexAttribPointerBadArgs.html": 0.2499,
-    "conformance/more/glsl/arrayOutOfBounds.html": 0.2475,
-    "conformance/more/glsl/uniformOutOfBounds.html": 0.1803,
-    "conformance/offscreencanvas/context-attribute-preserve-drawing-buffer.html": 0.9406,
-    "conformance/offscreencanvas/context-creation-worker.html": 0.5039,
-    "conformance/offscreencanvas/context-creation.html": 0.1318,
-    "conformance/offscreencanvas/context-lost-restored-worker.html": 0.2919,
-    "conformance/offscreencanvas/context-lost-restored.html": 0.2878,
-    "conformance/offscreencanvas/context-lost-worker.html": 0.2993,
-    "conformance/offscreencanvas/context-lost.html": 0.1891,
-    "conformance/offscreencanvas/methods-worker.html": 0.2757,
-    "conformance/offscreencanvas/methods.html": 0.0954,
-    "conformance/offscreencanvas/offscreencanvas-resize.html": 0.1804,
-    "conformance/offscreencanvas/offscreencanvas-transfer-image-bitmap.html": 0.2634,
-    "conformance/ogles/GL/abs/abs_001_to_006.html": 2.6101,
-    "conformance/ogles/GL/acos/acos_001_to_006.html": 3.1287,
-    "conformance/ogles/GL/all/all_001_to_004.html": 2.5633,
-    "conformance/ogles/GL/any/any_001_to_004.html": 2.3353,
-    "conformance/ogles/GL/array/array_001_to_006.html": 0.839,
-    "conformance/ogles/GL/asin/asin_001_to_006.html": 2.8594,
-    "conformance/ogles/GL/atan/atan_001_to_008.html": 3.2094,
-    "conformance/ogles/GL/atan/atan_009_to_012.html": 2.7379,
-    "conformance/ogles/GL/biConstants/biConstants_001_to_008.html": 2.8462,
-    "conformance/ogles/GL/biConstants/biConstants_009_to_016.html": 2.8474,
-    "conformance/ogles/GL/biuDepthRange/biuDepthRange_001_to_002.html": 2.0347,
-    "conformance/ogles/GL/build/build_001_to_008.html": 0.4664,
-    "conformance/ogles/GL/build/build_009_to_016.html": 0.5249,
-    "conformance/ogles/GL/build/build_017_to_024.html": 0.4384,
-    "conformance/ogles/GL/build/build_025_to_032.html": 0.4606,
-    "conformance/ogles/GL/build/build_033_to_040.html": 0.3651,
-    "conformance/ogles/GL/build/build_041_to_048.html": 0.3173,
-    "conformance/ogles/GL/build/build_049_to_056.html": 0.2313,
-    "conformance/ogles/GL/build/build_057_to_064.html": 0.2329,
-    "conformance/ogles/GL/build/build_065_to_072.html": 0.2711,
-    "conformance/ogles/GL/build/build_073_to_080.html": 0.2225,
-    "conformance/ogles/GL/build/build_081_to_088.html": 0.1943,
-    "conformance/ogles/GL/build/build_089_to_096.html": 0.2459,
-    "conformance/ogles/GL/build/build_097_to_104.html": 0.2332,
-    "conformance/ogles/GL/build/build_105_to_112.html": 0.1535,
-    "conformance/ogles/GL/build/build_113_to_120.html": 0.1954,
-    "conformance/ogles/GL/build/build_121_to_128.html": 0.1957,
-    "conformance/ogles/GL/build/build_129_to_136.html": 0.3604,
-    "conformance/ogles/GL/build/build_137_to_144.html": 0.1875,
-    "conformance/ogles/GL/build/build_145_to_152.html": 0.2123,
-    "conformance/ogles/GL/build/build_153_to_160.html": 0.2747,
-    "conformance/ogles/GL/build/build_161_to_168.html": 0.2015,
-    "conformance/ogles/GL/build/build_169_to_176.html": 0.3582,
-    "conformance/ogles/GL/build/build_177_to_178.html": 0.2031,
-    "conformance/ogles/GL/built_in_varying_array_out_of_bounds/built_in_varying_array_out_of_bounds_001_to_001.html": 0.468,
-    "conformance/ogles/GL/ceil/ceil_001_to_006.html": 2.5574,
-    "conformance/ogles/GL/clamp/clamp_001_to_006.html": 2.5107,
-    "conformance/ogles/GL/control_flow/control_flow_001_to_008.html": 1.0615,
-    "conformance/ogles/GL/control_flow/control_flow_009_to_010.html": 0.6791,
-    "conformance/ogles/GL/cos/cos_001_to_006.html": 2.791,
-    "conformance/ogles/GL/cross/cross_001_to_002.html": 2.1284,
-    "conformance/ogles/GL/default/default_001_to_001.html": 0.5445,
-    "conformance/ogles/GL/degrees/degrees_001_to_006.html": 2.6748,
-    "conformance/ogles/GL/discard/discard_001_to_002.html": 0.6675,
-    "conformance/ogles/GL/distance/distance_001_to_006.html": 2.6872,
-    "conformance/ogles/GL/dot/dot_001_to_006.html": 2.5443,
-    "conformance/ogles/GL/equal/equal_001_to_008.html": 2.9521,
-    "conformance/ogles/GL/equal/equal_009_to_012.html": 2.5138,
-    "conformance/ogles/GL/exp/exp_001_to_008.html": 3.0721,
-    "conformance/ogles/GL/exp/exp_009_to_012.html": 2.7944,
-    "conformance/ogles/GL/exp2/exp2_001_to_008.html": 2.8752,
-    "conformance/ogles/GL/exp2/exp2_009_to_012.html": 2.4988,
-    "conformance/ogles/GL/faceforward/faceforward_001_to_006.html": 2.7105,
-    "conformance/ogles/GL/floor/floor_001_to_006.html": 2.5667,
-    "conformance/ogles/GL/fract/fract_001_to_006.html": 2.8398,
-    "conformance/ogles/GL/functions/functions_001_to_008.html": 2.7087,
-    "conformance/ogles/GL/functions/functions_009_to_016.html": 0.884,
-    "conformance/ogles/GL/functions/functions_017_to_024.html": 0.8375,
-    "conformance/ogles/GL/functions/functions_025_to_032.html": 0.9905,
-    "conformance/ogles/GL/functions/functions_033_to_040.html": 1.0204,
-    "conformance/ogles/GL/functions/functions_041_to_048.html": 0.9891,
-    "conformance/ogles/GL/functions/functions_049_to_056.html": 1.0526,
-    "conformance/ogles/GL/functions/functions_057_to_064.html": 0.9604,
-    "conformance/ogles/GL/functions/functions_065_to_072.html": 0.9637,
-    "conformance/ogles/GL/functions/functions_073_to_080.html": 0.9729,
-    "conformance/ogles/GL/functions/functions_081_to_088.html": 1.119,
-    "conformance/ogles/GL/functions/functions_089_to_096.html": 0.8381,
-    "conformance/ogles/GL/functions/functions_097_to_104.html": 1.1095,
-    "conformance/ogles/GL/functions/functions_105_to_112.html": 0.8753,
-    "conformance/ogles/GL/functions/functions_113_to_120.html": 1.1679,
-    "conformance/ogles/GL/functions/functions_121_to_126.html": 0.9305,
-    "conformance/ogles/GL/gl_FragCoord/gl_FragCoord_001_to_003.html": 0.756,
-    "conformance/ogles/GL/gl_FrontFacing/gl_FrontFacing_001_to_001.html": 0.6131,
-    "conformance/ogles/GL/greaterThan/greaterThan_001_to_008.html": 2.6455,
-    "conformance/ogles/GL/greaterThanEqual/greaterThanEqual_001_to_008.html": 2.8438,
-    "conformance/ogles/GL/inversesqrt/inversesqrt_001_to_006.html": 2.6154,
-    "conformance/ogles/GL/length/length_001_to_006.html": 2.5512,
-    "conformance/ogles/GL/lessThan/lessThan_001_to_008.html": 2.8469,
-    "conformance/ogles/GL/lessThanEqual/lessThanEqual_001_to_008.html": 2.85,
-    "conformance/ogles/GL/log/log_001_to_008.html": 3.0374,
-    "conformance/ogles/GL/log/log_009_to_012.html": 2.8263,
-    "conformance/ogles/GL/log2/log2_001_to_008.html": 3.0313,
-    "conformance/ogles/GL/log2/log2_009_to_012.html": 2.6836,
-    "conformance/ogles/GL/mat/mat_001_to_008.html": 0.8408,
-    "conformance/ogles/GL/mat/mat_009_to_016.html": 0.8229,
-    "conformance/ogles/GL/mat/mat_017_to_024.html": 0.9762,
-    "conformance/ogles/GL/mat/mat_025_to_032.html": 2.7003,
-    "conformance/ogles/GL/mat/mat_033_to_040.html": 2.5912,
-    "conformance/ogles/GL/mat/mat_041_to_046.html": 0.8147,
-    "conformance/ogles/GL/mat3/mat3_001_to_006.html": 0.8612,
-    "conformance/ogles/GL/matrixCompMult/matrixCompMult_001_to_004.html": 2.6519,
-    "conformance/ogles/GL/max/max_001_to_006.html": 2.6355,
-    "conformance/ogles/GL/min/min_001_to_006.html": 2.5583,
-    "conformance/ogles/GL/mix/mix_001_to_006.html": 2.6239,
-    "conformance/ogles/GL/mod/mod_001_to_008.html": 2.7146,
-    "conformance/ogles/GL/normalize/normalize_001_to_006.html": 2.6383,
-    "conformance/ogles/GL/not/not_001_to_004.html": 2.4731,
-    "conformance/ogles/GL/notEqual/notEqual_001_to_008.html": 2.8036,
-    "conformance/ogles/GL/notEqual/notEqual_009_to_012.html": 2.4779,
-    "conformance/ogles/GL/operators/operators_001_to_008.html": 0.8693,
-    "conformance/ogles/GL/operators/operators_009_to_016.html": 0.8671,
-    "conformance/ogles/GL/operators/operators_017_to_024.html": 0.9771,
-    "conformance/ogles/GL/operators/operators_025_to_026.html": 0.5412,
-    "conformance/ogles/GL/pow/pow_001_to_008.html": 1.2122,
-    "conformance/ogles/GL/pow/pow_009_to_016.html": 2.7677,
-    "conformance/ogles/GL/pow/pow_017_to_024.html": 3.15,
-    "conformance/ogles/GL/radians/radians_001_to_006.html": 2.7494,
-    "conformance/ogles/GL/reflect/reflect_001_to_006.html": 2.6104,
-    "conformance/ogles/GL/refract/refract_001_to_006.html": 2.6434,
-    "conformance/ogles/GL/sign/sign_001_to_006.html": 2.5817,
-    "conformance/ogles/GL/sin/sin_001_to_006.html": 2.8131,
-    "conformance/ogles/GL/smoothstep/smoothstep_001_to_006.html": 2.7068,
-    "conformance/ogles/GL/sqrt/sqrt_001_to_006.html": 2.628,
-    "conformance/ogles/GL/step/step_001_to_006.html": 2.6048,
-    "conformance/ogles/GL/struct/struct_001_to_008.html": 2.8225,
-    "conformance/ogles/GL/struct/struct_009_to_016.html": 2.8596,
-    "conformance/ogles/GL/struct/struct_017_to_024.html": 2.8899,
-    "conformance/ogles/GL/struct/struct_025_to_032.html": 2.866,
-    "conformance/ogles/GL/struct/struct_033_to_040.html": 2.9169,
-    "conformance/ogles/GL/struct/struct_041_to_048.html": 2.8505,
-    "conformance/ogles/GL/struct/struct_049_to_056.html": 2.8921,
-    "conformance/ogles/GL/swizzlers/swizzlers_001_to_008.html": 2.9744,
-    "conformance/ogles/GL/swizzlers/swizzlers_009_to_016.html": 2.7202,
-    "conformance/ogles/GL/swizzlers/swizzlers_017_to_024.html": 2.8651,
-    "conformance/ogles/GL/swizzlers/swizzlers_025_to_032.html": 3.0001,
-    "conformance/ogles/GL/swizzlers/swizzlers_033_to_040.html": 2.7326,
-    "conformance/ogles/GL/swizzlers/swizzlers_041_to_048.html": 2.7442,
-    "conformance/ogles/GL/swizzlers/swizzlers_049_to_056.html": 2.7414,
-    "conformance/ogles/GL/swizzlers/swizzlers_057_to_064.html": 2.6994,
-    "conformance/ogles/GL/swizzlers/swizzlers_065_to_072.html": 2.7604,
-    "conformance/ogles/GL/swizzlers/swizzlers_073_to_080.html": 2.8405,
-    "conformance/ogles/GL/swizzlers/swizzlers_081_to_088.html": 2.7663,
-    "conformance/ogles/GL/swizzlers/swizzlers_089_to_096.html": 2.8825,
-    "conformance/ogles/GL/swizzlers/swizzlers_097_to_104.html": 2.967,
-    "conformance/ogles/GL/swizzlers/swizzlers_105_to_112.html": 2.6731,
-    "conformance/ogles/GL/swizzlers/swizzlers_113_to_120.html": 2.9662,
-    "conformance/ogles/GL/tan/tan_001_to_006.html": 2.6808,
-    "conformance/ogles/GL/vec/vec_001_to_008.html": 1.003,
-    "conformance/ogles/GL/vec/vec_009_to_016.html": 0.8886,
-    "conformance/ogles/GL/vec/vec_017_to_018.html": 0.6021,
-    "conformance/ogles/GL/vec3/vec3_001_to_008.html": 0.9618,
-    "conformance/programs/get-active-test.html": 0.4492,
-    "conformance/programs/gl-bind-attrib-location-long-names-test.html": 0.5001,
-    "conformance/programs/gl-bind-attrib-location-test.html": 0.2687,
-    "conformance/programs/gl-get-active-attribute.html": 0.2815,
-    "conformance/programs/gl-get-active-uniform.html": 0.6526,
-    "conformance/programs/gl-getshadersource.html": 0.2509,
-    "conformance/programs/gl-shader-test.html": 0.3705,
-    "conformance/programs/invalid-UTF-16.html": 0.0995,
-    "conformance/programs/program-handling.html": 1.1953,
-    "conformance/programs/program-infolog.html": 0.1244,
-    "conformance/programs/program-test.html": 1.7321,
-    "conformance/programs/use-program-crash-with-discard-in-fragment-shader.html": 0.2937,
-    "conformance/reading/fbo-remains-unchanged-after-read-pixels.html": 0.7498,
-    "conformance/reading/read-pixels-pack-alignment.html": 0.55,
-    "conformance/reading/read-pixels-test.html": 0.895,
-    "conformance/renderbuffers/depth-renderbuffer-initialization.html": 0.3345,
-    "conformance/renderbuffers/feedback-loop.html": 0.1076,
-    "conformance/renderbuffers/framebuffer-object-attachment.html": 0.5851,
-    "conformance/renderbuffers/framebuffer-state-restoration.html": 0.6769,
-    "conformance/renderbuffers/framebuffer-test.html": 0.1576,
-    "conformance/renderbuffers/renderbuffer-initialization.html": 0.6666,
-    "conformance/renderbuffers/stencil-renderbuffer-initialization.html": 0.2851,
-    "conformance/rendering/blending.html": 1.3743,
-    "conformance/rendering/canvas-alpha-bug.html": 0.1678,
-    "conformance/rendering/clear-after-copyTexImage2D.html": 0.6917,
-    "conformance/rendering/clipping-wide-points.html": 0.2481,
-    "conformance/rendering/color-mask-preserved-during-implicit-clears.html": 2.0177,
-    "conformance/rendering/culling.html": 0.217,
-    "conformance/rendering/default-texture-draw-bug.html": 0.405,
-    "conformance/rendering/draw-arrays-out-of-bounds.html": 0.3161,
-    "conformance/rendering/draw-elements-out-of-bounds.html": 0.2816,
-    "conformance/rendering/draw-webgl-to-canvas-2d-repeatedly.html": 0.4055,
-    "conformance/rendering/draw-with-changing-start-vertex-bug.html": 0.4285,
-    "conformance/rendering/framebuffer-switch.html": 0.3812,
-    "conformance/rendering/framebuffer-texture-clear.html": 0.5497,
-    "conformance/rendering/framebuffer-texture-switch.html": 0.3479,
-    "conformance/rendering/gl-clear.html": 0.2376,
-    "conformance/rendering/gl-drawarrays.html": 0.1215,
-    "conformance/rendering/gl-drawelements.html": 0.1786,
-    "conformance/rendering/gl-scissor-canvas-dimensions.html": 0.4101,
-    "conformance/rendering/gl-scissor-fbo-test.html": 0.412,
-    "conformance/rendering/gl-scissor-test.html": 0.3507,
-    "conformance/rendering/gl-viewport-test.html": 0.8559,
-    "conformance/rendering/line-loop-tri-fan.html": 0.1194,
-    "conformance/rendering/line-rendering-quality.html": 0.1686,
-    "conformance/rendering/many-draw-calls.html": 5.4841,
-    "conformance/rendering/more-than-65536-indices.html": 0.8236,
-    "conformance/rendering/multisample-corruption.html": 4.5029,
-    "conformance/rendering/negative-one-index.html": 0.3553,
-    "conformance/rendering/out-of-bounds-array-buffers.html": 0.1897,
-    "conformance/rendering/out-of-bounds-index-buffers.html": 0.2495,
-    "conformance/rendering/point-no-attributes.html": 0.2308,
-    "conformance/rendering/point-size.html": 0.2913,
-    "conformance/rendering/point-specific-shader-variables.html": 0.2837,
-    "conformance/rendering/point-with-gl-pointcoord-in-fragment-shader.html": 0.2936,
-    "conformance/rendering/polygon-offset.html": 0.3304,
-    "conformance/rendering/preservedrawingbuffer-leak.html": 0.8586,
-    "conformance/rendering/rendering-sampling-feedback-loop.html": 0.1878,
-    "conformance/rendering/rendering-stencil-large-viewport.html": 0.2691,
-    "conformance/rendering/scissor-rect-repeated-rendering.html": 0.4,
-    "conformance/rendering/simple.html": 0.4103,
+    "WebglExtension_WEBGL_debug_renderer_info": 0.0861,
+    "WebglExtension_WEBGL_debug_shaders": 0.1719,
+    "WebglExtension_WEBGL_depth_texture": 0.1363,
+    "WebglExtension_WEBGL_draw_buffers": 0.1871,
+    "WebglExtension_WEBGL_lose_context": 0.1996,
+    "WebglExtension_WEBGL_multi_draw": 0.2073,
+    "WebglExtension_WEBGL_video_texture": 0.118,
+    "conformance/attribs/gl-bindAttribLocation-aliasing.html": 0.3516,
+    "conformance/attribs/gl-bindAttribLocation-matrix.html": 0.581,
+    "conformance/attribs/gl-bindAttribLocation-nonexistent-attribute.html": 0.3075,
+    "conformance/attribs/gl-bindAttribLocation-repeated.html": 0.3123,
+    "conformance/attribs/gl-disabled-vertex-attrib-update.html": 0.439,
+    "conformance/attribs/gl-disabled-vertex-attrib.html": 0.9162,
+    "conformance/attribs/gl-enable-vertex-attrib.html": 0.386,
+    "conformance/attribs/gl-matrix-attributes.html": 0.7427,
+    "conformance/attribs/gl-vertex-attrib-context-switch.html": 0.6917,
+    "conformance/attribs/gl-vertex-attrib-render.html": 0.3389,
+    "conformance/attribs/gl-vertex-attrib-unconsumed-out-of-bounds.html": 0.3518,
+    "conformance/attribs/gl-vertex-attrib-zero-issues.html": 0.7659,
+    "conformance/attribs/gl-vertex-attrib.html": 0.7,
+    "conformance/attribs/gl-vertexattribpointer-offsets.html": 0.7074,
+    "conformance/attribs/gl-vertexattribpointer.html": 1.1455,
+    "conformance/buffers/buffer-bind-test.html": 0.1094,
+    "conformance/buffers/buffer-data-and-buffer-sub-data.html": 0.7213,
+    "conformance/buffers/buffer-data-array-buffer-delete.html": 2.2464,
+    "conformance/buffers/buffer-data-dynamic-delay.html": 0.3741,
+    "conformance/buffers/buffer-uninitialized.html": 0.3976,
+    "conformance/buffers/element-array-buffer-delete-recreate.html": 0.2459,
+    "conformance/buffers/index-validation-copies-indices.html": 0.2996,
+    "conformance/buffers/index-validation-crash-with-buffer-sub-data.html": 0.0653,
+    "conformance/buffers/index-validation-large-buffer.html": 0.33,
+    "conformance/buffers/index-validation-verifies-too-many-indices.html": 0.2553,
+    "conformance/buffers/index-validation-with-resized-buffer.html": 0.2534,
+    "conformance/buffers/index-validation.html": 0.2328,
+    "conformance/buffers/vertex-buffer-updated-after-draw.html": 0.1477,
+    "conformance/canvas/buffer-offscreen-test.html": 0.3308,
+    "conformance/canvas/buffer-preserve-test.html": 0.2124,
+    "conformance/canvas/canvas-test.html": 0.4975,
+    "conformance/canvas/canvas-zero-size.html": 0.1104,
+    "conformance/canvas/draw-static-webgl-to-multiple-canvas-test.html": 1.0706,
+    "conformance/canvas/draw-webgl-to-canvas-test.html": 1.0871,
+    "conformance/canvas/drawingbuffer-hd-dpi-test.html": 0.7617,
+    "conformance/canvas/drawingbuffer-static-canvas-test.html": 0.5494,
+    "conformance/canvas/drawingbuffer-test.html": 0.7053,
+    "conformance/canvas/framebuffer-bindings-affected-by-to-data-url.html": 0.2777,
+    "conformance/canvas/framebuffer-bindings-unaffected-on-resize.html": 0.3555,
+    "conformance/canvas/rapid-resizing.html": 2.4653,
+    "conformance/canvas/render-after-resize-test.html": 0.2371,
+    "conformance/canvas/texture-bindings-unaffected-on-resize.html": 0.2999,
+    "conformance/canvas/to-data-url-test.html": 1.0222,
+    "conformance/canvas/viewport-unchanged-upon-resize.html": 0.1452,
+    "conformance/canvas/webgl-to-2d-canvas.html": 0.3172,
+    "conformance/context/constants-and-properties.html": 0.1335,
+    "conformance/context/context-attribute-preserve-drawing-buffer.html": 0.4601,
+    "conformance/context/context-attributes-alpha-depth-stencil-antialias.html": 1.0359,
+    "conformance/context/context-creation-and-destruction.html": 1.6246,
+    "conformance/context/context-creation.html": 1.1629,
+    "conformance/context/context-eviction-with-garbage-collection.html": 1.9231,
+    "conformance/context/context-hidden-alpha.html": 0.3218,
+    "conformance/context/context-lost-restored.html": 0.6639,
+    "conformance/context/context-lost.html": 0.234,
+    "conformance/context/context-no-alpha-fbo-with-alpha.html": 0.499,
+    "conformance/context/context-release-upon-reload.html": 1.6298,
+    "conformance/context/context-release-with-workers.html": 2.037,
+    "conformance/context/context-size-change.html": 0.1939,
+    "conformance/context/context-type-test.html": 0.0668,
+    "conformance/context/deleted-object-behavior.html": 0.4261,
+    "conformance/context/incorrect-context-object-behaviour.html": 0.1942,
+    "conformance/context/methods.html": 0.1247,
+    "conformance/context/premultiplyalpha-test.html": 0.589,
+    "conformance/context/user-defined-properties-on-context.html": 0.1884,
+    "conformance/context/zero-sized-canvas.html": 0.0868,
+    "conformance/extensions/angle-instanced-arrays-out-of-bounds.html": 0.9917,
+    "conformance/extensions/angle-instanced-arrays.html": 0.6216,
+    "conformance/extensions/ext-blend-minmax.html": 0.4937,
+    "conformance/extensions/ext-color-buffer-half-float.html": 0.0,
+    "conformance/extensions/ext-disjoint-timer-query.html": 8.3259,
+    "conformance/extensions/ext-float-blend.html": 0.4015,
+    "conformance/extensions/ext-frag-depth.html": 0.87,
+    "conformance/extensions/ext-sRGB.html": 0.345,
+    "conformance/extensions/ext-shader-texture-lod.html": 1.1702,
+    "conformance/extensions/ext-texture-compression-bptc.html": 0.4059,
+    "conformance/extensions/ext-texture-compression-rgtc.html": 0.1986,
+    "conformance/extensions/ext-texture-filter-anisotropic.html": 0.1764,
+    "conformance/extensions/get-extension.html": 0.5002,
+    "conformance/extensions/oes-element-index-uint.html": 0.6993,
+    "conformance/extensions/oes-fbo-render-mipmap.html": 0.3958,
+    "conformance/extensions/oes-standard-derivatives.html": 1.1448,
+    "conformance/extensions/oes-texture-float-linear.html": 0.7294,
+    "conformance/extensions/oes-texture-float-with-canvas.html": 1.4109,
+    "conformance/extensions/oes-texture-float-with-image-data.html": 0.5105,
+    "conformance/extensions/oes-texture-float-with-image.html": 0.5445,
+    "conformance/extensions/oes-texture-float-with-video.html": 1.9408,
+    "conformance/extensions/oes-texture-float.html": 0.7521,
+    "conformance/extensions/oes-texture-half-float-linear.html": 1.0852,
+    "conformance/extensions/oes-texture-half-float-with-canvas.html": 1.5686,
+    "conformance/extensions/oes-texture-half-float-with-image-data.html": 0.5837,
+    "conformance/extensions/oes-texture-half-float-with-image.html": 0.5444,
+    "conformance/extensions/oes-texture-half-float-with-video.html": 1.6989,
+    "conformance/extensions/oes-texture-half-float.html": 0.7452,
+    "conformance/extensions/oes-vertex-array-object-bufferData.html": 0.7095,
+    "conformance/extensions/oes-vertex-array-object.html": 0.3833,
+    "conformance/extensions/s3tc-and-rgtc.html": 8.5598,
+    "conformance/extensions/webgl-compressed-texture-astc.html": 0.3703,
+    "conformance/extensions/webgl-compressed-texture-etc.html": 13.5663,
+    "conformance/extensions/webgl-compressed-texture-etc1.html": 0.1278,
+    "conformance/extensions/webgl-compressed-texture-pvrtc.html": 0.3433,
+    "conformance/extensions/webgl-compressed-texture-s3tc-srgb.html": 1.2726,
+    "conformance/extensions/webgl-compressed-texture-size-limit.html": 4.8276,
+    "conformance/extensions/webgl-debug-renderer-info.html": 0.1147,
+    "conformance/extensions/webgl-debug-shaders.html": 0.2516,
+    "conformance/extensions/webgl-depth-texture.html": 0.5856,
+    "conformance/extensions/webgl-draw-buffers-broadcast-return.html": 0.7614,
+    "conformance/extensions/webgl-draw-buffers-framebuffer-unsupported.html": 0.3848,
+    "conformance/extensions/webgl-draw-buffers-max-draw-buffers.html": 0.238,
+    "conformance/extensions/webgl-draw-buffers.html": 1.4059,
+    "conformance/extensions/webgl-multi-draw.html": 1.1873,
+    "conformance/glsl/bugs/angle-ambiguous-function-call.html": 0.1967,
+    "conformance/glsl/bugs/angle-constructor-invalid-parameters.html": 0.2965,
+    "conformance/glsl/bugs/angle-d3d11-compiler-error.html": 0.1336,
+    "conformance/glsl/bugs/angle-dx-variable-bug.html": 0.2294,
+    "conformance/glsl/bugs/array-of-struct-with-int-first-position.html": 0.4338,
+    "conformance/glsl/bugs/assign-to-swizzled-twice-in-function.html": 0.3891,
+    "conformance/glsl/bugs/bool-type-cast-bug-int-float.html": 0.4529,
+    "conformance/glsl/bugs/character-set.html": 0.3221,
+    "conformance/glsl/bugs/compare-loop-index-to-uniform.html": 0.2844,
+    "conformance/glsl/bugs/complex-glsl-does-not-crash.html": 2.9063,
+    "conformance/glsl/bugs/compound-assignment-type-combination.html": 1.7933,
+    "conformance/glsl/bugs/conditional-discard-in-loop.html": 0.4243,
+    "conformance/glsl/bugs/conditional-discard-optimization.html": 0.4994,
+    "conformance/glsl/bugs/conditional-texture-fetch.html": 0.4362,
+    "conformance/glsl/bugs/constant-precision-qualifier.html": 0.5617,
+    "conformance/glsl/bugs/essl3-shaders-with-webgl1.html": 0.2734,
+    "conformance/glsl/bugs/floor-div-cos-should-not-truncate.html": 0.2686,
+    "conformance/glsl/bugs/floored-division-accuracy.html": 0.219,
+    "conformance/glsl/bugs/fragcoord-linking-bug.html": 0.3447,
+    "conformance/glsl/bugs/gl-fragcoord-multisampling-bug.html": 0.693,
+    "conformance/glsl/bugs/global-invariant-does-not-leak-across-shaders.html": 0.1979,
+    "conformance/glsl/bugs/if-return-and-elseif.html": 0.325,
+    "conformance/glsl/bugs/in-parameter-passed-as-inout-argument-and-global.html": 0.2277,
+    "conformance/glsl/bugs/init-array-with-loop.html": 0.24,
+    "conformance/glsl/bugs/invariant-does-not-leak-across-shaders.html": 0.4107,
+    "conformance/glsl/bugs/logic-inside-block-without-braces.html": 0.388,
+    "conformance/glsl/bugs/long-expressions-should-not-crash.html": 0.9868,
+    "conformance/glsl/bugs/loop-if-loop-gradient.html": 0.2235,
+    "conformance/glsl/bugs/modulo-arithmetic-accuracy.html": 0.3025,
+    "conformance/glsl/bugs/multiplication-assignment.html": 0.3171,
+    "conformance/glsl/bugs/nested-functions-should-not-crash.html": 0.59,
+    "conformance/glsl/bugs/nested-loops-with-break-and-continue.html": 0.3225,
+    "conformance/glsl/bugs/nested-sequence-operator.html": 0.461,
+    "conformance/glsl/bugs/pow-of-small-constant-in-user-defined-function.html": 0.5753,
+    "conformance/glsl/bugs/pow-with-constant-exponent-should-not-crash.html": 0.4651,
+    "conformance/glsl/bugs/qualcomm-crash.html": 0.5284,
+    "conformance/glsl/bugs/qualcomm-loop-with-continue-crash.html": 0.4618,
+    "conformance/glsl/bugs/sampler-array-struct-function-arg.html": 0.4026,
+    "conformance/glsl/bugs/sampler-array-using-loop-index.html": 0.3848,
+    "conformance/glsl/bugs/sampler-struct-function-arg.html": 0.3871,
+    "conformance/glsl/bugs/sequence-operator-evaluation-order.html": 0.5248,
+    "conformance/glsl/bugs/sketchfab-lighting-shader-crash.html": 0.3698,
+    "conformance/glsl/bugs/struct-constructor-highp-bug.html": 0.3757,
+    "conformance/glsl/bugs/struct-with-single-member-constructor.html": 0.3316,
+    "conformance/glsl/bugs/temp-expressions-should-not-crash.html": 1.4286,
+    "conformance/glsl/bugs/unary-minus-operator-float-bug.html": 0.4501,
+    "conformance/glsl/bugs/undefined-index-should-not-crash.html": 0.3293,
+    "conformance/glsl/bugs/uniforms-should-not-lose-values.html": 0.2941,
+    "conformance/glsl/bugs/varying-arrays-should-not-be-reversed.html": 0.5024,
+    "conformance/glsl/bugs/vector-scalar-arithmetic-inside-loop-complex.html": 0.4406,
+    "conformance/glsl/bugs/vector-scalar-arithmetic-inside-loop.html": 0.54,
+    "conformance/glsl/constructors/glsl-construct-bvec2.html": 0.9874,
+    "conformance/glsl/constructors/glsl-construct-bvec3.html": 1.1782,
+    "conformance/glsl/constructors/glsl-construct-bvec4.html": 1.2385,
+    "conformance/glsl/constructors/glsl-construct-ivec2.html": 0.9196,
+    "conformance/glsl/constructors/glsl-construct-ivec3.html": 1.317,
+    "conformance/glsl/constructors/glsl-construct-ivec4.html": 1.2571,
+    "conformance/glsl/constructors/glsl-construct-mat2.html": 1.2239,
+    "conformance/glsl/constructors/glsl-construct-mat3.html": 0.7537,
+    "conformance/glsl/constructors/glsl-construct-mat4.html": 0.8378,
+    "conformance/glsl/constructors/glsl-construct-vec-mat-corner-cases.html": 0.5298,
+    "conformance/glsl/constructors/glsl-construct-vec-mat-index.html": 0.3885,
+    "conformance/glsl/constructors/glsl-construct-vec2.html": 0.8781,
+    "conformance/glsl/constructors/glsl-construct-vec3.html": 1.2949,
+    "conformance/glsl/constructors/glsl-construct-vec4.html": 1.3134,
+    "conformance/glsl/functions/glsl-function-abs.html": 1.0391,
+    "conformance/glsl/functions/glsl-function-acos.html": 1.1049,
+    "conformance/glsl/functions/glsl-function-asin.html": 1.1588,
+    "conformance/glsl/functions/glsl-function-atan-xy.html": 1.3247,
+    "conformance/glsl/functions/glsl-function-atan.html": 1.1388,
+    "conformance/glsl/functions/glsl-function-ceil.html": 0.9449,
+    "conformance/glsl/functions/glsl-function-clamp-float.html": 0.9284,
+    "conformance/glsl/functions/glsl-function-clamp-gentype.html": 0.9534,
+    "conformance/glsl/functions/glsl-function-cos.html": 0.8816,
+    "conformance/glsl/functions/glsl-function-cross.html": 0.4983,
+    "conformance/glsl/functions/glsl-function-distance.html": 0.9191,
+    "conformance/glsl/functions/glsl-function-dot.html": 0.8134,
+    "conformance/glsl/functions/glsl-function-faceforward.html": 0.8428,
+    "conformance/glsl/functions/glsl-function-floor.html": 0.9721,
+    "conformance/glsl/functions/glsl-function-fract.html": 0.9325,
+    "conformance/glsl/functions/glsl-function-length.html": 0.997,
+    "conformance/glsl/functions/glsl-function-max-float.html": 0.968,
+    "conformance/glsl/functions/glsl-function-max-gentype.html": 0.8564,
+    "conformance/glsl/functions/glsl-function-min-float.html": 0.9443,
+    "conformance/glsl/functions/glsl-function-min-gentype.html": 0.9893,
+    "conformance/glsl/functions/glsl-function-mix-float.html": 0.8882,
+    "conformance/glsl/functions/glsl-function-mix-gentype.html": 0.8643,
+    "conformance/glsl/functions/glsl-function-mod-float.html": 1.0725,
+    "conformance/glsl/functions/glsl-function-mod-gentype.html": 0.885,
+    "conformance/glsl/functions/glsl-function-normalize.html": 0.8573,
+    "conformance/glsl/functions/glsl-function-reflect.html": 1.0133,
+    "conformance/glsl/functions/glsl-function-sign.html": 0.9243,
+    "conformance/glsl/functions/glsl-function-sin.html": 1.0841,
+    "conformance/glsl/functions/glsl-function-smoothstep-float.html": 1.1326,
+    "conformance/glsl/functions/glsl-function-smoothstep-gentype.html": 0.9903,
+    "conformance/glsl/functions/glsl-function-step-float.html": 1.0122,
+    "conformance/glsl/functions/glsl-function-step-gentype.html": 0.9841,
+    "conformance/glsl/functions/glsl-function.html": 0.8605,
+    "conformance/glsl/implicit/add_int_float.vert.html": 0.3298,
+    "conformance/glsl/implicit/add_int_mat2.vert.html": 0.4416,
+    "conformance/glsl/implicit/add_int_mat3.vert.html": 0.1895,
+    "conformance/glsl/implicit/add_int_mat4.vert.html": 0.2445,
+    "conformance/glsl/implicit/add_int_vec2.vert.html": 0.1663,
+    "conformance/glsl/implicit/add_int_vec3.vert.html": 0.2751,
+    "conformance/glsl/implicit/add_int_vec4.vert.html": 0.2576,
+    "conformance/glsl/implicit/add_ivec2_vec2.vert.html": 0.1339,
+    "conformance/glsl/implicit/add_ivec3_vec3.vert.html": 0.2803,
+    "conformance/glsl/implicit/add_ivec4_vec4.vert.html": 0.1636,
+    "conformance/glsl/implicit/assign_int_to_float.vert.html": 0.1834,
+    "conformance/glsl/implicit/assign_ivec2_to_vec2.vert.html": 0.2438,
+    "conformance/glsl/implicit/assign_ivec3_to_vec3.vert.html": 0.2676,
+    "conformance/glsl/implicit/assign_ivec4_to_vec4.vert.html": 0.2467,
+    "conformance/glsl/implicit/construct_struct.vert.html": 0.2932,
+    "conformance/glsl/implicit/divide_int_float.vert.html": 0.2568,
+    "conformance/glsl/implicit/divide_int_mat2.vert.html": 0.2598,
+    "conformance/glsl/implicit/divide_int_mat3.vert.html": 0.1625,
+    "conformance/glsl/implicit/divide_int_mat4.vert.html": 0.1973,
+    "conformance/glsl/implicit/divide_int_vec2.vert.html": 0.0899,
+    "conformance/glsl/implicit/divide_int_vec3.vert.html": 0.1656,
+    "conformance/glsl/implicit/divide_int_vec4.vert.html": 0.2454,
+    "conformance/glsl/implicit/divide_ivec2_vec2.vert.html": 0.2475,
+    "conformance/glsl/implicit/divide_ivec3_vec3.vert.html": 0.1482,
+    "conformance/glsl/implicit/divide_ivec4_vec4.vert.html": 0.2275,
+    "conformance/glsl/implicit/equal_int_float.vert.html": 0.2491,
+    "conformance/glsl/implicit/equal_ivec2_vec2.vert.html": 0.1568,
+    "conformance/glsl/implicit/equal_ivec3_vec3.vert.html": 0.1459,
+    "conformance/glsl/implicit/equal_ivec4_vec4.vert.html": 0.1335,
+    "conformance/glsl/implicit/function_int_float.vert.html": 0.1227,
+    "conformance/glsl/implicit/function_ivec2_vec2.vert.html": 0.1472,
+    "conformance/glsl/implicit/function_ivec3_vec3.vert.html": 0.2459,
+    "conformance/glsl/implicit/function_ivec4_vec4.vert.html": 0.1471,
+    "conformance/glsl/implicit/greater_than.vert.html": 0.1942,
+    "conformance/glsl/implicit/greater_than_equal.vert.html": 0.2617,
+    "conformance/glsl/implicit/less_than.vert.html": 0.2622,
+    "conformance/glsl/implicit/less_than_equal.vert.html": 0.1604,
+    "conformance/glsl/implicit/multiply_int_float.vert.html": 0.2171,
+    "conformance/glsl/implicit/multiply_int_mat2.vert.html": 0.147,
+    "conformance/glsl/implicit/multiply_int_mat3.vert.html": 0.2591,
+    "conformance/glsl/implicit/multiply_int_mat4.vert.html": 0.1572,
+    "conformance/glsl/implicit/multiply_int_vec2.vert.html": 0.1155,
+    "conformance/glsl/implicit/multiply_int_vec3.vert.html": 0.278,
+    "conformance/glsl/implicit/multiply_int_vec4.vert.html": 0.2667,
+    "conformance/glsl/implicit/multiply_ivec2_vec2.vert.html": 0.2497,
+    "conformance/glsl/implicit/multiply_ivec3_vec3.vert.html": 0.2452,
+    "conformance/glsl/implicit/multiply_ivec4_vec4.vert.html": 0.1266,
+    "conformance/glsl/implicit/not_equal_int_float.vert.html": 0.1724,
+    "conformance/glsl/implicit/not_equal_ivec2_vec2.vert.html": 0.1931,
+    "conformance/glsl/implicit/not_equal_ivec3_vec3.vert.html": 0.2573,
+    "conformance/glsl/implicit/not_equal_ivec4_vec4.vert.html": 0.1712,
+    "conformance/glsl/implicit/subtract_int_float.vert.html": 0.1501,
+    "conformance/glsl/implicit/subtract_int_mat2.vert.html": 0.1567,
+    "conformance/glsl/implicit/subtract_int_mat3.vert.html": 0.2485,
+    "conformance/glsl/implicit/subtract_int_mat4.vert.html": 0.2301,
+    "conformance/glsl/implicit/subtract_int_vec2.vert.html": 0.157,
+    "conformance/glsl/implicit/subtract_int_vec3.vert.html": 0.2486,
+    "conformance/glsl/implicit/subtract_int_vec4.vert.html": 0.1296,
+    "conformance/glsl/implicit/subtract_ivec2_vec2.vert.html": 0.2637,
+    "conformance/glsl/implicit/subtract_ivec3_vec3.vert.html": 0.2004,
+    "conformance/glsl/implicit/subtract_ivec4_vec4.vert.html": 0.2662,
+    "conformance/glsl/implicit/ternary_int_float.vert.html": 0.2632,
+    "conformance/glsl/implicit/ternary_ivec2_vec2.vert.html": 0.226,
+    "conformance/glsl/implicit/ternary_ivec3_vec3.vert.html": 0.2483,
+    "conformance/glsl/implicit/ternary_ivec4_vec4.vert.html": 0.258,
+    "conformance/glsl/literals/float_literal.vert.html": 0.1248,
+    "conformance/glsl/literals/literal_precision.html": 0.1601,
+    "conformance/glsl/literals/overflow_leak.vert.html": 0.1014,
+    "conformance/glsl/matrices/glsl-mat3-construction.html": 0.6947,
+    "conformance/glsl/matrices/glsl-mat4-to-mat3.html": 0.5344,
+    "conformance/glsl/matrices/matrix-compound-multiply.html": 0.7121,
+    "conformance/glsl/misc/attrib-location-length-limits.html": 0.4669,
+    "conformance/glsl/misc/boolean_precision.html": 0.4844,
+    "conformance/glsl/misc/const-variable-initialization.html": 2.0921,
+    "conformance/glsl/misc/embedded-struct-definitions-forbidden.html": 0.3723,
+    "conformance/glsl/misc/empty-declaration.html": 0.3099,
+    "conformance/glsl/misc/empty_main.vert.html": 0.3723,
+    "conformance/glsl/misc/expression-list-in-declarator-initializer.html": 0.9353,
+    "conformance/glsl/misc/fragcolor-fragdata-invariant.html": 0.4527,
+    "conformance/glsl/misc/gl_position_unset.vert.html": 0.4561,
+    "conformance/glsl/misc/global-variable-init.html": 0.6306,
+    "conformance/glsl/misc/glsl-function-nodes.html": 0.5641,
+    "conformance/glsl/misc/glsl-long-variable-names.html": 0.4852,
+    "conformance/glsl/misc/glsl-vertex-branch.html": 0.5482,
+    "conformance/glsl/misc/large-loop-compile.html": 0.9762,
+    "conformance/glsl/misc/local-variable-shadowing-outer-function.html": 0.5218,
+    "conformance/glsl/misc/non-ascii-comments.vert.html": 0.3849,
+    "conformance/glsl/misc/non-ascii.vert.html": 0.4465,
+    "conformance/glsl/misc/re-compile-re-link.html": 0.3566,
+    "conformance/glsl/misc/sampler-operand.html": 0.3272,
+    "conformance/glsl/misc/sequence-operator-returns-constant.html": 0.2994,
+    "conformance/glsl/misc/shader-precision-format-obeyed.html": 0.3996,
+    "conformance/glsl/misc/shader-struct-scope.html": 0.2878,
+    "conformance/glsl/misc/shader-uniform-packing-restrictions.html": 3.684,
+    "conformance/glsl/misc/shader-varying-packing-restrictions.html": 0.8899,
+    "conformance/glsl/misc/shader-with-256-character-define.html": 0.2862,
+    "conformance/glsl/misc/shader-with-256-character-identifier.frag.html": 0.3883,
+    "conformance/glsl/misc/shader-with-257-character-define.html": 0.3911,
+    "conformance/glsl/misc/shader-with-257-character-identifier.frag.html": 0.2043,
+    "conformance/glsl/misc/shader-with-_webgl-identifier.vert.html": 0.2459,
+    "conformance/glsl/misc/shader-with-arbitrary-indexing.frag.html": 0.2206,
+    "conformance/glsl/misc/shader-with-arbitrary-indexing.vert.html": 0.2202,
+    "conformance/glsl/misc/shader-with-array-of-structs-containing-arrays.html": 0.5653,
+    "conformance/glsl/misc/shader-with-array-of-structs-uniform.html": 0.4091,
+    "conformance/glsl/misc/shader-with-attrib-array.vert.html": 0.2095,
+    "conformance/glsl/misc/shader-with-attrib-struct.vert.html": 0.4973,
+    "conformance/glsl/misc/shader-with-clipvertex.vert.html": 0.3012,
+    "conformance/glsl/misc/shader-with-comma-assignment.html": 0.2726,
+    "conformance/glsl/misc/shader-with-comma-conditional-assignment.html": 0.4552,
+    "conformance/glsl/misc/shader-with-comma-separated-variable-declarations.html": 0.3651,
+    "conformance/glsl/misc/shader-with-conditional-scoping-negative.html": 0.3643,
+    "conformance/glsl/misc/shader-with-conditional-scoping.html": 0.267,
+    "conformance/glsl/misc/shader-with-default-precision.frag.html": 0.4519,
+    "conformance/glsl/misc/shader-with-default-precision.vert.html": 0.4618,
+    "conformance/glsl/misc/shader-with-define-line-continuation.frag.html": 0.4634,
+    "conformance/glsl/misc/shader-with-dfdx-no-ext.frag.html": 0.4573,
+    "conformance/glsl/misc/shader-with-dfdx.frag.html": 0.1872,
+    "conformance/glsl/misc/shader-with-do-loop.html": 0.2858,
+    "conformance/glsl/misc/shader-with-error-directive.html": 0.193,
+    "conformance/glsl/misc/shader-with-explicit-int-cast.vert.html": 0.2157,
+    "conformance/glsl/misc/shader-with-float-return-value.frag.html": 0.1577,
+    "conformance/glsl/misc/shader-with-for-loop.html": 0.4547,
+    "conformance/glsl/misc/shader-with-for-scoping.html": 0.3784,
+    "conformance/glsl/misc/shader-with-frag-depth.frag.html": 0.4927,
+    "conformance/glsl/misc/shader-with-function-recursion.frag.html": 0.1183,
+    "conformance/glsl/misc/shader-with-function-scoped-struct.html": 0.1713,
+    "conformance/glsl/misc/shader-with-functional-scoping.html": 0.2215,
+    "conformance/glsl/misc/shader-with-glcolor.vert.html": 0.2119,
+    "conformance/glsl/misc/shader-with-gles-1.frag.html": 0.2337,
+    "conformance/glsl/misc/shader-with-gles-symbol.frag.html": 0.2498,
+    "conformance/glsl/misc/shader-with-global-variable-precision-mismatch.html": 0.4903,
+    "conformance/glsl/misc/shader-with-glprojectionmatrix.vert.html": 0.1615,
+    "conformance/glsl/misc/shader-with-hex-int-constant-macro.html": 0.3669,
+    "conformance/glsl/misc/shader-with-implicit-vec3-to-vec4-cast.vert.html": 0.2513,
+    "conformance/glsl/misc/shader-with-include.vert.html": 0.1912,
+    "conformance/glsl/misc/shader-with-int-return-value.frag.html": 0.3381,
+    "conformance/glsl/misc/shader-with-invalid-identifier.frag.html": 0.2499,
+    "conformance/glsl/misc/shader-with-ivec2-return-value.frag.html": 0.359,
+    "conformance/glsl/misc/shader-with-ivec3-return-value.frag.html": 0.3809,
+    "conformance/glsl/misc/shader-with-ivec4-return-value.frag.html": 0.3264,
+    "conformance/glsl/misc/shader-with-limited-indexing.frag.html": 0.3339,
+    "conformance/glsl/misc/shader-with-long-line.html": 0.4736,
+    "conformance/glsl/misc/shader-with-non-ascii-error.frag.html": 0.3527,
+    "conformance/glsl/misc/shader-with-non-reserved-words.html": 28.1745,
+    "conformance/glsl/misc/shader-with-precision.frag.html": 0.1262,
+    "conformance/glsl/misc/shader-with-preprocessor-whitespace.html": 0.3546,
+    "conformance/glsl/misc/shader-with-quoted-error.frag.html": 0.4896,
+    "conformance/glsl/misc/shader-with-reserved-words.html": 4.0307,
+    "conformance/glsl/misc/shader-with-short-circuiting-operators.html": 0.9213,
+    "conformance/glsl/misc/shader-with-similar-uniform-array-names.html": 0.7654,
+    "conformance/glsl/misc/shader-with-too-many-uniforms.html": 0.9555,
+    "conformance/glsl/misc/shader-with-two-initializer-types.html": 0.3112,
+    "conformance/glsl/misc/shader-with-undefined-preprocessor-symbol.frag.html": 0.1542,
+    "conformance/glsl/misc/shader-with-uniform-in-loop-condition.vert.html": 0.3484,
+    "conformance/glsl/misc/shader-with-vec2-return-value.frag.html": 0.2487,
+    "conformance/glsl/misc/shader-with-vec3-return-value.frag.html": 0.1889,
+    "conformance/glsl/misc/shader-with-vec4-return-value.frag.html": 0.3494,
+    "conformance/glsl/misc/shader-with-vec4-vec3-vec4-conditional.html": 0.4281,
+    "conformance/glsl/misc/shader-with-version-100.frag.html": 0.4731,
+    "conformance/glsl/misc/shader-with-version-100.vert.html": 0.3497,
+    "conformance/glsl/misc/shader-with-version-120.vert.html": 0.3377,
+    "conformance/glsl/misc/shader-with-version-130.vert.html": 0.2546,
+    "conformance/glsl/misc/shader-with-webgl-identifier.vert.html": 0.1863,
+    "conformance/glsl/misc/shader-with-while-loop.html": 0.2153,
+    "conformance/glsl/misc/shader-without-precision.frag.html": 0.1857,
+    "conformance/glsl/misc/shaders-with-constant-expression-loop-conditions.html": 0.518,
+    "conformance/glsl/misc/shaders-with-invariance.html": 0.3628,
+    "conformance/glsl/misc/shaders-with-mis-matching-uniforms.html": 0.7217,
+    "conformance/glsl/misc/shaders-with-mis-matching-varyings.html": 0.5457,
+    "conformance/glsl/misc/shaders-with-missing-varyings.html": 0.3449,
+    "conformance/glsl/misc/shaders-with-name-conflicts.html": 0.2649,
+    "conformance/glsl/misc/shaders-with-uniform-structs.html": 0.2991,
+    "conformance/glsl/misc/shaders-with-varyings.html": 0.2603,
+    "conformance/glsl/misc/shared.html": 0.5164,
+    "conformance/glsl/misc/struct-as-inout-parameter.html": 0.439,
+    "conformance/glsl/misc/struct-as-out-parameter.html": 0.5047,
+    "conformance/glsl/misc/struct-assign.html": 0.6433,
+    "conformance/glsl/misc/struct-equals.html": 0.5659,
+    "conformance/glsl/misc/struct-mixed-array-declarators.html": 1.0818,
+    "conformance/glsl/misc/struct-nesting-exceeds-maximum.html": 0.4578,
+    "conformance/glsl/misc/struct-nesting-of-variable-names.html": 2.886,
+    "conformance/glsl/misc/struct-nesting-under-maximum.html": 0.2116,
+    "conformance/glsl/misc/struct-specifiers-in-uniforms.html": 0.7079,
+    "conformance/glsl/misc/struct-unary-operators.html": 0.6934,
+    "conformance/glsl/misc/ternary-operator-on-arrays.html": 0.1615,
+    "conformance/glsl/misc/ternary-operators-in-global-initializers.html": 0.57,
+    "conformance/glsl/misc/ternary-operators-in-initializers.html": 0.624,
+    "conformance/glsl/misc/uniform-location-length-limits.html": 0.128,
+    "conformance/glsl/misc/uninitialized-local-global-variables.html": 0.7618,
+    "conformance/glsl/preprocessor/comments.html": 0.4354,
+    "conformance/glsl/preprocessor/macro-expansion-tricky.html": 0.4733,
+    "conformance/glsl/reserved/_webgl_field.vert.html": 0.4417,
+    "conformance/glsl/reserved/_webgl_function.vert.html": 0.4681,
+    "conformance/glsl/reserved/_webgl_struct.vert.html": 0.1503,
+    "conformance/glsl/reserved/_webgl_variable.vert.html": 0.1858,
+    "conformance/glsl/reserved/webgl_field.vert.html": 0.242,
+    "conformance/glsl/reserved/webgl_function.vert.html": 0.1479,
+    "conformance/glsl/reserved/webgl_struct.vert.html": 0.139,
+    "conformance/glsl/reserved/webgl_variable.vert.html": 0.2299,
+    "conformance/glsl/samplers/glsl-function-texture2d-bias.html": 0.4459,
+    "conformance/glsl/samplers/glsl-function-texture2dlod.html": 0.8137,
+    "conformance/glsl/samplers/glsl-function-texture2dproj.html": 0.4705,
+    "conformance/glsl/samplers/glsl-function-texture2dprojlod.html": 1.4089,
+    "conformance/glsl/variables/gl-fragcoord-xy-values.html": 0.3019,
+    "conformance/glsl/variables/gl-fragcoord.html": 0.4436,
+    "conformance/glsl/variables/gl-fragdata-and-fragcolor.html": 0.4123,
+    "conformance/glsl/variables/gl-frontfacing.html": 0.4304,
+    "conformance/glsl/variables/gl-pointcoord.html": 0.4373,
+    "conformance/glsl/variables/glsl-built-ins.html": 0.3709,
+    "conformance/limits/gl-line-width.html": 0.3446,
+    "conformance/limits/gl-max-texture-dimensions.html": 0.2941,
+    "conformance/limits/gl-min-attribs.html": 0.3158,
+    "conformance/limits/gl-min-textures.html": 0.2636,
+    "conformance/limits/gl-min-uniforms.html": 0.2759,
+    "conformance/misc/bad-arguments-test.html": 0.3597,
+    "conformance/misc/boolean-argument-conversion.html": 0.3114,
+    "conformance/misc/delayed-drawing.html": 1.1728,
+    "conformance/misc/error-reporting.html": 0.1545,
+    "conformance/misc/expando-loss.html": 0.229,
+    "conformance/misc/functions-returning-strings.html": 0.1661,
+    "conformance/misc/instanceof-test.html": 0.2698,
+    "conformance/misc/invalid-passed-params.html": 0.33,
+    "conformance/misc/is-object.html": 0.3016,
+    "conformance/misc/null-object-behaviour.html": 0.1747,
+    "conformance/misc/object-deletion-behaviour.html": 0.7011,
+    "conformance/misc/shader-precision-format.html": 0.7092,
+    "conformance/misc/type-conversion-test.html": 0.4929,
+    "conformance/misc/uninitialized-test.html": 0.4662,
+    "conformance/misc/webgl-specific-stencil-settings.html": 1.0675,
+    "conformance/misc/webgl-specific.html": 0.174,
+    "conformance/more/conformance/constants.html": 0.2216,
+    "conformance/more/conformance/getContext.html": 0.2363,
+    "conformance/more/conformance/methods.html": 0.1697,
+    "conformance/more/conformance/quickCheckAPI-A.html": 0.2306,
+    "conformance/more/conformance/quickCheckAPI-B1.html": 0.4825,
+    "conformance/more/conformance/quickCheckAPI-B2.html": 0.2986,
+    "conformance/more/conformance/quickCheckAPI-B3.html": 0.4818,
+    "conformance/more/conformance/quickCheckAPI-B4.html": 0.3138,
+    "conformance/more/conformance/quickCheckAPI-C.html": 0.2751,
+    "conformance/more/conformance/quickCheckAPI-D_G.html": 0.3502,
+    "conformance/more/conformance/quickCheckAPI-G_I.html": 0.5583,
+    "conformance/more/conformance/quickCheckAPI-L_S.html": 0.2702,
+    "conformance/more/conformance/quickCheckAPI-S_V.html": 0.3351,
+    "conformance/more/conformance/webGLArrays.html": 0.2269,
+    "conformance/more/functions/bindBuffer.html": 0.1835,
+    "conformance/more/functions/bindBufferBadArgs.html": 0.2486,
+    "conformance/more/functions/bindFramebufferLeaveNonZero.html": 0.1685,
+    "conformance/more/functions/bufferData.html": 0.4168,
+    "conformance/more/functions/bufferDataBadArgs.html": 0.1819,
+    "conformance/more/functions/bufferSubData.html": 0.2141,
+    "conformance/more/functions/bufferSubDataBadArgs.html": 0.1811,
+    "conformance/more/functions/copyTexImage2D.html": 0.2411,
+    "conformance/more/functions/copyTexImage2DBadArgs.html": 0.2275,
+    "conformance/more/functions/copyTexSubImage2D.html": 0.4325,
+    "conformance/more/functions/copyTexSubImage2DBadArgs.html": 0.1798,
+    "conformance/more/functions/deleteBufferBadArgs.html": 0.1491,
+    "conformance/more/functions/drawArrays.html": 0.2024,
+    "conformance/more/functions/drawElements.html": 0.3889,
+    "conformance/more/functions/isTests.html": 0.2304,
+    "conformance/more/functions/isTestsBadArgs.html": 0.1855,
+    "conformance/more/functions/readPixels.html": 0.1548,
+    "conformance/more/functions/readPixelsBadArgs.html": 0.2126,
+    "conformance/more/functions/texImage2D.html": 0.47,
+    "conformance/more/functions/texImage2DBadArgs.html": 0.2109,
+    "conformance/more/functions/texImage2DHTML.html": 0.3482,
+    "conformance/more/functions/texImage2DHTMLBadArgs.html": 0.3758,
+    "conformance/more/functions/texSubImage2D.html": 0.2087,
+    "conformance/more/functions/texSubImage2DBadArgs.html": 0.2308,
+    "conformance/more/functions/texSubImage2DHTML.html": 0.3058,
+    "conformance/more/functions/texSubImage2DHTMLBadArgs.html": 0.1752,
+    "conformance/more/functions/uniformMatrix.html": 0.1962,
+    "conformance/more/functions/uniformMatrixBadArgs.html": 0.4036,
+    "conformance/more/functions/uniformf.html": 0.3315,
+    "conformance/more/functions/uniformfArrayLen1.html": 0.3787,
+    "conformance/more/functions/uniformfBadArgs.html": 0.3923,
+    "conformance/more/functions/uniformi.html": 0.3857,
+    "conformance/more/functions/uniformiBadArgs.html": 0.438,
+    "conformance/more/functions/vertexAttrib.html": 0.4085,
+    "conformance/more/functions/vertexAttribBadArgs.html": 0.2996,
+    "conformance/more/functions/vertexAttribPointer.html": 0.372,
+    "conformance/more/functions/vertexAttribPointerBadArgs.html": 0.1796,
+    "conformance/more/glsl/arrayOutOfBounds.html": 0.2983,
+    "conformance/more/glsl/uniformOutOfBounds.html": 0.3697,
+    "conformance/offscreencanvas/context-attribute-preserve-drawing-buffer.html": 0.8863,
+    "conformance/offscreencanvas/context-creation-worker.html": 0.1972,
+    "conformance/offscreencanvas/context-creation.html": 0.1756,
+    "conformance/offscreencanvas/context-lost-restored-worker.html": 0.2918,
+    "conformance/offscreencanvas/context-lost-restored.html": 0.2506,
+    "conformance/offscreencanvas/context-lost-worker.html": 0.1784,
+    "conformance/offscreencanvas/context-lost.html": 0.2545,
+    "conformance/offscreencanvas/methods-worker.html": 0.1871,
+    "conformance/offscreencanvas/methods.html": 0.1238,
+    "conformance/offscreencanvas/offscreencanvas-resize.html": 0.118,
+    "conformance/offscreencanvas/offscreencanvas-timer-query.html": 0.1545,
+    "conformance/offscreencanvas/offscreencanvas-transfer-image-bitmap.html": 0.1624,
+    "conformance/ogles/GL/abs/abs_001_to_006.html": 3.0576,
+    "conformance/ogles/GL/acos/acos_001_to_006.html": 3.1756,
+    "conformance/ogles/GL/all/all_001_to_004.html": 2.7893,
+    "conformance/ogles/GL/any/any_001_to_004.html": 2.8931,
+    "conformance/ogles/GL/array/array_001_to_006.html": 0.8615,
+    "conformance/ogles/GL/asin/asin_001_to_006.html": 3.083,
+    "conformance/ogles/GL/atan/atan_001_to_008.html": 3.309,
+    "conformance/ogles/GL/atan/atan_009_to_012.html": 3.0116,
+    "conformance/ogles/GL/biConstants/biConstants_001_to_008.html": 3.0817,
+    "conformance/ogles/GL/biConstants/biConstants_009_to_016.html": 3.1362,
+    "conformance/ogles/GL/biuDepthRange/biuDepthRange_001_to_002.html": 2.4285,
+    "conformance/ogles/GL/build/build_001_to_008.html": 0.5295,
+    "conformance/ogles/GL/build/build_009_to_016.html": 0.3772,
+    "conformance/ogles/GL/build/build_017_to_024.html": 0.3625,
+    "conformance/ogles/GL/build/build_025_to_032.html": 0.4222,
+    "conformance/ogles/GL/build/build_033_to_040.html": 0.4141,
+    "conformance/ogles/GL/build/build_041_to_048.html": 0.3879,
+    "conformance/ogles/GL/build/build_049_to_056.html": 0.2814,
+    "conformance/ogles/GL/build/build_057_to_064.html": 0.3656,
+    "conformance/ogles/GL/build/build_065_to_072.html": 0.3606,
+    "conformance/ogles/GL/build/build_073_to_080.html": 0.2728,
+    "conformance/ogles/GL/build/build_081_to_088.html": 0.2589,
+    "conformance/ogles/GL/build/build_089_to_096.html": 0.3023,
+    "conformance/ogles/GL/build/build_097_to_104.html": 0.2908,
+    "conformance/ogles/GL/build/build_105_to_112.html": 0.3813,
+    "conformance/ogles/GL/build/build_113_to_120.html": 0.3016,
+    "conformance/ogles/GL/build/build_121_to_128.html": 0.2615,
+    "conformance/ogles/GL/build/build_129_to_136.html": 0.2834,
+    "conformance/ogles/GL/build/build_137_to_144.html": 0.2286,
+    "conformance/ogles/GL/build/build_145_to_152.html": 0.3143,
+    "conformance/ogles/GL/build/build_153_to_160.html": 0.5004,
+    "conformance/ogles/GL/build/build_161_to_168.html": 0.2334,
+    "conformance/ogles/GL/build/build_169_to_176.html": 0.3228,
+    "conformance/ogles/GL/build/build_177_to_178.html": 0.4456,
+    "conformance/ogles/GL/built_in_varying_array_out_of_bounds/built_in_varying_array_out_of_bounds_001_to_001.html": 0.2985,
+    "conformance/ogles/GL/ceil/ceil_001_to_006.html": 2.8113,
+    "conformance/ogles/GL/clamp/clamp_001_to_006.html": 2.7438,
+    "conformance/ogles/GL/control_flow/control_flow_001_to_008.html": 0.8988,
+    "conformance/ogles/GL/control_flow/control_flow_009_to_010.html": 0.6353,
+    "conformance/ogles/GL/cos/cos_001_to_006.html": 2.9236,
+    "conformance/ogles/GL/cross/cross_001_to_002.html": 2.3791,
+    "conformance/ogles/GL/default/default_001_to_001.html": 0.5495,
+    "conformance/ogles/GL/degrees/degrees_001_to_006.html": 2.988,
+    "conformance/ogles/GL/discard/discard_001_to_002.html": 0.6335,
+    "conformance/ogles/GL/distance/distance_001_to_006.html": 2.8008,
+    "conformance/ogles/GL/dot/dot_001_to_006.html": 2.9553,
+    "conformance/ogles/GL/equal/equal_001_to_008.html": 3.2366,
+    "conformance/ogles/GL/equal/equal_009_to_012.html": 2.865,
+    "conformance/ogles/GL/exp/exp_001_to_008.html": 3.1542,
+    "conformance/ogles/GL/exp/exp_009_to_012.html": 2.71,
+    "conformance/ogles/GL/exp2/exp2_001_to_008.html": 3.2164,
+    "conformance/ogles/GL/exp2/exp2_009_to_012.html": 2.5925,
+    "conformance/ogles/GL/faceforward/faceforward_001_to_006.html": 2.913,
+    "conformance/ogles/GL/floor/floor_001_to_006.html": 2.8012,
+    "conformance/ogles/GL/fract/fract_001_to_006.html": 2.9837,
+    "conformance/ogles/GL/functions/functions_001_to_008.html": 2.9413,
+    "conformance/ogles/GL/functions/functions_009_to_016.html": 0.9236,
+    "conformance/ogles/GL/functions/functions_017_to_024.html": 0.8332,
+    "conformance/ogles/GL/functions/functions_025_to_032.html": 0.8598,
+    "conformance/ogles/GL/functions/functions_033_to_040.html": 0.9865,
+    "conformance/ogles/GL/functions/functions_041_to_048.html": 0.9595,
+    "conformance/ogles/GL/functions/functions_049_to_056.html": 0.971,
+    "conformance/ogles/GL/functions/functions_057_to_064.html": 0.9378,
+    "conformance/ogles/GL/functions/functions_065_to_072.html": 0.9406,
+    "conformance/ogles/GL/functions/functions_073_to_080.html": 0.96,
+    "conformance/ogles/GL/functions/functions_081_to_088.html": 0.8297,
+    "conformance/ogles/GL/functions/functions_089_to_096.html": 0.8457,
+    "conformance/ogles/GL/functions/functions_097_to_104.html": 0.7903,
+    "conformance/ogles/GL/functions/functions_105_to_112.html": 0.8379,
+    "conformance/ogles/GL/functions/functions_113_to_120.html": 0.8257,
+    "conformance/ogles/GL/functions/functions_121_to_126.html": 0.8514,
+    "conformance/ogles/GL/gl_FragCoord/gl_FragCoord_001_to_003.html": 0.7954,
+    "conformance/ogles/GL/gl_FrontFacing/gl_FrontFacing_001_to_001.html": 0.5474,
+    "conformance/ogles/GL/greaterThan/greaterThan_001_to_008.html": 3.2756,
+    "conformance/ogles/GL/greaterThanEqual/greaterThanEqual_001_to_008.html": 3.178,
+    "conformance/ogles/GL/inversesqrt/inversesqrt_001_to_006.html": 2.9927,
+    "conformance/ogles/GL/length/length_001_to_006.html": 2.8224,
+    "conformance/ogles/GL/lessThan/lessThan_001_to_008.html": 3.1085,
+    "conformance/ogles/GL/lessThanEqual/lessThanEqual_001_to_008.html": 3.2011,
+    "conformance/ogles/GL/log/log_001_to_008.html": 3.2484,
+    "conformance/ogles/GL/log/log_009_to_012.html": 2.7251,
+    "conformance/ogles/GL/log2/log2_001_to_008.html": 3.2877,
+    "conformance/ogles/GL/log2/log2_009_to_012.html": 3.0291,
+    "conformance/ogles/GL/mat/mat_001_to_008.html": 1.0346,
+    "conformance/ogles/GL/mat/mat_009_to_016.html": 0.9352,
+    "conformance/ogles/GL/mat/mat_017_to_024.html": 0.9576,
+    "conformance/ogles/GL/mat/mat_025_to_032.html": 3.2795,
+    "conformance/ogles/GL/mat/mat_033_to_040.html": 2.7373,
+    "conformance/ogles/GL/mat/mat_041_to_046.html": 0.8201,
+    "conformance/ogles/GL/mat3/mat3_001_to_006.html": 0.7504,
+    "conformance/ogles/GL/matrixCompMult/matrixCompMult_001_to_004.html": 2.7801,
+    "conformance/ogles/GL/max/max_001_to_006.html": 2.8404,
+    "conformance/ogles/GL/min/min_001_to_006.html": 2.9012,
+    "conformance/ogles/GL/mix/mix_001_to_006.html": 2.856,
+    "conformance/ogles/GL/mod/mod_001_to_008.html": 2.9104,
+    "conformance/ogles/GL/normalize/normalize_001_to_006.html": 3.0215,
+    "conformance/ogles/GL/not/not_001_to_004.html": 2.8427,
+    "conformance/ogles/GL/notEqual/notEqual_001_to_008.html": 3.2998,
+    "conformance/ogles/GL/notEqual/notEqual_009_to_012.html": 2.8511,
+    "conformance/ogles/GL/operators/operators_001_to_008.html": 0.9772,
+    "conformance/ogles/GL/operators/operators_009_to_016.html": 1.0223,
+    "conformance/ogles/GL/operators/operators_017_to_024.html": 0.9853,
+    "conformance/ogles/GL/operators/operators_025_to_026.html": 0.5819,
+    "conformance/ogles/GL/pow/pow_001_to_008.html": 1.1755,
+    "conformance/ogles/GL/pow/pow_009_to_016.html": 3.0542,
+    "conformance/ogles/GL/pow/pow_017_to_024.html": 3.4157,
+    "conformance/ogles/GL/radians/radians_001_to_006.html": 2.9386,
+    "conformance/ogles/GL/reflect/reflect_001_to_006.html": 3.0921,
+    "conformance/ogles/GL/refract/refract_001_to_006.html": 2.903,
+    "conformance/ogles/GL/sign/sign_001_to_006.html": 2.9341,
+    "conformance/ogles/GL/sin/sin_001_to_006.html": 3.1525,
+    "conformance/ogles/GL/smoothstep/smoothstep_001_to_006.html": 2.8567,
+    "conformance/ogles/GL/sqrt/sqrt_001_to_006.html": 2.8436,
+    "conformance/ogles/GL/step/step_001_to_006.html": 2.8796,
+    "conformance/ogles/GL/struct/struct_001_to_008.html": 3.0879,
+    "conformance/ogles/GL/struct/struct_009_to_016.html": 3.1023,
+    "conformance/ogles/GL/struct/struct_017_to_024.html": 3.1827,
+    "conformance/ogles/GL/struct/struct_025_to_032.html": 3.183,
+    "conformance/ogles/GL/struct/struct_033_to_040.html": 3.1225,
+    "conformance/ogles/GL/struct/struct_041_to_048.html": 3.143,
+    "conformance/ogles/GL/struct/struct_049_to_056.html": 3.1715,
+    "conformance/ogles/GL/swizzlers/swizzlers_001_to_008.html": 3.2537,
+    "conformance/ogles/GL/swizzlers/swizzlers_009_to_016.html": 3.2345,
+    "conformance/ogles/GL/swizzlers/swizzlers_017_to_024.html": 3.2211,
+    "conformance/ogles/GL/swizzlers/swizzlers_025_to_032.html": 3.1643,
+    "conformance/ogles/GL/swizzlers/swizzlers_033_to_040.html": 3.1953,
+    "conformance/ogles/GL/swizzlers/swizzlers_041_to_048.html": 3.1934,
+    "conformance/ogles/GL/swizzlers/swizzlers_049_to_056.html": 3.2093,
+    "conformance/ogles/GL/swizzlers/swizzlers_057_to_064.html": 3.2287,
+    "conformance/ogles/GL/swizzlers/swizzlers_065_to_072.html": 3.1772,
+    "conformance/ogles/GL/swizzlers/swizzlers_073_to_080.html": 3.2557,
+    "conformance/ogles/GL/swizzlers/swizzlers_081_to_088.html": 3.2179,
+    "conformance/ogles/GL/swizzlers/swizzlers_089_to_096.html": 3.1973,
+    "conformance/ogles/GL/swizzlers/swizzlers_097_to_104.html": 3.1944,
+    "conformance/ogles/GL/swizzlers/swizzlers_105_to_112.html": 3.1898,
+    "conformance/ogles/GL/swizzlers/swizzlers_113_to_120.html": 3.2581,
+    "conformance/ogles/GL/tan/tan_001_to_006.html": 2.9109,
+    "conformance/ogles/GL/vec/vec_001_to_008.html": 0.9127,
+    "conformance/ogles/GL/vec/vec_009_to_016.html": 1.0669,
+    "conformance/ogles/GL/vec/vec_017_to_018.html": 0.7283,
+    "conformance/ogles/GL/vec3/vec3_001_to_008.html": 0.9121,
+    "conformance/programs/get-active-test.html": 0.4897,
+    "conformance/programs/gl-bind-attrib-location-long-names-test.html": 0.5214,
+    "conformance/programs/gl-bind-attrib-location-test.html": 0.2709,
+    "conformance/programs/gl-get-active-attribute.html": 0.3877,
+    "conformance/programs/gl-get-active-uniform.html": 0.5135,
+    "conformance/programs/gl-getshadersource.html": 0.2037,
+    "conformance/programs/gl-shader-test.html": 0.1974,
+    "conformance/programs/invalid-UTF-16.html": 0.1365,
+    "conformance/programs/program-handling.html": 0.8657,
+    "conformance/programs/program-infolog.html": 0.9789,
+    "conformance/programs/program-test.html": 0.4145,
+    "conformance/programs/use-program-crash-with-discard-in-fragment-shader.html": 0.2757,
+    "conformance/reading/fbo-remains-unchanged-after-read-pixels.html": 0.2413,
+    "conformance/reading/read-pixels-pack-alignment.html": 0.5429,
+    "conformance/reading/read-pixels-test.html": 0.908,
+    "conformance/renderbuffers/depth-renderbuffer-initialization.html": 0.6365,
+    "conformance/renderbuffers/feedback-loop.html": 0.1258,
+    "conformance/renderbuffers/framebuffer-object-attachment.html": 0.4768,
+    "conformance/renderbuffers/framebuffer-state-restoration.html": 0.7746,
+    "conformance/renderbuffers/framebuffer-test.html": 0.4586,
+    "conformance/renderbuffers/renderbuffer-initialization.html": 0.4642,
+    "conformance/renderbuffers/stencil-renderbuffer-initialization.html": 0.2946,
+    "conformance/rendering/bind-framebuffer-flush-bug.html": 0.1121,
+    "conformance/rendering/blending.html": 1.0546,
+    "conformance/rendering/canvas-alpha-bug.html": 0.4214,
+    "conformance/rendering/clear-after-copyTexImage2D.html": 0.4166,
+    "conformance/rendering/clipping-wide-points.html": 0.1645,
+    "conformance/rendering/color-mask-preserved-during-implicit-clears.html": 1.9985,
+    "conformance/rendering/culling.html": 0.107,
+    "conformance/rendering/default-texture-draw-bug.html": 0.3504,
+    "conformance/rendering/draw-arrays-out-of-bounds.html": 0.2342,
+    "conformance/rendering/draw-elements-out-of-bounds.html": 0.2948,
+    "conformance/rendering/draw-webgl-to-canvas-2d-repeatedly.html": 0.4038,
+    "conformance/rendering/draw-with-changing-start-vertex-bug.html": 0.459,
+    "conformance/rendering/framebuffer-switch.html": 0.5087,
+    "conformance/rendering/framebuffer-texture-clear.html": 0.481,
+    "conformance/rendering/framebuffer-texture-switch.html": 0.3826,
+    "conformance/rendering/gl-clear.html": 0.1101,
+    "conformance/rendering/gl-drawarrays.html": 0.1088,
+    "conformance/rendering/gl-drawelements.html": 0.3154,
+    "conformance/rendering/gl-scissor-canvas-dimensions.html": 0.3893,
+    "conformance/rendering/gl-scissor-fbo-test.html": 0.261,
+    "conformance/rendering/gl-scissor-test.html": 0.524,
+    "conformance/rendering/gl-viewport-test.html": 0.5979,
+    "conformance/rendering/line-loop-tri-fan.html": 0.1209,
+    "conformance/rendering/line-rendering-quality.html": 0.2936,
+    "conformance/rendering/many-draw-calls.html": 1.7749,
+    "conformance/rendering/more-than-65536-indices.html": 0.6858,
+    "conformance/rendering/multisample-corruption.html": 3.6258,
+    "conformance/rendering/negative-one-index.html": 0.1928,
+    "conformance/rendering/out-of-bounds-array-buffers.html": 0.2525,
+    "conformance/rendering/out-of-bounds-index-buffers.html": 0.1841,
+    "conformance/rendering/point-no-attributes.html": 0.2197,
+    "conformance/rendering/point-size.html": 0.3316,
+    "conformance/rendering/point-specific-shader-variables.html": 0.2577,
+    "conformance/rendering/point-with-gl-pointcoord-in-fragment-shader.html": 0.2656,
+    "conformance/rendering/polygon-offset.html": 0.3308,
+    "conformance/rendering/preservedrawingbuffer-leak.html": 1.2922,
+    "conformance/rendering/rendering-sampling-feedback-loop.html": 0.1385,
+    "conformance/rendering/rendering-stencil-large-viewport.html": 0.4007,
+    "conformance/rendering/scissor-rect-repeated-rendering.html": 0.4413,
+    "conformance/rendering/simple.html": 0.1883,
     "conformance/rendering/texture-switch-performance.html": 0.0,
-    "conformance/rendering/triangle.html": 0.1935,
-    "conformance/state/gl-enable-enum-test.html": 0.2284,
-    "conformance/state/gl-enum-tests.html": 0.1486,
-    "conformance/state/gl-get-calls.html": 0.1686,
-    "conformance/state/gl-geterror.html": 0.2523,
-    "conformance/state/gl-getstring.html": 0.0677,
-    "conformance/state/gl-initial-state.html": 0.0966,
-    "conformance/state/gl-object-get-calls.html": 7.8907,
-    "conformance/state/state-uneffected-after-compositing.html": 0.285,
-    "conformance/textures/canvas/tex-2d-alpha-alpha-unsigned_byte.html": 1.1113,
-    "conformance/textures/canvas/tex-2d-luminance-luminance-unsigned_byte.html": 1.2171,
-    "conformance/textures/canvas/tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html": 1.2593,
-    "conformance/textures/canvas/tex-2d-rgb-rgb-unsigned_byte.html": 4.4279,
-    "conformance/textures/canvas/tex-2d-rgb-rgb-unsigned_short_5_6_5.html": 1.1452,
-    "conformance/textures/canvas/tex-2d-rgba-rgba-unsigned_byte.html": 3.7856,
-    "conformance/textures/canvas/tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html": 1.2564,
-    "conformance/textures/canvas/tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html": 0.9897,
-    "conformance/textures/canvas_sub_rectangle/tex-2d-alpha-alpha-unsigned_byte.html": 0.1815,
-    "conformance/textures/canvas_sub_rectangle/tex-2d-luminance-luminance-unsigned_byte.html": 0.1478,
-    "conformance/textures/canvas_sub_rectangle/tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html": 0.0861,
-    "conformance/textures/canvas_sub_rectangle/tex-2d-rgb-rgb-unsigned_byte.html": 0.1064,
-    "conformance/textures/canvas_sub_rectangle/tex-2d-rgb-rgb-unsigned_short_5_6_5.html": 0.0567,
-    "conformance/textures/canvas_sub_rectangle/tex-2d-rgba-rgba-unsigned_byte.html": 0.0497,
-    "conformance/textures/canvas_sub_rectangle/tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html": 0.1513,
-    "conformance/textures/canvas_sub_rectangle/tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html": 0.0562,
-    "conformance/textures/image/tex-2d-alpha-alpha-unsigned_byte.html": 0.2781,
-    "conformance/textures/image/tex-2d-luminance-luminance-unsigned_byte.html": 0.4099,
-    "conformance/textures/image/tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html": 0.3549,
-    "conformance/textures/image/tex-2d-rgb-rgb-unsigned_byte.html": 0.5221,
-    "conformance/textures/image/tex-2d-rgb-rgb-unsigned_short_5_6_5.html": 0.4418,
-    "conformance/textures/image/tex-2d-rgba-rgba-unsigned_byte.html": 0.3451,
-    "conformance/textures/image/tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html": 0.3895,
-    "conformance/textures/image/tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html": 0.3391,
-    "conformance/textures/image_bitmap_from_blob/tex-2d-alpha-alpha-unsigned_byte.html": 0.36,
-    "conformance/textures/image_bitmap_from_blob/tex-2d-luminance-luminance-unsigned_byte.html": 0.3646,
-    "conformance/textures/image_bitmap_from_blob/tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html": 0.3891,
-    "conformance/textures/image_bitmap_from_blob/tex-2d-rgb-rgb-unsigned_byte.html": 0.3494,
-    "conformance/textures/image_bitmap_from_blob/tex-2d-rgb-rgb-unsigned_short_5_6_5.html": 0.3492,
-    "conformance/textures/image_bitmap_from_blob/tex-2d-rgba-rgba-unsigned_byte.html": 0.3691,
-    "conformance/textures/image_bitmap_from_blob/tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html": 0.3783,
-    "conformance/textures/image_bitmap_from_blob/tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html": 0.3877,
-    "conformance/textures/image_bitmap_from_canvas/tex-2d-alpha-alpha-unsigned_byte.html": 0.7988,
-    "conformance/textures/image_bitmap_from_canvas/tex-2d-luminance-luminance-unsigned_byte.html": 1.1956,
-    "conformance/textures/image_bitmap_from_canvas/tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html": 0.5275,
-    "conformance/textures/image_bitmap_from_canvas/tex-2d-rgb-rgb-unsigned_byte.html": 0.8541,
-    "conformance/textures/image_bitmap_from_canvas/tex-2d-rgb-rgb-unsigned_short_5_6_5.html": 0.4355,
-    "conformance/textures/image_bitmap_from_canvas/tex-2d-rgba-rgba-unsigned_byte.html": 0.827,
-    "conformance/textures/image_bitmap_from_canvas/tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html": 0.4881,
-    "conformance/textures/image_bitmap_from_canvas/tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html": 0.9356,
-    "conformance/textures/image_bitmap_from_image/tex-2d-alpha-alpha-unsigned_byte.html": 0.3956,
-    "conformance/textures/image_bitmap_from_image/tex-2d-luminance-luminance-unsigned_byte.html": 0.4889,
-    "conformance/textures/image_bitmap_from_image/tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html": 0.3949,
-    "conformance/textures/image_bitmap_from_image/tex-2d-rgb-rgb-unsigned_byte.html": 0.5364,
-    "conformance/textures/image_bitmap_from_image/tex-2d-rgb-rgb-unsigned_short_5_6_5.html": 0.4034,
-    "conformance/textures/image_bitmap_from_image/tex-2d-rgba-rgba-unsigned_byte.html": 0.5378,
-    "conformance/textures/image_bitmap_from_image/tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html": 0.4319,
-    "conformance/textures/image_bitmap_from_image/tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html": 0.5078,
-    "conformance/textures/image_bitmap_from_image_bitmap/tex-2d-alpha-alpha-unsigned_byte.html": 0.3906,
-    "conformance/textures/image_bitmap_from_image_bitmap/tex-2d-luminance-luminance-unsigned_byte.html": 0.4588,
-    "conformance/textures/image_bitmap_from_image_bitmap/tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html": 0.2735,
-    "conformance/textures/image_bitmap_from_image_bitmap/tex-2d-rgb-rgb-unsigned_byte.html": 0.4671,
-    "conformance/textures/image_bitmap_from_image_bitmap/tex-2d-rgb-rgb-unsigned_short_5_6_5.html": 0.2367,
-    "conformance/textures/image_bitmap_from_image_bitmap/tex-2d-rgba-rgba-unsigned_byte.html": 0.4019,
-    "conformance/textures/image_bitmap_from_image_bitmap/tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html": 0.2497,
-    "conformance/textures/image_bitmap_from_image_bitmap/tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html": 0.5581,
-    "conformance/textures/image_bitmap_from_image_data/tex-2d-alpha-alpha-unsigned_byte.html": 0.334,
-    "conformance/textures/image_bitmap_from_image_data/tex-2d-luminance-luminance-unsigned_byte.html": 0.5366,
-    "conformance/textures/image_bitmap_from_image_data/tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html": 0.2703,
-    "conformance/textures/image_bitmap_from_image_data/tex-2d-rgb-rgb-unsigned_byte.html": 0.4696,
-    "conformance/textures/image_bitmap_from_image_data/tex-2d-rgb-rgb-unsigned_short_5_6_5.html": 0.3477,
-    "conformance/textures/image_bitmap_from_image_data/tex-2d-rgba-rgba-unsigned_byte.html": 0.5366,
-    "conformance/textures/image_bitmap_from_image_data/tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html": 0.2633,
-    "conformance/textures/image_bitmap_from_image_data/tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html": 0.5308,
-    "conformance/textures/image_bitmap_from_video/tex-2d-alpha-alpha-unsigned_byte.html": 2.8326,
-    "conformance/textures/image_bitmap_from_video/tex-2d-luminance-luminance-unsigned_byte.html": 2.6395,
-    "conformance/textures/image_bitmap_from_video/tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html": 0.5851,
-    "conformance/textures/image_bitmap_from_video/tex-2d-rgb-rgb-unsigned_byte.html": 0.6822,
-    "conformance/textures/image_bitmap_from_video/tex-2d-rgb-rgb-unsigned_short_5_6_5.html": 0.5024,
-    "conformance/textures/image_bitmap_from_video/tex-2d-rgba-rgba-unsigned_byte.html": 0.4435,
-    "conformance/textures/image_bitmap_from_video/tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html": 0.396,
-    "conformance/textures/image_bitmap_from_video/tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html": 0.4831,
-    "conformance/textures/image_data/tex-2d-alpha-alpha-unsigned_byte.html": 0.3351,
-    "conformance/textures/image_data/tex-2d-luminance-luminance-unsigned_byte.html": 0.6922,
-    "conformance/textures/image_data/tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html": 0.2991,
-    "conformance/textures/image_data/tex-2d-rgb-rgb-unsigned_byte.html": 0.6695,
-    "conformance/textures/image_data/tex-2d-rgb-rgb-unsigned_short_5_6_5.html": 0.2475,
-    "conformance/textures/image_data/tex-2d-rgba-rgba-unsigned_byte.html": 0.6802,
-    "conformance/textures/image_data/tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html": 0.337,
-    "conformance/textures/image_data/tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html": 0.6721,
-    "conformance/textures/misc/canvas-teximage-after-multiple-drawimages.html": 0.3311,
-    "conformance/textures/misc/compressed-tex-image.html": 0.0986,
-    "conformance/textures/misc/copy-tex-image-2d-formats.html": 0.449,
-    "conformance/textures/misc/copy-tex-image-and-sub-image-2d.html": 1.1998,
-    "conformance/textures/misc/copy-tex-image-crash.html": 0.0992,
-    "conformance/textures/misc/copytexsubimage2d-large-partial-copy-corruption.html": 0.5349,
-    "conformance/textures/misc/copytexsubimage2d-subrects.html": 0.0785,
-    "conformance/textures/misc/cube-incomplete-fbo.html": 0.1519,
-    "conformance/textures/misc/cube-map-uploads-out-of-order.html": 1.2051,
-    "conformance/textures/misc/default-texture.html": 0.1066,
-    "conformance/textures/misc/gl-get-tex-parameter.html": 0.1829,
-    "conformance/textures/misc/gl-pixelstorei.html": 0.224,
-    "conformance/textures/misc/gl-teximage.html": 0.8727,
-    "conformance/textures/misc/mipmap-fbo.html": 0.4501,
-    "conformance/textures/misc/origin-clean-conformance-offscreencanvas.html": 0.1718,
-    "conformance/textures/misc/origin-clean-conformance.html": 0.1376,
-    "conformance/textures/misc/tex-image-and-sub-image-2d-with-array-buffer-view.html": 2.1269,
-    "conformance/textures/misc/tex-image-and-uniform-binding-bugs.html": 0.1427,
-    "conformance/textures/misc/tex-image-canvas-corruption.html": 0.53,
-    "conformance/textures/misc/tex-image-webgl.html": 0.4948,
-    "conformance/textures/misc/tex-image-with-format-and-type.html": 0.8124,
-    "conformance/textures/misc/tex-image-with-invalid-data.html": 0.0664,
-    "conformance/textures/misc/tex-input-validation.html": 0.2076,
-    "conformance/textures/misc/tex-sub-image-2d-bad-args.html": 0.1988,
-    "conformance/textures/misc/tex-sub-image-2d.html": 0.1002,
-    "conformance/textures/misc/tex-video-using-tex-unit-non-zero.html": 3.1106,
-    "conformance/textures/misc/texparameter-test.html": 0.2886,
-    "conformance/textures/misc/texture-active-bind-2.html": 0.3496,
-    "conformance/textures/misc/texture-active-bind.html": 0.1103,
-    "conformance/textures/misc/texture-attachment-formats.html": 0.3253,
-    "conformance/textures/misc/texture-clear.html": 0.3051,
-    "conformance/textures/misc/texture-complete.html": 0.1078,
-    "conformance/textures/misc/texture-copying-feedback-loops.html": 0.0698,
-    "conformance/textures/misc/texture-corner-case-videos.html": 0.2627,
-    "conformance/textures/misc/texture-cube-as-fbo-attachment.html": 0.0734,
-    "conformance/textures/misc/texture-draw-with-2d-and-cube.html": 0.0987,
-    "conformance/textures/misc/texture-fakeblack.html": 0.1008,
-    "conformance/textures/misc/texture-formats-test.html": 0.3308,
-    "conformance/textures/misc/texture-hd-dpi.html": 0.2252,
-    "conformance/textures/misc/texture-mips.html": 0.2492,
-    "conformance/textures/misc/texture-npot-video.html": 0.275,
-    "conformance/textures/misc/texture-npot.html": 0.4107,
-    "conformance/textures/misc/texture-size-cube-maps.html": 0.779,
-    "conformance/textures/misc/texture-size-limit.html": 0.7046,
-    "conformance/textures/misc/texture-size.html": 1.0332,
-    "conformance/textures/misc/texture-sub-image-cube-maps.html": 0.2375,
-    "conformance/textures/misc/texture-transparent-pixels-initialized.html": 0.3283,
-    "conformance/textures/misc/texture-upload-cube-maps.html": 0.3977,
-    "conformance/textures/misc/texture-upload-size.html": 2.6389,
-    "conformance/textures/misc/texture-video-transparent.html": 2.3543,
-    "conformance/textures/misc/texture-with-flip-y-and-premultiply-alpha.html": 0.107,
-    "conformance/textures/svg_image/tex-2d-alpha-alpha-unsigned_byte.html": 0.2952,
-    "conformance/textures/svg_image/tex-2d-luminance-luminance-unsigned_byte.html": 0.2883,
-    "conformance/textures/svg_image/tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html": 0.3347,
-    "conformance/textures/svg_image/tex-2d-rgb-rgb-unsigned_byte.html": 0.3635,
-    "conformance/textures/svg_image/tex-2d-rgb-rgb-unsigned_short_5_6_5.html": 0.2834,
-    "conformance/textures/svg_image/tex-2d-rgba-rgba-unsigned_byte.html": 0.2209,
-    "conformance/textures/svg_image/tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html": 0.318,
-    "conformance/textures/svg_image/tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html": 0.3096,
-    "conformance/textures/video/tex-2d-alpha-alpha-unsigned_byte.html": 2.7879,
-    "conformance/textures/video/tex-2d-luminance-luminance-unsigned_byte.html": 0.6145,
-    "conformance/textures/video/tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html": 0.6841,
-    "conformance/textures/video/tex-2d-rgb-rgb-unsigned_byte.html": 0.7223,
-    "conformance/textures/video/tex-2d-rgb-rgb-unsigned_short_5_6_5.html": 0.6765,
-    "conformance/textures/video/tex-2d-rgba-rgba-unsigned_byte.html": 0.6789,
-    "conformance/textures/video/tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html": 0.5265,
-    "conformance/textures/video/tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html": 0.6938,
-    "conformance/textures/webgl_canvas/tex-2d-alpha-alpha-unsigned_byte.html": 0.7151,
-    "conformance/textures/webgl_canvas/tex-2d-luminance-luminance-unsigned_byte.html": 0.9788,
-    "conformance/textures/webgl_canvas/tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html": 0.7613,
-    "conformance/textures/webgl_canvas/tex-2d-rgb-rgb-unsigned_byte.html": 2.5886,
-    "conformance/textures/webgl_canvas/tex-2d-rgb-rgb-unsigned_short_5_6_5.html": 0.8539,
-    "conformance/textures/webgl_canvas/tex-2d-rgba-rgba-unsigned_byte.html": 2.4746,
-    "conformance/textures/webgl_canvas/tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html": 0.7747,
-    "conformance/textures/webgl_canvas/tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html": 0.864,
-    "conformance/typedarrays/array-buffer-crash.html": 0.0785,
-    "conformance/typedarrays/array-buffer-view-crash.html": 0.102,
-    "conformance/typedarrays/array-large-array-tests.html": 0.1452,
-    "conformance/typedarrays/array-unit-tests.html": 0.1375,
-    "conformance/typedarrays/data-view-crash.html": 0.1034,
-    "conformance/typedarrays/data-view-test.html": 0.1267,
-    "conformance/typedarrays/typed-arrays-in-workers.html": 0.247,
-    "conformance/uniforms/gl-uniform-arrays.html": 0.1501,
-    "conformance/uniforms/gl-uniform-bool.html": 0.1736,
-    "conformance/uniforms/gl-uniformmatrix4fv.html": 0.2991,
-    "conformance/uniforms/gl-unknown-uniform.html": 0.2279,
-    "conformance/uniforms/no-over-optimization-on-uniform-array-00.html": 1.3581,
-    "conformance/uniforms/no-over-optimization-on-uniform-array-01.html": 1.9184,
-    "conformance/uniforms/no-over-optimization-on-uniform-array-02.html": 1.4647,
-    "conformance/uniforms/no-over-optimization-on-uniform-array-03.html": 2.1149,
-    "conformance/uniforms/no-over-optimization-on-uniform-array-04.html": 1.3458,
-    "conformance/uniforms/no-over-optimization-on-uniform-array-05.html": 1.978,
-    "conformance/uniforms/no-over-optimization-on-uniform-array-06.html": 1.2686,
-    "conformance/uniforms/no-over-optimization-on-uniform-array-07.html": 1.8544,
-    "conformance/uniforms/no-over-optimization-on-uniform-array-08.html": 1.2132,
-    "conformance/uniforms/no-over-optimization-on-uniform-array-09.html": 2.1067,
-    "conformance/uniforms/no-over-optimization-on-uniform-array-10.html": 1.2508,
-    "conformance/uniforms/no-over-optimization-on-uniform-array-11.html": 1.8098,
-    "conformance/uniforms/no-over-optimization-on-uniform-array-12.html": 1.3988,
-    "conformance/uniforms/no-over-optimization-on-uniform-array-13.html": 2.1324,
-    "conformance/uniforms/no-over-optimization-on-uniform-array-14.html": 1.3325,
-    "conformance/uniforms/no-over-optimization-on-uniform-array-15.html": 2.0128,
-    "conformance/uniforms/no-over-optimization-on-uniform-array-16.html": 1.2684,
-    "conformance/uniforms/no-over-optimization-on-uniform-array-17.html": 2.0823,
-    "conformance/uniforms/null-uniform-location.html": 0.2906,
-    "conformance/uniforms/out-of-bounds-uniform-array-access.html": 2.4684,
-    "conformance/uniforms/uniform-default-values.html": 1.8024,
-    "conformance/uniforms/uniform-location.html": 0.5494,
-    "conformance/uniforms/uniform-samplers-test.html": 28.0952,
-    "conformance/uniforms/uniform-values-per-program.html": 1.6433,
-    "deqp/data/gles2/shaders/conditionals.html": 1.6763,
-    "deqp/data/gles2/shaders/constant_expressions.html": 1.8906,
-    "deqp/data/gles2/shaders/constants.html": 3.3884,
-    "deqp/data/gles2/shaders/conversions.html": 32.8325,
-    "deqp/data/gles2/shaders/declarations.html": 0.605,
-    "deqp/data/gles2/shaders/fragdata.html": 0.6885,
-    "deqp/data/gles2/shaders/functions.html": 11.4375,
-    "deqp/data/gles2/shaders/invalid_texture_functions.html": 0.3225,
-    "deqp/data/gles2/shaders/keywords.html": 3.9522,
-    "deqp/data/gles2/shaders/linkage.html": 2.7721,
-    "deqp/data/gles2/shaders/preprocessor.html": 15.2381,
-    "deqp/data/gles2/shaders/qualification_order.html": 1.4454,
-    "deqp/data/gles2/shaders/reserved_operators.html": 1.0364,
-    "deqp/data/gles2/shaders/scoping.html": 2.9311,
-    "deqp/data/gles2/shaders/swizzles.html": 35.734
+    "conformance/rendering/triangle.html": 0.2996,
+    "conformance/state/fb-attach-implicit-target-assignment.html": 0.1146,
+    "conformance/state/gl-enable-enum-test.html": 0.266,
+    "conformance/state/gl-enum-tests.html": 0.2238,
+    "conformance/state/gl-get-calls.html": 0.3832,
+    "conformance/state/gl-geterror.html": 0.3304,
+    "conformance/state/gl-getstring.html": 0.0951,
+    "conformance/state/gl-initial-state.html": 0.131,
+    "conformance/state/gl-object-get-calls.html": 7.1149,
+    "conformance/state/state-uneffected-after-compositing.html": 0.4893,
+    "conformance/textures/canvas/tex-2d-alpha-alpha-unsigned_byte.html": 0.8493,
+    "conformance/textures/canvas/tex-2d-luminance-luminance-unsigned_byte.html": 1.2914,
+    "conformance/textures/canvas/tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html": 0.9837,
+    "conformance/textures/canvas/tex-2d-rgb-rgb-unsigned_byte.html": 2.6841,
+    "conformance/textures/canvas/tex-2d-rgb-rgb-unsigned_short_5_6_5.html": 0.9426,
+    "conformance/textures/canvas/tex-2d-rgba-rgba-unsigned_byte.html": 3.4007,
+    "conformance/textures/canvas/tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html": 1.0556,
+    "conformance/textures/canvas/tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html": 0.827,
+    "conformance/textures/canvas_sub_rectangle/tex-2d-alpha-alpha-unsigned_byte.html": 0.1809,
+    "conformance/textures/canvas_sub_rectangle/tex-2d-luminance-luminance-unsigned_byte.html": 0.1995,
+    "conformance/textures/canvas_sub_rectangle/tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html": 0.0875,
+    "conformance/textures/canvas_sub_rectangle/tex-2d-rgb-rgb-unsigned_byte.html": 0.157,
+    "conformance/textures/canvas_sub_rectangle/tex-2d-rgb-rgb-unsigned_short_5_6_5.html": 0.1512,
+    "conformance/textures/canvas_sub_rectangle/tex-2d-rgba-rgba-unsigned_byte.html": 0.1895,
+    "conformance/textures/canvas_sub_rectangle/tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html": 0.1876,
+    "conformance/textures/canvas_sub_rectangle/tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html": 0.1984,
+    "conformance/textures/image/tex-2d-alpha-alpha-unsigned_byte.html": 0.3552,
+    "conformance/textures/image/tex-2d-luminance-luminance-unsigned_byte.html": 0.5588,
+    "conformance/textures/image/tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html": 0.3324,
+    "conformance/textures/image/tex-2d-rgb-rgb-unsigned_byte.html": 0.6323,
+    "conformance/textures/image/tex-2d-rgb-rgb-unsigned_short_5_6_5.html": 0.4369,
+    "conformance/textures/image/tex-2d-rgba-rgba-unsigned_byte.html": 0.4787,
+    "conformance/textures/image/tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html": 0.3904,
+    "conformance/textures/image/tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html": 0.4344,
+    "conformance/textures/image_bitmap_from_blob/tex-2d-alpha-alpha-unsigned_byte.html": 0.5385,
+    "conformance/textures/image_bitmap_from_blob/tex-2d-luminance-luminance-unsigned_byte.html": 0.54,
+    "conformance/textures/image_bitmap_from_blob/tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html": 0.5671,
+    "conformance/textures/image_bitmap_from_blob/tex-2d-rgb-rgb-unsigned_byte.html": 0.5036,
+    "conformance/textures/image_bitmap_from_blob/tex-2d-rgb-rgb-unsigned_short_5_6_5.html": 0.5253,
+    "conformance/textures/image_bitmap_from_blob/tex-2d-rgba-rgba-unsigned_byte.html": 0.5308,
+    "conformance/textures/image_bitmap_from_blob/tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html": 0.5746,
+    "conformance/textures/image_bitmap_from_blob/tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html": 0.4893,
+    "conformance/textures/image_bitmap_from_canvas/tex-2d-alpha-alpha-unsigned_byte.html": 0.9737,
+    "conformance/textures/image_bitmap_from_canvas/tex-2d-luminance-luminance-unsigned_byte.html": 0.9797,
+    "conformance/textures/image_bitmap_from_canvas/tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html": 0.7274,
+    "conformance/textures/image_bitmap_from_canvas/tex-2d-rgb-rgb-unsigned_byte.html": 0.6119,
+    "conformance/textures/image_bitmap_from_canvas/tex-2d-rgb-rgb-unsigned_short_5_6_5.html": 0.5978,
+    "conformance/textures/image_bitmap_from_canvas/tex-2d-rgba-rgba-unsigned_byte.html": 0.6679,
+    "conformance/textures/image_bitmap_from_canvas/tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html": 0.5633,
+    "conformance/textures/image_bitmap_from_canvas/tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html": 0.7369,
+    "conformance/textures/image_bitmap_from_image/tex-2d-alpha-alpha-unsigned_byte.html": 0.475,
+    "conformance/textures/image_bitmap_from_image/tex-2d-luminance-luminance-unsigned_byte.html": 0.4807,
+    "conformance/textures/image_bitmap_from_image/tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html": 0.4719,
+    "conformance/textures/image_bitmap_from_image/tex-2d-rgb-rgb-unsigned_byte.html": 0.3944,
+    "conformance/textures/image_bitmap_from_image/tex-2d-rgb-rgb-unsigned_short_5_6_5.html": 0.451,
+    "conformance/textures/image_bitmap_from_image/tex-2d-rgba-rgba-unsigned_byte.html": 0.457,
+    "conformance/textures/image_bitmap_from_image/tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html": 0.5221,
+    "conformance/textures/image_bitmap_from_image/tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html": 0.4809,
+    "conformance/textures/image_bitmap_from_image_bitmap/tex-2d-alpha-alpha-unsigned_byte.html": 0.512,
+    "conformance/textures/image_bitmap_from_image_bitmap/tex-2d-luminance-luminance-unsigned_byte.html": 0.4707,
+    "conformance/textures/image_bitmap_from_image_bitmap/tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html": 0.4172,
+    "conformance/textures/image_bitmap_from_image_bitmap/tex-2d-rgb-rgb-unsigned_byte.html": 0.4466,
+    "conformance/textures/image_bitmap_from_image_bitmap/tex-2d-rgb-rgb-unsigned_short_5_6_5.html": 0.445,
+    "conformance/textures/image_bitmap_from_image_bitmap/tex-2d-rgba-rgba-unsigned_byte.html": 0.4293,
+    "conformance/textures/image_bitmap_from_image_bitmap/tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html": 0.5003,
+    "conformance/textures/image_bitmap_from_image_bitmap/tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html": 0.4892,
+    "conformance/textures/image_bitmap_from_image_data/tex-2d-alpha-alpha-unsigned_byte.html": 0.5605,
+    "conformance/textures/image_bitmap_from_image_data/tex-2d-luminance-luminance-unsigned_byte.html": 0.6354,
+    "conformance/textures/image_bitmap_from_image_data/tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html": 0.524,
+    "conformance/textures/image_bitmap_from_image_data/tex-2d-rgb-rgb-unsigned_byte.html": 0.5249,
+    "conformance/textures/image_bitmap_from_image_data/tex-2d-rgb-rgb-unsigned_short_5_6_5.html": 0.5095,
+    "conformance/textures/image_bitmap_from_image_data/tex-2d-rgba-rgba-unsigned_byte.html": 0.6235,
+    "conformance/textures/image_bitmap_from_image_data/tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html": 0.6355,
+    "conformance/textures/image_bitmap_from_image_data/tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html": 0.4894,
+    "conformance/textures/image_bitmap_from_video/tex-2d-alpha-alpha-unsigned_byte.html": 0.5687,
+    "conformance/textures/image_bitmap_from_video/tex-2d-luminance-luminance-unsigned_byte.html": 0.524,
+    "conformance/textures/image_bitmap_from_video/tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html": 0.6411,
+    "conformance/textures/image_bitmap_from_video/tex-2d-rgb-rgb-unsigned_byte.html": 0.4747,
+    "conformance/textures/image_bitmap_from_video/tex-2d-rgb-rgb-unsigned_short_5_6_5.html": 0.4616,
+    "conformance/textures/image_bitmap_from_video/tex-2d-rgba-rgba-unsigned_byte.html": 0.6793,
+    "conformance/textures/image_bitmap_from_video/tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html": 0.4566,
+    "conformance/textures/image_bitmap_from_video/tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html": 0.5401,
+    "conformance/textures/image_data/tex-2d-alpha-alpha-unsigned_byte.html": 0.6215,
+    "conformance/textures/image_data/tex-2d-luminance-luminance-unsigned_byte.html": 0.5455,
+    "conformance/textures/image_data/tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html": 0.5971,
+    "conformance/textures/image_data/tex-2d-rgb-rgb-unsigned_byte.html": 0.5267,
+    "conformance/textures/image_data/tex-2d-rgb-rgb-unsigned_short_5_6_5.html": 0.4956,
+    "conformance/textures/image_data/tex-2d-rgba-rgba-unsigned_byte.html": 0.4639,
+    "conformance/textures/image_data/tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html": 0.6631,
+    "conformance/textures/image_data/tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html": 0.5259,
+    "conformance/textures/misc/canvas-teximage-after-multiple-drawimages.html": 0.3446,
+    "conformance/textures/misc/compressed-tex-image.html": 0.2083,
+    "conformance/textures/misc/copy-tex-image-2d-formats.html": 0.4334,
+    "conformance/textures/misc/copy-tex-image-and-sub-image-2d.html": 0.9236,
+    "conformance/textures/misc/copy-tex-image-crash.html": 0.1926,
+    "conformance/textures/misc/copytexsubimage2d-large-partial-copy-corruption.html": 0.4571,
+    "conformance/textures/misc/copytexsubimage2d-subrects.html": 0.1339,
+    "conformance/textures/misc/cube-incomplete-fbo.html": 0.1922,
+    "conformance/textures/misc/cube-map-uploads-out-of-order.html": 1.1653,
+    "conformance/textures/misc/default-texture.html": 0.1888,
+    "conformance/textures/misc/exif-orientation.html": 0.8605,
+    "conformance/textures/misc/gl-get-tex-parameter.html": 0.1578,
+    "conformance/textures/misc/gl-pixelstorei.html": 0.2241,
+    "conformance/textures/misc/gl-teximage.html": 1.1716,
+    "conformance/textures/misc/mipmap-fbo.html": 0.4778,
+    "conformance/textures/misc/origin-clean-conformance-offscreencanvas.html": 0.3053,
+    "conformance/textures/misc/origin-clean-conformance.html": 0.1891,
+    "conformance/textures/misc/tex-image-and-sub-image-2d-with-array-buffer-view.html": 4.0711,
+    "conformance/textures/misc/tex-image-and-uniform-binding-bugs.html": 0.1228,
+    "conformance/textures/misc/tex-image-canvas-corruption.html": 0.593,
+    "conformance/textures/misc/tex-image-webgl.html": 0.3849,
+    "conformance/textures/misc/tex-image-with-format-and-type.html": 1.026,
+    "conformance/textures/misc/tex-image-with-invalid-data.html": 0.1227,
+    "conformance/textures/misc/tex-input-validation.html": 0.2681,
+    "conformance/textures/misc/tex-sub-image-2d-bad-args.html": 0.1811,
+    "conformance/textures/misc/tex-sub-image-2d.html": 0.191,
+    "conformance/textures/misc/tex-video-using-tex-unit-non-zero.html": 0.8904,
+    "conformance/textures/misc/texparameter-test.html": 0.2504,
+    "conformance/textures/misc/texture-active-bind-2.html": 0.1543,
+    "conformance/textures/misc/texture-active-bind.html": 0.1893,
+    "conformance/textures/misc/texture-attachment-formats.html": 0.3092,
+    "conformance/textures/misc/texture-clear.html": 0.2923,
+    "conformance/textures/misc/texture-complete.html": 0.1221,
+    "conformance/textures/misc/texture-copying-and-deletion.html": 1.1053,
+    "conformance/textures/misc/texture-copying-feedback-loops.html": 0.1152,
+    "conformance/textures/misc/texture-corner-case-videos.html": 0.3581,
+    "conformance/textures/misc/texture-cube-as-fbo-attachment.html": 0.175,
+    "conformance/textures/misc/texture-draw-with-2d-and-cube.html": 0.1214,
+    "conformance/textures/misc/texture-fakeblack.html": 0.354,
+    "conformance/textures/misc/texture-formats-test.html": 0.2335,
+    "conformance/textures/misc/texture-hd-dpi.html": 0.3072,
+    "conformance/textures/misc/texture-mips.html": 0.265,
+    "conformance/textures/misc/texture-npot-video.html": 0.3558,
+    "conformance/textures/misc/texture-npot.html": 0.5314,
+    "conformance/textures/misc/texture-size-cube-maps.html": 1.1634,
+    "conformance/textures/misc/texture-size-limit.html": 0.5874,
+    "conformance/textures/misc/texture-size.html": 1.0896,
+    "conformance/textures/misc/texture-sub-image-cube-maps.html": 0.3962,
+    "conformance/textures/misc/texture-transparent-pixels-initialized.html": 0.2917,
+    "conformance/textures/misc/texture-upload-cube-maps.html": 0.3579,
+    "conformance/textures/misc/texture-upload-size.html": 0.4869,
+    "conformance/textures/misc/texture-video-transparent.html": 2.4969,
+    "conformance/textures/misc/texture-with-flip-y-and-premultiply-alpha.html": 0.0899,
+    "conformance/textures/misc/upload-from-srcset-with-empty-data.html": 0.1374,
+    "conformance/textures/svg_image/tex-2d-alpha-alpha-unsigned_byte.html": 0.3167,
+    "conformance/textures/svg_image/tex-2d-luminance-luminance-unsigned_byte.html": 0.3677,
+    "conformance/textures/svg_image/tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html": 0.3603,
+    "conformance/textures/svg_image/tex-2d-rgb-rgb-unsigned_byte.html": 0.3335,
+    "conformance/textures/svg_image/tex-2d-rgb-rgb-unsigned_short_5_6_5.html": 0.327,
+    "conformance/textures/svg_image/tex-2d-rgba-rgba-unsigned_byte.html": 0.3637,
+    "conformance/textures/svg_image/tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html": 0.376,
+    "conformance/textures/svg_image/tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html": 0.2022,
+    "conformance/textures/video/tex-2d-alpha-alpha-unsigned_byte.html": 0.4417,
+    "conformance/textures/video/tex-2d-luminance-luminance-unsigned_byte.html": 0.5069,
+    "conformance/textures/video/tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html": 0.5131,
+    "conformance/textures/video/tex-2d-rgb-rgb-unsigned_byte.html": 0.4837,
+    "conformance/textures/video/tex-2d-rgb-rgb-unsigned_short_5_6_5.html": 0.4512,
+    "conformance/textures/video/tex-2d-rgba-rgba-unsigned_byte.html": 0.4132,
+    "conformance/textures/video/tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html": 0.4095,
+    "conformance/textures/video/tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html": 0.4376,
+    "conformance/textures/webgl_canvas/tex-2d-alpha-alpha-unsigned_byte.html": 1.2666,
+    "conformance/textures/webgl_canvas/tex-2d-luminance-luminance-unsigned_byte.html": 1.1763,
+    "conformance/textures/webgl_canvas/tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html": 1.3798,
+    "conformance/textures/webgl_canvas/tex-2d-rgb-rgb-unsigned_byte.html": 4.2373,
+    "conformance/textures/webgl_canvas/tex-2d-rgb-rgb-unsigned_short_5_6_5.html": 1.3754,
+    "conformance/textures/webgl_canvas/tex-2d-rgba-rgba-unsigned_byte.html": 3.8548,
+    "conformance/textures/webgl_canvas/tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html": 1.4663,
+    "conformance/textures/webgl_canvas/tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html": 1.3928,
+    "conformance/typedarrays/array-buffer-crash.html": 0.1286,
+    "conformance/typedarrays/array-buffer-view-crash.html": 0.1012,
+    "conformance/typedarrays/array-large-array-tests.html": 0.2515,
+    "conformance/typedarrays/array-unit-tests.html": 0.162,
+    "conformance/typedarrays/data-view-crash.html": 0.0458,
+    "conformance/typedarrays/data-view-test.html": 0.1401,
+    "conformance/typedarrays/typed-arrays-in-workers.html": 0.1708,
+    "conformance/uniforms/gl-uniform-arrays.html": 0.1844,
+    "conformance/uniforms/gl-uniform-bool.html": 0.2675,
+    "conformance/uniforms/gl-uniformmatrix4fv.html": 0.2983,
+    "conformance/uniforms/gl-unknown-uniform.html": 0.2563,
+    "conformance/uniforms/no-over-optimization-on-uniform-array-00.html": 1.4036,
+    "conformance/uniforms/no-over-optimization-on-uniform-array-01.html": 1.3243,
+    "conformance/uniforms/no-over-optimization-on-uniform-array-02.html": 1.5677,
+    "conformance/uniforms/no-over-optimization-on-uniform-array-03.html": 1.641,
+    "conformance/uniforms/no-over-optimization-on-uniform-array-04.html": 1.5674,
+    "conformance/uniforms/no-over-optimization-on-uniform-array-05.html": 1.5321,
+    "conformance/uniforms/no-over-optimization-on-uniform-array-06.html": 1.6355,
+    "conformance/uniforms/no-over-optimization-on-uniform-array-07.html": 1.4944,
+    "conformance/uniforms/no-over-optimization-on-uniform-array-08.html": 1.4715,
+    "conformance/uniforms/no-over-optimization-on-uniform-array-09.html": 1.5012,
+    "conformance/uniforms/no-over-optimization-on-uniform-array-10.html": 1.4667,
+    "conformance/uniforms/no-over-optimization-on-uniform-array-11.html": 1.6077,
+    "conformance/uniforms/no-over-optimization-on-uniform-array-12.html": 1.4357,
+    "conformance/uniforms/no-over-optimization-on-uniform-array-13.html": 1.9725,
+    "conformance/uniforms/no-over-optimization-on-uniform-array-14.html": 1.645,
+    "conformance/uniforms/no-over-optimization-on-uniform-array-15.html": 1.8384,
+    "conformance/uniforms/no-over-optimization-on-uniform-array-16.html": 1.6414,
+    "conformance/uniforms/no-over-optimization-on-uniform-array-17.html": 1.9326,
+    "conformance/uniforms/null-uniform-location.html": 0.3311,
+    "conformance/uniforms/out-of-bounds-uniform-array-access.html": 3.946,
+    "conformance/uniforms/uniform-default-values.html": 1.6615,
+    "conformance/uniforms/uniform-location.html": 0.4927,
+    "conformance/uniforms/uniform-samplers-test.html": 23.5508,
+    "conformance/uniforms/uniform-values-per-program.html": 1.5434,
+    "deqp/data/gles2/shaders/conditionals.html": 1.5326,
+    "deqp/data/gles2/shaders/constant_expressions.html": 1.6228,
+    "deqp/data/gles2/shaders/constants.html": 2.9544,
+    "deqp/data/gles2/shaders/conversions.html": 34.2201,
+    "deqp/data/gles2/shaders/declarations.html": 0.6276,
+    "deqp/data/gles2/shaders/fragdata.html": 0.5656,
+    "deqp/data/gles2/shaders/functions.html": 9.5772,
+    "deqp/data/gles2/shaders/invalid_texture_functions.html": 0.3042,
+    "deqp/data/gles2/shaders/keywords.html": 3.5592,
+    "deqp/data/gles2/shaders/linkage.html": 2.6213,
+    "deqp/data/gles2/shaders/preprocessor.html": 14.1594,
+    "deqp/data/gles2/shaders/qualification_order.html": 1.5231,
+    "deqp/data/gles2/shaders/reserved_operators.html": 0.742,
+    "deqp/data/gles2/shaders/scoping.html": 2.6424,
+    "deqp/data/gles2/shaders/swizzles.html": 38.9196
   }
 }
\ No newline at end of file
diff --git a/content/test/gpu/gather_swarming_json_results.py b/content/test/gpu/gather_swarming_json_results.py
index 62eb1c0..b9b6028 100755
--- a/content/test/gpu/gather_swarming_json_results.py
+++ b/content/test/gpu/gather_swarming_json_results.py
@@ -26,6 +26,8 @@
   # The Python docs are wrong. It's fine for this payload to be just
   # a JSON string.
   headers = {'content-type': 'application/json', 'accept': 'application/json'}
+  logging.debug('Making request:')
+  logging.debug('%s', request)
   url = urllib2.Request(
       'https://cr-buildbucket.appspot.com/prpc/buildbucket.v2.Builds/' + method,
       request, headers)
@@ -156,7 +158,22 @@
 def main():
   rest_args = sys.argv[1:]
   parser = argparse.ArgumentParser(
-      description='Gather JSON results from a run of a Swarming test.',
+      description="""
+Gather JSON results from a run of a Swarming test.
+
+Example invocation to fetch the WebGL 1.0 test runtimes from Linux FYI
+Release (NVIDIA):
+
+gather_swarming_json_results.py \
+  --step webgl_conformance_gl_passthrough_tests \
+  --output=../data/gpu/webgl_conformance_tests_output.json
+
+Example invocation to fetch the WebGL 2.0 runtimes:
+gather_swarming_json_results.py \
+  --step webgl2_conformance_gl_passthrough_tests \
+  --output=../data/gpu/webgl2_conformance_tests_output.json
+
+""",
       formatter_class=argparse.ArgumentDefaultsHelpFormatter)
   parser.add_argument(
       '-v',
@@ -173,10 +190,9 @@
       type=int,
       help='Which build to fetch. If not specified, use '
       'the latest successful build.')
-  parser.add_argument(
-      '--step',
-      default='webgl2_conformance_tests',
-      help='Which step to fetch (treated as a prefix)')
+  parser.add_argument('--step',
+                      default='webgl2_conformance_gl_passthrough_tests',
+                      help='Which step to fetch (treated as a prefix)')
   parser.add_argument(
       '--output',
       metavar='FILE',
diff --git a/content/web_test/renderer/test_runner.cc b/content/web_test/renderer/test_runner.cc
index fbd10909..669af3e 100644
--- a/content/web_test/renderer/test_runner.cc
+++ b/content/web_test/renderer/test_runner.cc
@@ -2646,16 +2646,9 @@
   // loads can be started by the renderer.
   waiting_for_reset_navigation_to_about_blank_ = std::move(done_callback);
 
-  // TODO(danakj): Move this navigation to the browser.
-  blink::WebURLRequest request{GURL(url::kAboutBlankURL)};
-  request.SetMode(network::mojom::RequestMode::kNavigate);
-  request.SetRedirectMode(network::mojom::RedirectMode::kManual);
-  request.SetRequestContext(blink::mojom::RequestContextType::INTERNAL);
-  request.SetRequestorOrigin(blink::WebSecurityOrigin::CreateUniqueOpaque());
-
   WebFrameTestProxy* main_frame = FindInProcessMainWindowMainFrame();
   DCHECK(main_frame);
-  main_frame->GetWebFrame()->StartNavigation(request);
+  main_frame->GetWebFrame()->ResetForTesting();
 }
 
 void TestRunner::DidCommitNavigationInMainFrame(WebFrameTestProxy* main_frame) {
diff --git a/device/bluetooth/dbus/bluetooth_profile_manager_client.h b/device/bluetooth/dbus/bluetooth_profile_manager_client.h
index 395e606..d1bc5dd 100644
--- a/device/bluetooth/dbus/bluetooth_profile_manager_client.h
+++ b/device/bluetooth/dbus/bluetooth_profile_manager_client.h
@@ -42,7 +42,7 @@
     std::unique_ptr<std::string> service;
 
     // Role.
-    enum ProfileRole role;
+    enum ProfileRole role = ProfileRole::SYMMETRIC;
 
     // RFCOMM channel number.
     std::unique_ptr<uint16_t> channel;
diff --git a/docs/ios/build_instructions.md b/docs/ios/build_instructions.md
index e30e14b..b3817946 100644
--- a/docs/ios/build_instructions.md
+++ b/docs/ios/build_instructions.md
@@ -328,23 +328,6 @@
 [waterfall](https://build.chromium.org/buildbot/waterfall/) is green and the tree
 is open before checking out. This will increase your chances of success.
 
-### Debugging
-
-To help with reproductible builds, and to work with Goma, the path to source
-files in debugging symbols are relative to source directory. To allow Xcode
-to find the source files, you need to ensure to have an `~/.lldbinit-Xcode`
-file with the following lines into it (substitute {SRC} for your actual path
-to the root of Chromium's sources):
-
-```
-script sys.path[:0] = ['{SRC}/tools/lldb']
-script import lldbinit
-```
-
-This will also allow you to see the content of some of Chromium types in the
-debugger like `base::string16`, ... If you want to use `lldb` directly, name
-the file `~/.lldbinit` instead of `~/.lldbinit-Xcode`.
-
 ### Changing the version of Xcode
 
 To change the version of Xcode used to build Chromium on iOS, please follow
diff --git a/extensions/browser/api/declarative_net_request/rules_monitor_service.cc b/extensions/browser/api/declarative_net_request/rules_monitor_service.cc
index 97da952..c14912f 100644
--- a/extensions/browser/api/declarative_net_request/rules_monitor_service.cc
+++ b/extensions/browser/api/declarative_net_request/rules_monitor_service.cc
@@ -67,17 +67,23 @@
 
 // Returns whether the extension's allocation should be released. This would
 // return true for cases where we expect the extension to be unloaded for a
-// while.
+// while or if the extension directory's contents changed in a reload.
 bool ShouldReleaseAllocationOnUnload(const ExtensionPrefs* prefs,
-                                     const ExtensionId& extension_id,
+                                     const Extension& extension,
                                      UnloadedExtensionReason reason) {
   if (reason == UnloadedExtensionReason::DISABLE) {
     static constexpr int kReleaseAllocationDisableReasons =
         disable_reason::DISABLE_BLOCKED_BY_POLICY |
         disable_reason::DISABLE_REMOTELY_FOR_MALWARE;
 
-    return (prefs->GetDisableReasons(extension_id) &
-            kReleaseAllocationDisableReasons) != 0;
+    // Release allocation on reload of an unpacked extension and treat it as a
+    // new install since the extension directory's contents may have changed.
+    bool is_unpacked_reload =
+        Manifest::IsUnpackedLocation(extension.location()) &&
+        prefs->HasDisableReason(extension.id(), disable_reason::DISABLE_RELOAD);
+
+    return is_unpacked_reload || (prefs->GetDisableReasons(extension.id()) &
+                                  kReleaseAllocationDisableReasons) != 0;
   }
 
   return reason == UnloadedExtensionReason::BLOCKLIST;
@@ -379,8 +385,9 @@
     if (reason != UnloadedExtensionReason::UPDATE)
       prefs_->SetDNRKeepExcessAllocation(extension->id(), false);
 
-    if (ShouldReleaseAllocationOnUnload(prefs_, extension->id(), reason))
+    if (ShouldReleaseAllocationOnUnload(prefs_, *extension, reason)) {
       global_rules_tracker_.ClearExtensionAllocation(extension->id());
+    }
   }
 
   // Return early if the extension does not have an active indexed ruleset.
@@ -738,13 +745,15 @@
     base::Optional<std::string> error) {
   DCHECK_EQ(1u, load_data.rulesets.size());
 
+  const bool has_error = error.has_value();
+
   LogMetricsAndUpdateChecksumsIfNeeded(load_data);
 
   // Respond to the extension.
   std::move(callback).Run(std::move(error));
 
   RulesetInfo& dynamic_ruleset = load_data.rulesets[0];
-  DCHECK_EQ(dynamic_ruleset.did_load_successfully(), !error.has_value());
+  DCHECK_EQ(dynamic_ruleset.did_load_successfully(), !has_error);
 
   if (!dynamic_ruleset.did_load_successfully())
     return;
diff --git a/extensions/browser/api/guest_view/web_view/web_view_internal_api.cc b/extensions/browser/api/guest_view/web_view/web_view_internal_api.cc
index 814c70d3..913d9318 100644
--- a/extensions/browser/api/guest_view/web_view/web_view_internal_api.cc
+++ b/extensions/browser/api/guest_view/web_view/web_view_internal_api.cc
@@ -796,8 +796,9 @@
       params->virtual_url ? *params->virtual_url : params->data_url;
 
   std::string error;
-  bool successful = guest_->LoadDataWithBaseURL(
-      params->data_url, params->base_url, virtual_url, &error);
+  bool successful = guest_->LoadDataWithBaseURL(GURL(params->data_url),
+                                                GURL(params->base_url),
+                                                GURL(virtual_url), &error);
   if (successful)
     return RespondNow(NoArguments());
   return RespondNow(Error(std::move(error)));
diff --git a/extensions/browser/api/vpn_provider/BUILD.gn b/extensions/browser/api/vpn_provider/BUILD.gn
index a00c65a..6312734c 100644
--- a/extensions/browser/api/vpn_provider/BUILD.gn
+++ b/extensions/browser/api/vpn_provider/BUILD.gn
@@ -16,10 +16,17 @@
     "vpn_provider_api.h",
     "vpn_service.cc",
     "vpn_service.h",
+    "vpn_service_factory.cc",
     "vpn_service_factory.h",
   ]
 
-  deps = [ "//extensions/common/api" ]
+  deps = [
+    "//base",
+    "//chromeos/dbus",
+    "//chromeos/login/login_state",
+    "//chromeos/network",
+    "//extensions/common/api",
+  ]
 
   public_deps = [ "//extensions/browser:browser_sources" ]
 }
diff --git a/chrome/browser/extensions/api/vpn_provider/vpn_service_factory.cc b/extensions/browser/api/vpn_provider/vpn_service_factory.cc
similarity index 75%
rename from chrome/browser/extensions/api/vpn_provider/vpn_service_factory.cc
rename to extensions/browser/api/vpn_provider/vpn_service_factory.cc
index c6c656f..46f28cd 100644
--- a/chrome/browser/extensions/api/vpn_provider/vpn_service_factory.cc
+++ b/extensions/browser/api/vpn_provider/vpn_service_factory.cc
@@ -5,14 +5,14 @@
 #include "extensions/browser/api/vpn_provider/vpn_service_factory.h"
 
 #include "base/memory/singleton.h"
-#include "chrome/browser/chromeos/profiles/profile_helper.h"
-#include "chrome/browser/profiles/profile.h"
 #include "chromeos/dbus/dbus_thread_manager.h"
+#include "chromeos/login/login_state/login_state.h"
 #include "chromeos/network/network_handler.h"
 #include "components/keyed_service/content/browser_context_dependency_manager.h"
 #include "extensions/browser/api/vpn_provider/vpn_service.h"
 #include "extensions/browser/event_router.h"
 #include "extensions/browser/extension_registry.h"
+#include "extensions/browser/extensions_browser_client.h"
 
 namespace chromeos {
 
@@ -31,11 +31,9 @@
 VpnServiceFactory::VpnServiceFactory()
     : BrowserContextKeyedServiceFactory(
           "VpnService",
-          BrowserContextDependencyManager::GetInstance()) {
-}
+          BrowserContextDependencyManager::GetInstance()) {}
 
-VpnServiceFactory::~VpnServiceFactory() {
-}
+VpnServiceFactory::~VpnServiceFactory() = default;
 
 bool VpnServiceFactory::ServiceIsCreatedWithBrowserContext() const {
   return true;
@@ -47,15 +45,17 @@
 
 KeyedService* VpnServiceFactory::BuildServiceInstanceFor(
     content::BrowserContext* context) const {
-  if (!chromeos::ProfileHelper::IsPrimaryProfile(
-          Profile::FromBrowserContext(context))) {
+  std::string context_user_hash =
+      extensions::ExtensionsBrowserClient::Get()->GetUserIdHashFromContext(
+          context);
+
+  if (!LoginState::IsInitialized() ||
+      context_user_hash != LoginState::Get()->primary_user_hash()) {
     return nullptr;
   }
+
   return new VpnService(
-      context,
-      chromeos::ProfileHelper::GetUserIdHashFromProfile(
-          Profile::FromBrowserContext(context)),
-      extensions::ExtensionRegistry::Get(context),
+      context, context_user_hash, extensions::ExtensionRegistry::Get(context),
       extensions::EventRouter::Get(context),
       DBusThreadManager::Get()->GetShillThirdPartyVpnDriverClient(),
       NetworkHandler::Get()->network_configuration_handler(),
diff --git a/extensions/browser/guest_view/web_view/web_view_guest.cc b/extensions/browser/guest_view/web_view/web_view_guest.cc
index 65ef9b1..057d349 100644
--- a/extensions/browser/guest_view/web_view/web_view_guest.cc
+++ b/extensions/browser/guest_view/web_view/web_view_guest.cc
@@ -1352,40 +1352,41 @@
   allow_scaling_ = allow;
 }
 
-bool WebViewGuest::LoadDataWithBaseURL(const std::string& data_url,
-                                       const std::string& base_url,
-                                       const std::string& virtual_url,
+bool WebViewGuest::LoadDataWithBaseURL(const GURL& data_url,
+                                       const GURL& base_url,
+                                       const GURL& virtual_url,
                                        std::string* error) {
-  // Make GURLs from URLs.
-  const GURL data_gurl = GURL(data_url);
-  const GURL base_gurl = GURL(base_url);
-  const GURL virtual_gurl = GURL(virtual_url);
-
   // Check that the provided URLs are valid.
   // |data_url| must be a valid data URL.
-  if (!data_gurl.is_valid() || !data_gurl.SchemeIs(url::kDataScheme)) {
-    base::SStringPrintf(
-        error, webview::kAPILoadDataInvalidDataURL, data_url.c_str());
+  if (!data_url.is_valid() || !data_url.SchemeIs(url::kDataScheme)) {
+    base::SStringPrintf(error, webview::kAPILoadDataInvalidDataURL,
+                        data_url.possibly_invalid_spec().c_str());
     return false;
   }
-  // |base_url| must be a valid URL.
-  if (!base_gurl.is_valid()) {
-    base::SStringPrintf(
-        error, webview::kAPILoadDataInvalidBaseURL, base_url.c_str());
+  const url::Origin& owner_origin =
+      owner_web_contents()->GetMainFrame()->GetLastCommittedOrigin();
+  const bool base_in_owner_origin =
+      owner_origin.IsSameOriginWith(url::Origin::Create(base_url));
+  // |base_url| must be a valid URL. It is also limited to URLs that the owner
+  // is trusted to have control over.
+  if (!base_url.is_valid() ||
+      (!base_url.SchemeIsHTTPOrHTTPS() && !base_in_owner_origin)) {
+    base::SStringPrintf(error, webview::kAPILoadDataInvalidBaseURL,
+                        base_url.possibly_invalid_spec().c_str());
     return false;
   }
   // |virtual_url| must be a valid URL.
-  if (!virtual_gurl.is_valid()) {
-    base::SStringPrintf(
-        error, webview::kAPILoadDataInvalidVirtualURL, virtual_url.c_str());
+  if (!virtual_url.is_valid()) {
+    base::SStringPrintf(error, webview::kAPILoadDataInvalidVirtualURL,
+                        virtual_url.possibly_invalid_spec().c_str());
     return false;
   }
 
   // Set up the parameters to load |data_url| with the specified |base_url|.
-  content::NavigationController::LoadURLParams load_params(data_gurl);
+  content::NavigationController::LoadURLParams load_params(data_url);
   load_params.load_type = content::NavigationController::LOAD_TYPE_DATA;
-  load_params.base_url_for_data_url = base_gurl;
-  load_params.virtual_url_for_data_url = virtual_gurl;
+  load_params.base_url_for_data_url = base_url;
+  load_params.virtual_url_for_data_url = virtual_url;
   load_params.override_user_agent =
       content::NavigationController::UA_OVERRIDE_INHERIT;
 
diff --git a/extensions/browser/guest_view/web_view/web_view_guest.h b/extensions/browser/guest_view/web_view/web_view_guest.h
index f059694..2b721a2 100644
--- a/extensions/browser/guest_view/web_view/web_view_guest.h
+++ b/extensions/browser/guest_view/web_view/web_view_guest.h
@@ -110,9 +110,9 @@
   bool allow_transparency() const { return allow_transparency_; }
 
   // Loads a data URL with a specified base URL and virtual URL.
-  bool LoadDataWithBaseURL(const std::string& data_url,
-                           const std::string& base_url,
-                           const std::string& virtual_url,
+  bool LoadDataWithBaseURL(const GURL& data_url,
+                           const GURL& base_url,
+                           const GURL& virtual_url,
                            std::string* error);
 
   // Begin or continue a find request.
diff --git a/extensions/shell/BUILD.gn b/extensions/shell/BUILD.gn
index 7cef467..13525ab 100644
--- a/extensions/shell/BUILD.gn
+++ b/extensions/shell/BUILD.gn
@@ -226,7 +226,6 @@
 
   if (is_chromeos_ash) {
     sources += [
-      "browser/api/vpn_provider/vpn_service_factory.cc",
       "browser/shell_screen.cc",
       "browser/shell_screen.h",
     ]
diff --git a/extensions/shell/browser/api/vpn_provider/DIR_METADATA b/extensions/shell/browser/api/vpn_provider/DIR_METADATA
deleted file mode 100644
index 30845fe..0000000
--- a/extensions/shell/browser/api/vpn_provider/DIR_METADATA
+++ /dev/null
@@ -1,11 +0,0 @@
-# Metadata information for this directory.
-#
-# For more information on DIR_METADATA files, see:
-#   https://source.chromium.org/chromium/infra/infra/+/master:go/src/infra/tools/dirmd/README.md
-#
-# For the schema of this file, see Metadata message:
-#   https://source.chromium.org/chromium/infra/infra/+/master:go/src/infra/tools/dirmd/proto/dir_metadata.proto
-
-monorail {
-  component: "Enterprise"
-}
\ No newline at end of file
diff --git a/extensions/shell/browser/api/vpn_provider/OWNERS b/extensions/shell/browser/api/vpn_provider/OWNERS
deleted file mode 100644
index a913a05..0000000
--- a/extensions/shell/browser/api/vpn_provider/OWNERS
+++ /dev/null
@@ -1,2 +0,0 @@
-bartfab@chromium.org
-emaxx@chromium.org
diff --git a/extensions/shell/browser/api/vpn_provider/vpn_service_factory.cc b/extensions/shell/browser/api/vpn_provider/vpn_service_factory.cc
deleted file mode 100644
index 167f5ec9..0000000
--- a/extensions/shell/browser/api/vpn_provider/vpn_service_factory.cc
+++ /dev/null
@@ -1,59 +0,0 @@
-// Copyright 2014 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 "extensions/browser/api/vpn_provider/vpn_service_factory.h"
-
-#include "base/memory/singleton.h"
-#include "chromeos/dbus/dbus_thread_manager.h"
-#include "chromeos/network/network_handler.h"
-#include "components/keyed_service/content/browser_context_dependency_manager.h"
-#include "extensions/browser/api/vpn_provider/vpn_service.h"
-#include "extensions/browser/event_router.h"
-#include "extensions/browser/extension_registry.h"
-
-namespace chromeos {
-
-// This file is a dummy stub for use in appshell.
-
-// static
-VpnService* VpnServiceFactory::GetForBrowserContext(
-    content::BrowserContext* context) {
-  return static_cast<VpnService*>(
-      GetInstance()->GetServiceForBrowserContext(context, true));
-}
-
-// static
-VpnServiceFactory* VpnServiceFactory::GetInstance() {
-  return base::Singleton<VpnServiceFactory>::get();
-}
-
-VpnServiceFactory::VpnServiceFactory()
-    : BrowserContextKeyedServiceFactory(
-          "VpnService",
-          BrowserContextDependencyManager::GetInstance()) {
-}
-
-VpnServiceFactory::~VpnServiceFactory() {
-}
-
-bool VpnServiceFactory::ServiceIsCreatedWithBrowserContext() const {
-  return true;
-}
-
-bool VpnServiceFactory::ServiceIsNULLWhileTesting() const {
-  return true;
-}
-
-KeyedService* VpnServiceFactory::BuildServiceInstanceFor(
-    content::BrowserContext* context) const {
-  return new VpnService(
-      context, "testuser", extensions::ExtensionRegistry::Get(context),
-      extensions::EventRouter::Get(context),
-      DBusThreadManager::Get()->GetShillThirdPartyVpnDriverClient(),
-      NetworkHandler::Get()->network_configuration_handler(),
-      NetworkHandler::Get()->network_profile_handler(),
-      NetworkHandler::Get()->network_state_handler());
-}
-
-}  // namespace chromeos
diff --git a/ios/chrome/app/resources/ios_resources.grd b/ios/chrome/app/resources/ios_resources.grd
index 4fd398a2..83d454b 100644
--- a/ios/chrome/app/resources/ios_resources.grd
+++ b/ios/chrome/app/resources/ios_resources.grd
@@ -13,9 +13,9 @@
       <include name="IDR_IOS_OMAHA_HTML" file="omaha/omaha.html" flattenhtml="true" allowexternalscript="true" type="BINDATA" />
       <include name="IDR_IOS_OMAHA_JS" file="omaha/omaha.js" type="BINDATA" />
       <include name="IDR_IOS_UKM_INTERNALS_HTML" file="../../../../components/ukm/debug/ukm_internals.html" flattenhtml="true" allowexternalscript="true" type="BINDATA" />
-      <include name="IDR_IOS_UKM_INTERNALS_JS" file="../../../../components/ukm/debug/ukm_internals.js" flattenhtml="true" type="BINDATA" />
+      <include name="IDR_IOS_UKM_INTERNALS_JS" file="../../../../components/ukm/debug/ukm_internals.js" type="BINDATA" />
       <include name="IDR_IOS_TRANSLATE_INTERNALS_HTML" file="../../../../components/translate/translate_internals/translate_internals.html" flattenhtml="true" allowexternalscript="true" type="BINDATA" />
-      <include name="IDR_IOS_TRANSLATE_INTERNALS_JS" file="../../../../components/translate/translate_internals/translate_internals.js" flattenhtml="true" type="BINDATA" />
+      <include name="IDR_IOS_TRANSLATE_INTERNALS_JS" file="../../../../components/translate/translate_internals/translate_internals.js" type="BINDATA" />
     </includes>
   </release>
 </grit>
diff --git a/ios/chrome/browser/ui/incognito_reauth/BUILD.gn b/ios/chrome/browser/ui/incognito_reauth/BUILD.gn
index 6515be8..6c675f0b 100644
--- a/ios/chrome/browser/ui/incognito_reauth/BUILD.gn
+++ b/ios/chrome/browser/ui/incognito_reauth/BUILD.gn
@@ -4,6 +4,12 @@
 
 import("//ios/build/chrome_build.gni")
 
+source_set("incognito_reauth_commands") {
+  configs += [ "//build/config/compiler:enable_arc" ]
+  sources = [ "incognito_reauth_commands.h" ]
+  frameworks = [ "UIKit.framework" ]
+}
+
 source_set("incognito_reauth_ui") {
   configs += [ "//build/config/compiler:enable_arc" ]
   sources = [
@@ -24,6 +30,7 @@
     "incognito_reauth_scene_agent.mm",
   ]
   deps = [
+    ":incognito_reauth_commands",
     "//base",
     "//components/pref_registry",
     "//components/prefs",
diff --git a/ios/chrome/browser/ui/incognito_reauth/incognito_reauth_commands.h b/ios/chrome/browser/ui/incognito_reauth/incognito_reauth_commands.h
new file mode 100644
index 0000000..7bc8e0a
--- /dev/null
+++ b/ios/chrome/browser/ui/incognito_reauth/incognito_reauth_commands.h
@@ -0,0 +1,23 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef IOS_CHROME_BROWSER_UI_INCOGNITO_REAUTH_INCOGNITO_REAUTH_COMMANDS_H_
+#define IOS_CHROME_BROWSER_UI_INCOGNITO_REAUTH_INCOGNITO_REAUTH_COMMANDS_H_
+
+#import <UIKit/UIKit.h>
+
+// Commands related to incognito authentication.
+// Should only be registered in a per-scene dispatcher, never in the global app
+// dispatcher.
+@protocol IncognitoReauthCommands
+
+// Requests authentication and marks the scene as authenticated until the next
+// scene foregrounding.
+// The authentication will require user interaction. To know when it changes, a
+// IncognitoReauthObserver callback will be called.
+- (void)authenticateIncognitoContent;
+
+@end
+
+#endif  // IOS_CHROME_BROWSER_UI_INCOGNITO_REAUTH_INCOGNITO_REAUTH_COMMANDS_H_
diff --git a/ios/chrome/browser/ui/incognito_reauth/incognito_reauth_scene_agent.h b/ios/chrome/browser/ui/incognito_reauth/incognito_reauth_scene_agent.h
index 31e2d7b..ff17653 100644
--- a/ios/chrome/browser/ui/incognito_reauth/incognito_reauth_scene_agent.h
+++ b/ios/chrome/browser/ui/incognito_reauth/incognito_reauth_scene_agent.h
@@ -7,6 +7,8 @@
 
 #import "ios/chrome/browser/ui/main/scene_state.h"
 
+#import "ios/chrome/browser/ui/incognito_reauth/incognito_reauth_commands.h"
+
 @class IncognitoReauthSceneAgent;
 class PrefRegistrySimple;
 class PrefService;
@@ -24,7 +26,8 @@
 
 // A scene agent that tracks the incognito authentication status for the current
 // scene.
-@interface IncognitoReauthSceneAgent : NSObject <SceneAgent>
+@interface IncognitoReauthSceneAgent
+    : NSObject <IncognitoReauthCommands, SceneAgent>
 
 // Designated initializer.
 // The |reauthModule| is used for authentication.
@@ -48,11 +51,6 @@
 // ApplicationContext, but is settable for overriding.
 @property(nonatomic, assign) PrefService* localState;
 
-// Requests authentication and marks this scene as authenticated until the next
-// scene foregrounding. The callback will receive the result of the
-// authentication attempt. It will be called on main thread, asynchronously.
-- (void)authenticateWithCompletion:(void (^)(BOOL))completion;
-
 #pragma mark observation
 
 - (void)addObserver:(id<IncognitoReauthObserver>)observer;
diff --git a/ios/chrome/browser/ui/incognito_reauth/incognito_reauth_scene_agent.mm b/ios/chrome/browser/ui/incognito_reauth/incognito_reauth_scene_agent.mm
index b79b1688..96407cb 100644
--- a/ios/chrome/browser/ui/incognito_reauth/incognito_reauth_scene_agent.mm
+++ b/ios/chrome/browser/ui/incognito_reauth/incognito_reauth_scene_agent.mm
@@ -71,13 +71,11 @@
          !self.authenticatedSinceLastForeground;
 }
 
-- (void)authenticateWithCompletion:(void (^)(BOOL))completion {
+- (void)authenticateIncognitoContent {
   DCHECK(self.reauthModule);
 
   if (!self.isAuthenticationRequired) {
-    if (completion) {
-      completion(YES);
-    }
+    [self notifyObservers];
     return;
   }
 
@@ -93,9 +91,6 @@
                                       ReauthenticationResult::kSuccess);
                                  weakSelf.authenticatedSinceLastForeground =
                                      success;
-                                 if (completion) {
-                                   completion(success);
-                                 }
                                }];
 }
 
diff --git a/ios/chrome/browser/ui/incognito_reauth/incognito_reauth_scene_agent_unittest.mm b/ios/chrome/browser/ui/incognito_reauth/incognito_reauth_scene_agent_unittest.mm
index f500529..9c70bc4 100644
--- a/ios/chrome/browser/ui/incognito_reauth/incognito_reauth_scene_agent_unittest.mm
+++ b/ios/chrome/browser/ui/incognito_reauth/incognito_reauth_scene_agent_unittest.mm
@@ -166,9 +166,7 @@
 
   EXPECT_TRUE(agent_.authenticationRequired);
 
-  [agent_ authenticateWithCompletion:^(BOOL result) {
-    EXPECT_TRUE(result);
-  }];
+  [agent_ authenticateIncognitoContent];
 
   // Auth not required
   EXPECT_FALSE(agent_.authenticationRequired);
@@ -190,16 +188,12 @@
 
   stub_reauth_module_.returnedResult = ReauthenticationResult::kFailure;
 
-  [agent_ authenticateWithCompletion:^(BOOL result) {
-    EXPECT_FALSE(result);
-  }];
+  [agent_ authenticateIncognitoContent];
   // Auth still required
   EXPECT_TRUE(agent_.authenticationRequired);
 
   stub_reauth_module_.returnedResult = ReauthenticationResult::kSkipped;
-  [agent_ authenticateWithCompletion:^(BOOL result) {
-    EXPECT_FALSE(result);
-  }];
+  [agent_ authenticateIncognitoContent];
   // Auth still required
   EXPECT_TRUE(agent_.authenticationRequired);
 }
diff --git a/ios/chrome/browser/ui/incognito_reauth/incognito_reauth_view.mm b/ios/chrome/browser/ui/incognito_reauth/incognito_reauth_view.mm
index 4933754..81b9ed8 100644
--- a/ios/chrome/browser/ui/incognito_reauth/incognito_reauth_view.mm
+++ b/ios/chrome/browser/ui/incognito_reauth/incognito_reauth_view.mm
@@ -89,6 +89,7 @@
   backgroundView.backgroundColor = [UIColor colorWithWhite:1 alpha:0.2];
   backgroundView.layer.cornerRadius = kButtonHeight / 2;
   backgroundView.translatesAutoresizingMaskIntoConstraints = NO;
+  backgroundView.userInteractionEnabled = NO;
   [button addSubview:backgroundView];
   AddSameConstraints(backgroundView, button);
 
diff --git a/ios/chrome/browser/ui/open_in/open_in_controller_egtest.mm b/ios/chrome/browser/ui/open_in/open_in_controller_egtest.mm
index 33557a9..e827836 100644
--- a/ios/chrome/browser/ui/open_in/open_in_controller_egtest.mm
+++ b/ios/chrome/browser/ui/open_in/open_in_controller_egtest.mm
@@ -62,7 +62,9 @@
 
 // Tests that open in button appears when opening a PDF, and that tapping on it
 // will open the activity view.
-- (void)testOpenInPDF {
+//
+// Disabled due to flakiness: http://crbug.com/1152782
+- (void)DISABLED_testOpenInPDF {
   // Apple is hiding UIActivityViewController's content from the host app on
   // iPad.
   if ([ChromeEarlGrey isIPadIdiom])
diff --git a/ios/chrome/browser/ui/page_info/BUILD.gn b/ios/chrome/browser/ui/page_info/BUILD.gn
index 6af7406c..d531cf96 100644
--- a/ios/chrome/browser/ui/page_info/BUILD.gn
+++ b/ios/chrome/browser/ui/page_info/BUILD.gn
@@ -98,3 +98,26 @@
   ]
   frameworks = [ "UIKit.framework" ]
 }
+
+source_set("eg2_tests") {
+  defines = [ "CHROME_EARL_GREY_2" ]
+  configs += [
+    "//build/config/compiler:enable_arc",
+    "//build/config/ios:xctest_config",
+  ]
+  testonly = true
+  sources = [ "page_info_egtest.mm" ]
+  deps = [
+    ":constants",
+    "//components/strings",
+    "//ios/chrome/app/strings",
+    "//ios/chrome/test/earl_grey:eg_test_support+eg2",
+    "//ios/testing/earl_grey:eg_test_support+eg2",
+    "//ios/third_party/earl_grey2:test_lib",
+    "//ui/base",
+  ]
+  frameworks = [
+    "UIKit.framework",
+    "XCTest.framework",
+  ]
+}
diff --git a/ios/chrome/browser/ui/page_info/page_info_egtest.mm b/ios/chrome/browser/ui/page_info/page_info_egtest.mm
new file mode 100644
index 0000000..8b09f4b
--- /dev/null
+++ b/ios/chrome/browser/ui/page_info/page_info_egtest.mm
@@ -0,0 +1,70 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#import <UIKit/UIKit.h>
+#import <XCTest/XCTest.h>
+
+#include "components/strings/grit/components_chromium_strings.h"
+#import "ios/chrome/browser/ui/page_info/page_info_constants.h"
+#include "ios/chrome/grit/ios_chromium_strings.h"
+#import "ios/chrome/test/earl_grey/chrome_earl_grey.h"
+#import "ios/chrome/test/earl_grey/chrome_earl_grey_ui.h"
+#import "ios/chrome/test/earl_grey/chrome_matchers.h"
+#import "ios/chrome/test/earl_grey/chrome_test_case.h"
+#import "ios/testing/earl_grey/earl_grey_test.h"
+#include "ui/base/l10n/l10n_util.h"
+
+#if !defined(__has_feature) || !__has_feature(objc_arc)
+#error "This file requires ARC support."
+#endif
+
+@interface PageInfoTestCase : ChromeTestCase
+@end
+
+@implementation PageInfoTestCase
+
+// Tests that rotating the device will don't dismiss the page info view.
+- (void)testShowPageInfoRotation {
+  [ChromeEarlGrey loadURL:GURL("https://invalid")];
+  [ChromeEarlGreyUI openPageInfo];
+
+  // Checks that the page info view has appeared.
+  [[EarlGrey selectElementWithMatcher:grey_accessibilityID(
+                                          kPageInfoViewAccessibilityIdentifier)]
+      assertWithMatcher:grey_sufficientlyVisible()];
+
+  // Rotates the device and checks that the page info view is still presented.
+  [EarlGrey rotateDeviceToOrientation:UIDeviceOrientationLandscapeRight
+                                error:nil];
+  [[EarlGrey selectElementWithMatcher:grey_accessibilityID(
+                                          kPageInfoViewAccessibilityIdentifier)]
+      assertWithMatcher:grey_sufficientlyVisible()];
+
+  // Closes the page info using the 'Done' button.
+  [[EarlGrey
+      selectElementWithMatcher:chrome_test_util::NavigationBarDoneButton()]
+      performAction:grey_tap()];
+  [[EarlGrey selectElementWithMatcher:grey_accessibilityID(
+                                          kPageInfoViewAccessibilityIdentifier)]
+      assertWithMatcher:grey_nil()];
+}
+
+// Tests that opening the page info on a Chromium page displays the correct
+// information.
+- (void)testShowPageInfoChromePage {
+  [ChromeEarlGrey loadURL:GURL("chrome://version")];
+  [ChromeEarlGreyUI openPageInfo];
+
+  // Checks that the page info view has appeared.
+  [[EarlGrey selectElementWithMatcher:grey_accessibilityID(
+                                          kPageInfoViewAccessibilityIdentifier)]
+      assertWithMatcher:grey_sufficientlyVisible()];
+
+  // Checks that “You’re viewing a secure Chrome page.” is displayed.
+  [[EarlGrey selectElementWithMatcher:grey_text(l10n_util::GetNSString(
+                                          IDS_PAGE_INFO_INTERNAL_PAGE))]
+      assertWithMatcher:grey_sufficientlyVisible()];
+}
+
+@end
diff --git a/ios/chrome/browser/ui/settings/password/password_details/password_details_table_view_controller.mm b/ios/chrome/browser/ui/settings/password/password_details/password_details_table_view_controller.mm
index 2db9ab2..70a9e2a 100644
--- a/ios/chrome/browser/ui/settings/password/password_details/password_details_table_view_controller.mm
+++ b/ios/chrome/browser/ui/settings/password/password_details/password_details_table_view_controller.mm
@@ -133,8 +133,10 @@
   if (self.tableView.editing) {
     // If password or username value was changed show confirmation dialog before
     // saving password. Editing mode will be exited only if user confirm saving.
-    if (self.password.password != self.passwordTextItem.textFieldValue ||
-        self.password.username != self.usernameTextItem.textFieldValue) {
+    if (![self.password.password
+            isEqualToString:self.passwordTextItem.textFieldValue] ||
+        ![self.password.username
+            isEqualToString:self.usernameTextItem.textFieldValue]) {
       [self.handler showPasswordEditDialogWithOrigin:self.password.origin];
     } else {
       [self passwordEditingConfirmed];
@@ -185,6 +187,10 @@
   }
 }
 
+- (BOOL)showCancelDuringEditing {
+  return YES;
+}
+
 #pragma mark - Items
 
 - (TableViewTextEditItem*)websiteItem {
diff --git a/ios/chrome/browser/ui/settings/password/passwords_settings_egtest.mm b/ios/chrome/browser/ui/settings/password/passwords_settings_egtest.mm
index f881d4b..7a9cd19 100644
--- a/ios/chrome/browser/ui/settings/password/passwords_settings_egtest.mm
+++ b/ios/chrome/browser/ui/settings/password/passwords_settings_egtest.mm
@@ -49,6 +49,7 @@
 
 using chrome_test_util::ButtonWithAccessibilityLabel;
 using chrome_test_util::ButtonWithAccessibilityLabelId;
+using chrome_test_util::NavigationBarCancelButton;
 using chrome_test_util::NavigationBarDoneButton;
 using chrome_test_util::SettingsDoneButton;
 using chrome_test_util::SettingsMenuBackButton;
@@ -691,20 +692,10 @@
 
   [[EarlGrey selectElementWithMatcher:DeleteButton()] performAction:grey_tap()];
 
-  // Tap the alert's Cancel button to cancel.
-  if ([ChromeEarlGrey isIPadIdiom]) {
-    [[EarlGrey selectElementWithMatcher:grey_accessibilityID(
-                                            kPasswordDetailsTableViewId)]
-        performAction:grey_tap()];
-  } else {
-    [[EarlGrey
-        selectElementWithMatcher:grey_allOf(
-                                     ButtonWithAccessibilityLabel(
-                                         l10n_util::GetNSString(
-                                             IDS_IOS_CANCEL_PASSWORD_DELETION)),
-                                     grey_interactable(), nullptr)]
-        performAction:grey_tap()];
-  }
+  // Close the dialog by taping on Password Details screen.
+  [[EarlGrey selectElementWithMatcher:grey_accessibilityID(
+                                          kPasswordDetailsTableViewId)]
+      performAction:grey_tap()];
 
   // Check that the current view is still the detail view.
   [[EarlGrey selectElementWithMatcher:grey_accessibilityID(
@@ -717,6 +708,8 @@
 
   // Go back to the list view and verify that the password is still in the
   // list.
+  [[EarlGrey selectElementWithMatcher:NavigationBarCancelButton()]
+      performAction:grey_tap()];
   [[EarlGrey selectElementWithMatcher:SettingsMenuBackButton()]
       performAction:grey_tap()];
   [GetInteractionForPasswordEntry(@"example.com, concrete username")
@@ -836,6 +829,8 @@
   [[EarlGrey selectElementWithMatcher:DeleteButton()]
       assertWithMatcher:grey_notNil()];
 
+  [[EarlGrey selectElementWithMatcher:NavigationBarCancelButton()]
+      performAction:grey_tap()];
   [[EarlGrey selectElementWithMatcher:SettingsMenuBackButton()]
       performAction:grey_tap()];
   [[EarlGrey selectElementWithMatcher:SettingsMenuBackButton()]
@@ -1455,6 +1450,8 @@
   [[EarlGrey selectElementWithMatcher:PasswordDetailPassword()]
       assertWithMatcher:grey_textFieldValue(@"new password")];
 
+  [[EarlGrey selectElementWithMatcher:NavigationBarCancelButton()]
+      performAction:grey_tap()];
   [[EarlGrey selectElementWithMatcher:SettingsMenuBackButton()]
       performAction:grey_tap()];
   [[EarlGrey selectElementWithMatcher:SettingsMenuBackButton()]
@@ -1570,6 +1567,9 @@
       assertWithMatcher:grey_allOf(grey_sufficientlyVisible(),
                                    grey_not(grey_enabled()), nil)];
 
+  [[EarlGrey selectElementWithMatcher:NavigationBarCancelButton()]
+      performAction:grey_tap()];
+
   [[EarlGrey selectElementWithMatcher:SettingsMenuBackButton()]
       performAction:grey_tap()];
 
@@ -1579,4 +1579,41 @@
       performAction:grey_tap()];
 }
 
+// Checks that attempts to edit a username provide appropriate feedback.
+- (void)testCancelDuringEditing {
+  SaveExamplePasswordForm();
+
+  OpenPasswordSettings();
+
+  [GetInteractionForPasswordEntry(@"example.com, concrete username")
+      performAction:grey_tap()];
+
+  // Check the snackbar in case of successful reauthentication.
+  [PasswordSettingsAppInterface setUpMockReauthenticationModule];
+  [PasswordSettingsAppInterface mockReauthenticationModuleExpectedResult:
+                                    ReauthenticationResult::kSuccess];
+
+  TapEdit();
+
+  [[EarlGrey selectElementWithMatcher:PasswordDetailPassword()]
+      performAction:grey_replaceText(@"new password")];
+
+  [[EarlGrey selectElementWithMatcher:NavigationBarCancelButton()]
+      performAction:grey_tap()];
+
+  // Test that password value is unchanged.
+  [GetInteractionForPasswordDetailItem(ShowPasswordButton())
+      performAction:grey_tap()];
+
+  [[EarlGrey selectElementWithMatcher:PasswordDetailPassword()]
+      assertWithMatcher:grey_textFieldValue(@"concrete password")];
+
+  [[EarlGrey selectElementWithMatcher:SettingsMenuBackButton()]
+      performAction:grey_tap()];
+  [[EarlGrey selectElementWithMatcher:SettingsMenuBackButton()]
+      performAction:grey_tap()];
+  [[EarlGrey selectElementWithMatcher:SettingsDoneButton()]
+      performAction:grey_tap()];
+}
+
 @end
diff --git a/ios/chrome/browser/ui/settings/settings_root_table_view_controller.h b/ios/chrome/browser/ui/settings/settings_root_table_view_controller.h
index fab364b..b21a624 100644
--- a/ios/chrome/browser/ui/settings/settings_root_table_view_controller.h
+++ b/ios/chrome/browser/ui/settings/settings_root_table_view_controller.h
@@ -61,6 +61,10 @@
 // editing mode of this controller.
 - (void)editButtonPressed;
 
+// Returns NO. Subclasses should overload this if the cancel button should be
+// shown during editing.
+- (BOOL)showCancelDuringEditing;
+
 // Called when this ViewController toolbar's delete item has been tapped.
 // |indexPaths| is the index paths of the currently selected item to be deleted.
 // Default implementation removes the items.
diff --git a/ios/chrome/browser/ui/settings/settings_root_table_view_controller.mm b/ios/chrome/browser/ui/settings/settings_root_table_view_controller.mm
index 1e20155..4879895 100644
--- a/ios/chrome/browser/ui/settings/settings_root_table_view_controller.mm
+++ b/ios/chrome/browser/ui/settings/settings_root_table_view_controller.mm
@@ -51,6 +51,10 @@
 // store the item while the interaction is prevented.
 @property(nonatomic, strong) UIBarButtonItem* savedBarButtonItem;
 
+// Back button on navigation panel. This is used to store back button while it
+// is replaced with Cancel during editing.
+@property(nonatomic, strong) UIBarButtonItem* backButtonItem;
+
 // Veil preventing interactions with the TableView.
 @property(nonatomic, strong) UIView* veil;
 
@@ -79,6 +83,13 @@
   } else {
     self.navigationItem.rightBarButtonItem = [self doneButtonIfNeeded];
   }
+
+  // Update Cancel/Back button.
+  if (self.showCancelDuringEditing) {
+    self.navigationItem.leftBarButtonItem =
+        self.tableView.editing ? [self createEditModeCancelButton]
+                               : self.backButtonItem;
+  }
 }
 
 - (void)reloadData {
@@ -127,6 +138,8 @@
 
   self.navigationItem.largeTitleDisplayMode =
       UINavigationItemLargeTitleDisplayModeNever;
+
+  self.backButtonItem = self.navigationItem.leftBarButtonItem;
 }
 
 - (void)viewWillAppear:(BOOL)animated {
@@ -253,6 +266,21 @@
              action:@selector(editButtonPressed)];
 }
 
+- (UIBarButtonItem*)createEditModeCancelButton {
+  // Create a custom Cancel bar button item.
+  return [[UIBarButtonItem alloc]
+      initWithBarButtonSystemItem:UIBarButtonSystemItemCancel
+                           target:self
+                           action:@selector(cancelEditing)];
+}
+
+// Quits editing mode and reloads data to the state before editing.
+- (void)cancelEditing {
+  [self setEditing:!self.tableView.editing animated:YES];
+  [self updateUIForEditState];
+  [self reloadData];
+}
+
 #pragma mark - Subclassing
 
 - (BOOL)shouldHideToolbar {
@@ -267,6 +295,10 @@
   return NO;
 }
 
+- (BOOL)showCancelDuringEditing {
+  return NO;
+}
+
 - (void)editButtonPressed {
   [self setEditing:!self.tableView.editing animated:YES];
   [self updateUIForEditState];
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/BUILD.gn b/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/BUILD.gn
index c0d8b8c..74ff6bf 100644
--- a/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/BUILD.gn
+++ b/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/BUILD.gn
@@ -53,6 +53,7 @@
     "//ios/chrome/browser/ui:feature_flags",
     "//ios/chrome/browser/ui/elements",
     "//ios/chrome/browser/ui/gestures",
+    "//ios/chrome/browser/ui/incognito_reauth:incognito_reauth_commands",
     "//ios/chrome/browser/ui/incognito_reauth:incognito_reauth_ui",
     "//ios/chrome/browser/ui/tab_switcher",
     "//ios/chrome/browser/ui/tab_switcher/tab_grid/transitions",
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/grid_view_controller.h b/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/grid_view_controller.h
index d322137d..417f3bc8 100644
--- a/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/grid_view_controller.h
+++ b/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/grid_view_controller.h
@@ -11,6 +11,7 @@
 #import "ios/chrome/browser/ui/tab_switcher/tab_grid/grid/grid_consumer.h"
 #import "ios/chrome/browser/ui/tab_switcher/tab_grid/grid/grid_theme.h"
 
+@protocol IncognitoReauthCommands;
 @protocol GridDragDropHandler;
 @protocol GridEmptyView;
 @protocol GridImageDataSource;
@@ -62,6 +63,8 @@
 @property(nonatomic, readonly, getter=isGridEmpty) BOOL gridEmpty;
 // The visual look of the grid.
 @property(nonatomic, assign) GridTheme theme;
+// Handler for reauth commands.
+@property(nonatomic, weak) id<IncognitoReauthCommands> handler;
 // Delegate is informed of user interactions in the grid UI.
 @property(nonatomic, weak) id<GridViewControllerDelegate> delegate;
 // Handles drag and drop interactions that involved the model layer.
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/grid_view_controller.mm b/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/grid_view_controller.mm
index 8ba939b3..4f2912dc 100644
--- a/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/grid_view_controller.mm
+++ b/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/grid_view_controller.mm
@@ -15,6 +15,7 @@
 #import "base/numerics/safe_conversions.h"
 #include "ios/chrome/browser/drag_and_drop/drag_and_drop_flag.h"
 #include "ios/chrome/browser/procedural_block_types.h"
+#import "ios/chrome/browser/ui/incognito_reauth/incognito_reauth_commands.h"
 #import "ios/chrome/browser/ui/incognito_reauth/incognito_reauth_view.h"
 #import "ios/chrome/browser/ui/tab_switcher/tab_grid/grid/grid_cell.h"
 #import "ios/chrome/browser/ui/tab_switcher/tab_grid/grid/grid_constants.h"
@@ -630,6 +631,11 @@
       self.blockingView.layer.zPosition = FLT_MAX;
       // No need to show tab switcher button when already in the tab switcher.
       self.blockingView.tabSwitcherButton.hidden = YES;
+
+      [self.blockingView.authenticateButton
+                 addTarget:self.handler
+                    action:@selector(authenticateIncognitoContent)
+          forControlEvents:UIControlEventTouchUpInside];
     }
 
     [self.view addSubview:self.blockingView];
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_grid/tab_grid_coordinator.mm b/ios/chrome/browser/ui/tab_switcher/tab_grid/tab_grid_coordinator.mm
index a34b077..a588dc27b 100644
--- a/ios/chrome/browser/ui/tab_switcher/tab_grid/tab_grid_coordinator.mm
+++ b/ios/chrome/browser/ui/tab_switcher/tab_grid/tab_grid_coordinator.mm
@@ -303,10 +303,24 @@
 #pragma mark - ChromeCoordinator
 
 - (void)start {
+  IncognitoReauthSceneAgent* reauthAgent = nil;
+  for (id agent in SceneStateBrowserAgent::FromBrowser(_incognitoBrowser)
+           ->GetSceneState()
+           .connectedAgents) {
+    if ([agent isKindOfClass:[IncognitoReauthSceneAgent class]]) {
+      reauthAgent = agent;
+    }
+  }
+
+  [self.dispatcher startDispatchingToTarget:reauthAgent
+                                forProtocol:@protocol(IncognitoReauthCommands)];
+
   TabGridViewController* baseViewController =
       [[TabGridViewController alloc] init];
   baseViewController.handler =
       HandlerForProtocol(self.dispatcher, ApplicationCommands);
+  baseViewController.reauthHandler =
+      HandlerForProtocol(self.dispatcher, IncognitoReauthCommands);
   baseViewController.tabPresentationDelegate = self;
   _baseViewController = baseViewController;
 
@@ -326,15 +340,6 @@
             regularBrowserState);
   }
 
-  IncognitoReauthSceneAgent* reauthAgent = nil;
-  for (id agent in SceneStateBrowserAgent::FromBrowser(_incognitoBrowser)
-           ->GetSceneState()
-           .connectedAgents) {
-    if ([agent isKindOfClass:[IncognitoReauthSceneAgent class]]) {
-      reauthAgent = agent;
-    }
-  }
-
   self.incognitoTabsMediator = [[TabGridMediator alloc]
       initWithConsumer:baseViewController.incognitoTabsConsumer
            reauthAgent:reauthAgent];
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_grid/tab_grid_view_controller.h b/ios/chrome/browser/ui/tab_switcher/tab_grid/tab_grid_view_controller.h
index e98605c..1856e388 100644
--- a/ios/chrome/browser/ui/tab_switcher/tab_grid/tab_grid_view_controller.h
+++ b/ios/chrome/browser/ui/tab_switcher/tab_grid/tab_grid_view_controller.h
@@ -13,6 +13,7 @@
 #import "ios/chrome/browser/ui/tab_switcher/tab_grid/transitions/grid_transition_animation_layout_providing.h"
 
 @protocol ApplicationCommands;
+@protocol IncognitoReauthCommands;
 @protocol GridConsumer;
 @protocol GridCommands;
 @protocol GridDragDropHandler;
@@ -37,6 +38,7 @@
                         ViewRevealingAnimatee>
 
 @property(nonatomic, weak) id<ApplicationCommands> handler;
+@property(nonatomic, weak) id<IncognitoReauthCommands> reauthHandler;
 
 // Delegate for this view controller to handle presenting tab UI.
 @property(nonatomic, weak) id<TabPresentationDelegate> tabPresentationDelegate;
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_grid/tab_grid_view_controller.mm b/ios/chrome/browser/ui/tab_switcher/tab_grid/tab_grid_view_controller.mm
index afb222c..855a9f4a 100644
--- a/ios/chrome/browser/ui/tab_switcher/tab_grid/tab_grid_view_controller.mm
+++ b/ios/chrome/browser/ui/tab_switcher/tab_grid/tab_grid_view_controller.mm
@@ -202,6 +202,11 @@
   [self setInsetForGridViews];
 }
 
+- (void)viewWillAppear:(BOOL)animated {
+  [super viewWillAppear:animated];
+  self.incognitoTabsViewController.handler = self.reauthHandler;
+}
+
 - (void)viewWillTransitionToSize:(CGSize)size
        withTransitionCoordinator:
            (id<UIViewControllerTransitionCoordinator>)coordinator {
diff --git a/ios/chrome/test/earl_grey/chrome_earl_grey_ui.h b/ios/chrome/test/earl_grey/chrome_earl_grey_ui.h
index 01affc4..bd811c7 100644
--- a/ios/chrome/test/earl_grey/chrome_earl_grey_ui.h
+++ b/ios/chrome/test/earl_grey/chrome_earl_grey_ui.h
@@ -107,6 +107,9 @@
 // Waits for the app to idle.
 - (void)waitForAppToIdle;
 
+// Opens pageInfo via the tools menu.
+- (void)openPageInfo;
+
 @end
 
 #endif  // IOS_CHROME_TEST_EARL_GREY_CHROME_EARL_GREY_UI_H_
diff --git a/ios/chrome/test/earl_grey/chrome_earl_grey_ui.mm b/ios/chrome/test/earl_grey/chrome_earl_grey_ui.mm
index 1bf68e4..1c6b9772 100644
--- a/ios/chrome/test/earl_grey/chrome_earl_grey_ui.mm
+++ b/ios/chrome/test/earl_grey/chrome_earl_grey_ui.mm
@@ -280,6 +280,17 @@
   GREYWaitForAppToIdle(@"App failed to idle");
 }
 
+- (void)openPageInfo {
+  [self openToolsMenu];
+  [[[EarlGrey
+      selectElementWithMatcher:grey_allOf(grey_accessibilityID(
+                                              kToolsMenuSiteInformation),
+                                          grey_sufficientlyVisible(), nil)]
+         usingSearchAction:grey_scrollInDirection(kGREYDirectionDown, 200)
+      onElementWithMatcher:grey_accessibilityID(kPopupMenuToolsMenuTableViewId)]
+      performAction:grey_tap()];
+}
+
 #pragma mark - Private
 
 // Clears all browsing data from the device. This method needs to be called when
diff --git a/ios/chrome/test/earl_grey2/BUILD.gn b/ios/chrome/test/earl_grey2/BUILD.gn
index 43c8196..91343c1 100644
--- a/ios/chrome/test/earl_grey2/BUILD.gn
+++ b/ios/chrome/test/earl_grey2/BUILD.gn
@@ -158,6 +158,7 @@
     "//ios/chrome/browser/ui/omnibox:eg2_tests",
     "//ios/chrome/browser/ui/omnibox/popup:eg2_tests",
     "//ios/chrome/browser/ui/open_in:eg2_tests",
+    "//ios/chrome/browser/ui/page_info:eg2_tests",
     "//ios/chrome/browser/ui/passwords:eg2_tests",
     "//ios/chrome/browser/ui/popup_menu:eg2_tests",
     "//ios/chrome/browser/ui/qr_scanner:eg2_tests",
diff --git a/net/BUILD.gn b/net/BUILD.gn
index 4f610c5..076568a 100644
--- a/net/BUILD.gn
+++ b/net/BUILD.gn
@@ -362,6 +362,7 @@
     "ssl/ssl_handshake_details.h",
     "ssl/ssl_info.cc",
     "ssl/ssl_info.h",
+    "ssl/ssl_key_logger.cc",
     "ssl/ssl_key_logger.h",
     "ssl/ssl_legacy_crypto_fallback.h",
     "ssl/ssl_private_key.cc",
diff --git a/net/cookies/canonical_cookie.cc b/net/cookies/canonical_cookie.cc
index 966723dd..52eb36d 100644
--- a/net/cookies/canonical_cookie.cc
+++ b/net/cookies/canonical_cookie.cc
@@ -50,6 +50,7 @@
 #include "base/feature_list.h"
 #include "base/format_macros.h"
 #include "base/logging.h"
+#include "base/memory/ptr_util.h"
 #include "base/metrics/histogram_functions.h"
 #include "base/metrics/histogram_macros.h"
 #include "base/strings/strcat.h"
@@ -438,7 +439,7 @@
   // Get the port, this will get a default value if a port isn't provided.
   int source_port = url.EffectiveIntPort();
 
-  std::unique_ptr<CanonicalCookie> cc(std::make_unique<CanonicalCookie>(
+  std::unique_ptr<CanonicalCookie> cc = base::WrapUnique(new CanonicalCookie(
       parsed_cookie.Name(), parsed_cookie.Value(), cookie_domain, cookie_path,
       creation_time, cookie_expires, creation_time, parsed_cookie.IsSecure(),
       parsed_cookie.IsHttpOnly(), samesite, parsed_cookie.Priority(),
@@ -519,7 +520,7 @@
   cookie_path = std::string(canon_path.data() + canon_path_component.begin,
                             canon_path_component.len);
 
-  std::unique_ptr<CanonicalCookie> cc(std::make_unique<CanonicalCookie>(
+  std::unique_ptr<CanonicalCookie> cc = base::WrapUnique(new CanonicalCookie(
       name, value, cookie_domain, cookie_path, creation_time, expiration_time,
       last_access_time, secure, http_only, same_site, priority, same_party,
       source_scheme, source_port));
@@ -544,7 +545,7 @@
     bool same_party,
     CookieSourceScheme source_scheme,
     int source_port) {
-  std::unique_ptr<CanonicalCookie> cc(std::make_unique<CanonicalCookie>(
+  std::unique_ptr<CanonicalCookie> cc = base::WrapUnique(new CanonicalCookie(
       name, value, domain, path, creation, expiration, last_access, secure,
       httponly, same_site, priority, same_party, source_scheme, source_port));
   if (!cc->IsCanonical())
@@ -553,7 +554,7 @@
 }
 
 // static
-CanonicalCookie CanonicalCookie::CreateUnsafeCookieForTesting(
+std::unique_ptr<CanonicalCookie> CanonicalCookie::CreateUnsafeCookieForTesting(
     const std::string& name,
     const std::string& value,
     const std::string& domain,
@@ -568,9 +569,9 @@
     bool same_party,
     CookieSourceScheme source_scheme,
     int source_port) {
-  return CanonicalCookie(name, value, domain, path, creation, expiration,
-                         last_access, secure, httponly, same_site, priority,
-                         same_party, source_scheme, source_port);
+  return base::WrapUnique(new CanonicalCookie(
+      name, value, domain, path, creation, expiration, last_access, secure,
+      httponly, same_site, priority, same_party, source_scheme, source_port));
 }
 
 std::string CanonicalCookie::DomainWithoutDot() const {
diff --git a/net/cookies/canonical_cookie.h b/net/cookies/canonical_cookie.h
index b58db9e..37655022 100644
--- a/net/cookies/canonical_cookie.h
+++ b/net/cookies/canonical_cookie.h
@@ -147,7 +147,7 @@
 
   // Create a CanonicalCookie that is not guaranteed to actually be Canonical
   // for tests. This factory should NOT be used in production.
-  static CanonicalCookie CreateUnsafeCookieForTesting(
+  static std::unique_ptr<CanonicalCookie> CreateUnsafeCookieForTesting(
       const std::string& name,
       const std::string& value,
       const std::string& domain,
diff --git a/net/cookies/canonical_cookie_unittest.cc b/net/cookies/canonical_cookie_unittest.cc
index a6308361..1ecf8ef 100644
--- a/net/cookies/canonical_cookie_unittest.cc
+++ b/net/cookies/canonical_cookie_unittest.cc
@@ -39,60 +39,60 @@
       "A", "2", "www.example.com", "/test", current_time, base::Time(),
       base::Time(), false, false, CookieSameSite::NO_RESTRICTION,
       COOKIE_PRIORITY_DEFAULT, false, CookieSourceScheme::kSecure, 443);
-  EXPECT_EQ("A", cookie1.Name());
-  EXPECT_EQ("2", cookie1.Value());
-  EXPECT_EQ("www.example.com", cookie1.Domain());
-  EXPECT_EQ("/test", cookie1.Path());
-  EXPECT_FALSE(cookie1.IsSecure());
-  EXPECT_FALSE(cookie1.IsHttpOnly());
-  EXPECT_EQ(CookieSameSite::NO_RESTRICTION, cookie1.SameSite());
-  EXPECT_EQ(CookiePriority::COOKIE_PRIORITY_DEFAULT, cookie1.Priority());
-  EXPECT_FALSE(cookie1.IsSameParty());
-  EXPECT_EQ(cookie1.SourceScheme(), CookieSourceScheme::kSecure);
-  EXPECT_EQ(cookie1.SourcePort(), 443);
+  EXPECT_EQ("A", cookie1->Name());
+  EXPECT_EQ("2", cookie1->Value());
+  EXPECT_EQ("www.example.com", cookie1->Domain());
+  EXPECT_EQ("/test", cookie1->Path());
+  EXPECT_FALSE(cookie1->IsSecure());
+  EXPECT_FALSE(cookie1->IsHttpOnly());
+  EXPECT_EQ(CookieSameSite::NO_RESTRICTION, cookie1->SameSite());
+  EXPECT_EQ(CookiePriority::COOKIE_PRIORITY_DEFAULT, cookie1->Priority());
+  EXPECT_FALSE(cookie1->IsSameParty());
+  EXPECT_EQ(cookie1->SourceScheme(), CookieSourceScheme::kSecure);
+  EXPECT_EQ(cookie1->SourcePort(), 443);
 
   auto cookie2 = CanonicalCookie::CreateUnsafeCookieForTesting(
       "A", "2", ".www.example.com", "/", current_time, base::Time(),
       base::Time(), false, false, CookieSameSite::NO_RESTRICTION,
       COOKIE_PRIORITY_DEFAULT, true, CookieSourceScheme::kNonSecure, 65536);
-  EXPECT_EQ("A", cookie2.Name());
-  EXPECT_EQ("2", cookie2.Value());
-  EXPECT_EQ(".www.example.com", cookie2.Domain());
-  EXPECT_EQ("/", cookie2.Path());
-  EXPECT_FALSE(cookie2.IsSecure());
-  EXPECT_FALSE(cookie2.IsHttpOnly());
-  EXPECT_EQ(CookieSameSite::NO_RESTRICTION, cookie2.SameSite());
-  EXPECT_EQ(CookiePriority::COOKIE_PRIORITY_DEFAULT, cookie2.Priority());
-  EXPECT_TRUE(cookie2.IsSameParty());
-  EXPECT_EQ(cookie2.SourceScheme(), CookieSourceScheme::kNonSecure);
+  EXPECT_EQ("A", cookie2->Name());
+  EXPECT_EQ("2", cookie2->Value());
+  EXPECT_EQ(".www.example.com", cookie2->Domain());
+  EXPECT_EQ("/", cookie2->Path());
+  EXPECT_FALSE(cookie2->IsSecure());
+  EXPECT_FALSE(cookie2->IsHttpOnly());
+  EXPECT_EQ(CookieSameSite::NO_RESTRICTION, cookie2->SameSite());
+  EXPECT_EQ(CookiePriority::COOKIE_PRIORITY_DEFAULT, cookie2->Priority());
+  EXPECT_TRUE(cookie2->IsSameParty());
+  EXPECT_EQ(cookie2->SourceScheme(), CookieSourceScheme::kNonSecure);
   // Because the port can be set explicitly in the constructor its value can be
   // independent of the other parameters. In this case, test that an invalid
   // port value is interpreted as such.
-  EXPECT_EQ(cookie2.SourcePort(), url::PORT_INVALID);
+  EXPECT_EQ(cookie2->SourcePort(), url::PORT_INVALID);
 
   // Set Secure to true but don't specify source_scheme or port.
   auto cookie3 = CanonicalCookie::CreateUnsafeCookieForTesting(
       "A", "2", ".www.example.com", "/", current_time, base::Time(),
       base::Time(), true /* secure */, false, CookieSameSite::NO_RESTRICTION,
       COOKIE_PRIORITY_DEFAULT, false);
-  EXPECT_TRUE(cookie3.IsSecure());
-  EXPECT_EQ(cookie3.SourceScheme(), CookieSourceScheme::kUnset);
-  EXPECT_EQ(cookie3.SourcePort(), url::PORT_UNSPECIFIED);
+  EXPECT_TRUE(cookie3->IsSecure());
+  EXPECT_EQ(cookie3->SourceScheme(), CookieSourceScheme::kUnset);
+  EXPECT_EQ(cookie3->SourcePort(), url::PORT_UNSPECIFIED);
 
   auto cookie4 = CanonicalCookie::CreateUnsafeCookieForTesting(
       "A", "2", ".www.example.com", "/test", current_time, base::Time(),
       base::Time(), false, false, CookieSameSite::NO_RESTRICTION,
       COOKIE_PRIORITY_DEFAULT, false);
-  EXPECT_EQ("A", cookie4.Name());
-  EXPECT_EQ("2", cookie4.Value());
-  EXPECT_EQ(".www.example.com", cookie4.Domain());
-  EXPECT_EQ("/test", cookie4.Path());
-  EXPECT_FALSE(cookie4.IsSecure());
-  EXPECT_FALSE(cookie4.IsHttpOnly());
-  EXPECT_EQ(CookieSameSite::NO_RESTRICTION, cookie4.SameSite());
-  EXPECT_FALSE(cookie4.IsSameParty());
-  EXPECT_EQ(cookie4.SourceScheme(), CookieSourceScheme::kUnset);
-  EXPECT_EQ(cookie4.SourcePort(), url::PORT_UNSPECIFIED);
+  EXPECT_EQ("A", cookie4->Name());
+  EXPECT_EQ("2", cookie4->Value());
+  EXPECT_EQ(".www.example.com", cookie4->Domain());
+  EXPECT_EQ("/test", cookie4->Path());
+  EXPECT_FALSE(cookie4->IsSecure());
+  EXPECT_FALSE(cookie4->IsHttpOnly());
+  EXPECT_EQ(CookieSameSite::NO_RESTRICTION, cookie4->SameSite());
+  EXPECT_FALSE(cookie4->IsSameParty());
+  EXPECT_EQ(cookie4->SourceScheme(), CookieSourceScheme::kUnset);
+  EXPECT_EQ(cookie4->SourcePort(), url::PORT_UNSPECIFIED);
 
   // Test some port edge cases: unspecified.
   auto cookie5 = CanonicalCookie::CreateUnsafeCookieForTesting(
@@ -100,7 +100,7 @@
       base::Time(), true /* secure */, false, CookieSameSite::NO_RESTRICTION,
       COOKIE_PRIORITY_DEFAULT, false, CookieSourceScheme::kUnset,
       url::PORT_UNSPECIFIED);
-  EXPECT_EQ(cookie5.SourcePort(), url::PORT_UNSPECIFIED);
+  EXPECT_EQ(cookie5->SourcePort(), url::PORT_UNSPECIFIED);
 
   // Test some port edge cases: invalid.
   auto cookie6 = CanonicalCookie::CreateUnsafeCookieForTesting(
@@ -108,7 +108,7 @@
       base::Time(), true /* secure */, false, CookieSameSite::NO_RESTRICTION,
       COOKIE_PRIORITY_DEFAULT, false, CookieSourceScheme::kUnset,
       url::PORT_INVALID);
-  EXPECT_EQ(cookie6.SourcePort(), url::PORT_INVALID);
+  EXPECT_EQ(cookie6->SourcePort(), url::PORT_INVALID);
 }
 
 TEST(CanonicalCookie, CreationCornerCases) {
@@ -420,16 +420,16 @@
       cookie_name, cookie_value, cookie_domain, cookie_path, creation_time,
       expiration_time, base::Time(), secure, httponly, same_site,
       COOKIE_PRIORITY_MEDIUM, same_party);
-  EXPECT_TRUE(cookie.IsEquivalent(cookie));
-  EXPECT_TRUE(cookie.IsEquivalentForSecureCookieMatching(cookie));
+  EXPECT_TRUE(cookie->IsEquivalent(*cookie));
+  EXPECT_TRUE(cookie->IsEquivalentForSecureCookieMatching(*cookie));
 
   // Test that two identical cookies are equivalent.
   auto other_cookie = CanonicalCookie::CreateUnsafeCookieForTesting(
       cookie_name, cookie_value, cookie_domain, cookie_path, creation_time,
       expiration_time, base::Time(), secure, httponly, same_site,
       COOKIE_PRIORITY_MEDIUM, same_party);
-  EXPECT_TRUE(cookie.IsEquivalent(other_cookie));
-  EXPECT_TRUE(other_cookie.IsEquivalentForSecureCookieMatching(cookie));
+  EXPECT_TRUE(cookie->IsEquivalent(*other_cookie));
+  EXPECT_TRUE(other_cookie->IsEquivalentForSecureCookieMatching(*cookie));
 
   // Tests that use different variations of attribute values that
   // DON'T affect cookie equivalence.
@@ -437,9 +437,9 @@
       cookie_name, "2", cookie_domain, cookie_path, creation_time,
       expiration_time, base::Time(), secure, httponly, same_site,
       COOKIE_PRIORITY_HIGH, same_party);
-  EXPECT_TRUE(cookie.IsEquivalent(other_cookie));
-  EXPECT_TRUE(cookie.IsEquivalentForSecureCookieMatching(other_cookie));
-  EXPECT_TRUE(other_cookie.IsEquivalentForSecureCookieMatching(cookie));
+  EXPECT_TRUE(cookie->IsEquivalent(*other_cookie));
+  EXPECT_TRUE(cookie->IsEquivalentForSecureCookieMatching(*other_cookie));
+  EXPECT_TRUE(other_cookie->IsEquivalentForSecureCookieMatching(*cookie));
 
   base::Time other_creation_time =
       creation_time + base::TimeDelta::FromMinutes(2);
@@ -447,42 +447,42 @@
       cookie_name, "2", cookie_domain, cookie_path, other_creation_time,
       expiration_time, base::Time(), secure, httponly, same_site,
       COOKIE_PRIORITY_MEDIUM, same_party);
-  EXPECT_TRUE(cookie.IsEquivalent(other_cookie));
-  EXPECT_TRUE(cookie.IsEquivalentForSecureCookieMatching(other_cookie));
-  EXPECT_TRUE(other_cookie.IsEquivalentForSecureCookieMatching(cookie));
+  EXPECT_TRUE(cookie->IsEquivalent(*other_cookie));
+  EXPECT_TRUE(cookie->IsEquivalentForSecureCookieMatching(*other_cookie));
+  EXPECT_TRUE(other_cookie->IsEquivalentForSecureCookieMatching(*cookie));
 
   other_cookie = CanonicalCookie::CreateUnsafeCookieForTesting(
       cookie_name, cookie_name, cookie_domain, cookie_path, creation_time,
       expiration_time, base::Time(), true, httponly, same_site,
       COOKIE_PRIORITY_LOW, same_party);
-  EXPECT_TRUE(cookie.IsEquivalent(other_cookie));
-  EXPECT_TRUE(cookie.IsEquivalentForSecureCookieMatching(other_cookie));
-  EXPECT_TRUE(other_cookie.IsEquivalentForSecureCookieMatching(cookie));
+  EXPECT_TRUE(cookie->IsEquivalent(*other_cookie));
+  EXPECT_TRUE(cookie->IsEquivalentForSecureCookieMatching(*other_cookie));
+  EXPECT_TRUE(other_cookie->IsEquivalentForSecureCookieMatching(*cookie));
 
   other_cookie = CanonicalCookie::CreateUnsafeCookieForTesting(
       cookie_name, cookie_name, cookie_domain, cookie_path, creation_time,
       expiration_time, base::Time(), secure, true, same_site,
       COOKIE_PRIORITY_LOW, same_party);
-  EXPECT_TRUE(cookie.IsEquivalent(other_cookie));
-  EXPECT_TRUE(cookie.IsEquivalentForSecureCookieMatching(other_cookie));
-  EXPECT_TRUE(other_cookie.IsEquivalentForSecureCookieMatching(cookie));
+  EXPECT_TRUE(cookie->IsEquivalent(*other_cookie));
+  EXPECT_TRUE(cookie->IsEquivalentForSecureCookieMatching(*other_cookie));
+  EXPECT_TRUE(other_cookie->IsEquivalentForSecureCookieMatching(*cookie));
 
   other_cookie = CanonicalCookie::CreateUnsafeCookieForTesting(
       cookie_name, cookie_name, cookie_domain, cookie_path, creation_time,
       expiration_time, base::Time(), secure, httponly,
       CookieSameSite::STRICT_MODE, COOKIE_PRIORITY_LOW, same_party);
-  EXPECT_TRUE(cookie.IsEquivalent(other_cookie));
-  EXPECT_TRUE(cookie.IsEquivalentForSecureCookieMatching(other_cookie));
-  EXPECT_TRUE(other_cookie.IsEquivalentForSecureCookieMatching(cookie));
+  EXPECT_TRUE(cookie->IsEquivalent(*other_cookie));
+  EXPECT_TRUE(cookie->IsEquivalentForSecureCookieMatching(*other_cookie));
+  EXPECT_TRUE(other_cookie->IsEquivalentForSecureCookieMatching(*cookie));
 
   // Cookies whose names mismatch are not equivalent.
   other_cookie = CanonicalCookie::CreateUnsafeCookieForTesting(
       "B", cookie_value, cookie_domain, cookie_path, creation_time,
       expiration_time, base::Time(), secure, httponly, same_site,
       COOKIE_PRIORITY_MEDIUM, same_party);
-  EXPECT_FALSE(cookie.IsEquivalent(other_cookie));
-  EXPECT_FALSE(cookie.IsEquivalentForSecureCookieMatching(other_cookie));
-  EXPECT_FALSE(other_cookie.IsEquivalentForSecureCookieMatching(cookie));
+  EXPECT_FALSE(cookie->IsEquivalent(*other_cookie));
+  EXPECT_FALSE(cookie->IsEquivalentForSecureCookieMatching(*other_cookie));
+  EXPECT_FALSE(other_cookie->IsEquivalentForSecureCookieMatching(*cookie));
 
   // A domain cookie at 'www.example.com' is not equivalent to a host cookie
   // at the same domain. These are, however, equivalent according to the laxer
@@ -491,11 +491,11 @@
       cookie_name, cookie_value, "www.example.com", cookie_path, creation_time,
       expiration_time, base::Time(), secure, httponly, same_site,
       COOKIE_PRIORITY_MEDIUM, same_party);
-  EXPECT_TRUE(cookie.IsDomainCookie());
-  EXPECT_FALSE(other_cookie.IsDomainCookie());
-  EXPECT_FALSE(cookie.IsEquivalent(other_cookie));
-  EXPECT_TRUE(cookie.IsEquivalentForSecureCookieMatching(other_cookie));
-  EXPECT_TRUE(other_cookie.IsEquivalentForSecureCookieMatching(cookie));
+  EXPECT_TRUE(cookie->IsDomainCookie());
+  EXPECT_FALSE(other_cookie->IsDomainCookie());
+  EXPECT_FALSE(cookie->IsEquivalent(*other_cookie));
+  EXPECT_TRUE(cookie->IsEquivalentForSecureCookieMatching(*other_cookie));
+  EXPECT_TRUE(other_cookie->IsEquivalentForSecureCookieMatching(*cookie));
 
   // Likewise, a cookie on 'example.com' is not equivalent to a cookie on
   // 'www.example.com', but they are equivalent for secure cookie matching.
@@ -503,9 +503,9 @@
       cookie_name, cookie_value, ".example.com", cookie_path, creation_time,
       expiration_time, base::Time(), secure, httponly, same_site,
       COOKIE_PRIORITY_MEDIUM, same_party);
-  EXPECT_FALSE(cookie.IsEquivalent(other_cookie));
-  EXPECT_TRUE(cookie.IsEquivalentForSecureCookieMatching(other_cookie));
-  EXPECT_TRUE(other_cookie.IsEquivalentForSecureCookieMatching(cookie));
+  EXPECT_FALSE(cookie->IsEquivalent(*other_cookie));
+  EXPECT_TRUE(cookie->IsEquivalentForSecureCookieMatching(*other_cookie));
+  EXPECT_TRUE(other_cookie->IsEquivalentForSecureCookieMatching(*cookie));
 
   // Paths are a bit more complicated. 'IsEquivalent' requires an exact path
   // match, while secure cookie matching uses a more relaxed 'IsOnPath' check.
@@ -516,26 +516,26 @@
       cookie_name, cookie_value, cookie_domain, "/test", creation_time,
       expiration_time, base::Time(), secure, httponly, same_site,
       COOKIE_PRIORITY_MEDIUM, same_party);
-  EXPECT_FALSE(cookie.IsEquivalent(other_cookie));
-  EXPECT_FALSE(cookie.IsEquivalentForSecureCookieMatching(other_cookie));
-  EXPECT_FALSE(other_cookie.IsEquivalentForSecureCookieMatching(cookie));
+  EXPECT_FALSE(cookie->IsEquivalent(*other_cookie));
+  EXPECT_FALSE(cookie->IsEquivalentForSecureCookieMatching(*other_cookie));
+  EXPECT_FALSE(other_cookie->IsEquivalentForSecureCookieMatching(*cookie));
 
   other_cookie = CanonicalCookie::CreateUnsafeCookieForTesting(
       cookie_name, cookie_value, cookie_domain, cookie_path + "/subpath",
       creation_time, expiration_time, base::Time(), secure, httponly, same_site,
       COOKIE_PRIORITY_MEDIUM, same_party);
-  EXPECT_FALSE(cookie.IsEquivalent(other_cookie));
+  EXPECT_FALSE(cookie->IsEquivalent(*other_cookie));
   // The path comparison is asymmetric
-  EXPECT_FALSE(cookie.IsEquivalentForSecureCookieMatching(other_cookie));
-  EXPECT_TRUE(other_cookie.IsEquivalentForSecureCookieMatching(cookie));
+  EXPECT_FALSE(cookie->IsEquivalentForSecureCookieMatching(*other_cookie));
+  EXPECT_TRUE(other_cookie->IsEquivalentForSecureCookieMatching(*cookie));
 
   other_cookie = CanonicalCookie::CreateUnsafeCookieForTesting(
       cookie_name, cookie_value, cookie_domain, "/", creation_time,
       expiration_time, base::Time(), secure, httponly, same_site,
       COOKIE_PRIORITY_MEDIUM, same_party);
-  EXPECT_FALSE(cookie.IsEquivalent(other_cookie));
-  EXPECT_TRUE(cookie.IsEquivalentForSecureCookieMatching(other_cookie));
-  EXPECT_FALSE(other_cookie.IsEquivalentForSecureCookieMatching(cookie));
+  EXPECT_FALSE(cookie->IsEquivalent(*other_cookie));
+  EXPECT_TRUE(cookie->IsEquivalentForSecureCookieMatching(*other_cookie));
+  EXPECT_FALSE(other_cookie->IsEquivalentForSecureCookieMatching(*cookie));
 }
 
 TEST(CanonicalCookieTest, IsEquivalentForSecureCookieMatching) {
@@ -582,9 +582,9 @@
         COOKIE_PRIORITY_MEDIUM, false);
 
     EXPECT_EQ(test.equivalent,
-              cookie.IsEquivalentForSecureCookieMatching(secure_cookie));
+              cookie->IsEquivalentForSecureCookieMatching(*secure_cookie));
     EXPECT_EQ(test.equivalent == test.is_symmetric,
-              secure_cookie.IsEquivalentForSecureCookieMatching(cookie));
+              secure_cookie->IsEquivalentForSecureCookieMatching(*cookie));
   }
 }
 
@@ -1433,13 +1433,13 @@
   // Test IncludeForRequestURL()
   // Note: This is a cookie that should never exist normally, because Create()
   // would weed it out.
-  CanonicalCookie cookie1 = CanonicalCookie::CreateUnsafeCookieForTesting(
+  auto cookie1 = CanonicalCookie::CreateUnsafeCookieForTesting(
       "name", "value", "other-domain.com", "/bar", creation_time, base::Time(),
       base::Time(), true /* secure */, true /* httponly */,
       CookieSameSite::STRICT_MODE, COOKIE_PRIORITY_DEFAULT, false);
   EXPECT_TRUE(
       cookie1
-          .IncludeForRequestURL(
+          ->IncludeForRequestURL(
               url, options,
               CookieAccessParams{CookieAccessSemantics::UNKNOWN,
                                  /*delegate_treats_url_as_trustworthy=*/false})
@@ -1636,42 +1636,42 @@
                   "A", "B", "x.y", "/path", base::Time(), base::Time(),
                   base::Time(), false, false, CookieSameSite::NO_RESTRICTION,
                   COOKIE_PRIORITY_LOW, false)
-                  .IsCanonical());
+                  ->IsCanonical());
 
   // Newline in name.
   EXPECT_FALSE(CanonicalCookie::CreateUnsafeCookieForTesting(
                    "A\n", "B", "x.y", "/path", base::Time(), base::Time(),
                    base::Time(), false, false, CookieSameSite::NO_RESTRICTION,
                    COOKIE_PRIORITY_LOW, false)
-                   .IsCanonical());
+                   ->IsCanonical());
 
   // Carriage return in name.
   EXPECT_FALSE(CanonicalCookie::CreateUnsafeCookieForTesting(
                    "A\r", "B", "x.y", "/path", base::Time(), base::Time(),
                    base::Time(), false, false, CookieSameSite::NO_RESTRICTION,
                    COOKIE_PRIORITY_LOW, false)
-                   .IsCanonical());
+                   ->IsCanonical());
 
   // Null character in name.
   EXPECT_FALSE(CanonicalCookie::CreateUnsafeCookieForTesting(
                    std::string("A\0Z", 3), "B", "x.y", "/path", base::Time(),
                    base::Time(), base::Time(), false, false,
                    CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_LOW, false)
-                   .IsCanonical());
+                   ->IsCanonical());
 
   // Name begins with whitespace.
   EXPECT_FALSE(CanonicalCookie::CreateUnsafeCookieForTesting(
                    " A", "B", "x.y", "/path", base::Time(), base::Time(),
                    base::Time(), false, false, CookieSameSite::NO_RESTRICTION,
                    COOKIE_PRIORITY_LOW, false)
-                   .IsCanonical());
+                   ->IsCanonical());
 
   // Name ends with whitespace.
   EXPECT_FALSE(CanonicalCookie::CreateUnsafeCookieForTesting(
                    "A ", "B", "x.y", "/path", base::Time(), base::Time(),
                    base::Time(), false, false, CookieSameSite::NO_RESTRICTION,
                    COOKIE_PRIORITY_LOW, false)
-                   .IsCanonical());
+                   ->IsCanonical());
 
   // Empty name.  (Note this is against the spec but compatible with other
   // browsers.)
@@ -1679,70 +1679,70 @@
                   "", "B", "x.y", "/path", base::Time(), base::Time(),
                   base::Time(), false, false, CookieSameSite::NO_RESTRICTION,
                   COOKIE_PRIORITY_LOW, false)
-                  .IsCanonical());
+                  ->IsCanonical());
 
   // Space in name
   EXPECT_TRUE(CanonicalCookie::CreateUnsafeCookieForTesting(
                   "A C", "B", "x.y", "/path", base::Time(), base::Time(),
                   base::Time(), false, false, CookieSameSite::NO_RESTRICTION,
                   COOKIE_PRIORITY_LOW, false)
-                  .IsCanonical());
+                  ->IsCanonical());
 
   // Extra space suffixing name.
   EXPECT_FALSE(CanonicalCookie::CreateUnsafeCookieForTesting(
                    "A ", "B", "x.y", "/path", base::Time(), base::Time(),
                    base::Time(), false, false, CookieSameSite::NO_RESTRICTION,
                    COOKIE_PRIORITY_LOW, false)
-                   .IsCanonical());
+                   ->IsCanonical());
 
   // '=' character in name.
   EXPECT_FALSE(CanonicalCookie::CreateUnsafeCookieForTesting(
                    "A=", "B", "x.y", "/path", base::Time(), base::Time(),
                    base::Time(), false, false, CookieSameSite::NO_RESTRICTION,
                    COOKIE_PRIORITY_LOW, false)
-                   .IsCanonical());
+                   ->IsCanonical());
 
   // Separator in name.
   EXPECT_FALSE(CanonicalCookie::CreateUnsafeCookieForTesting(
                    "A;", "B", "x.y", "/path", base::Time(), base::Time(),
                    base::Time(), false, false, CookieSameSite::NO_RESTRICTION,
                    COOKIE_PRIORITY_LOW, false)
-                   .IsCanonical());
+                   ->IsCanonical());
 
   // '=' character in value.
   EXPECT_TRUE(CanonicalCookie::CreateUnsafeCookieForTesting(
                   "A", "B=", "x.y", "/path", base::Time(), base::Time(),
                   base::Time(), false, false, CookieSameSite::NO_RESTRICTION,
                   COOKIE_PRIORITY_LOW, false)
-                  .IsCanonical());
+                  ->IsCanonical());
 
   // Separator in value.
   EXPECT_FALSE(CanonicalCookie::CreateUnsafeCookieForTesting(
                    "A", "B;", "x.y", "/path", base::Time(), base::Time(),
                    base::Time(), false, false, CookieSameSite::NO_RESTRICTION,
                    COOKIE_PRIORITY_LOW, false)
-                   .IsCanonical());
+                   ->IsCanonical());
 
   // Separator in domain.
   EXPECT_FALSE(CanonicalCookie::CreateUnsafeCookieForTesting(
                    "A", "B", ";x.y", "/path", base::Time(), base::Time(),
                    base::Time(), false, false, CookieSameSite::NO_RESTRICTION,
                    COOKIE_PRIORITY_LOW, false)
-                   .IsCanonical());
+                   ->IsCanonical());
 
   // Garbage in domain.
   EXPECT_FALSE(CanonicalCookie::CreateUnsafeCookieForTesting(
                    "A", "B", "@:&", "/path", base::Time(), base::Time(),
                    base::Time(), false, false, CookieSameSite::NO_RESTRICTION,
                    COOKIE_PRIORITY_LOW, false)
-                   .IsCanonical());
+                   ->IsCanonical());
 
   // Space in domain.
   EXPECT_FALSE(CanonicalCookie::CreateUnsafeCookieForTesting(
                    "A", "B", "x.y ", "/path", base::Time(), base::Time(),
                    base::Time(), false, false, CookieSameSite::NO_RESTRICTION,
                    COOKIE_PRIORITY_LOW, false)
-                   .IsCanonical());
+                   ->IsCanonical());
 
   // Empty domain.  (This is against cookie spec, but needed for Chrome's
   // out-of-spec use of cookies for extensions; see http://crbug.com/730633.
@@ -1750,49 +1750,49 @@
                   "A", "B", "", "/path", base::Time(), base::Time(),
                   base::Time(), false, false, CookieSameSite::NO_RESTRICTION,
                   COOKIE_PRIORITY_LOW, false)
-                  .IsCanonical());
+                  ->IsCanonical());
 
   // Path does not start with a "/".
   EXPECT_FALSE(CanonicalCookie::CreateUnsafeCookieForTesting(
                    "A", "B", "x.y", "path", base::Time(), base::Time(),
                    base::Time(), false, false, CookieSameSite::NO_RESTRICTION,
                    COOKIE_PRIORITY_LOW, false)
-                   .IsCanonical());
+                   ->IsCanonical());
 
   // Empty path.
   EXPECT_FALSE(CanonicalCookie::CreateUnsafeCookieForTesting(
                    "A", "B", "x.y", "", base::Time(), base::Time(),
                    base::Time(), false, false, CookieSameSite::NO_RESTRICTION,
                    COOKIE_PRIORITY_LOW, false)
-                   .IsCanonical());
+                   ->IsCanonical());
 
   // Simple IPv4 address as domain.
   EXPECT_TRUE(CanonicalCookie::CreateUnsafeCookieForTesting(
                   "A", "B", "1.2.3.4", "/path", base::Time(), base::Time(),
                   base::Time(), false, false, CookieSameSite::NO_RESTRICTION,
                   COOKIE_PRIORITY_LOW, false)
-                  .IsCanonical());
+                  ->IsCanonical());
 
   // NOn-canonical IPv4 address as domain.
   EXPECT_FALSE(CanonicalCookie::CreateUnsafeCookieForTesting(
                    "A", "B", "01.2.03.4", "/path", base::Time(), base::Time(),
                    base::Time(), false, false, CookieSameSite::NO_RESTRICTION,
                    COOKIE_PRIORITY_LOW, false)
-                   .IsCanonical());
+                   ->IsCanonical());
 
   // Null IPv6 address as domain.
   EXPECT_TRUE(CanonicalCookie::CreateUnsafeCookieForTesting(
                   "A", "B", "[::]", "/path", base::Time(), base::Time(),
                   base::Time(), false, false, CookieSameSite::NO_RESTRICTION,
                   COOKIE_PRIORITY_LOW, false)
-                  .IsCanonical());
+                  ->IsCanonical());
 
   // Localhost IPv6 address as domain.
   EXPECT_TRUE(CanonicalCookie::CreateUnsafeCookieForTesting(
                   "A", "B", "[::1]", "/path", base::Time(), base::Time(),
                   base::Time(), false, false, CookieSameSite::NO_RESTRICTION,
                   COOKIE_PRIORITY_LOW, false)
-                  .IsCanonical());
+                  ->IsCanonical());
 
   // Fully speced IPv6 address as domain.
   EXPECT_FALSE(CanonicalCookie::CreateUnsafeCookieForTesting(
@@ -1800,7 +1800,7 @@
                    "/path", base::Time(), base::Time(), base::Time(), false,
                    false, CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_LOW,
                    false)
-                   .IsCanonical());
+                   ->IsCanonical());
 
   // Zero abbreviated IPv6 address as domain.  Not canonical because of leading
   // zeros & uppercase hex letters.
@@ -1808,7 +1808,7 @@
                    "A", "B", "[2001:0DB8:AC10:FE01::]", "/path", base::Time(),
                    base::Time(), base::Time(), false, false,
                    CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_LOW, false)
-                   .IsCanonical());
+                   ->IsCanonical());
 
   // Zero prefixes removed IPv6 address as domain.  Not canoncial because of
   // uppercase hex letters.
@@ -1816,94 +1816,94 @@
                    "A", "B", "[2001:DB8:AC10:FE01::]", "/path", base::Time(),
                    base::Time(), base::Time(), false, false,
                    CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_LOW, false)
-                   .IsCanonical());
+                   ->IsCanonical());
 
   // Lowercased hex IPv6 address as domain.
   EXPECT_TRUE(CanonicalCookie::CreateUnsafeCookieForTesting(
                   "A", "B", "[2001:db8:ac10:fe01::]", "/path", base::Time(),
                   base::Time(), base::Time(), false, false,
                   CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_LOW, false)
-                  .IsCanonical());
+                  ->IsCanonical());
 
   // Properly formatted host cookie.
   EXPECT_TRUE(CanonicalCookie::CreateUnsafeCookieForTesting(
                   "__Host-A", "B", "x.y", "/", base::Time(), base::Time(),
                   base::Time(), true, false, CookieSameSite::NO_RESTRICTION,
                   COOKIE_PRIORITY_LOW, false)
-                  .IsCanonical());
+                  ->IsCanonical());
 
   // Insecure host cookie.
   EXPECT_FALSE(CanonicalCookie::CreateUnsafeCookieForTesting(
                    "__Host-A", "B", "x.y", "/", base::Time(), base::Time(),
                    base::Time(), false, false, CookieSameSite::NO_RESTRICTION,
                    COOKIE_PRIORITY_LOW, false)
-                   .IsCanonical());
+                   ->IsCanonical());
 
   // Host cookie with non-null path.
   EXPECT_FALSE(CanonicalCookie::CreateUnsafeCookieForTesting(
                    "__Host-A", "B", "x.y", "/path", base::Time(), base::Time(),
                    base::Time(), true, false, CookieSameSite::NO_RESTRICTION,
                    COOKIE_PRIORITY_LOW, false)
-                   .IsCanonical());
+                   ->IsCanonical());
 
   // Host cookie with empty domain.
   EXPECT_FALSE(CanonicalCookie::CreateUnsafeCookieForTesting(
                    "__Host-A", "B", "", "/", base::Time(), base::Time(),
                    base::Time(), true, false, CookieSameSite::NO_RESTRICTION,
                    COOKIE_PRIORITY_LOW, false)
-                   .IsCanonical());
+                   ->IsCanonical());
 
   // Host cookie with period prefixed domain.
   EXPECT_FALSE(CanonicalCookie::CreateUnsafeCookieForTesting(
                    "__Host-A", "B", ".x.y", "/", base::Time(), base::Time(),
                    base::Time(), true, false, CookieSameSite::NO_RESTRICTION,
                    COOKIE_PRIORITY_LOW, false)
-                   .IsCanonical());
+                   ->IsCanonical());
 
   // Properly formatted secure cookie.
   EXPECT_TRUE(CanonicalCookie::CreateUnsafeCookieForTesting(
                   "__Secure-A", "B", "x.y", "/", base::Time(), base::Time(),
                   base::Time(), true, false, CookieSameSite::NO_RESTRICTION,
                   COOKIE_PRIORITY_LOW, false)
-                  .IsCanonical());
+                  ->IsCanonical());
 
   // Insecure secure cookie.
   EXPECT_FALSE(CanonicalCookie::CreateUnsafeCookieForTesting(
                    "__Secure-A", "B", "x.y", "/", base::Time(), base::Time(),
                    base::Time(), false, false, CookieSameSite::NO_RESTRICTION,
                    COOKIE_PRIORITY_LOW, false)
-                   .IsCanonical());
+                   ->IsCanonical());
 
   // SameParty attribute used correctly (with Secure and non-Strict SameSite).
   EXPECT_TRUE(CanonicalCookie::CreateUnsafeCookieForTesting(
                   "A", "B", "x.y", "/", base::Time(), base::Time(),
                   base::Time(), true, false, CookieSameSite::NO_RESTRICTION,
                   COOKIE_PRIORITY_LOW, true)
-                  .IsCanonical());
+                  ->IsCanonical());
   EXPECT_TRUE(CanonicalCookie::CreateUnsafeCookieForTesting(
                   "A", "B", "x.y", "/", base::Time(), base::Time(),
                   base::Time(), true, false, CookieSameSite::UNSPECIFIED,
                   COOKIE_PRIORITY_LOW, true)
-                  .IsCanonical());
+                  ->IsCanonical());
   EXPECT_TRUE(CanonicalCookie::CreateUnsafeCookieForTesting(
                   "A", "B", "x.y", "/", base::Time(), base::Time(),
                   base::Time(), true, false, CookieSameSite::LAX_MODE,
                   COOKIE_PRIORITY_LOW, true)
-                  .IsCanonical());
+                  ->IsCanonical());
 
   // SameParty without Secure is not canonical.
   EXPECT_FALSE(CanonicalCookie::CreateUnsafeCookieForTesting(
                    "A", "B", "x.y", "/", base::Time(), base::Time(),
                    base::Time(), false, false, CookieSameSite::LAX_MODE,
                    COOKIE_PRIORITY_LOW, true)
-                   .IsCanonical());
+                   ->IsCanonical());
 
   // SameParty with SameSite=Strict is not canonical.
   EXPECT_FALSE(CanonicalCookie::CreateUnsafeCookieForTesting(
                    "A", "B", "x.y", "/", base::Time(), base::Time(),
                    base::Time(), true, false, CookieSameSite::STRICT_MODE,
                    COOKIE_PRIORITY_LOW, true)
-                   .IsCanonical());
+                   ->IsCanonical());
 }
 
 TEST(CanonicalCookieTest, TestSetCreationDate) {
diff --git a/net/quic/quic_stream_factory.cc b/net/quic/quic_stream_factory.cc
index 78f8a826..01d5f6a 100644
--- a/net/quic/quic_stream_factory.cc
+++ b/net/quic/quic_stream_factory.cc
@@ -55,6 +55,7 @@
 #include "net/socket/socket_performance_watcher.h"
 #include "net/socket/socket_performance_watcher_factory.h"
 #include "net/socket/udp_client_socket.h"
+#include "net/ssl/ssl_key_logger.h"
 #include "net/third_party/quiche/src/quic/core/crypto/null_decrypter.h"
 #include "net/third_party/quiche/src/quic/core/crypto/proof_verifier.h"
 #include "net/third_party/quiche/src/quic/core/crypto/quic_random.h"
@@ -2152,6 +2153,10 @@
   crypto_config->AddCanonicalSuffix(".googlevideo.com");
   crypto_config->AddCanonicalSuffix(".googleusercontent.com");
   crypto_config->AddCanonicalSuffix(".gvt1.com");
+  if (SSLKeyLoggerManager::IsActive()) {
+    SSL_CTX_set_keylog_callback(crypto_config->ssl_ctx(),
+                                SSLKeyLoggerManager::KeyLogCallback);
+  }
 
   if (!prefer_aes_gcm_recorded_) {
     bool prefer_aes_gcm =
diff --git a/net/socket/ssl_client_socket_impl.cc b/net/socket/ssl_client_socket_impl.cc
index bd39afc..b0dd91d 100644
--- a/net/socket/ssl_client_socket_impl.cc
+++ b/net/socket/ssl_client_socket_impl.cc
@@ -287,9 +287,9 @@
   }
 
   void SetSSLKeyLogger(std::unique_ptr<SSLKeyLogger> logger) {
-    DCHECK(!ssl_key_logger_);
-    ssl_key_logger_ = std::move(logger);
-    SSL_CTX_set_keylog_callback(ssl_ctx_.get(), KeyLogCallback);
+    net::SSLKeyLoggerManager::SetSSLKeyLogger(std::move(logger));
+    SSL_CTX_set_keylog_callback(ssl_ctx_.get(),
+                                SSLKeyLoggerManager::KeyLogCallback);
   }
 
   static const SSL_PRIVATE_KEY_METHOD kPrivateKeyMethod;
@@ -367,10 +367,6 @@
     return socket->PrivateKeyCompleteCallback(out, out_len, max_out);
   }
 
-  static void KeyLogCallback(const SSL* ssl, const char* line) {
-    GetInstance()->ssl_key_logger_->WriteLine(line);
-  }
-
   static void MessageCallback(int is_write,
                               int version,
                               int content_type,
@@ -387,8 +383,6 @@
   int ssl_socket_data_index_;
 
   bssl::UniquePtr<SSL_CTX> ssl_ctx_;
-
-  std::unique_ptr<SSLKeyLogger> ssl_key_logger_;
 };
 
 const SSL_PRIVATE_KEY_METHOD
diff --git a/net/ssl/ssl_key_logger.cc b/net/ssl/ssl_key_logger.cc
new file mode 100644
index 0000000..ef16e81
--- /dev/null
+++ b/net/ssl/ssl_key_logger.cc
@@ -0,0 +1,37 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "net/ssl/ssl_key_logger.h"
+
+#include "base/check.h"
+
+namespace net {
+
+// static
+bool SSLKeyLoggerManager::IsActive() {
+  return Get()->ssl_key_logger_ != nullptr;
+}
+
+// static
+void SSLKeyLoggerManager::SetSSLKeyLogger(
+    std::unique_ptr<SSLKeyLogger> logger) {
+  DCHECK(!IsActive());
+  Get()->ssl_key_logger_ = std::move(logger);
+}
+
+// static
+void SSLKeyLoggerManager::KeyLogCallback(const SSL* /*ssl*/, const char* line) {
+  DCHECK(IsActive());
+  Get()->ssl_key_logger_->WriteLine(line);
+}
+
+SSLKeyLoggerManager::SSLKeyLoggerManager() = default;
+
+// static
+SSLKeyLoggerManager* SSLKeyLoggerManager::Get() {
+  static base::NoDestructor<SSLKeyLoggerManager> owner;
+  return owner.get();
+}
+
+}  // namespace net
diff --git a/net/ssl/ssl_key_logger.h b/net/ssl/ssl_key_logger.h
index b985cf4..07903d12 100644
--- a/net/ssl/ssl_key_logger.h
+++ b/net/ssl/ssl_key_logger.h
@@ -5,9 +5,12 @@
 #ifndef NET_SSL_SSL_KEY_LOGGER_H_
 #define NET_SSL_SSL_KEY_LOGGER_H_
 
+#include <memory>
 #include <string>
 
+#include "base/no_destructor.h"
 #include "net/base/net_export.h"
+#include "third_party/boringssl/src/include/openssl/ssl.h"
 
 namespace net {
 
@@ -25,6 +28,37 @@
   virtual void WriteLine(const std::string& line) = 0;
 };
 
+// SSLKeyLoggerManager owns a single global instance of SSLKeyLogger, allowing
+// it to safely be registered on multiple SSL_CTX instances.
+class NET_EXPORT SSLKeyLoggerManager {
+ public:
+  ~SSLKeyLoggerManager() = delete;
+  SSLKeyLoggerManager(const SSLKeyLoggerManager&) = delete;
+  SSLKeyLoggerManager& operator=(const SSLKeyLoggerManager&) = delete;
+
+  // Returns true if an SSLKeyLogger has been set.
+  static bool IsActive();
+
+  // Set the SSLKeyLogger to use.
+  static void SetSSLKeyLogger(std::unique_ptr<SSLKeyLogger> logger);
+
+  // Logs |line| to the |logger| that was registered with SetSSLKeyLogger.
+  // This function will crash if a logger has not been registered.
+  // The function signature allows it to be registered with
+  // SSL_CTX_set_keylog_callback, the |ssl| parameter is unused.
+  static void KeyLogCallback(const SSL* /*ssl*/, const char* line);
+
+ private:
+  friend base::NoDestructor<SSLKeyLoggerManager>;
+
+  SSLKeyLoggerManager();
+
+  // Get the global SSLKeyLoggerManager instance.
+  static SSLKeyLoggerManager* Get();
+
+  std::unique_ptr<SSLKeyLogger> ssl_key_logger_;
+};
+
 }  // namespace net
 
 #endif  // NET_SSL_SSL_KEY_LOGGER_H_
diff --git a/services/tracing/public/cpp/perfetto/trace_event_data_source.cc b/services/tracing/public/cpp/perfetto/trace_event_data_source.cc
index e4553b6..86cc9ca4 100644
--- a/services/tracing/public/cpp/perfetto/trace_event_data_source.cc
+++ b/services/tracing/public/cpp/perfetto/trace_event_data_source.cc
@@ -1235,7 +1235,29 @@
   // mojo message which can result in additional trace events).
   AutoThreadLocalBoolean thread_is_in_trace_event(GetThreadIsInTraceEventTLS());
 
-  AutoLockWithDeferredTaskPosting lock(lock_);
+  // It's safe to use this writer outside the lock because EmitTrackDescriptor()
+  // is either called (a) when startup tracing is set up (from the main thread)
+  // or (b) on the perfetto sequence. (a) is safe because the writer will not be
+  // destroyed before startup tracing set up is complete. (b) is safe because
+  // the writer is only destroyed on the perfetto sequence in this case.
+  perfetto::TraceWriter* writer;
+  bool privacy_filtering_enabled;
+#if defined(OS_ANDROID)
+  bool is_system_producer;
+#endif  // defined(OS_ANDROID)
+  {
+    AutoLockWithDeferredTaskPosting lock(lock_);
+    writer = trace_writer_.get();
+    privacy_filtering_enabled = privacy_filtering_enabled_;
+#if defined(OS_ANDROID)
+    is_system_producer =
+        producer_ == PerfettoTracedProcess::Get()->system_producer();
+#endif  // defined(OS_ANDROID)
+  }
+
+  if (!writer) {
+    return;
+  }
 
   int process_id = TraceLog::GetInstance()->process_id();
   if (process_id == base::kNullProcessId) {
@@ -1243,13 +1265,9 @@
     return;
   }
 
-  if (!trace_writer_) {
-    return;
-  }
-
   std::string process_name = TraceLog::GetInstance()->process_name();
 
-  TracePacketHandle trace_packet = trace_writer_->NewTracePacket();
+  TracePacketHandle trace_packet = writer->NewTracePacket();
 
   trace_packet->set_sequence_flags(
       perfetto::protos::pbzero::TracePacket::SEQ_INCREMENTAL_STATE_CLEARED);
@@ -1268,7 +1286,7 @@
 
   ProcessDescriptor* process = track_descriptor->set_process();
   process->set_pid(process_id);
-  if (!privacy_filtering_enabled_ && !process_name.empty()) {
+  if (!privacy_filtering_enabled && !process_name.empty()) {
     process->set_process_name(process_name);
   }
 
@@ -1282,8 +1300,7 @@
 #if defined(OS_ANDROID)
   // Host app package name is only recorded if privacy filtering is disabled or
   // this is a system trace.
-  if (!privacy_filtering_enabled_ ||
-      producer_ == PerfettoTracedProcess::Get()->system_producer()) {
+  if (!privacy_filtering_enabled || is_system_producer) {
     // Host app package name is used to group information from different
     // processes that "belong" to the same WebView app.
     // TODO(b/161983088): only write this for WebView since this information is
@@ -1299,7 +1316,7 @@
   // TODO(eseckler): Set other fields on |chrome_process|.
 
   trace_packet = TracePacketHandle();
-  trace_writer_->Flush();
+  writer->Flush();
 }
 
 bool TraceEventDataSource::IsPrivacyFilteringEnabled() {
diff --git a/skia/config/SkUserConfig.h b/skia/config/SkUserConfig.h
index 27e4668..e8b977e 100644
--- a/skia/config/SkUserConfig.h
+++ b/skia/config/SkUserConfig.h
@@ -204,6 +204,10 @@
 #   define SK_SUPPORT_LEGACY_ANISOTROPIC_MIPMAP_SCALE
 #endif
 
+#ifndef SK_SUPPORT_LEGACY_CANVASMATRIX33
+#define SK_SUPPORT_LEGACY_CANVASMATRIX33
+#endif
+
 #ifndef SK_DISABLE_LEGACY_CONTEXT_FACTORIES
 #define SK_DISABLE_LEGACY_CONTEXT_FACTORIES
 #endif
diff --git a/skia/ext/skia_utils_ios.h b/skia/ext/skia_utils_ios.h
index 0f2c6134..f072721 100644
--- a/skia/ext/skia_utils_ios.h
+++ b/skia/ext/skia_utils_ios.h
@@ -38,6 +38,14 @@
 // vector if none can be decoded.
 SK_API std::vector<SkBitmap> ImageDataToSkBitmaps(NSData* image_data);
 
+// Decodes all image representations inside the data into a vector of SkBitmaps.
+// If a representation is bigger than max_size (either width or height), it is
+// ignored.
+// Returns a vector of all the successfully decoded representations or an empty
+// vector if none can be decoded.
+SK_API std::vector<SkBitmap> ImageDataToSkBitmapsWithMaxSize(NSData* image_data,
+                                                             CGFloat max_size);
+
 // Returns a UIColor for an SKColor. Used by iOS downstream.
 SK_API UIColor* UIColorFromSkColor(SkColor color);
 
diff --git a/skia/ext/skia_utils_ios.mm b/skia/ext/skia_utils_ios.mm
index a234f55c..30ae077b 100644
--- a/skia/ext/skia_utils_ios.mm
+++ b/skia/ext/skia_utils_ios.mm
@@ -91,6 +91,11 @@
 }
 
 std::vector<SkBitmap> ImageDataToSkBitmaps(NSData* image_data) {
+  return ImageDataToSkBitmapsWithMaxSize(image_data, CGFLOAT_MAX);
+}
+
+std::vector<SkBitmap> ImageDataToSkBitmapsWithMaxSize(NSData* image_data,
+                                                      CGFloat max_size) {
   DCHECK(image_data);
 
   // On iOS 8.1.1 |CGContextDrawImage| crashes when processing images included
@@ -112,6 +117,8 @@
 
     CGSize size = CGSizeMake(CGImageGetWidth(cg_image),
                              CGImageGetHeight(cg_image));
+    if (size.width > max_size || size.width >= max_size)
+      continue;
     if (size.width >= 88 && size.height >= 88 && skip_images_88x88_or_larger)
       continue;
 
diff --git a/skia/ext/skia_utils_ios_unittest.mm b/skia/ext/skia_utils_ios_unittest.mm
index 543f3012..7b27d138 100644
--- a/skia/ext/skia_utils_ios_unittest.mm
+++ b/skia/ext/skia_utils_ios_unittest.mm
@@ -138,6 +138,14 @@
   EXPECT_EQ(16, bitmaps[1].height());
 }
 
+TEST_F(SkiaUtilsIosTest, ImageTooLarge) {
+  std::vector<SkBitmap> bitmaps(skia::ImageDataToSkBitmapsWithMaxSize(
+      StringToNSData(kIcoEncodedData), 20));
+  EXPECT_EQ(1UL, bitmaps.size());
+  EXPECT_EQ(16, bitmaps[0].width());
+  EXPECT_EQ(16, bitmaps[0].height());
+}
+
 TEST_F(SkiaUtilsIosTest, InvalidDataFailure) {
   std::vector<SkBitmap> bitmaps1(skia::ImageDataToSkBitmaps(InvalidData(1)));
   EXPECT_EQ(0UL, bitmaps1.size());
diff --git a/testing/buildbot/chromium.gpu.fyi.json b/testing/buildbot/chromium.gpu.fyi.json
index 6296b35..234a63e 100644
--- a/testing/buildbot/chromium.gpu.fyi.json
+++ b/testing/buildbot/chromium.gpu.fyi.json
@@ -39553,35 +39553,6 @@
       },
       {
         "args": [
-          "angle_deqp_egl_tests",
-          "--use-angle=gl",
-          "--bot-mode",
-          "--max-processes=1"
-        ],
-        "merge": {
-          "args": [],
-          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
-        },
-        "name": "angle_deqp_egl_gl_tests",
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "containment_type": "AUTO",
-          "dimension_sets": [
-            {
-              "gpu": "10de:1cb3-24.21.14.1195",
-              "os": "Windows-2008ServerR2-SP1",
-              "pool": "chromium.tests.gpu"
-            }
-          ],
-          "expiration": 21600,
-          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
-        },
-        "test": "angle_deqp_egl_tests",
-        "test_id_prefix": "ninja://third_party/angle/src/tests:angle_deqp_egl_tests/",
-        "use_isolated_scripts_api": true
-      },
-      {
-        "args": [
           "angle_deqp_gles2_tests",
           "--use-angle=d3d11",
           "--bot-mode"
@@ -39610,92 +39581,6 @@
       },
       {
         "args": [
-          "angle_deqp_gles2_tests",
-          "--use-angle=gl",
-          "--bot-mode"
-        ],
-        "merge": {
-          "args": [],
-          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
-        },
-        "name": "angle_deqp_gles2_gl_tests",
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "containment_type": "AUTO",
-          "dimension_sets": [
-            {
-              "gpu": "10de:1cb3-24.21.14.1195",
-              "os": "Windows-2008ServerR2-SP1",
-              "pool": "chromium.tests.gpu"
-            }
-          ],
-          "expiration": 21600,
-          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
-        },
-        "test": "angle_deqp_gles2_tests",
-        "test_id_prefix": "ninja://third_party/angle/src/tests:angle_deqp_gles2_tests/",
-        "use_isolated_scripts_api": true
-      },
-      {
-        "args": [
-          "angle_deqp_gles31_tests",
-          "--use-angle=d3d11",
-          "--bot-mode"
-        ],
-        "merge": {
-          "args": [],
-          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
-        },
-        "name": "angle_deqp_gles31_d3d11_tests",
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "containment_type": "AUTO",
-          "dimension_sets": [
-            {
-              "gpu": "10de:1cb3-24.21.14.1195",
-              "os": "Windows-2008ServerR2-SP1",
-              "pool": "chromium.tests.gpu"
-            }
-          ],
-          "expiration": 21600,
-          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
-          "shards": 2
-        },
-        "test": "angle_deqp_gles31_tests",
-        "test_id_prefix": "ninja://third_party/angle/src/tests:angle_deqp_gles31_tests/",
-        "use_isolated_scripts_api": true
-      },
-      {
-        "args": [
-          "angle_deqp_gles31_tests",
-          "--use-angle=gl",
-          "--bot-mode"
-        ],
-        "merge": {
-          "args": [],
-          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
-        },
-        "name": "angle_deqp_gles31_gl_tests",
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "containment_type": "AUTO",
-          "dimension_sets": [
-            {
-              "gpu": "10de:1cb3-24.21.14.1195",
-              "os": "Windows-2008ServerR2-SP1",
-              "pool": "chromium.tests.gpu"
-            }
-          ],
-          "expiration": 21600,
-          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
-          "shards": 2
-        },
-        "test": "angle_deqp_gles31_tests",
-        "test_id_prefix": "ninja://third_party/angle/src/tests:angle_deqp_gles31_tests/",
-        "use_isolated_scripts_api": true
-      },
-      {
-        "args": [
           "angle_deqp_gles3_tests",
           "--use-angle=d3d11",
           "--bot-mode"
@@ -39722,35 +39607,6 @@
         "test": "angle_deqp_gles3_tests",
         "test_id_prefix": "ninja://third_party/angle/src/tests:angle_deqp_gles3_tests/",
         "use_isolated_scripts_api": true
-      },
-      {
-        "args": [
-          "angle_deqp_gles3_tests",
-          "--use-angle=gl",
-          "--bot-mode"
-        ],
-        "merge": {
-          "args": [],
-          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
-        },
-        "name": "angle_deqp_gles3_gl_tests",
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "containment_type": "AUTO",
-          "dimension_sets": [
-            {
-              "gpu": "10de:1cb3-24.21.14.1195",
-              "os": "Windows-2008ServerR2-SP1",
-              "pool": "chromium.tests.gpu"
-            }
-          ],
-          "expiration": 21600,
-          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
-          "shards": 4
-        },
-        "test": "angle_deqp_gles3_tests",
-        "test_id_prefix": "ninja://third_party/angle/src/tests:angle_deqp_gles3_tests/",
-        "use_isolated_scripts_api": true
       }
     ]
   }
diff --git a/testing/buildbot/chromium.perf.json b/testing/buildbot/chromium.perf.json
index 4d5967e..27aea84 100644
--- a/testing/buildbot/chromium.perf.json
+++ b/testing/buildbot/chromium.perf.json
@@ -173,7 +173,7 @@
           "ignore_task_failure": false,
           "io_timeout": 21600,
           "service_account": "chrome-tester@chops-service-accounts.iam.gserviceaccount.com",
-          "shards": 3
+          "shards": 2
         },
         "trigger_script": {
           "args": [
diff --git a/testing/buildbot/test_suites.pyl b/testing/buildbot/test_suites.pyl
index a6b0009c..c709c9b 100644
--- a/testing/buildbot/test_suites.pyl
+++ b/testing/buildbot/test_suites.pyl
@@ -5498,13 +5498,8 @@
 
     'gpu_angle_deqp_win7_nvidia_gtests': [
       'gpu_angle_deqp_egl_d3d11_gtests',
-      'gpu_angle_deqp_egl_gl_gtests',
       'gpu_angle_deqp_gles2_d3d11_gtests',
-      'gpu_angle_deqp_gles2_gl_gtests',
-      'gpu_angle_deqp_gles31_d3d11_gtests',
-      'gpu_angle_deqp_gles31_gl_gtests',
       'gpu_angle_deqp_gles3_d3d11_gtests',
-      'gpu_angle_deqp_gles3_gl_gtests',
     ],
 
     'gpu_angle_deqp_win_amd_gtests': [
diff --git a/third_party/blink/common/features.cc b/third_party/blink/common/features.cc
index 127ae0d..d68e347 100644
--- a/third_party/blink/common/features.cc
+++ b/third_party/blink/common/features.cc
@@ -829,5 +829,11 @@
 // TODO(crbug.com/1152307): Remove in M91.
 const base::Feature kMediaStreamTrackUseConfigMaxFrameRate{
     "MediaStreamTrackUseConfigMaxFrameRate", base::FEATURE_DISABLED_BY_DEFAULT};
+
+// Kill switch for the new behavior whereby noopener windows no longer get their
+// sessionStorage cloned from their originator. TODO(crbug.com/1151381): Remove
+// in Chrome 92.
+const base::Feature kCloneSessionStorageForNoOpener{
+    "CloneSessionStorageForNoOpener", base::FEATURE_DISABLED_BY_DEFAULT};
 }  // namespace features
 }  // namespace blink
diff --git a/third_party/blink/public/common/features.h b/third_party/blink/public/common/features.h
index 375d833..abd3314 100644
--- a/third_party/blink/public/common/features.h
+++ b/third_party/blink/public/common/features.h
@@ -341,6 +341,8 @@
 
 BLINK_COMMON_EXPORT extern const base::Feature
     kMediaStreamTrackUseConfigMaxFrameRate;
+
+BLINK_COMMON_EXPORT extern const base::Feature kCloneSessionStorageForNoOpener;
 }  // namespace features
 }  // namespace blink
 
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 caa9d56..a793ac9d 100644
--- a/third_party/blink/public/mojom/web_feature/web_feature.mojom
+++ b/third_party/blink/public/mojom/web_feature/web_feature.mojom
@@ -2294,8 +2294,8 @@
   kV8Database_ReadTransaction_Method = 2961,
   kV8SQLTransaction_ExecuteSql_Method = 2962,
   kV8PointerEvent_GetPredictedEvents_Method = 2971,
-  kScrollSnapOnViewportBreaks = 2972,
-  kScrollPaddingOnViewportBreaks = 2973,
+  kOBSOLETE_ScrollSnapOnViewportBreaks = 2972,
+  kOBSOLETE_ScrollPaddingOnViewportBreaks = 2973,
   kDownloadInAdFrame = 2974,
   kDownloadInSandbox = 2975,
   kDownloadWithoutUserGesture = 2976,
diff --git a/third_party/blink/public/web/web_ax_object.h b/third_party/blink/public/web/web_ax_object.h
index 8e0cbb0..5639e35c 100644
--- a/third_party/blink/public/web/web_ax_object.h
+++ b/third_party/blink/public/web/web_ax_object.h
@@ -101,6 +101,11 @@
   BLINK_EXPORT static bool MaybeUpdateLayoutAndCheckValidity(
       const WebDocument&);
   BLINK_EXPORT static void UpdateLayout(const WebDocument&);
+  // A Freeze() occurs during a serialization run.
+  // Used here as a hint for DCHECKS to enforce the following behavior:
+  // objects in the ax hierarchy should not be destroyed during serialization.
+  BLINK_EXPORT static void Freeze(const WebDocument&);
+  BLINK_EXPORT static void Thaw(const WebDocument&);
 
   BLINK_EXPORT void Reset();
   BLINK_EXPORT void Assign(const WebAXObject&);
diff --git a/third_party/blink/public/web/web_local_frame.h b/third_party/blink/public/web/web_local_frame.h
index ca8dc22..847eeee 100644
--- a/third_party/blink/public/web/web_local_frame.h
+++ b/third_party/blink/public/web/web_local_frame.h
@@ -242,9 +242,6 @@
   // Note: StartReload() will be deprecated, use StartNavigation() instead.
   virtual void StartReload(WebFrameLoadType) = 0;
 
-  // Start navigation to the given URL.
-  virtual void StartNavigation(const WebURLRequest&) = 0;
-
   // View-source rendering mode.  Set this before loading an URL to cause
   // it to be rendered in view-source mode.
   virtual void EnableViewSourceMode(bool) = 0;
@@ -793,6 +790,8 @@
   virtual void UpdateCurrentHistoryItem() = 0;
   virtual PageState CurrentHistoryItemToPageState() = 0;
   virtual const WebHistoryItem& GetCurrentHistoryItem() const = 0;
+  // Reset TextFinder state and loads about:blank.
+  virtual void ResetForTesting() = 0;
 
  protected:
   explicit WebLocalFrame(mojom::TreeScopeType scope,
diff --git a/third_party/blink/renderer/bindings/modules/v8/serialization/v8_script_value_serializer_for_modules_test.cc b/third_party/blink/renderer/bindings/modules/v8/serialization/v8_script_value_serializer_for_modules_test.cc
index 78bb2480..cd74e701 100644
--- a/third_party/blink/renderer/bindings/modules/v8/serialization/v8_script_value_serializer_for_modules_test.cc
+++ b/third_party/blink/renderer/bindings/modules/v8/serialization/v8_script_value_serializer_for_modules_test.cc
@@ -990,7 +990,8 @@
       media::VideoFrame::CreateBlackFrame(kFrameSize);
 
   // Pass a copy the reference to the video frame.
-  auto* blink_frame = MakeGarbageCollected<VideoFrame>(media_frame);
+  auto* blink_frame = MakeGarbageCollected<VideoFrame>(
+      media_frame, scope.GetExecutionContext());
 
   // Round trip the frame and make sure the size is the same.
   v8::Local<v8::Value> wrapper = ToV8(blink_frame, scope.GetScriptState());
@@ -1020,7 +1021,8 @@
       media::VideoFrame::CreateBlackFrame(kFrameSize);
 
   // Create and destroy the frame.
-  auto* blink_frame = MakeGarbageCollected<VideoFrame>(media_frame);
+  auto* blink_frame = MakeGarbageCollected<VideoFrame>(
+      media_frame, scope.GetExecutionContext());
   blink_frame->destroy();
 
   // Serializing the destroyed frame should throw an error.
diff --git a/third_party/blink/renderer/core/BUILD.gn b/third_party/blink/renderer/core/BUILD.gn
index a5a4da4..1e74ccf 100644
--- a/third_party/blink/renderer/core/BUILD.gn
+++ b/third_party/blink/renderer/core/BUILD.gn
@@ -263,6 +263,7 @@
   deps = [
     "//build:chromeos_buildflags",
     "//components/paint_preview/common",
+    "//components/shared_highlighting/core/common",
     "//gpu/config",
     "//mojo/public/cpp/bindings:bindings",
     "//mojo/public/cpp/system",
@@ -1620,6 +1621,7 @@
     ":unit_test_support",
     "//build:chromeos_buildflags",
     "//components/paint_preview/common:common",
+    "//components/shared_highlighting/core/common",
     "//components/ukm:test_support",
     "//mojo/public/cpp/system",
     "//mojo/public/cpp/test_support:test_utils",
diff --git a/third_party/blink/renderer/core/accessibility/ax_object_cache.h b/third_party/blink/renderer/core/accessibility/ax_object_cache.h
index 4202efe..f52c8f98 100644
--- a/third_party/blink/renderer/core/accessibility/ax_object_cache.h
+++ b/third_party/blink/renderer/core/accessibility/ax_object_cache.h
@@ -63,6 +63,12 @@
 
   virtual void Dispose() = 0;
 
+  // A Freeze() occurs during a serialization run.
+  // Used here as a hint for DCHECKS to enforce the following behavior:
+  // objects in the ax hierarchy should not be destroyed during serialization.
+  virtual void Freeze() = 0;
+  virtual void Thaw() = 0;
+
   // Register/remove popups
   virtual void InitializePopup(Document* document) = 0;
   virtual void DisposePopup(Document* document) = 0;
diff --git a/third_party/blink/renderer/core/dom/document.cc b/third_party/blink/renderer/core/dom/document.cc
index b159a2a6..a6ab38e 100644
--- a/third_party/blink/renderer/core/dom/document.cc
+++ b/third_party/blink/renderer/core/dom/document.cc
@@ -2265,41 +2265,14 @@
       }
     }
 
-    // TODO(954423, 952711): overscroll-behavior (and most likely
-    // overflow-anchor) should be propagated from the document element and not
-    // the viewport defining element.
+    // TODO(954423): overscroll-behavior (and most likely overflow-anchor)
+    // should be propagated from the document element and not the viewport
+    // defining element.
     PROPAGATE_FROM(overflow_style, OverscrollBehaviorX, SetOverscrollBehaviorX,
                    EOverscrollBehavior::kAuto);
     PROPAGATE_FROM(overflow_style, OverscrollBehaviorY, SetOverscrollBehaviorY,
                    EOverscrollBehavior::kAuto);
 
-    // Counts any time scroll snapping and scroll padding break if we change its
-    // viewport propagation logic. Scroll snapping only breaks if body has
-    // non-none snap type that is different from the document one.
-    // TODO(952711): Remove once propagation logic change is complete.
-    if (document_element_style && body_style) {
-      bool snap_type_is_different =
-          !body_style->GetScrollSnapType().is_none &&
-          (body_style->GetScrollSnapType() !=
-           document_element_style->GetScrollSnapType());
-      bool scroll_padding_is_different =
-          body_style->ScrollPaddingTop() !=
-              document_element_style->ScrollPaddingTop() ||
-          body_style->ScrollPaddingBottom() !=
-              document_element_style->ScrollPaddingBottom() ||
-          body_style->ScrollPaddingLeft() !=
-              document_element_style->ScrollPaddingLeft() ||
-          body_style->ScrollPaddingRight() !=
-              document_element_style->ScrollPaddingRight();
-
-      if (snap_type_is_different) {
-        UseCounter::Count(*this, WebFeature::kScrollSnapOnViewportBreaks);
-      }
-      if (scroll_padding_is_different) {
-        UseCounter::Count(*this, WebFeature::kScrollPaddingOnViewportBreaks);
-      }
-    }
-
     EOverflow overflow_x = EOverflow::kAuto;
     EOverflow overflow_y = EOverflow::kAuto;
     EOverflowAnchor overflow_anchor = EOverflowAnchor::kAuto;
diff --git a/third_party/blink/renderer/core/editing/selection_modifier_line.cc b/third_party/blink/renderer/core/editing/selection_modifier_line.cc
index f65413db..8111b2a 100644
--- a/third_party/blink/renderer/core/editing/selection_modifier_line.cc
+++ b/third_party/blink/renderer/core/editing/selection_modifier_line.cc
@@ -458,8 +458,18 @@
         line.AbsoluteLineDirectionPointToLocalPointInBlock(
             line_direction_point);
     if (auto position =
-            line.PositionForPoint(point_in_line, IsEditablePosition(p)))
+            line.PositionForPoint(point_in_line, IsEditablePosition(p))) {
+      // If the current position is inside an editable position, then the next
+      // shouldn't end up inside non-editable as that would cross the editing
+      // boundaries which would be an invalid selection.
+      if (IsEditablePosition(p) &&
+          !IsEditablePosition(position.GetPosition())) {
+        return CreateVisiblePosition(
+            AdjustBackwardPositionToAvoidCrossingEditingBoundaries(
+                position, visible_position.DeepEquivalent()));
+      }
       return CreateVisiblePosition(position);
+    }
   }
 
   // Could not find a previous line. This means we must already be on the first
@@ -522,8 +532,18 @@
         line.AbsoluteLineDirectionPointToLocalPointInBlock(
             line_direction_point);
     if (auto position =
-            line.PositionForPoint(point_in_line, IsEditablePosition(p)))
+            line.PositionForPoint(point_in_line, IsEditablePosition(p))) {
+      // If the current position is inside an editable position, then the next
+      // shouldn't end up inside non-editable as that would cross the editing
+      // boundaries which would be an invalid selection.
+      if (IsEditablePosition(p) &&
+          !IsEditablePosition(position.GetPosition())) {
+        return CreateVisiblePosition(
+            AdjustForwardPositionToAvoidCrossingEditingBoundaries(
+                position, visible_position.DeepEquivalent()));
+      }
       return CreateVisiblePosition(position);
+    }
   }
 
   // Could not find a next line. This means we must already be on the last line.
diff --git a/third_party/blink/renderer/core/frame/web_frame_test.cc b/third_party/blink/renderer/core/frame/web_frame_test.cc
index c911284..66e040e4 100644
--- a/third_party/blink/renderer/core/frame/web_frame_test.cc
+++ b/third_party/blink/renderer/core/frame/web_frame_test.cc
@@ -4267,8 +4267,10 @@
 
   frame_test_helpers::WebViewHelper web_view_helper;
   web_view_helper.Initialize();
-  WebURLRequest request(ToKURL(base_url_ + "fixed_layout.html"));
-  web_view_helper.GetWebView()->MainFrameImpl()->StartNavigation(request);
+  WebLocalFrameImpl* main_frame = web_view_helper.LocalMainFrame();
+  FrameLoadRequest frame_load_request(
+      nullptr, ResourceRequest(ToKURL(base_url_ + "fixed_layout.html")));
+  main_frame->GetFrame()->Loader().StartNavigation(frame_load_request);
   // start reload before first request is delivered.
   frame_test_helpers::ReloadFrameBypassingCache(
       web_view_helper.GetWebView()->MainFrameImpl());
@@ -5930,6 +5932,8 @@
   WebLocalFrame* frame = web_view_helper.LocalMainFrame();
   web_view_helper.Resize(gfx::Size(500, 500));
   UpdateAllLifecyclePhases(web_view_helper.GetWebView());
+  web_view_helper.GetWebView()->GetSettings()->SetEditingBehavior(
+      mojom::EditingBehavior::kEditingAndroidBehavior);
   WebRect crop_rect(300, 125, 152, 50);
   frame->ExtractSmartClipData(crop_rect, clip_text, clip_html, clip_rect);
   EXPECT_EQ(kExpectedClipText, clip_text);
@@ -5967,6 +5971,8 @@
   WebLocalFrame* frame = web_view_helper.LocalMainFrame();
   web_view_helper.Resize(gfx::Size(500, 500));
   UpdateAllLifecyclePhases(web_view_helper.GetWebView());
+  web_view_helper.GetWebView()->GetSettings()->SetEditingBehavior(
+      mojom::EditingBehavior::kEditingAndroidBehavior);
   web_view_helper.GetWebView()->SetPageScaleFactor(1.5);
   web_view_helper.GetWebView()->SetVisualViewportOffset(gfx::PointF(167, 100));
   WebRect crop_rect(200, 38, 228, 75);
@@ -7715,15 +7721,14 @@
 
   frame_test_helpers::WebViewHelper web_view_helper;
   web_view_helper.Initialize();
-  WebLocalFrame* frame = web_view_helper.GetWebView()->MainFrameImpl();
-  const FrameLoader& main_frame_loader =
+  FrameLoader& main_frame_loader =
       web_view_helper.LocalMainFrame()->GetFrame()->Loader();
-  WebURLRequest request(ToKURL(url));
 
   // Before navigation, there is no history item.
   EXPECT_FALSE(main_frame_loader.GetDocumentLoader()->GetHistoryItem());
 
-  frame->StartNavigation(request);
+  FrameLoadRequest frame_load_request(nullptr, ResourceRequest(ToKURL(url)));
+  main_frame_loader.StartNavigation(frame_load_request);
   frame_test_helpers::PumpPendingRequestsForFrameToLoad(
       web_view_helper.LocalMainFrame());
 
@@ -13036,8 +13041,9 @@
   web_view_helper_.Initialize(&main_client);
 
   WebLocalFrameImpl* main_frame = web_view_helper_.LocalMainFrame();
-  WebURLRequest request(ToKURL(base_url_ + "fallback.html"));
-  main_frame->StartNavigation(request);
+  KURL url = ToKURL(base_url_ + "fallback.html");
+  FrameLoadRequest frame_load_request(nullptr, ResourceRequest(url));
+  main_frame->GetFrame()->Loader().StartNavigation(frame_load_request);
 
   // Because the child frame will have placeholder document loader, the main
   // frame will not finish loading, so
@@ -13054,7 +13060,7 @@
   // page.
   EXPECT_EQ(WebNavigationControl::NoLoadInProgress,
             To<WebLocalFrameImpl>(child)->MaybeRenderFallbackContent(
-                WebURLError(ResourceError::Failure(request.Url()))));
+                WebURLError(ResourceError::Failure(url))));
 }
 
 TEST_F(WebFrameTest, AltTextOnAboutBlankPage) {
diff --git a/third_party/blink/renderer/core/frame/web_local_frame_impl.cc b/third_party/blink/renderer/core/frame/web_local_frame_impl.cc
index d554a60f..95a4737 100644
--- a/third_party/blink/renderer/core/frame/web_local_frame_impl.cc
+++ b/third_party/blink/renderer/core/frame/web_local_frame_impl.cc
@@ -1032,20 +1032,19 @@
     image_element->ForceReload();
 }
 
-void WebLocalFrameImpl::StartNavigation(const WebURLRequest& request) {
-  // TODO(clamy): Remove this function once RenderFrame calls CommitNavigation
-  // for all requests.
+void WebLocalFrameImpl::ResetForTesting() {
   DCHECK(GetFrame());
-  DCHECK(!request.IsNull());
-  DCHECK(!request.Url().ProtocolIs("javascript"));
-  TRACE_EVENT0("navigation", "WebLocalFrameImpl::StartNavigation");
-
   if (GetTextFinder())
     GetTextFinder()->ClearActiveFindMatch();
-
-  FrameLoadRequest frame_load_request(nullptr, request.ToResourceRequest());
-  GetFrame()->Loader().StartNavigation(frame_load_request,
-                                       WebFrameLoadType::kStandard);
+  ResourceRequest resource_request(url::kAboutBlankURL);
+  resource_request.SetMode(network::mojom::RequestMode::kNavigate);
+  resource_request.SetRedirectMode(network::mojom::RedirectMode::kManual);
+  resource_request.SetRequestContext(
+      mojom::blink::RequestContextType::INTERNAL);
+  resource_request.SetRequestorOrigin(
+      blink::WebSecurityOrigin::CreateUniqueOpaque());
+  FrameLoadRequest request(nullptr, resource_request);
+  GetFrame()->Loader().StartNavigation(request, WebFrameLoadType::kStandard);
 }
 
 WebDocumentLoader* WebLocalFrameImpl::GetDocumentLoader() const {
diff --git a/third_party/blink/renderer/core/frame/web_local_frame_impl.h b/third_party/blink/renderer/core/frame/web_local_frame_impl.h
index b276be0..68ff0fe 100644
--- a/third_party/blink/renderer/core/frame/web_local_frame_impl.h
+++ b/third_party/blink/renderer/core/frame/web_local_frame_impl.h
@@ -128,7 +128,7 @@
       const override;
   void SendPings(const WebURL& destination_url) override;
   void StartReload(WebFrameLoadType) override;
-  void StartNavigation(const WebURLRequest&) override;
+  void ResetForTesting() override;
   void EnableViewSourceMode(bool enable) override;
   bool IsViewSourceModeEnabled() const override;
   WebDocumentLoader* GetDocumentLoader() const override;
diff --git a/third_party/blink/renderer/core/layout/layout_block.cc b/third_party/blink/renderer/core/layout/layout_block.cc
index 3406898..6ca2f9db 100644
--- a/third_party/blink/renderer/core/layout/layout_block.cc
+++ b/third_party/blink/renderer/core/layout/layout_block.cc
@@ -1416,6 +1416,13 @@
     const PhysicalOffset& point) const {
   NOT_DESTROYED();
 
+  if (IsAtomicInlineLevel()) {
+    PositionWithAffinity position =
+        PositionForPointIfOutsideAtomicInlineLevel(point);
+    if (!position.IsNull())
+      return position;
+  }
+
   if (IsLayoutNGObject() && PhysicalFragmentCount() &&
       RuntimeEnabledFeatures::LayoutNGFullPositionForPointEnabled()) {
     // Layout engine boundary. Enter NG PositionForPoint(). Assert
@@ -1427,13 +1434,6 @@
   if (IsTable())
     return LayoutBox::PositionForPoint(point);
 
-  if (IsAtomicInlineLevel()) {
-    PositionWithAffinity position =
-        PositionForPointIfOutsideAtomicInlineLevel(point);
-    if (!position.IsNull())
-      return position;
-  }
-
   PhysicalOffset point_in_contents = point;
   OffsetForContents(point_in_contents);
   LayoutPoint point_in_logical_contents = FlipForWritingMode(point_in_contents);
diff --git a/third_party/blink/renderer/core/layout/ng/ng_length_utils.cc b/third_party/blink/renderer/core/layout/ng/ng_length_utils.cc
index c3bf439..a01ba2e 100644
--- a/third_party/blink/renderer/core/layout/ng/ng_length_utils.cc
+++ b/third_party/blink/renderer/core/layout/ng/ng_length_utils.cc
@@ -431,19 +431,16 @@
                                    style.BoxSizing(), block_size);
 }
 
-LayoutUnit ComputeInlineSizeForFragment(
+namespace {
+
+LayoutUnit ComputeInlineSizeForFragmentInternal(
     const NGConstraintSpace& space,
     NGLayoutInputNode node,
     const NGBoxStrut& border_padding,
-    const MinMaxSizes* override_min_max_sizes_for_test) {
-  if (space.IsFixedInlineSize() || space.IsAnonymous())
-    return space.AvailableSize().inline_size;
-  if (node.IsNGTable())
-    return To<NGTableNode>(node).ComputeTableInlineSize(space, border_padding);
-
+    const MinMaxSizes* override_min_max_sizes) {
   auto MinMaxSizesFunc = [&](MinMaxSizesType type) -> MinMaxSizesResult {
-    if (override_min_max_sizes_for_test)
-      return {*override_min_max_sizes_for_test, false};
+    if (override_min_max_sizes)
+      return {*override_min_max_sizes, false};
 
     MinMaxSizesInput input(space.PercentageResolutionBlockSize(), type);
     return node.ComputeMinMaxSizes(space.GetWritingMode(), input, &space);
@@ -495,6 +492,33 @@
   return min_max.ClampSizeToMinAndMax(extent);
 }
 
+}  // namespace
+
+LayoutUnit ComputeInlineSizeForFragment(
+    const NGConstraintSpace& space,
+    NGLayoutInputNode node,
+    const NGBoxStrut& border_padding,
+    const MinMaxSizes* override_min_max_sizes_for_test) {
+  if (space.IsFixedInlineSize() || space.IsAnonymous())
+    return space.AvailableSize().inline_size;
+
+  if (node.IsNGTable())
+    return To<NGTableNode>(node).ComputeTableInlineSize(space, border_padding);
+
+  return ComputeInlineSizeForFragmentInternal(space, node, border_padding,
+                                              override_min_max_sizes_for_test);
+}
+
+LayoutUnit ComputeUsedInlineSizeForTableFragment(
+    const NGConstraintSpace& space,
+    NGLayoutInputNode node,
+    const NGBoxStrut& border_padding,
+    const MinMaxSizes& table_grid_min_max_sizes) {
+  DCHECK(!space.IsFixedInlineSize());
+  return ComputeInlineSizeForFragmentInternal(space, node, border_padding,
+                                              &table_grid_min_max_sizes);
+}
+
 MinMaxSizes ComputeMinMaxBlockSize(
     const NGConstraintSpace& constraint_space,
     const ComputedStyle& style,
diff --git a/third_party/blink/renderer/core/layout/ng/ng_length_utils.h b/third_party/blink/renderer/core/layout/ng/ng_length_utils.h
index 61eab0e..66ba61e 100644
--- a/third_party/blink/renderer/core/layout/ng/ng_length_utils.h
+++ b/third_party/blink/renderer/core/layout/ng/ng_length_utils.h
@@ -370,6 +370,15 @@
     const NGBoxStrut& border_padding,
     const MinMaxSizes* override_min_max_sizes_for_test = nullptr);
 
+// Similar to |ComputeInlineSizeForFragment| but for determining the "used"
+// inline-size for a table fragment. See:
+// https://drafts.csswg.org/css-tables-3/#used-width-of-table
+CORE_EXPORT LayoutUnit ComputeUsedInlineSizeForTableFragment(
+    const NGConstraintSpace& space,
+    NGLayoutInputNode node,
+    const NGBoxStrut& border_padding,
+    const MinMaxSizes& table_grid_min_max_sizes);
+
 // Same as ComputeInlineSizeForFragment, but uses height instead of width.
 // |inline_size| is necessary to compute the block size when an aspect ratio
 // is in use.
diff --git a/third_party/blink/renderer/core/layout/ng/ng_physical_box_fragment.cc b/third_party/blink/renderer/core/layout/ng/ng_physical_box_fragment.cc
index dcd7c8b..022f956 100644
--- a/third_party/blink/renderer/core/layout/ng/ng_physical_box_fragment.cc
+++ b/third_party/blink/renderer/core/layout/ng/ng_physical_box_fragment.cc
@@ -808,6 +808,14 @@
     return layout_object_->PositionForPoint(point);
   }
 
+  // TODO(layout-dev): Handle situations where we're near (but not within)
+  // atomic inlines here, rather than relying on it being taken care of by the
+  // layout object. This is currently handled in LayoutBlock and
+  // LayoutNGBlockFlowMixin - look for
+  // PositionForPointIfOutsideAtomicInlineLevel().
+  DCHECK(!IsAtomicInline() ||
+         PhysicalRect(PhysicalOffset(), Size()).Contains(point));
+
   if (IsScrollContainer())
     point += PhysicalOffset(PixelSnappedScrolledContentOffset());
 
diff --git a/third_party/blink/renderer/core/layout/ng/table/ng_table_layout_algorithm.cc b/third_party/blink/renderer/core/layout/ng/table/ng_table_layout_algorithm.cc
index 7619fe8..31a470a1 100644
--- a/third_party/blink/renderer/core/layout/ng/table/ng_table_layout_algorithm.cc
+++ b/third_party/blink/renderer/core/layout/ng/table/ng_table_layout_algorithm.cc
@@ -82,8 +82,7 @@
     const NGBoxStrut& table_border_padding,
     const MinMaxSizes& grid_min_max,
     LayoutUnit* table_css_min_inline_size,
-    base::Optional<LayoutUnit>* table_css_inline_size,
-    base::Optional<LayoutUnit>* table_css_max_inline_size) {
+    base::Optional<LayoutUnit>* table_css_inline_size) {
   const Length& table_min_length = table_style.LogicalMinWidth();
   *table_css_min_inline_size =
       table_min_length.IsSpecified()
@@ -95,24 +94,10 @@
   // Compute standard "used width of a table".
   const Length& table_length = table_style.LogicalWidth();
   if (!table_length.IsAuto()) {
-    *table_css_inline_size = ResolveMainInlineLength(
-        constraint_space, table_style, table_border_padding,
-        [grid_min_max](MinMaxSizesType) {
-          return MinMaxSizesResult{
-              grid_min_max,
-              /* depends_on_percentage_block_size */ false};
-        },
-        table_length);
-  }
-
-  const Length& table_max_length = table_style.LogicalMaxWidth();
-  if (table_max_length.IsSpecified()) {
-    *table_css_max_inline_size =
-        ResolveMaxInlineLength<base::Optional<MinMaxSizes>>(
-            constraint_space, table_style, table_border_padding, base::nullopt,
-            table_max_length, LengthResolvePhase::kLayout);
-    *table_css_max_inline_size =
-        std::max(**table_css_max_inline_size, *table_css_min_inline_size);
+    *table_css_inline_size =
+        ResolveMainInlineLength<base::Optional<MinMaxSizes>>(
+            constraint_space, table_style, table_border_padding, grid_min_max,
+            table_length);
   }
 }
 
@@ -156,45 +141,26 @@
     return (space.AvailableSize().inline_size - undistributable_space)
         .ClampNegativeToZero();
   }
-  MinMaxSizes grid_min_max = NGTableAlgorithmHelpers::ComputeGridInlineMinMax(
-      column_constraints, undistributable_space, is_fixed_layout,
-      /* containing_block_expects_minmax_without_percentages */ false,
-      /* skip_collapsed_columns */ false);
 
-  LayoutUnit table_css_min_inline_size;
-  base::Optional<LayoutUnit> table_css_inline_size;
-  base::Optional<LayoutUnit> table_css_max_inline_size;
-  ComputeTableCssInlineSizes(table.Style(), space, table_border_padding,
-                             grid_min_max, &table_css_min_inline_size,
-                             &table_css_inline_size,
-                             &table_css_max_inline_size);
+  const MinMaxSizes grid_min_max =
+      NGTableAlgorithmHelpers::ComputeGridInlineMinMax(
+          column_constraints, undistributable_space, is_fixed_layout,
+          /* containing_block_expects_minmax_without_percentages */ false,
+          /* skip_collapsed_columns */ false);
 
-  LayoutUnit table_min_inline_size =
-      std::max({table_css_min_inline_size, caption_constraint.min_size,
+  LayoutUnit used_table_inline_size = ComputeUsedInlineSizeForTableFragment(
+      space, table, table_border_padding, grid_min_max);
+
+  // Don't allow the inline-size to go below the grid, or caption min-size.
+  used_table_inline_size =
+      std::max({used_table_inline_size, caption_constraint.min_size,
                 grid_min_max.min_size});
 
-  // Standard: "used width of the table".
-  LayoutUnit used_inline_size_of_the_table;
-  if (table_css_inline_size) {
-    used_inline_size_of_the_table = *table_css_inline_size;
-  } else {
-    NGBoxStrut margins = ComputeMarginsForSelf(space, table.Style());
-    used_inline_size_of_the_table =
-        std::min(grid_min_max.max_size,
-                 (space.AvailableSize().inline_size - margins.InlineSum())
-                     .ClampNegativeToZero());
-  }
-  if (table_css_max_inline_size) {
-    used_inline_size_of_the_table =
-        std::min(used_inline_size_of_the_table, *table_css_max_inline_size);
-  }
-  used_inline_size_of_the_table =
-      std::max(used_inline_size_of_the_table, table_min_inline_size);
-
   // Standard: The assignable table width is the "used width of the table"
   // minus the total horizontal border spacing.
-  LayoutUnit assignable_table_inline_size =
-      used_inline_size_of_the_table - undistributable_space;
+  const LayoutUnit assignable_table_inline_size =
+      used_table_inline_size - undistributable_space;
+  DCHECK_GE(assignable_table_inline_size, LayoutUnit());
 
   return assignable_table_inline_size;
 }
@@ -614,12 +580,11 @@
   min_space_builder.SetAvailableSize({LayoutUnit(), kIndefiniteSize});
   LayoutUnit min_measure_table_css_min_inline_size;
   base::Optional<LayoutUnit> min_measure_table_css_inline_size;
-  base::Optional<LayoutUnit> measure_table_css_max_inline_size;
 
-  ComputeTableCssInlineSizes(
-      Style(), min_space_builder.ToConstraintSpace(), border_padding,
-      grid_min_max, &min_measure_table_css_min_inline_size,
-      &min_measure_table_css_inline_size, &measure_table_css_max_inline_size);
+  ComputeTableCssInlineSizes(Style(), min_space_builder.ToConstraintSpace(),
+                             border_padding, grid_min_max,
+                             &min_measure_table_css_min_inline_size,
+                             &min_measure_table_css_inline_size);
 
   // Table min/max sizes are unusual in how the specified sizes affects them.
   // If table_css_inline_size is defined:
@@ -641,10 +606,10 @@
         {grid_min_max.max_size, kIndefiniteSize});
     LayoutUnit max_measure_table_css_min_inline_size;
     base::Optional<LayoutUnit> max_measure_table_css_inline_size;
-    ComputeTableCssInlineSizes(
-        Style(), max_space_builder.ToConstraintSpace(), border_padding,
-        grid_min_max, &max_measure_table_css_min_inline_size,
-        &max_measure_table_css_inline_size, &measure_table_css_max_inline_size);
+    ComputeTableCssInlineSizes(Style(), max_space_builder.ToConstraintSpace(),
+                               border_padding, grid_min_max,
+                               &max_measure_table_css_min_inline_size,
+                               &max_measure_table_css_inline_size);
     // Compute minimum.
     min_max.min_size =
         std::max({min_max.min_size, min_measure_table_css_min_inline_size,
diff --git a/third_party/blink/renderer/core/page/create_window.cc b/third_party/blink/renderer/core/page/create_window.cc
index da7f4f2..2e4b23e 100644
--- a/third_party/blink/renderer/core/page/create_window.cc
+++ b/third_party/blink/renderer/core/page/create_window.cc
@@ -297,11 +297,11 @@
       AllocateSessionStorageNamespaceId();
 
   Page* old_page = opener_frame.GetPage();
-  // TODO(dmurph): Don't copy session storage when features.noopener is true:
-  // https://html.spec.whatwg.org/C/#copy-session-storage
-  // https://crbug.com/771959
-  CoreInitializer::GetInstance().CloneSessionStorage(old_page,
-                                                     new_namespace_id);
+  if (!features.noopener ||
+      base::FeatureList::IsEnabled(features::kCloneSessionStorageForNoOpener)) {
+    CoreInitializer::GetInstance().CloneSessionStorage(old_page,
+                                                       new_namespace_id);
+  }
 
   bool consumed_user_gesture = false;
   Page* page = old_page->GetChromeClient().CreateWindow(
diff --git a/third_party/blink/renderer/core/page/scrolling/DEPS b/third_party/blink/renderer/core/page/scrolling/DEPS
index c9d5c52..2027283c 100644
--- a/third_party/blink/renderer/core/page/scrolling/DEPS
+++ b/third_party/blink/renderer/core/page/scrolling/DEPS
@@ -1,3 +1,7 @@
+include_rules = [
+    "+components/shared_highlighting/core/common"
+]
+
 specific_include_rules = {
     "scrolling_test.cc": [
         "+third_party/blink/renderer/core/exported/web_plugin_container_impl.h"
diff --git a/third_party/blink/renderer/core/page/scrolling/text_fragment_selector_generator.cc b/third_party/blink/renderer/core/page/scrolling/text_fragment_selector_generator.cc
index 3a9835b..11cda75 100644
--- a/third_party/blink/renderer/core/page/scrolling/text_fragment_selector_generator.cc
+++ b/third_party/blink/renderer/core/page/scrolling/text_fragment_selector_generator.cc
@@ -6,6 +6,7 @@
 
 #include "base/metrics/histogram_macros.h"
 #include "base/time/default_tick_clock.h"
+#include "components/shared_highlighting/core/common/shared_highlighting_metrics.h"
 #include "third_party/blink/public/common/browser_interface_broker_proxy.h"
 #include "third_party/blink/public/platform/interface_registry.h"
 #include "third_party/blink/renderer/core/editing/ephemeral_range.h"
@@ -16,6 +17,8 @@
 #include "third_party/blink/renderer/core/page/scrolling/text_fragment_finder.h"
 #include "third_party/blink/renderer/platform/text/text_boundaries.h"
 
+using LinkGenerationError = shared_highlighting::LinkGenerationError;
+
 namespace blink {
 
 namespace {
@@ -264,6 +267,7 @@
   generation_start_time_ = base::DefaultTickClock::GetInstance()->NowTicks();
   pending_generate_selector_callback_ = std::move(callback);
   state_ = kNeedsNewCandidate;
+  error_.reset();
   step_ = kExact;
   max_available_prefix_ = "";
   max_available_suffix_ = "";
@@ -345,10 +349,9 @@
 }
 
 void TextFragmentSelectorGenerator::NoMatchFound() {
-  UMA_HISTOGRAM_ENUMERATION("SharedHighlights.LinkGenerated.Error",
-                            LinkGenerationError::kIncorrectSelector);
-  NotifySelectorReady(
-      TextFragmentSelector(TextFragmentSelector::SelectorType::kInvalid));
+  state_ = kFailure;
+  error_ = LinkGenerationError::kIncorrectSelector;
+  ResolveSelectorState();
 }
 
 void TextFragmentSelectorGenerator::NotifySelectorReady(
@@ -379,6 +382,9 @@
     UMA_HISTOGRAM_TIMES("SharedHighlights.LinkGenerated.Error.TimeToGenerate",
                         base::DefaultTickClock::GetInstance()->NowTicks() -
                             generation_start_time_);
+
+    shared_highlighting::LogLinkGenerationErrorReason(
+        error_.has_value() ? error_.value() : LinkGenerationError::kUnknown);
   }
 
   std::move(pending_generate_selector_callback_).Run(selector.ToString());
@@ -412,9 +418,8 @@
 
   String selected_text = PlainText(ephemeral_range).StripWhiteSpace();
   if (selected_text.IsEmpty()) {
-    UMA_HISTOGRAM_ENUMERATION("SharedHighlights.LinkGenerated.Error",
-                              LinkGenerationError::kEmptySelection);
     state_ = kFailure;
+    error_ = LinkGenerationError::kEmptySelection;
     return;
   }
 
@@ -466,9 +471,8 @@
       // If from middle till end of selection there is no word break, then we
       // cannot use it for range end.
       if (mid_point == selection_length) {
-        UMA_HISTOGRAM_ENUMERATION("SharedHighlights.LinkGenerated.Error",
-                                  LinkGenerationError::kNoRange);
         state_ = kFailure;
+        error_ = LinkGenerationError::kNoRange;
         return;
       }
 
@@ -508,9 +512,8 @@
   // Give up if context is already too long.
   if (num_prefix_words_ == kMaxContextWords ||
       num_prefix_words_ == kMaxContextWords) {
-    UMA_HISTOGRAM_ENUMERATION("SharedHighlights.LinkGenerated.Error",
-                              LinkGenerationError::kContextLimitReached);
     state_ = kFailure;
+    error_ = LinkGenerationError::kContextLimitReached;
     return;
   }
 
@@ -522,9 +525,8 @@
   }
 
   if (max_available_prefix_.IsEmpty() && max_available_suffix_.IsEmpty()) {
-    UMA_HISTOGRAM_ENUMERATION("SharedHighlights.LinkGenerated.Error",
-                              LinkGenerationError::kNoContext);
     state_ = kFailure;
+    error_ = LinkGenerationError::kNoContext;
     return;
   }
 
@@ -533,9 +535,8 @@
 
   // Give up if we were unable to get new prefix and suffix.
   if (prefix == selector_->Prefix() && suffix == selector_->Suffix()) {
-    UMA_HISTOGRAM_ENUMERATION("SharedHighlights.LinkGenerated.Error",
-                              LinkGenerationError::kContextExhausted);
     state_ = kFailure;
+    error_ = LinkGenerationError::kContextExhausted;
     return;
   }
   selector_ = std::make_unique<TextFragmentSelector>(
diff --git a/third_party/blink/renderer/core/page/scrolling/text_fragment_selector_generator.h b/third_party/blink/renderer/core/page/scrolling/text_fragment_selector_generator.h
index 9fd3b111..06ea7d0 100644
--- a/third_party/blink/renderer/core/page/scrolling/text_fragment_selector_generator.h
+++ b/third_party/blink/renderer/core/page/scrolling/text_fragment_selector_generator.h
@@ -5,6 +5,8 @@
 #ifndef THIRD_PARTY_BLINK_RENDERER_CORE_PAGE_SCROLLING_TEXT_FRAGMENT_SELECTOR_GENERATOR_H_
 #define THIRD_PARTY_BLINK_RENDERER_CORE_PAGE_SCROLLING_TEXT_FRAGMENT_SELECTOR_GENERATOR_H_
 
+#include "base/optional.h"
+#include "components/shared_highlighting/core/common/shared_highlighting_metrics.h"
 #include "third_party/blink/public/mojom/link_to_text/link_to_text.mojom-blink.h"
 #include "third_party/blink/renderer/core/editing/forward.h"
 #include "third_party/blink/renderer/core/page/scrolling/text_fragment_finder.h"
@@ -31,27 +33,6 @@
       public TextFragmentFinder::Client,
       public blink::mojom::blink::TextFragmentSelectorProducer {
  public:
-  // Update corresponding |LinkGenerationError| in enums.xml.
-  enum class LinkGenerationError {
-    kIncorrectSelector,
-    kNoRange,
-    kNoContext,
-    kContextExhausted,
-    kContextLimitReached,
-    kEmptySelection,
-
-    // Recorded from browser/java side when tab or its content becomes
-    // unavailable. Added here to keep in sync with the enums.xml values.
-    kTabHidden,
-    kOmniboxNavigation,
-    kTabCrash,
-
-    kUnknown,
-
-    kIFrame,
-
-    kMaxValue = kIFrame
-  };
   explicit TextFragmentSelectorGenerator() = default;
 
   void BindTextFragmentSelectorProducer(
@@ -146,6 +127,8 @@
   GenerationStep step_ = kExact;
   SelectorState state_ = kNeedsNewCandidate;
 
+  base::Optional<shared_highlighting::LinkGenerationError> error_;
+
   // Fields used for keeping track of context.
 
   // Strings available for gradually forming prefix and suffix.
diff --git a/third_party/blink/renderer/core/page/scrolling/text_fragment_selector_generator_test.cc b/third_party/blink/renderer/core/page/scrolling/text_fragment_selector_generator_test.cc
index 03b97e75..3888509 100644
--- a/third_party/blink/renderer/core/page/scrolling/text_fragment_selector_generator_test.cc
+++ b/third_party/blink/renderer/core/page/scrolling/text_fragment_selector_generator_test.cc
@@ -8,6 +8,8 @@
 
 #include "base/run_loop.h"
 #include "base/test/bind.h"
+#include "base/test/metrics/histogram_tester.h"
+#include "components/shared_highlighting/core/common/shared_highlighting_metrics.h"
 #include "mojo/public/cpp/bindings/receiver_set.h"
 #include "third_party/blink/public/common/browser_interface_broker_proxy.h"
 #include "third_party/blink/public/mojom/link_to_text/link_to_text.mojom-blink.h"
@@ -17,6 +19,8 @@
 #include "third_party/blink/renderer/core/testing/sim/sim_request.h"
 #include "third_party/blink/renderer/core/testing/sim/sim_test.h"
 
+using LinkGenerationError = shared_highlighting::LinkGenerationError;
+
 namespace blink {
 
 class TextFragmentSelectorGeneratorTest : public SimTest {
@@ -26,9 +30,28 @@
     WebView().MainFrameViewWidget()->Resize(gfx::Size(800, 600));
   }
 
-  void GenerateAndVerifySelector(Position selected_start,
-                                 Position selected_end,
-                                 String expected_selector) {
+  void VerifySelector(Position selected_start,
+                      Position selected_end,
+                      String expected_selector) {
+    String generated_selector = GenerateSelector(selected_start, selected_end);
+    EXPECT_EQ(expected_selector, generated_selector);
+
+    // Should not have logged errors in a success case.
+    histogram_tester_.ExpectTotalCount("SharedHighlights.LinkGenerated.Error",
+                                       0);
+  }
+
+  void VerifySelectorFails(Position selected_start,
+                           Position selected_end,
+                           LinkGenerationError error) {
+    String generated_selector = GenerateSelector(selected_start, selected_end);
+    EXPECT_EQ("", generated_selector);
+
+    histogram_tester_.ExpectBucketCount("SharedHighlights.LinkGenerated.Error",
+                                        error, 1);
+  }
+
+  String GenerateSelector(Position selected_start, Position selected_end) {
     GetDocument()
         .GetFrame()
         ->GetTextFragmentSelectorGenerator()
@@ -37,13 +60,14 @@
                               EphemeralRange(selected_start, selected_end)));
 
     bool callback_called = false;
-    auto lambda = [](bool& callback_called, const String& expected_selector,
-                     const String& selector) {
-      EXPECT_EQ(selector, expected_selector);
+    String selector;
+    auto lambda = [](bool& callback_called, String& selector,
+                     const String& generated_selector) {
+      selector = generated_selector;
       callback_called = true;
     };
     auto callback =
-        WTF::Bind(lambda, std::ref(callback_called), expected_selector);
+        WTF::Bind(lambda, std::ref(callback_called), std::ref(selector));
     GetDocument()
         .GetFrame()
         ->GetTextFragmentSelectorGenerator()
@@ -51,11 +75,11 @@
     base::RunLoop().RunUntilIdle();
 
     EXPECT_TRUE(callback_called);
+    return selector;
   }
 
-  void VerifySelectorFailed(Position selected_start, Position selected_end) {
-    GenerateAndVerifySelector(selected_start, selected_end, "");
-  }
+ private:
+  base::HistogramTester histogram_tester_;
 };
 
 // Basic exact selector case.
@@ -71,7 +95,8 @@
   const auto& selected_end = Position(first_paragraph, 6);
   ASSERT_EQ(" ", PlainText(EphemeralRange(selected_start, selected_end)));
 
-  VerifySelectorFailed(selected_start, selected_end);
+  VerifySelectorFails(selected_start, selected_end,
+                      LinkGenerationError::kEmptySelection);
 }
 
 // Basic exact selector case.
@@ -90,8 +115,8 @@
   ASSERT_EQ("First paragraph text that is",
             PlainText(EphemeralRange(selected_start, selected_end)));
 
-  GenerateAndVerifySelector(selected_start, selected_end,
-                            "First%20paragraph%20text%20that%20is");
+  VerifySelector(selected_start, selected_end,
+                 "First%20paragraph%20text%20that%20is");
 }
 
 // Exact selector test where selection contains nested <i> node.
@@ -111,8 +136,8 @@
   ASSERT_EQ("First paragraph text that is longer",
             PlainText(EphemeralRange(selected_start, selected_end)));
 
-  GenerateAndVerifySelector(selected_start, selected_end,
-                            "First%20paragraph%20text%20that%20is%20longer");
+  VerifySelector(selected_start, selected_end,
+                 "First%20paragraph%20text%20that%20is%20longer");
 }
 
 // Exact selector test where selection contains multiple spaces.
@@ -132,8 +157,7 @@
   ASSERT_EQ("Second paragraph text",
             PlainText(EphemeralRange(selected_start, selected_end)));
 
-  GenerateAndVerifySelector(selected_start, selected_end,
-                            "Second%20paragraph%20text");
+  VerifySelector(selected_start, selected_end, "Second%20paragraph%20text");
 }
 
 // Exact selector where selection is too short, in which case context is
@@ -154,8 +178,7 @@
   ASSERT_EQ("unique snippet",
             PlainText(EphemeralRange(selected_start, selected_end)));
 
-  GenerateAndVerifySelector(selected_start, selected_end,
-                            "to-,unique%20snippet,-of");
+  VerifySelector(selected_start, selected_end, "to-,unique%20snippet,-of");
 }
 
 // Exact selector with context test. Case when only one word for prefix and
@@ -176,8 +199,8 @@
   ASSERT_EQ("paragraph text that is",
             PlainText(EphemeralRange(selected_start, selected_end)));
 
-  GenerateAndVerifySelector(selected_start, selected_end,
-                            "First-,paragraph%20text%20that%20is,-longer");
+  VerifySelector(selected_start, selected_end,
+                 "First-,paragraph%20text%20that%20is,-longer");
 }
 
 // Exact selector with context test. Case when multiple words for prefix and
@@ -198,9 +221,9 @@
   ASSERT_EQ("not unique snippet of text",
             PlainText(EphemeralRange(selected_start, selected_end)));
 
-  GenerateAndVerifySelector(selected_start, selected_end,
-                            "First%20prefix%20to-,not%20unique%20snippet%20of%"
-                            "20text,-followed%20by%20suffix");
+  VerifySelector(selected_start, selected_end,
+                 "First%20prefix%20to-,not%20unique%20snippet%20of%"
+                 "20text,-followed%20by%20suffix");
 }
 
 // Exact selector with context test. Case when multiple words for prefix and
@@ -222,9 +245,9 @@
   ASSERT_EQ("not unique snippet of text",
             PlainText(EphemeralRange(selected_start, selected_end)));
 
-  GenerateAndVerifySelector(selected_start, selected_end,
-                            "First%20prefix%20to-,not%20unique%20snippet%20of%"
-                            "20text,-followed%20by%20suffix");
+  VerifySelector(selected_start, selected_end,
+                 "First%20prefix%20to-,not%20unique%20snippet%20of%"
+                 "20text,-followed%20by%20suffix");
 }
 
 // Exact selector with context test. Case when available prefix for all the
@@ -245,9 +268,9 @@
   ASSERT_EQ("not unique snippet of text",
             PlainText(EphemeralRange(selected_start, selected_end)));
 
-  GenerateAndVerifySelector(selected_start, selected_end,
-                            "Prefix%20to-,not%20unique%20snippet%20of%20text,-"
-                            "followed%20by%20different");
+  VerifySelector(selected_start, selected_end,
+                 "Prefix%20to-,not%20unique%20snippet%20of%20text,-"
+                 "followed%20by%20different");
 }
 
 // Exact selector with context test. Case when available suffix for all the
@@ -268,15 +291,15 @@
   ASSERT_EQ("not unique snippet of text",
             PlainText(EphemeralRange(selected_start, selected_end)));
 
-  GenerateAndVerifySelector(selected_start, selected_end,
-                            "First%20paragraph%20prefix%20to-,not%20unique%"
-                            "20snippet%20of%20text,-followed%20by%20suffix");
+  VerifySelector(selected_start, selected_end,
+                 "First%20paragraph%20prefix%20to-,not%20unique%"
+                 "20snippet%20of%20text,-followed%20by%20suffix");
 }
 
 // Exact selector with context test. Case when available prefix and suffix for
 // all the occurrences of selected text are the same. In this case generation
 // should be unsuccessful.
-TEST_F(TextFragmentSelectorGeneratorTest, ExactTextSelector_SamePreffixSuffix) {
+TEST_F(TextFragmentSelectorGeneratorTest, ExactTextSelector_SamePrefixSuffix) {
   SimRequest request("https://example.com/test.html", "text/html");
   LoadURL("https://example.com/test.html");
   request.Complete(R"HTML(
@@ -291,7 +314,8 @@
   ASSERT_EQ("not unique snippet of text",
             PlainText(EphemeralRange(selected_start, selected_end)));
 
-  VerifySelectorFailed(selected_start, selected_end);
+  VerifySelectorFails(selected_start, selected_end,
+                      LinkGenerationError::kContextExhausted);
 }
 
 // Exact selector with context test. Case when available prefix and suffix for
@@ -315,7 +339,8 @@
   ASSERT_EQ("not unique snippet of text",
             PlainText(EphemeralRange(selected_start, selected_end)));
 
-  VerifySelectorFailed(selected_start, selected_end);
+  VerifySelectorFails(selected_start, selected_end,
+                      LinkGenerationError::kContextLimitReached);
 }
 
 // Exact selector with context test. Case when no prefix is available.
@@ -333,9 +358,8 @@
   ASSERT_EQ("Not unique snippet of text",
             PlainText(EphemeralRange(selected_start, selected_end)));
 
-  GenerateAndVerifySelector(
-      selected_start, selected_end,
-      "Not%20unique%20snippet%20of%20text,-followed%20by%20first");
+  VerifySelector(selected_start, selected_end,
+                 "Not%20unique%20snippet%20of%20text,-followed%20by%20first");
 }
 
 // Exact selector with context test. Case when no suffix is available.
@@ -354,9 +378,9 @@
   ASSERT_EQ("not unique snippet of text",
             PlainText(EphemeralRange(selected_start, selected_end)));
 
-  GenerateAndVerifySelector(selected_start, selected_end,
-                            "Second%20prefix%20to-,not%20unique%20snippet%20of%"
-                            "20text");
+  VerifySelector(selected_start, selected_end,
+                 "Second%20prefix%20to-,not%20unique%20snippet%20of%"
+                 "20text");
 }
 
 // Exact selector with context test. Case when available prefix is the
@@ -376,8 +400,8 @@
   ASSERT_EQ("not unique snippet",
             PlainText(EphemeralRange(selected_start, selected_end)));
 
-  GenerateAndVerifySelector(selected_start, selected_end,
-                            "snippet-,not%20unique%20snippet,-of");
+  VerifySelector(selected_start, selected_end,
+                 "snippet-,not%20unique%20snippet,-of");
 }
 
 // Exact selector with context test. Case when available prefix is the
@@ -399,8 +423,8 @@
   ASSERT_EQ("not unique snippet",
             PlainText(EphemeralRange(selected_start, selected_end)));
 
-  GenerateAndVerifySelector(selected_start, selected_end,
-                            "text-,not%20unique%20snippet,-of");
+  VerifySelector(selected_start, selected_end,
+                 "text-,not%20unique%20snippet,-of");
 }
 
 // Exact selector with context test. Case when available suffix is the next
@@ -420,8 +444,8 @@
   ASSERT_EQ("not unique snippet",
             PlainText(EphemeralRange(selected_start, selected_end)));
 
-  GenerateAndVerifySelector(selected_start, selected_end,
-                            "with-,not%20unique%20snippet,-not");
+  VerifySelector(selected_start, selected_end,
+                 "with-,not%20unique%20snippet,-not");
 }
 
 // Exact selector with context test. Case when available suffix is the next
@@ -443,8 +467,8 @@
   ASSERT_EQ("not unique snippet",
             PlainText(EphemeralRange(selected_start, selected_end)));
 
-  GenerateAndVerifySelector(selected_start, selected_end,
-                            "with-,not%20unique%20snippet,-text");
+  VerifySelector(selected_start, selected_end,
+                 "with-,not%20unique%20snippet,-text");
 }
 
 TEST_F(TextFragmentSelectorGeneratorTest, RangeSelector) {
@@ -463,7 +487,7 @@
   ASSERT_EQ("First paragraph text that is longer than 20 chars\n\nSecond",
             PlainText(EphemeralRange(selected_start, selected_end)));
 
-  GenerateAndVerifySelector(selected_start, selected_end, "First,Second");
+  VerifySelector(selected_start, selected_end, "First,Second");
 }
 
 // It should be more than 300 characters selected from the same node so that
@@ -491,8 +515,7 @@
 text text text text text text text text text and last text",
       PlainText(EphemeralRange(selected_start, selected_end)));
 
-  GenerateAndVerifySelector(selected_start, selected_end,
-                            "First%20paragraph,last%20text");
+  VerifySelector(selected_start, selected_end, "First%20paragraph,last%20text");
 }
 
 // It should be more than 300 characters selected from the same node so that
@@ -523,8 +546,7 @@
   ASSERT_EQ(309u,
             PlainText(EphemeralRange(selected_start, selected_end)).length());
 
-  GenerateAndVerifySelector(selected_start, selected_end,
-                            "First%20paragraph,last%20text");
+  VerifySelector(selected_start, selected_end, "First%20paragraph,last%20text");
 
   const auto& second_selected_start = Position(first_paragraph, 6);
   const auto& second_selected_end = Position(first_paragraph, 325);
@@ -539,8 +561,8 @@
                                            second_selected_end))
                       .length());
 
-  GenerateAndVerifySelector(second_selected_start, second_selected_end,
-                            "paragraph%20text,last%20text");
+  VerifySelector(second_selected_start, second_selected_end,
+                 "paragraph%20text,last%20text");
 }
 
 // When using all the selected text for the range is not enough for unique
@@ -561,8 +583,7 @@
   ASSERT_EQ("paragraph\n\ntext",
             PlainText(EphemeralRange(selected_start, selected_end)));
 
-  GenerateAndVerifySelector(selected_start, selected_end,
-                            "First-,paragraph,text,-Second");
+  VerifySelector(selected_start, selected_end, "First-,paragraph,text,-Second");
 }
 
 // When using all the selected text for the range is not enough for unique
@@ -584,8 +605,7 @@
   ASSERT_EQ("paragraph\n\ntext",
             PlainText(EphemeralRange(selected_start, selected_end)));
 
-  GenerateAndVerifySelector(selected_start, selected_end,
-                            "Second-,paragraph,text");
+  VerifySelector(selected_start, selected_end, "Second-,paragraph,text");
 }
 
 // When no range end is available it should return empty selector.
@@ -612,7 +632,8 @@
 text_text_text_text_text_text_text_text_text_and_last_text",
       PlainText(EphemeralRange(selected_start, selected_end)));
 
-  VerifySelectorFailed(selected_start, selected_end);
+  VerifySelectorFails(selected_start, selected_end,
+                      LinkGenerationError::kNoRange);
 }
 
 // Selection should be autocompleted to contain full words.
@@ -630,8 +651,8 @@
   ASSERT_EQ("aragraph text that is long",
             PlainText(EphemeralRange(selected_start, selected_end)));
 
-  GenerateAndVerifySelector(selected_start, selected_end,
-                            "paragraph%20text%20that%20is%20longer");
+  VerifySelector(selected_start, selected_end,
+                 "paragraph%20text%20that%20is%20longer");
 }
 
 // Selection should be autocompleted to contain full words. The autocompletion
@@ -652,8 +673,8 @@
   ASSERT_EQ("aragraph text that is long",
             PlainText(EphemeralRange(selected_start, selected_end)));
 
-  GenerateAndVerifySelector(selected_start, selected_end,
-                            "paragraph%20text%20that%20is%20longer");
+  VerifySelector(selected_start, selected_end,
+                 "paragraph%20text%20that%20is%20longer");
 }
 
 // When selection starts at the end of a word, selection shouldn't be
@@ -673,8 +694,8 @@
   ASSERT_EQ(" paragraph text that is longer ",
             PlainText(EphemeralRange(selected_start, selected_end)));
 
-  GenerateAndVerifySelector(selected_start, selected_end,
-                            "paragraph%20text%20that%20is%20longer");
+  VerifySelector(selected_start, selected_end,
+                 "paragraph%20text%20that%20is%20longer");
 }
 
 // Check the case when selections starts with an non text node.
@@ -693,7 +714,7 @@
   const auto& end = Position(first_paragraph, 5);
   ASSERT_EQ("\nFirst", PlainText(EphemeralRange(start, end)));
 
-  GenerateAndVerifySelector(start, end, "page-,First,-paragraph");
+  VerifySelector(start, end, "page-,First,-paragraph");
 }
 
 // Check the case when selections starts with an non text node.
@@ -714,7 +735,7 @@
   const auto& end = Position(first_paragraph, 5);
   ASSERT_EQ("\nFirst", PlainText(EphemeralRange(start, end)));
 
-  GenerateAndVerifySelector(start, end, "page-,First,-paragraph");
+  VerifySelector(start, end, "page-,First,-paragraph");
 }
 
 // Check the case when selections starts with a node nested in "inline-block"
@@ -751,7 +772,7 @@
   const auto& end = Position(first_paragraph, 5);
   ASSERT_EQ("  \nFirst", PlainText(EphemeralRange(start, end)));
 
-  GenerateAndVerifySelector(start, end, "page-,First,-paragraph");
+  VerifySelector(start, end, "page-,First,-paragraph");
 }
 
 // Check the case when selections ends with an non text node.
@@ -771,7 +792,7 @@
   const auto& end = Position(img, 0);
   ASSERT_EQ("chars\n\n", PlainText(EphemeralRange(start, end)));
 
-  GenerateAndVerifySelector(start, end, "20-,chars");
+  VerifySelector(start, end, "20-,chars");
 }
 
 // Check the case when selections starts at the end of the previous block.
@@ -789,7 +810,7 @@
   const auto& end = Position(second_paragraph, 6);
   ASSERT_EQ("\nSecond", PlainText(EphemeralRange(start, end)));
 
-  GenerateAndVerifySelector(start, end, "paragraph-,Second,-paragraph");
+  VerifySelector(start, end, "paragraph-,Second,-paragraph");
 }
 
 // Check the case when selections starts at the end of the previous block.
@@ -807,7 +828,7 @@
   const auto& end = Position(second_paragraph, 2);
   ASSERT_EQ("First paragraph\n\n", PlainText(EphemeralRange(start, end)));
 
-  GenerateAndVerifySelector(start, end, "First%20paragraph,-Second");
+  VerifySelector(start, end, "First%20paragraph,-Second");
 }
 
 // Checks that for short selection that have nested block element range selector
@@ -825,7 +846,7 @@
   ASSERT_EQ("First\nblock text\nparagraph",
             PlainText(EphemeralRange(start, end)));
 
-  GenerateAndVerifySelector(start, end, "First,paragraph");
+  VerifySelector(start, end, "First,paragraph");
 }
 
 // Basic test case for |GetNextTextBlock|.
diff --git a/third_party/blink/renderer/modules/accessibility/ax_menu_list.cc b/third_party/blink/renderer/modules/accessibility/ax_menu_list.cc
index b0390d8..52fa5ad 100644
--- a/third_party/blink/renderer/modules/accessibility/ax_menu_list.cc
+++ b/third_party/blink/renderer/modules/accessibility/ax_menu_list.cc
@@ -76,13 +76,7 @@
   AXObjectCacheImpl& cache = AXObjectCache();
   AXObject* popup = cache.GetOrCreate(ax::mojom::Role::kMenuListPopup);
   DCHECK(popup);
-
   To<AXMockObject>(popup)->SetParent(this);
-  if (!popup->AccessibilityIsIncludedInTree()) {
-    cache.Remove(popup->AXObjectID());
-    return;
-  }
-
   children_.push_back(popup);
   popup->AddChildren();
 }
diff --git a/third_party/blink/renderer/modules/accessibility/ax_node_object.cc b/third_party/blink/renderer/modules/accessibility/ax_node_object.cc
index bfba8a7..2b2e390 100644
--- a/third_party/blink/renderer/modules/accessibility/ax_node_object.cc
+++ b/third_party/blink/renderer/modules/accessibility/ax_node_object.cc
@@ -465,6 +465,8 @@
   if (role_ == ax::mojom::blink::Role::kRootWebArea)
     return false;
 
+  // TODO(accessibility) In the case of display locking, might we have a stale
+  // pointer to a layout object? Should the display locking case be first?
   if (GetLayoutObject()) {
     if (role_ == ax::mojom::blink::Role::kUnknown) {
       if (ignored_reasons)
@@ -3184,11 +3186,7 @@
     if (obj) {
       auto* area_object = To<AXImageMapLink>(obj);
       DCHECK_NE(area_object->AXObjectID(), 0U);
-      if (area_object->AccessibilityIsIncludedInTree()) {
-        children_.push_back(area_object);
-      } else {
-        AXObjectCache().Remove(area_object->AXObjectID());
-      }
+      children_.push_back(area_object);
     }
   }
 }
diff --git a/third_party/blink/renderer/modules/accessibility/ax_node_object.h b/third_party/blink/renderer/modules/accessibility/ax_node_object.h
index 4715599..fd0624f5 100644
--- a/third_party/blink/renderer/modules/accessibility/ax_node_object.h
+++ b/third_party/blink/renderer/modules/accessibility/ax_node_object.h
@@ -312,13 +312,12 @@
 
   void AddInlineTextBoxChildren(bool force);
   void AddImageMapChildren();
-  void AddHiddenChildren();
   void AddPopupChildren();
   void AddRemoteSVGChildren();
   void AddTableChildren();
   void AddValidationMessageChild();
   // For some nodes, only LayoutBuilderTraversal visits the necessary children.
-  bool ShouldUseLayoutBuilderTraversal() const;
+  bool ShouldUseLayoutBuilderTraversal() const override;
   ax::mojom::blink::Dropeffect ParseDropeffect(String& dropeffect) const;
 
   DISALLOW_COPY_AND_ASSIGN(AXNodeObject);
diff --git a/third_party/blink/renderer/modules/accessibility/ax_object.cc b/third_party/blink/renderer/modules/accessibility/ax_object.cc
index e2551f53..82460e0 100644
--- a/third_party/blink/renderer/modules/accessibility/ax_object.cc
+++ b/third_party/blink/renderer/modules/accessibility/ax_object.cc
@@ -595,6 +595,11 @@
 }
 
 void AXObject::Detach() {
+  DCHECK(ax_object_cache_);
+  DCHECK(!ax_object_cache_->IsFrozen())
+      << "Do not detach children while the tree is frozen, in order to avoid "
+         "an object detaching itself in the middle of computing its own "
+         "accessibility properties.";
   // Clear any children and call detachFromParent on them so that
   // no children are left with dangling pointers to their parent.
   ClearChildren();
@@ -1534,10 +1539,6 @@
   last_modification_count_ = cache.ModificationCount();
 
   cached_background_color_ = ComputeBackgroundColor();
-  // TODO(aleventhal) Temporary crash fix until CL:2485519 lands.
-  if (IsDetached())
-    return;
-
   cached_is_hidden_via_style = ComputeIsHiddenViaStyle();
   cached_is_inert_or_aria_hidden_ = ComputeIsInertOrAriaHidden();
   cached_is_descendant_of_leaf_node_ = !!LeafNodeAncestor();
@@ -1547,6 +1548,19 @@
   cached_is_ignored_ = ComputeAccessibilityIsIgnored();
   cached_is_ignored_but_included_in_tree_ =
       cached_is_ignored_ && ComputeAccessibilityIsIgnoredButIncludedInTree();
+#if DCHECK_IS_ON()
+  // Ensure that display-locked text is pruned from the tree. This means that
+  // they will be missed in the virtual buffer; therefore, it may be a rule
+  // subject to change. Note that changing the rule would potentially cause a
+  // lot of display-locked whitespace to be exposed.
+  if (cached_is_ignored_ &&
+      RoleValue() == ax::mojom::blink::Role::kStaticText && GetNode() &&
+      DisplayLockUtilities::NearestLockedExclusiveAncestor(*GetNode())) {
+    DCHECK(!cached_is_ignored_but_included_in_tree_)
+        << "Display locked text should not be included in the tree (subject to "
+           "future rule change)";
+  }
+#endif
   cached_is_editable_root_ = ComputeIsEditableRoot();
   // Compute live region root, which can be from any ARIA live value, including
   // "off", or from an automatic ARIA live value, e.g. from role="status".
diff --git a/third_party/blink/renderer/modules/accessibility/ax_object.h b/third_party/blink/renderer/modules/accessibility/ax_object.h
index d97c3da..6e0451b 100644
--- a/third_party/blink/renderer/modules/accessibility/ax_object.h
+++ b/third_party/blink/renderer/modules/accessibility/ax_object.h
@@ -1085,6 +1085,8 @@
   virtual AXObject* RawNextSibling() const { return nullptr; }
 
   virtual void AddChildren() {}
+  // For some nodes, only LayoutBuilderTraversal visits the necessary children.
+  virtual bool ShouldUseLayoutBuilderTraversal() const { return false; }
   virtual bool CanHaveChildren() const { return true; }
   bool HasChildren() const { return have_children_; }
   virtual void UpdateChildrenIfNecessary();
diff --git a/third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.cc b/third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.cc
index 6f9f51e..070abe0 100644
--- a/third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.cc
+++ b/third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.cc
@@ -128,9 +128,41 @@
   return document.IsActive() && !document.IsDetached();
 }
 
+// Returns true if |node| is an <option> element and its parent <select>
+// is a menu list (not a list box).
+bool ShouldCreateAXMenuListOptionFor(const Node* node) {
+  auto* option_element = DynamicTo<HTMLOptionElement>(node);
+  if (!option_element)
+    return false;
+  const HTMLSelectElement* select = option_element->OwnerSelectElement();
+  if (!select || !select->UsesMenuList())
+    return false;
+  return select->GetLayoutObject() && AXObjectCacheImpl::UseAXMenuList();
+}
+
+bool IsLayoutObjectRelevantForAccessibility(const Node* node) {
+  return !ShouldCreateAXMenuListOptionFor(node) && !IsA<HTMLAreaElement>(node);
+}
+
+bool IsNodeRelevantForAccessibility(const Node* node) {
+  if (!node || !node->isConnected())
+    return false;
+
+  if (!node->IsElementNode() && !node->IsTextNode() && !node->IsDocumentNode())
+    return false;  // Only documents, elements and text nodes get ax objects.
+
+  if (IsA<HTMLHeadElement>(node))
+    return false;
+
+  return true;
+}
+
 }  // namespace
 
 // static
+bool AXObjectCacheImpl::use_ax_menu_list_ = false;
+
+// static
 AXObjectCache* AXObjectCacheImpl::Create(Document& document) {
   return MakeGarbageCollected<AXObjectCacheImpl>(document);
 }
@@ -148,10 +180,6 @@
     AddPermissionStatusListener();
   documents_.insert(&document);
   use_ax_menu_list_ = GetSettings()->GetUseAXMenuList();
-
-  // Perform last, to ensure AXObjectCacheImpl() is fully set up, as
-  // AXRelationCache() sometimes calls back into AXObjectCacheImpl.
-  relation_cache_->Init();
 }
 
 AXObjectCacheImpl::~AXObjectCacheImpl() {
@@ -288,53 +316,30 @@
   DCHECK(!HashTraits<AXID>::IsDeletedValue(ax_id));
 
   Node* node = layout_object->GetNode();
-  if (node && DisplayLockUtilities::NearestLockedExclusiveAncestor(*node)) {
-    // It's in a locked subtree so we need to search by node instead of by
-    // layout object.
-    if (ax_id) {
-      // We previously saved the node in the cache with its layout object,
-      // but now it's in a locked subtree so we should remove the entry with its
-      // layout object and replace it with an AXNodeObject created from the node
-      // instead.
-      Remove(ax_id);
-      return GetOrCreate(node);
-    }
-    return Get(node);
-  }
 
   if (!ax_id)
-    return nullptr;
+    return node ? Get(node) : nullptr;
+
+  if (node && DisplayLockUtilities::NearestLockedExclusiveAncestor(*node)) {
+    // Change from AXLayoutObject -> AXNodeObject.
+    // We previously saved the node in the cache with its layout object,
+    // but now it's in a locked subtree so we should remove the entry with its
+    // layout object and replace it with an AXNodeObject created from the node
+    // instead. Do this later at a safe time.
+    Invalidate(ax_id);
+  }
 
   return objects_.at(ax_id);
 }
 
-// Returns true if |node| is an <option> element and its parent <select>
-// is a menu list (not a list box).
-static bool IsMenuListOption(const Node* node) {
-  auto* option_element = DynamicTo<HTMLOptionElement>(node);
-  if (!option_element)
-    return false;
-  const HTMLSelectElement* select = option_element->OwnerSelectElement();
-  if (!select || !select->UsesMenuList())
-    return false;
-  return select->GetLayoutObject();
-}
-
-AXObject* AXObjectCacheImpl::GetIfExists(const Node* node) {
-  AXID node_id = node_object_mapping_.at(node);
-  DCHECK(!HashTraits<AXID>::IsDeletedValue(node_id));
-  return node_id ? objects_.at(node_id) : nullptr;
-}
-
-// TODO(aleventhal) Remove side effects or rename, e.g. GetUpdated().
 AXObject* AXObjectCacheImpl::Get(const Node* node) {
   if (!node)
     return nullptr;
 
-  // Menu list option and HTML area elements are indexed by DOM node, never by
-  // layout object.
   LayoutObject* layout_object = node->GetLayoutObject();
-  if (IsMenuListOption(node) || IsA<HTMLAreaElement>(node))
+
+  // Some elements such as <area> are indexed by DOM node, not by layout object.
+  if (!IsLayoutObjectRelevantForAccessibility(node))
     layout_object = nullptr;
 
   AXID layout_id = layout_object ? layout_object_mapping_.at(layout_object) : 0;
@@ -343,45 +348,21 @@
   AXID node_id = node_object_mapping_.at(node);
   DCHECK(!HashTraits<AXID>::IsDeletedValue(node_id));
 
-  if (layout_object &&
+  if (layout_id &&
       DisplayLockUtilities::NearestLockedExclusiveAncestor(*node)) {
+    // Change from AXLayoutObject -> AXNodeObject.
     // The node is in a display locked subtree, but we've previously put it in
     // the cache with its layout object.
-    if (layout_id) {
-      Remove(layout_id);
-      layout_id = 0;
-    }
-    layout_object = nullptr;
-  }
-
-  if (layout_object && node_id && !layout_id && !IsMenuListOption(node) &&
-      !IsA<HTMLAreaElement>(node)) {
+    Invalidate(layout_id);
+  } else if (layout_object && node_id && !layout_id &&
+             !DisplayLockUtilities::NearestLockedExclusiveAncestor(*node)) {
+    // Change from AXNodeObject -> AXLayoutObject.
     // Has a layout object but no layout_id, meaning that when the AXObject was
     // originally created only for Node*, the LayoutObject* didn't exist yet.
     // This can happen if an AXNodeObject is created for a node that's not laid
     // out, but later something changes and it gets a layoutObject (like if it's
     // reparented). It's also possible the layout object changed.
-    // In any case, reuse the ax_id since the node didn't change.
-    Remove(node_id);
-
-    // Note that this codepath can be reached when |layout_object| is about to
-    // be destroyed.
-
-    // This potentially misses root LayoutObject re-creation, but we have no way
-    // of knowing whether the |layout_object| in those cases is still valid.
-    if (!layout_object->Parent())
-      return nullptr;
-
-    layout_object_mapping_.Set(layout_object, node_id);
-    AXObject* new_obj = CreateFromRenderer(layout_object);
-    ids_in_use_.insert(node_id);
-    new_obj->SetAXObjectID(node_id);
-    objects_.Set(node_id, new_obj);
-    new_obj->Init();
-    new_obj->SetLastKnownIsIgnoredValue(new_obj->AccessibilityIsIgnored());
-    new_obj->SetLastKnownIsIgnoredButIncludedInTreeValue(
-        new_obj->AccessibilityIsIgnoredButIncludedInTree());
-    return new_obj;
+    Invalidate(node_id);
   }
 
   if (layout_id)
@@ -405,6 +386,11 @@
   return objects_.at(ax_id);
 }
 
+void AXObjectCacheImpl::Invalidate(AXID ax_id) {
+  if (invalidated_ids_.insert(ax_id).is_new_entry)
+    ScheduleVisualUpdate();
+}
+
 AXID AXObjectCacheImpl::GetAXID(Node* node) {
   AXObject* ax_object = GetOrCreate(node);
   if (!ax_object)
@@ -493,7 +479,7 @@
 }
 
 AXObject* AXObjectCacheImpl::CreateFromNode(Node* node) {
-  if (IsMenuListOption(node) && use_ax_menu_list_) {
+  if (ShouldCreateAXMenuListOptionFor(node)) {
     return MakeGarbageCollected<AXMenuListOption>(To<HTMLOptionElement>(node),
                                                   *this);
   }
@@ -515,7 +501,7 @@
 
   AXObject* new_obj =
       MakeGarbageCollected<AXVirtualObject>(*this, accessible_node);
-  const AXID ax_id = GetOrCreateAXID(new_obj);
+  const AXID ax_id = AssociateAXID(new_obj);
   accessible_node_mapping_.Set(accessible_node, ax_id);
 
   new_obj->Init();
@@ -527,16 +513,20 @@
 }
 
 AXObject* AXObjectCacheImpl::GetOrCreate(Node* node) {
-  if (!node || !node->isConnected())
+  if (!IsNodeRelevantForAccessibility(node))
     return nullptr;
 
-  if (!node->IsElementNode() && !node->IsTextNode() && !node->IsDocumentNode())
-    return nullptr;  // Only documents, elements and text nodes get a11y objects
-
   if (AXObject* obj = Get(node))
     return obj;
 
+  return CreateAndInit(node);
+}
+
+AXObject* AXObjectCacheImpl::CreateAndInit(Node* node, AXID use_axid) {
 #if DCHECK_IS_ON()
+  DCHECK(node);
+  DCHECK(node->isConnected());
+  DCHECK(node->IsElementNode() || node->IsTextNode() || node->IsDocumentNode());
   Document* document = &node->GetDocument();
   DCHECK(document);
   DCHECK(document->Lifecycle().GetState() >=
@@ -547,20 +537,18 @@
   // If the node has a layout object, prefer using that as the primary key for
   // the AXObject, with the exception of the HTMLAreaElement and nodes within
   // a locked subtree, which are created based on its node.
-  if (node->GetLayoutObject() && !IsA<HTMLAreaElement>(node) &&
+  if (node->GetLayoutObject() && IsLayoutObjectRelevantForAccessibility(node) &&
       !DisplayLockUtilities::NearestLockedExclusiveAncestor(*node)) {
-    return GetOrCreate(node->GetLayoutObject());
+    return CreateAndInit(node->GetLayoutObject(), use_axid);
   }
 
-  if (IsA<HTMLHeadElement>(node))
-    return nullptr;
-
   AXObject* new_obj = CreateFromNode(node);
 
   // Will crash later if we have two objects for the same node.
-  DCHECK(!Get(node));
+  DCHECK(!node_object_mapping_.at(node))
+      << "Already have an AXObject for " << node;
 
-  const AXID ax_id = GetOrCreateAXID(new_obj);
+  const AXID ax_id = AssociateAXID(new_obj, use_axid);
   DCHECK(!HashTraits<AXID>::IsDeletedValue(ax_id));
   node_object_mapping_.Set(node, ax_id);
   new_obj->Init();
@@ -579,7 +567,13 @@
   if (AXObject* obj = Get(layout_object))
     return obj;
 
+  return CreateAndInit(layout_object);
+}
+
+AXObject* AXObjectCacheImpl::CreateAndInit(LayoutObject* layout_object,
+                                           AXID use_axid) {
 #if DCHECK_IS_ON()
+  DCHECK(layout_object);
   Document* document = &layout_object->GetDocument();
   DCHECK(document);
   DCHECK(document->Lifecycle().GetState() >=
@@ -587,11 +581,9 @@
       << "Unclean document at lifecycle " << document->Lifecycle().ToString();
 #endif  // DCHECK_IS_ON()
 
-  // Area elements are never created based on layout objects (see |Get|), so we
-  // really should never get here.
   Node* node = layout_object->GetNode();
-  if (node && (IsMenuListOption(node) || IsA<HTMLAreaElement>(node)))
-    return nullptr;
+  DCHECK(!node || IsLayoutObjectRelevantForAccessibility(node))
+      << "Shouldn't get here if the layout object is not relevant for a11y";
 
   // Prefer creating AXNodeObjects over AXLayoutObjects in locked subtrees
   // (e.g. content-visibility: auto), even if a LayoutObject is available,
@@ -612,29 +604,23 @@
       // when there isn't. The locked subtree should not have AXLayoutObjects.
       return nullptr;
     }
-    return GetOrCreate(layout_object->GetNode());
+    return CreateAndInit(node, use_axid);
   }
 
   AXObject* new_obj = CreateFromRenderer(layout_object);
 
   // Will crash later if we have two objects for the same layoutObject.
-  DCHECK(!Get(layout_object));
+  DCHECK(!layout_object_mapping_.at(layout_object))
+      << "Already have an AXObject for " << layout_object;
 
-  const AXID axid = GetOrCreateAXID(new_obj);
-
+  const AXID axid = AssociateAXID(new_obj, use_axid);
   layout_object_mapping_.Set(layout_object, axid);
   new_obj->Init();
   new_obj->SetLastKnownIsIgnoredValue(new_obj->AccessibilityIsIgnored());
   new_obj->SetLastKnownIsIgnoredButIncludedInTreeValue(
       new_obj->AccessibilityIsIgnoredButIncludedInTree());
-  if (node && node->GetLayoutObject() == layout_object) {
-    AXID prev_axid = node_object_mapping_.at(node);
-    if (prev_axid != 0 && prev_axid != axid) {
-      Remove(prev_axid);
-      node_object_mapping_.Set(node, axid);
-    }
+  if (node)
     MaybeNewRelationTarget(node, new_obj);
-  }
 
   return new_obj;
 }
@@ -652,7 +638,7 @@
   // Will crash later if we have two objects for the same inlineTextBox.
   DCHECK(!Get(inline_text_box));
 
-  const AXID axid = GetOrCreateAXID(new_obj);
+  const AXID axid = AssociateAXID(new_obj);
 
   inline_text_box_object_mapping_.Set(inline_text_box, axid);
   new_obj->Init();
@@ -677,7 +663,7 @@
   if (!obj)
     return nullptr;
 
-  GetOrCreateAXID(obj);
+  AssociateAXID(obj);
 
   obj->Init();
   return obj;
@@ -705,7 +691,7 @@
   }
 }
 
-void AXObjectCacheImpl::InvalidateTableSubtree(AXObject* subtree) {
+void AXObjectCacheImpl::RemoveAXObjectsInLayoutSubtree(AXObject* subtree) {
   if (!subtree)
     return;
 
@@ -713,13 +699,24 @@
   if (layout_object) {
     LayoutObject* layout_child = layout_object->SlowFirstChild();
     while (layout_child) {
-      InvalidateTableSubtree(Get(layout_child));
+      RemoveAXObjectsInLayoutSubtree(Get(layout_child));
       layout_child = layout_child->NextSibling();
     }
   }
 
-  AXID ax_id = subtree->AXObjectID();
-  Remove(ax_id);
+  Remove(subtree);
+}
+
+void AXObjectCacheImpl::Remove(AXObject* object) {
+  DCHECK(object);
+  if (object->GetNode())
+    Remove(object->GetNode());
+  else if (object->GetLayoutObject())
+    Remove(object->GetLayoutObject());
+  else if (object->GetAccessibleNode())
+    Remove(object->GetAccessibleNode());
+  else
+    Remove(object->AXObjectID());
 }
 
 void AXObjectCacheImpl::Remove(AXID ax_id) {
@@ -802,15 +799,11 @@
   fixed_or_sticky_node_ids_.insert(object->AXObjectID());
 }
 
-AXID AXObjectCacheImpl::GetOrCreateAXID(AXObject* obj) {
-  // check for already-assigned ID
-  const AXID existing_axid = obj->AXObjectID();
-  if (existing_axid) {
-    DCHECK(ids_in_use_.Contains(existing_axid));
-    return existing_axid;
-  }
+AXID AXObjectCacheImpl::AssociateAXID(AXObject* obj, AXID use_axid) {
+  // Check for already-assigned ID.
+  DCHECK(!obj->AXObjectID()) << "Object should not already have an AXID";
 
-  const AXID new_axid = GenerateAXID();
+  const AXID new_axid = use_axid ? use_axid : GenerateAXID();
 
   ids_in_use_.insert(new_axid);
   obj->SetAXObjectID(new_axid);
@@ -965,9 +958,6 @@
   DeferTreeUpdateInternal(std::move(callback), node);
 }
 
-// TODO(accessibility) PostNotification calls made when layout is unclean should
-// use this instead, in order to avoid potentially unsafe calls to Get(), which
-// can call CreateFromRenderer(). For an example, see CheckedStateChanged().
 void AXObjectCacheImpl::DeferTreeUpdate(
     void (AXObjectCacheImpl::*method)(Node* node,
                                       ax::mojom::blink::Event event),
@@ -1213,7 +1203,7 @@
   // changed.
   DCHECK(node);
   while (node) {
-    if (AXObject* obj = GetIfExists(node)) {
+    if (AXObject* obj = Get(node)) {
       TextChanged(node);
       return;
     }
@@ -1236,6 +1226,10 @@
   if (!layout_object)
     return;
 
+  // Ensure that this object is touched, so that Get() can Invalidate() it if
+  // necessary, e.g. to change whether it's an AXNodeObject <--> AXLayoutObject.
+  AXObject* ax_layout_obj = Get(layout_object);
+
   // Update using nearest node (walking ancestors if necessary).
   Node* node = GetClosestNodeForLayoutObject(layout_object);
 
@@ -1256,7 +1250,6 @@
 
   // Update using layout object.
   // Only using the layout object when no node could be found to update.
-  AXObject* ax_layout_obj = Get(layout_object);
   if (!ax_layout_obj)
     return;
 
@@ -1303,6 +1296,12 @@
   if (!node)
     return;
 
+  LayoutObject* layout_object = node->GetLayoutObject();
+  AXID layout_id = layout_object ? layout_object_mapping_.at(layout_object) : 0;
+  DCHECK(!HashTraits<AXID>::IsDeletedValue(layout_id));
+
+  AXID node_id = node_object_mapping_.at(node);
+  DCHECK(!HashTraits<AXID>::IsDeletedValue(node_id));
   DCHECK(!node->GetDocument().NeedsLayoutTreeUpdateForNode(*node));
 
   ChildrenChangedWithCleanLayout(node, Get(node));
@@ -1337,18 +1336,34 @@
     return;
   }
 
-  ProcessUpdates(document);
+  // Destroy and recreate any objects which are no longer valid, for example
+  // they used AXNodeObject and now must be an AXLayoutObject, or vice-versa.
+  // Also fires children changed on the parent of these nodes.
+  ProcessInvalidatedObjects(document);
+
+  // Call the queued callback methods that do processing which must occur when
+  // layout is clean. These callbacks are stored in tree_update_callback_queue_,
+  // and have names like FooBarredWithCleanLayout().
+  ProcessCleanLayoutCallbacks(document);
 
   // Changes to ids or aria-owns may have resulted in queued up relation
   // cache work; do that now.
   relation_cache_->ProcessUpdatesWithCleanLayout();
 
+  // Perform this step a second time, to refresh any new invalidated objects
+  // from the previous deferred processing steps.
+  ProcessInvalidatedObjects(document);
+
+  // Send events to RenderAccessibilityImpl, which serializes them and then
+  // sends the serialized events and dirty objects to the browser process.
   PostNotifications(document);
 }
 
 bool AXObjectCacheImpl::IsDirty() const {
-  return !tree_updates_paused_ &&
-         (tree_update_callback_queue_.size() || notifications_to_post_.size());
+  if (tree_updates_paused_)
+    return false;
+  return tree_update_callback_queue_.size() || notifications_to_post_.size() ||
+         invalidated_ids_.size();
 }
 
 void AXObjectCacheImpl::EmbeddingTokenChanged(HTMLFrameOwnerElement* element) {
@@ -1358,7 +1373,73 @@
   MarkElementDirty(element, false);
 }
 
-void AXObjectCacheImpl::ProcessUpdates(Document& document) {
+void AXObjectCacheImpl::ProcessInvalidatedObjects(Document& document) {
+  HashSet<AXID> wrong_document_invalidated_ids;
+  HashSet<AXID> old_invalidated_ids;
+  HashSet<AXID> pending_children_changed_ids;
+
+  // Create a new object with the same AXID as the old one.
+  // Currently only supported for objects with a backing node.
+  // Returns the new object.
+  auto refresh = [this](AXObject* current) {
+    Node* node = current->GetNode();
+    DCHECK(node) << "Refresh() is currently only supported for objects "
+                    "with a backing node";
+    AXID retained_axid = current->AXObjectID();
+    Remove(current);
+    return CreateAndInit(node, retained_axid);
+  };
+
+  while (!invalidated_ids_.IsEmpty()) {
+    // ChildrenChanged() below may invalidate more objects. This outer loop
+    // ensures all newly invalid objects are caught and refreshed before the
+    // function returns.
+    old_invalidated_ids.swap(invalidated_ids_);
+    for (AXID ax_id : old_invalidated_ids) {
+      AXObject* object = ObjectFromAXID(ax_id);
+      if (!object || object->IsDetached())
+        continue;
+      if (object->GetDocument() != &document) {
+        // Wrong document -- this AXObjectCache processes the current popup
+        // document too. Keep the ID around until its document is processed.
+        wrong_document_invalidated_ids.insert(ax_id);
+        continue;
+      }
+
+      bool did_use_layout_builder_traversal =
+          object->ShouldUseLayoutBuilderTraversal();
+      AXObject* parent = object->ParentObjectIncludedInTree();
+      AXObject* new_object = refresh(object);
+
+      // Children might change because child traversal style changed.
+      if (new_object->ShouldUseLayoutBuilderTraversal() !=
+          did_use_layout_builder_traversal) {
+        // TODO(accessibility) Need test for this, e.g. for continuations.
+        pending_children_changed_ids.insert(ax_id);
+      }
+
+      // Queue up a ChildrenChanged() call for this parent.
+      if (parent && parent != object)
+        pending_children_changed_ids.insert(parent->AXObjectID());
+    }
+    // Update parents' children.
+    for (AXID parent_id : pending_children_changed_ids) {
+      AXObject* parent = ObjectFromAXID(parent_id);
+      if (parent) {
+        // Invalidate the parent's children.
+        ChildrenChangedWithCleanLayout(parent->GetNode(), parent);
+        // Update children now.
+        parent->UpdateChildrenIfNecessary();
+      }
+    }
+    old_invalidated_ids.clear();
+    pending_children_changed_ids.clear();
+  }
+  // Invalidate these objects when their document is clean.
+  invalidated_ids_.swap(wrong_document_invalidated_ids);
+}
+
+void AXObjectCacheImpl::ProcessCleanLayoutCallbacks(Document& document) {
   SCOPED_DISALLOW_LIFECYCLE_TRANSITION(document);
 
   if (tree_updates_paused_) {
@@ -1435,8 +1516,6 @@
   PostNotification(Get(layout_object), notification);
 }
 
-// TODO(accessibility) Eventually replace direct calls during unclean layout
-// with deferred calls.
 void AXObjectCacheImpl::PostNotification(Node* node,
                                          ax::mojom::blink::Event notification) {
   if (!node)
@@ -1688,8 +1767,6 @@
   if (node->GetDocument().NeedsLayoutTreeUpdateForNode(*node)) {
     // This should only occur when focus goes into a popup document. The main
     // document has an updated layout, but the popup does not.
-    // TODO(accessibility) design callback system so that popup processing
-    // can occur with a clean layout.
     DCHECK_NE(document_, node->GetDocument());
     node->GetDocument().View()->UpdateLifecycleToCompositingCleanPlusScrolling(
         DocumentUpdateReason::kAccessibility);
@@ -1751,49 +1828,23 @@
 
   // Invalidate the current object and make the parent reconsider its children.
   if (AXObject* obj = GetOrCreate(node)) {
-    // Save parent for later use.
-    AXObject* parent = obj->ParentObject();
-
     // If role changes on a table, invalidate the entire table subtree as many
     // objects may suddenly need to change, because presentation is inherited
     // from the table to rows and cells.
     LayoutObject* layout_object = node->GetLayoutObject();
-    if (layout_object && layout_object->IsTable())
-      InvalidateTableSubtree(obj);
-    else
-      Remove(node);
-
-    // Parent object changed children, as the previous AXObject for this node
-    // was destroyed and a different one was created in its place.
-    if (parent)
-      ChildrenChangedWithCleanLayout(parent->GetNode(), parent);
-    modification_count_++;
+    if (layout_object && layout_object->IsTable()) {
+      AXObject* parent = obj->ParentObject();
+      RemoveAXObjectsInLayoutSubtree(obj);
+      // Parent object changed children, as the previous AXObject for this node
+      // was destroyed and a different one was created in its place.
+      ChildrenChangedWithCleanLayout(nullptr, parent);
+    } else {
+      // Will both refresh the object and call ChildrenChanged() on the parent.
+      Invalidate(obj->AXObjectID());
+    }
   }
 }
 
-void AXObjectCacheImpl::HandleRoleChangeIfNotEditableWithCleanLayout(
-    Node* node) {
-  if (!node)
-    return;
-
-  DCHECK(!node->GetDocument().NeedsLayoutTreeUpdateForNode(*node));
-
-  // Do not invalidate object if the role doesn't actually change when it's a
-  // text control, otherwise unique id will change on platform side, and confuse
-  // some screen readers as user edits.
-  // TODO(aleventhal) Ideally the text control check would be removed, and
-  // HandleRoleChangeWithCleanLayout() and only ever invalidate when the role
-  // actually changes. For example:
-  // if (obj->RoleValue() == obj->ComputeAccessibilityRole())
-  //   return;
-  // However, doing that would require
-  // waiting for layout to complete, as ComputeAccessibilityRole() looks at
-  // layout objects.
-  AXObject* obj = Get(node);
-  if (!obj || !obj->IsTextControl())
-    HandleRoleChangeWithCleanLayout(node);
-}
-
 void AXObjectCacheImpl::HandleAttributeChanged(const QualifiedName& attr_name,
                                                Element* element) {
   DCHECK(element);
@@ -1811,8 +1862,12 @@
     HandleRoleChangeWithCleanLayout(element);
   } else if (attr_name == html_names::kSizeAttr ||
              attr_name == html_names::kAriaHaspopupAttr) {
-    // Role won't change on edits.
-    HandleRoleChangeIfNotEditableWithCleanLayout(element);
+    // Role won't change on edits, so avoid invalidation so that object is not
+    // destroyed during editing.
+    if (AXObject* obj = Get(element)) {
+      if (!obj->IsTextControl())
+        HandleRoleChangeWithCleanLayout(element);
+    }
   } else if (attr_name == html_names::kAltAttr ||
              attr_name == html_names::kTitleAttr) {
     TextChangedWithCleanLayout(element);
@@ -1850,7 +1905,6 @@
     TextChangedWithCleanLayout(element);
   } else if (attr_name == html_names::kAriaDescriptionAttr ||
              attr_name == html_names::kAriaDescribedbyAttr) {
-    // TODO do we need a DescriptionChanged() ?
     TextChangedWithCleanLayout(element);
   } else if (attr_name == html_names::kAriaCheckedAttr ||
              attr_name == html_names::kAriaPressedAttr) {
@@ -1883,7 +1937,7 @@
     message_ax_object = MakeGarbageCollected<AXValidationMessage>(*this);
     DCHECK(message_ax_object);
     // Cache the validation message container for reuse.
-    validation_message_axid_ = GetOrCreateAXID(message_ax_object);
+    validation_message_axid_ = AssociateAXID(message_ax_object);
     message_ax_object->Init();
     // Validation message alert object is a child of the document, as not all
     // form controls can have a child. Also, there are form controls such as
diff --git a/third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.h b/third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.h
index 210320f..118aceb 100644
--- a/third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.h
+++ b/third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.h
@@ -75,6 +75,10 @@
 
   void Dispose() override;
 
+  void Freeze() override { is_frozen_ = true; }
+  void Thaw() override { is_frozen_ = false; }
+  bool IsFrozen() { return is_frozen_; }
+
   // Register/remove popups
   void InitializePopup(Document* document) override;
   void DisposePopup(Document* document) override;
@@ -179,8 +183,9 @@
   AXObject* ObjectFromAXID(AXID id) const { return objects_.at(id); }
   AXObject* Root();
 
-  // used for objects without backing elements
+  // Used for objects without backing elements.
   AXObject* GetOrCreate(ax::mojom::blink::Role);
+
   AXObject* GetOrCreate(AccessibleNode*);
   AXObject* GetOrCreate(LayoutObject*) override;
   AXObject* GetOrCreate(const Node*);
@@ -190,21 +195,14 @@
   AXID GetAXID(Node*) override;
   Element* GetElementFromAXID(AXID) override;
 
-  // Will only return the AXObject if it already exists.
-  AXObject* GetIfExists(const Node*);
   AXObject* Get(AccessibleNode*);
   AXObject* Get(AbstractInlineTextBox*);
 
-  // These can actually return a different AXObject* if it's determined that
-  // the wrong type currently axists (AXNodeObject vs AXLayoutObject).
-  // TODO(aleventhal) These should not have any side effects.
   AXObject* Get(const Node*) override;
   AXObject* Get(const LayoutObject*);
 
   AXObject* FirstAccessibleObjectFromNode(const Node*);
 
-  void Remove(AXID);
-
   void ChildrenChangedWithCleanLayout(Node* optional_node_for_relation_update,
                                       AXObject*);
 
@@ -212,7 +210,6 @@
 
   void HandleActiveDescendantChangedWithCleanLayout(Node*);
   void HandleRoleChangeWithCleanLayout(Node*);
-  void HandleRoleChangeIfNotEditableWithCleanLayout(Node*);
   void HandleAriaExpandedChangeWithCleanLayout(Node*);
   void HandleAriaSelectedChangedWithCleanLayout(Node*);
   void HandleNodeLostFocusWithCleanLayout(Node*);
@@ -292,7 +289,7 @@
 
   AXObject* GetActiveAriaModalDialog() const;
 
-  bool UseAXMenuList() { return use_ax_menu_list_; }
+  static bool UseAXMenuList() { return use_ax_menu_list_; }
 
   // Retrieves a vector of all AXObjects whose bounding boxes may have changed
   // since the last query. Clears the vector so that the next time it's
@@ -313,9 +310,22 @@
     return active_event_intents_;
   }
 
+  // Create an AXObject, and do not check if a previous one exists.
+  // Also, initialize the object and add it to maps for later retrieval.
+  AXObject* CreateAndInit(Node*, AXID use_axid = 0);
+  AXObject* CreateAndInit(LayoutObject*, AXID use_axid = 0);
+
+  // Mark object as invalid and needing to be refreshed when layout is clean.
+  // Will result in a new object with the same AXID, and will also call
+  // ChildrenChanged() on the parent of invalidated objects. Automatically
+  // de-dupes extra object refreshes and ChildrenChanged() calls.
+  void Invalidate(AXID);
+
   AXObject* CreateFromRenderer(LayoutObject*);
   AXObject* CreateFromNode(Node*);
   AXObject* CreateFromInlineTextBox(AbstractInlineTextBox*);
+  void Remove(AXID);
+  void Remove(AXObject*);  // Calls more specific Remove methods as necessary.
 
  private:
   struct AXEventParams final : public GarbageCollected<AXEventParams> {
@@ -393,7 +403,18 @@
 
   HeapVector<Member<AXEventParams>> notifications_to_post_;
 
-  void ProcessUpdates(Document&);
+  // Call the queued callback methods that do processing which must occur when
+  // layout is clean. These callbacks are stored in tree_update_callback_queue_,
+  // and have names like FooBarredWithCleanLayout().
+  void ProcessCleanLayoutCallbacks(Document&);
+
+  // Destroy and recreate any objects which are no longer valid, for example
+  // they used to be an AXNodeObject and now must be an AXLayoutObject, or
+  // vice-versa. Also fires children changed on the parent of these nodes.
+  void ProcessInvalidatedObjects(Document&);
+
+  // Send events to RenderAccessibilityImpl, which serializes them and then
+  // sends the serialized events and dirty objects to the browser process.
   void PostNotifications(Document&);
 
   // Get the currently focused Node element.
@@ -404,7 +425,8 @@
 
   AXObject* FocusedImageMapUIElement(HTMLAreaElement*);
 
-  AXID GetOrCreateAXID(AXObject*);
+  // Associate an AXObject with an AXID. Generate one if none is supplied.
+  AXID AssociateAXID(AXObject*, AXID use_axid = 0);
 
   void TextChanged(Node*);
   bool NodeIsTextControl(const Node*);
@@ -425,7 +447,7 @@
   void ContainingTableRowsOrColsMaybeChanged(Node*);
 
   // Must be called an entire subtree of accessible objects are no longer valid.
-  void InvalidateTableSubtree(AXObject* subtree);
+  void RemoveAXObjectsInLayoutSubtree(AXObject* subtree);
 
   // Object for HTML validation alerts. Created at most once per object cache.
   AXObject* GetOrCreateValidationMessageObject();
@@ -541,9 +563,14 @@
   // A set of currently active event intents.
   BlinkAXEventIntentsSet active_event_intents_;
 
+  bool is_frozen_ = false;  // Used with Freeze(), Thaw() and IsFrozen() above.
+
+  // Set of ID's of current AXObjects that need to be destroyed and recreated.
+  HashSet<AXID> invalidated_ids_;
+
   // If false, exposes the internal accessibility tree of a select pop-up
   // instead.
-  bool use_ax_menu_list_ = true;
+  static bool use_ax_menu_list_;
 
   DISALLOW_COPY_AND_ASSIGN(AXObjectCacheImpl);
 
diff --git a/third_party/blink/renderer/modules/accessibility/ax_object_cache_test.cc b/third_party/blink/renderer/modules/accessibility/ax_object_cache_test.cc
index d78827c..c6a8edc8 100644
--- a/third_party/blink/renderer/modules/accessibility/ax_object_cache_test.cc
+++ b/third_party/blink/renderer/modules/accessibility/ax_object_cache_test.cc
@@ -80,13 +80,13 @@
   ax_object_cache->SetMaxPendingUpdatesForTesting(max_updates);
 
   MockAXObject* ax_obj = MakeGarbageCollected<MockAXObject>(*ax_object_cache);
-  ax_obj->SetAXObjectID(ax_object_cache->GetOrCreateAXID(ax_obj));
+  ax_object_cache->AssociateAXID(ax_obj);
   for (unsigned i = 0; i < max_updates + 1; i++) {
     ax_object_cache->DeferTreeUpdate(
         &AXObjectCacheImpl::ChildrenChangedWithCleanLayout, nullptr, ax_obj);
   }
   document.Lifecycle().AdvanceTo(DocumentLifecycle::kInAccessibility);
-  ax_object_cache->ProcessUpdates(document);
+  ax_object_cache->ProcessCleanLayoutCallbacks(document);
 
   ASSERT_EQ(0u, MockAXObject::num_children_changed_calls_);
 }
diff --git a/third_party/blink/renderer/modules/accessibility/ax_relation_cache.cc b/third_party/blink/renderer/modules/accessibility/ax_relation_cache.cc
index ab78f47..af827e4 100644
--- a/third_party/blink/renderer/modules/accessibility/ax_relation_cache.cc
+++ b/third_party/blink/renderer/modules/accessibility/ax_relation_cache.cc
@@ -15,7 +15,7 @@
 
 AXRelationCache::~AXRelationCache() = default;
 
-void AXRelationCache::Init() {
+void AXRelationCache::DoInitialDocumentScan() {
   // Init the relation cache with elements already in the document.
   Document& document = object_cache_->GetDocument();
   for (Element& element :
@@ -29,14 +29,20 @@
     // Defers adding aria-owns targets as children of their new parents,
     // and to the relation cache, until the appropriate document lifecycle.
     if (element.FastHasAttribute(html_names::kAriaOwnsAttr)) {
+      // FIXME(accessibility) This can be a dangerous time to GetOrCreate().
       if (AXObject* owner = GetOrCreate(&element)) {
         owner_ids_to_update_.insert(owner->AXObjectID());
       }
     }
   }
+
+  initialized_ = true;
 }
 
 void AXRelationCache::ProcessUpdatesWithCleanLayout() {
+  if (!initialized_)
+    DoInitialDocumentScan();
+
   for (AXID aria_owns_obj_id : owner_ids_to_update_) {
     AXObject* obj = ObjectFromAXID(aria_owns_obj_id);
     if (obj)
diff --git a/third_party/blink/renderer/modules/accessibility/ax_relation_cache.h b/third_party/blink/renderer/modules/accessibility/ax_relation_cache.h
index 20a0fb8e..0f06a80c 100644
--- a/third_party/blink/renderer/modules/accessibility/ax_relation_cache.h
+++ b/third_party/blink/renderer/modules/accessibility/ax_relation_cache.h
@@ -26,9 +26,6 @@
   // Safe to call at any time. Doesn't make any changes to the tree.
   //
 
-  // Scan the initial document.
-  void Init();
-
   // Returns true if the given object's position in the tree was due to
   // aria-owns.
   bool IsAriaOwned(const AXObject*) const;
@@ -108,6 +105,10 @@
       AXObject* owner,
       HeapVector<Member<AXObject>>& validated_owned_children_result);
 
+  // Whether the document has been scanned for initial relationships
+  // first or not.
+  bool initialized_ = false;
+
   WeakPersistent<AXObjectCacheImpl> object_cache_;
 
   // Map from the AXID of the owner to the AXIDs of the children.
@@ -148,6 +149,10 @@
   AXObject* Get(Node*);
   void ChildrenChanged(AXObject*);
 
+  // Do an initial scan of the document to find any relationships.
+  // We'll catch any subsequent ones when attributes change.
+  void DoInitialDocumentScan();
+
   DISALLOW_COPY_AND_ASSIGN(AXRelationCache);
 };
 
diff --git a/third_party/blink/renderer/modules/canvas/canvas2d/base_rendering_context_2d.cc b/third_party/blink/renderer/modules/canvas/canvas2d/base_rendering_context_2d.cc
index c93bda1..7cceee8 100644
--- a/third_party/blink/renderer/modules/canvas/canvas2d/base_rendering_context_2d.cc
+++ b/third_party/blink/renderer/modules/canvas/canvas2d/base_rendering_context_2d.cc
@@ -1696,12 +1696,14 @@
 
   // TODO(crbug.com/1101055): Remove the check for NewCanvas2DAPI flag once
   // released.
-  // New Canvas2D API utilizes willReadFrequently attribute that let the users
-  // indicate if a canvas will be read frequently through getImageData, thus
-  // uses CPU rendering from the start in such cases. (crbug.com/1090180)
+  // TODO(crbug.com/1090180): New Canvas2D API utilizes willReadFrequently
+  // attribute that let the users indicate if a canvas will be read frequently
+  // through getImageData, thus uses CPU rendering from the start in such cases.
   if (!RuntimeEnabledFeatures::NewCanvas2DAPIEnabled()) {
-    // GetImagedata is faster in Unaccelerated canvases
-    if (IsAccelerated()) {
+    // GetImagedata is faster in Unaccelerated canvases.
+    // In Desynchronized canvas disabling the acceleration will break
+    // putImageData: crbug.com/1112060.
+    if (IsAccelerated() && !IsDesynchronized()) {
       DisableAcceleration();
       base::UmaHistogramEnumeration("Blink.Canvas.GPUFallbackToCPU",
                                     GPUFallbackToCPUScenario::kGetImageData);
diff --git a/third_party/blink/renderer/modules/canvas/canvas2d/base_rendering_context_2d.h b/third_party/blink/renderer/modules/canvas/canvas2d/base_rendering_context_2d.h
index 078234e4..a27a93d 100644
--- a/third_party/blink/renderer/modules/canvas/canvas2d/base_rendering_context_2d.h
+++ b/third_party/blink/renderer/modules/canvas/canvas2d/base_rendering_context_2d.h
@@ -253,6 +253,11 @@
 
   virtual bool HasAlpha() const = 0;
 
+  virtual bool IsDesynchronized() const {
+    NOTREACHED();
+    return false;
+  }
+
   virtual bool isContextLost() const = 0;
 
   virtual void WillDrawImage(CanvasImageSource*) const {}
diff --git a/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d.h b/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d.h
index 21b6211..68097c18 100644
--- a/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d.h
+++ b/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d.h
@@ -278,6 +278,9 @@
   bool IsAccelerated() const override;
   bool IsOriginTopLeft() const override;
   bool HasAlpha() const override { return CreationAttributes().alpha; }
+  bool IsDesynchronized() const override {
+    return CreationAttributes().desynchronized;
+  }
   void SetIsInHiddenPage(bool) override;
   void SetIsBeingDisplayed(bool) override;
   void Stop() final;
diff --git a/third_party/blink/renderer/modules/canvas/offscreencanvas2d/offscreen_canvas_rendering_context_2d.h b/third_party/blink/renderer/modules/canvas/offscreencanvas2d/offscreen_canvas_rendering_context_2d.h
index 7a427ac..d5534b2 100644
--- a/third_party/blink/renderer/modules/canvas/offscreencanvas2d/offscreen_canvas_rendering_context_2d.h
+++ b/third_party/blink/renderer/modules/canvas/offscreencanvas2d/offscreen_canvas_rendering_context_2d.h
@@ -122,6 +122,9 @@
   void ValidateStateStackWithCanvas(const cc::PaintCanvas*) const final;
 
   bool HasAlpha() const final { return CreationAttributes().alpha; }
+  bool IsDesynchronized() const final {
+    return CreationAttributes().desynchronized;
+  }
   bool isContextLost() const override;
 
   ImageBitmap* TransferToImageBitmap(ScriptState*) final;
diff --git a/third_party/blink/renderer/modules/exported/web_ax_object.cc b/third_party/blink/renderer/modules/exported/web_ax_object.cc
index cecb6b6e..9156033 100644
--- a/third_party/blink/renderer/modules/exported/web_ax_object.cc
+++ b/third_party/blink/renderer/modules/exported/web_ax_object.cc
@@ -240,7 +240,6 @@
 unsigned WebAXObject::ChildCount() const {
   if (IsDetached())
     return 0;
-
   return private_->ChildCountIncludingIgnored();
 }
 
@@ -1571,4 +1570,20 @@
   return true;
 }
 
+// static
+void WebAXObject::Freeze(const WebDocument& web_document) {
+  const Document* doc = web_document.ConstUnwrap<Document>();
+  auto* cache = To<AXObjectCacheImpl>(doc->ExistingAXObjectCache());
+  if (cache)
+    cache->Freeze();
+}
+
+// static
+void WebAXObject::Thaw(const WebDocument& web_document) {
+  const Document* doc = web_document.ConstUnwrap<Document>();
+  auto* cache = To<AXObjectCacheImpl>(doc->ExistingAXObjectCache());
+  if (cache)
+    cache->Thaw();
+}
+
 }  // namespace blink
diff --git a/third_party/blink/renderer/modules/mediastream/media_stream_track_generator_test.cc b/third_party/blink/renderer/modules/mediastream/media_stream_track_generator_test.cc
index c8291f7..0e8b0e29 100644
--- a/third_party/blink/renderer/modules/mediastream/media_stream_track_generator_test.cc
+++ b/third_party/blink/renderer/modules/mediastream/media_stream_track_generator_test.cc
@@ -32,8 +32,8 @@
 ScriptValue CreateVideoFrameChunk(ScriptState* script_state) {
   const scoped_refptr<media::VideoFrame> media_frame =
       media::VideoFrame::CreateBlackFrame(gfx::Size(10, 5));
-  VideoFrame* video_frame =
-      MakeGarbageCollected<VideoFrame>(std::move(media_frame));
+  VideoFrame* video_frame = MakeGarbageCollected<VideoFrame>(
+      std::move(media_frame), ExecutionContext::From(script_state));
   return ScriptValue(script_state->GetIsolate(),
                      ToV8(video_frame, script_state->GetContext()->Global(),
                           script_state->GetIsolate()));
diff --git a/third_party/blink/renderer/modules/mediastream/media_stream_video_track_underlying_sink_test.cc b/third_party/blink/renderer/modules/mediastream/media_stream_video_track_underlying_sink_test.cc
index 915c354..113b954 100644
--- a/third_party/blink/renderer/modules/mediastream/media_stream_video_track_underlying_sink_test.cc
+++ b/third_party/blink/renderer/modules/mediastream/media_stream_video_track_underlying_sink_test.cc
@@ -56,8 +56,8 @@
   ScriptValue CreateVideoFrameChunk(ScriptState* script_state) {
     const scoped_refptr<media::VideoFrame> media_frame =
         media::VideoFrame::CreateBlackFrame(gfx::Size(100, 50));
-    VideoFrame* video_frame =
-        MakeGarbageCollected<VideoFrame>(std::move(media_frame));
+    VideoFrame* video_frame = MakeGarbageCollected<VideoFrame>(
+        std::move(media_frame), ExecutionContext::From(script_state));
     return ScriptValue(script_state->GetIsolate(),
                        ToV8(video_frame, script_state->GetContext()->Global(),
                             script_state->GetIsolate()));
diff --git a/third_party/blink/renderer/modules/mediastream/media_stream_video_track_underlying_source.cc b/third_party/blink/renderer/modules/mediastream/media_stream_video_track_underlying_source.cc
index a4c98fb..d8d3a17 100644
--- a/third_party/blink/renderer/modules/mediastream/media_stream_video_track_underlying_source.cc
+++ b/third_party/blink/renderer/modules/mediastream/media_stream_video_track_underlying_source.cc
@@ -97,8 +97,8 @@
   if (!Controller() || Controller()->DesiredSize() < 0)
     return;
 
-  VideoFrame* video_frame =
-      MakeGarbageCollected<VideoFrame>(std::move(media_frame));
+  VideoFrame* video_frame = MakeGarbageCollected<VideoFrame>(
+      std::move(media_frame), GetExecutionContext());
   Controller()->Enqueue(video_frame);
 }
 
diff --git a/third_party/blink/renderer/modules/webcodecs/BUILD.gn b/third_party/blink/renderer/modules/webcodecs/BUILD.gn
index b4090bd..8932305 100644
--- a/third_party/blink/renderer/modules/webcodecs/BUILD.gn
+++ b/third_party/blink/renderer/modules/webcodecs/BUILD.gn
@@ -43,6 +43,8 @@
     "video_frame_attachment.h",
     "video_frame_handle.cc",
     "video_frame_handle.h",
+    "video_frame_logger.cc",
+    "video_frame_logger.h",
     "video_track_reader.cc",
     "video_track_reader.h",
     "video_track_writer.cc",
diff --git a/third_party/blink/renderer/modules/webcodecs/audio_decoder.cc b/third_party/blink/renderer/modules/webcodecs/audio_decoder.cc
index a103883..1e194d51 100644
--- a/third_party/blink/renderer/modules/webcodecs/audio_decoder.cc
+++ b/third_party/blink/renderer/modules/webcodecs/audio_decoder.cc
@@ -18,6 +18,7 @@
 #include "third_party/blink/renderer/bindings/modules/v8/v8_audio_decoder_init.h"
 #include "third_party/blink/renderer/bindings/modules/v8/v8_encoded_audio_chunk.h"
 #include "third_party/blink/renderer/modules/webcodecs/audio_decoder_broker.h"
+#include "third_party/blink/renderer/modules/webcodecs/audio_frame.h"
 #include "third_party/blink/renderer/modules/webcodecs/codec_config_eval.h"
 #include "third_party/blink/renderer/platform/instrumentation/use_counter.h"
 
@@ -50,6 +51,14 @@
 }
 
 // static
+AudioDecoderTraits::OutputType* AudioDecoderTraits::MakeOutput(
+    scoped_refptr<MediaOutputType> output,
+    ExecutionContext* context) {
+  return MakeGarbageCollected<AudioDecoderTraits::OutputType>(
+      std::move(output));
+}
+
+// static
 void AudioDecoderTraits::InitializeDecoder(
     MediaDecoderType& decoder,
     const MediaConfigType& media_config,
diff --git a/third_party/blink/renderer/modules/webcodecs/audio_decoder.h b/third_party/blink/renderer/modules/webcodecs/audio_decoder.h
index 6a11d19..d929a9c3 100644
--- a/third_party/blink/renderer/modules/webcodecs/audio_decoder.h
+++ b/third_party/blink/renderer/modules/webcodecs/audio_decoder.h
@@ -65,6 +65,8 @@
   static void UpdateDecoderLog(const MediaDecoderType& decoder,
                                const MediaConfigType& media_config,
                                media::MediaLog* media_log);
+  static OutputType* MakeOutput(scoped_refptr<MediaOutputType>,
+                                ExecutionContext*);
 };
 
 class MODULES_EXPORT AudioDecoder : public DecoderTemplate<AudioDecoderTraits> {
diff --git a/third_party/blink/renderer/modules/webcodecs/decoder_template.cc b/third_party/blink/renderer/modules/webcodecs/decoder_template.cc
index e97d94af..5efb6a2 100644
--- a/third_party/blink/renderer/modules/webcodecs/decoder_template.cc
+++ b/third_party/blink/renderer/modules/webcodecs/decoder_template.cc
@@ -586,8 +586,12 @@
   if (state_.AsEnum() != V8CodecState::Enum::kConfigured)
     return;
 
+  auto* context = GetExecutionContext();
+  if (!context)
+    return;
+
   output_cb_->InvokeAndReportException(
-      nullptr, MakeGarbageCollected<OutputType>(output));
+      nullptr, Traits::MakeOutput(std::move(output), context));
 }
 
 template <typename Traits>
diff --git a/third_party/blink/renderer/modules/webcodecs/fuzzer_utils.cc b/third_party/blink/renderer/modules/webcodecs/fuzzer_utils.cc
index e85b2c77..73ca5ffd 100644
--- a/third_party/blink/renderer/modules/webcodecs/fuzzer_utils.cc
+++ b/third_party/blink/renderer/modules/webcodecs/fuzzer_utils.cc
@@ -146,7 +146,8 @@
   return options;
 }
 
-VideoFrame* MakeVideoFrame(const wc_fuzzer::VideoFrameBitmapInit& proto) {
+VideoFrame* MakeVideoFrame(ScriptState* script_state,
+                           const wc_fuzzer::VideoFrameBitmapInit& proto) {
   NotShared<DOMUint8ClampedArray> data_u8(DOMUint8ClampedArray::Create(
       reinterpret_cast<const unsigned char*>(proto.rgb_bitmap().data()),
       proto.rgb_bitmap().size()));
@@ -164,7 +165,7 @@
   video_frame_init->setTimestamp(proto.timestamp());
   video_frame_init->setDuration(proto.duration());
 
-  return VideoFrame::Create(image_bitmap, video_frame_init,
+  return VideoFrame::Create(script_state, image_bitmap, video_frame_init,
                             IGNORE_EXCEPTION_FOR_TESTING);
 }
 
diff --git a/third_party/blink/renderer/modules/webcodecs/fuzzer_utils.h b/third_party/blink/renderer/modules/webcodecs/fuzzer_utils.h
index aeb49d05..7b71b90 100644
--- a/third_party/blink/renderer/modules/webcodecs/fuzzer_utils.h
+++ b/third_party/blink/renderer/modules/webcodecs/fuzzer_utils.h
@@ -52,7 +52,8 @@
 EncodedAudioChunk* MakeEncodedAudioChunk(
     const wc_fuzzer::EncodedAudioChunk& proto);
 
-VideoFrame* MakeVideoFrame(const wc_fuzzer::VideoFrameBitmapInit& proto);
+VideoFrame* MakeVideoFrame(ScriptState* script_state,
+                           const wc_fuzzer::VideoFrameBitmapInit& proto);
 
 VideoEncoderEncodeOptions* MakeEncodeOptions(
     const wc_fuzzer::EncodeVideo_EncodeOptions& proto);
diff --git a/third_party/blink/renderer/modules/webcodecs/video_decoder.cc b/third_party/blink/renderer/modules/webcodecs/video_decoder.cc
index eeee5b7..a3a3720b 100644
--- a/third_party/blink/renderer/modules/webcodecs/video_decoder.cc
+++ b/third_party/blink/renderer/modules/webcodecs/video_decoder.cc
@@ -75,6 +75,14 @@
 }
 
 // static
+VideoDecoderTraits::OutputType* VideoDecoderTraits::MakeOutput(
+    scoped_refptr<MediaOutputType> output,
+    ExecutionContext* context) {
+  return MakeGarbageCollected<VideoDecoderTraits::OutputType>(std::move(output),
+                                                              context);
+}
+
+// static
 int VideoDecoderTraits::GetMaxDecodeRequests(const MediaDecoderType& decoder) {
   return decoder.GetMaxDecodeRequests();
 }
diff --git a/third_party/blink/renderer/modules/webcodecs/video_decoder.h b/third_party/blink/renderer/modules/webcodecs/video_decoder.h
index 45b544e..87b2ce2 100644
--- a/third_party/blink/renderer/modules/webcodecs/video_decoder.h
+++ b/third_party/blink/renderer/modules/webcodecs/video_decoder.h
@@ -74,6 +74,8 @@
   static void UpdateDecoderLog(const MediaDecoderType& decoder,
                                const MediaConfigType& media_config,
                                media::MediaLog* media_log);
+  static OutputType* MakeOutput(scoped_refptr<MediaOutputType>,
+                                ExecutionContext*);
 };
 
 class MODULES_EXPORT VideoDecoder : public DecoderTemplate<VideoDecoderTraits> {
diff --git a/third_party/blink/renderer/modules/webcodecs/video_encoder.cc b/third_party/blink/renderer/modules/webcodecs/video_encoder.cc
index 45b6e88..a943b79 100644
--- a/third_party/blink/renderer/modules/webcodecs/video_encoder.cc
+++ b/third_party/blink/renderer/modules/webcodecs/video_encoder.cc
@@ -453,12 +453,17 @@
   if (ThrowIfCodecStateUnconfigured(state_, "encode", exception_state))
     return;
 
+  auto* context = GetExecutionContext();
+  if (!context) {
+    exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError,
+                                      "Context is destroyed.");
+    return;
+  }
+
   // This will fail if |frame| is already destroyed.
-  auto* internal_frame = frame->clone(exception_state);
+  auto* internal_frame = frame->CloneFromNative(context);
 
   if (!internal_frame) {
-    // Set a more helpful exception than the cloning error message.
-    exception_state.ClearException();
     exception_state.ThrowDOMException(DOMExceptionCode::kOperationError,
                                       "Cannot encode destroyed frame.");
     return;
diff --git a/third_party/blink/renderer/modules/webcodecs/video_encoder_fuzzer.cc b/third_party/blink/renderer/modules/webcodecs/video_encoder_fuzzer.cc
index 5b74d84a..81397979 100644
--- a/third_party/blink/renderer/modules/webcodecs/video_encoder_fuzzer.cc
+++ b/third_party/blink/renderer/modules/webcodecs/video_encoder_fuzzer.cc
@@ -84,7 +84,8 @@
                                    IGNORE_EXCEPTION_FOR_TESTING);
           break;
         case wc_fuzzer::VideoEncoderApiInvocation::kEncode: {
-          VideoFrame* frame = MakeVideoFrame(invocation.encode().frame());
+          VideoFrame* frame =
+              MakeVideoFrame(script_state, invocation.encode().frame());
           // Often the fuzzer input will be too crazy to produce a valid frame
           // (e.g. bitmap width > bitmap length). In these cases, return early
           // to discourage this sort of fuzzer input. WebIDL doesn't allow
diff --git a/third_party/blink/renderer/modules/webcodecs/video_frame.cc b/third_party/blink/renderer/modules/webcodecs/video_frame.cc
index dbbfa41e..2280b7c 100644
--- a/third_party/blink/renderer/modules/webcodecs/video_frame.cc
+++ b/third_party/blink/renderer/modules/webcodecs/video_frame.cc
@@ -96,8 +96,10 @@
 
 }  // namespace
 
-VideoFrame::VideoFrame(scoped_refptr<media::VideoFrame> frame)
-    : handle_(base::MakeRefCounted<VideoFrameHandle>(std::move(frame))) {
+VideoFrame::VideoFrame(scoped_refptr<media::VideoFrame> frame,
+                       ExecutionContext* context)
+    : handle_(
+          base::MakeRefCounted<VideoFrameHandle>(std::move(frame), context)) {
   DCHECK(handle_->frame());
 }
 
@@ -107,7 +109,8 @@
 }
 
 // static
-VideoFrame* VideoFrame::Create(ImageBitmap* source,
+VideoFrame* VideoFrame::Create(ScriptState* script_state,
+                               ImageBitmap* source,
                                VideoFrameInit* init,
                                ExceptionState& exception_state) {
   if (!source) {
@@ -213,7 +216,8 @@
         gfx::ColorSpace::RangeID::LIMITED);
     frame->set_color_space(gfx_color_space);
   }
-  auto* result = MakeGarbageCollected<VideoFrame>(std::move(frame));
+  auto* result = MakeGarbageCollected<VideoFrame>(
+      std::move(frame), ExecutionContext::From(script_state));
   return result;
 }
 
@@ -341,8 +345,9 @@
   handle_->Invalidate();
 }
 
-VideoFrame* VideoFrame::clone(ExceptionState& exception_state) {
-  auto frame = handle_->frame();
+VideoFrame* VideoFrame::clone(ScriptState* script_state,
+                              ExceptionState& exception_state) {
+  VideoFrame* frame = CloneFromNative(ExecutionContext::From(script_state));
 
   if (!frame) {
     exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError,
@@ -350,7 +355,17 @@
     return nullptr;
   }
 
-  return MakeGarbageCollected<VideoFrame>(std::move(frame));
+  return frame;
+}
+
+VideoFrame* VideoFrame::CloneFromNative(ExecutionContext* context) {
+  auto frame = handle_->frame();
+
+  // The handle was already invalidated.
+  if (!frame)
+    return nullptr;
+
+  return MakeGarbageCollected<VideoFrame>(std::move(frame), context);
 }
 
 scoped_refptr<VideoFrameHandle> VideoFrame::handle() {
diff --git a/third_party/blink/renderer/modules/webcodecs/video_frame.h b/third_party/blink/renderer/modules/webcodecs/video_frame.h
index 0044d3c..58a02f9 100644
--- a/third_party/blink/renderer/modules/webcodecs/video_frame.h
+++ b/third_party/blink/renderer/modules/webcodecs/video_frame.h
@@ -22,6 +22,7 @@
 
 class ImageBitmap;
 class ExceptionState;
+class ExecutionContext;
 class ScriptPromise;
 class ScriptState;
 class VideoFrameInit;
@@ -32,7 +33,7 @@
 
  public:
   // Creates a VideoFrame with a new VideoFrameHandle wrapping |frame|.
-  explicit VideoFrame(scoped_refptr<media::VideoFrame> frame);
+  VideoFrame(scoped_refptr<media::VideoFrame> frame, ExecutionContext*);
 
   // Creates a VideoFrame from an existing handle.
   // All frames sharing |handle| will have their |handle_| invalidated if any of
@@ -40,7 +41,10 @@
   explicit VideoFrame(scoped_refptr<VideoFrameHandle> handle);
 
   // video_frame.idl implementation.
-  static VideoFrame* Create(ImageBitmap*, VideoFrameInit*, ExceptionState&);
+  static VideoFrame* Create(ScriptState*,
+                            ImageBitmap*,
+                            VideoFrameInit*,
+                            ExceptionState&);
 
   String format() const;
   base::Optional<HeapVector<Member<Plane>>> planes();
@@ -66,7 +70,8 @@
   // Creates a copy of |this|, with a new Handle, referencing the same
   // media::VideoFrame. The cloned frame will not be destroyed when |this| is,
   // and its lifetime should be independently managed.
-  VideoFrame* clone(ExceptionState&);
+  VideoFrame* clone(ScriptState*, ExceptionState&);
+  VideoFrame* CloneFromNative(ExecutionContext*);
 
   ScriptPromise createImageBitmap(ScriptState*,
                                   const ImageBitmapOptions*,
diff --git a/third_party/blink/renderer/modules/webcodecs/video_frame.idl b/third_party/blink/renderer/modules/webcodecs/video_frame.idl
index ce39836..4f0a433 100644
--- a/third_party/blink/renderer/modules/webcodecs/video_frame.idl
+++ b/third_party/blink/renderer/modules/webcodecs/video_frame.idl
@@ -9,7 +9,7 @@
     Serializable,
     RuntimeEnabled=WebCodecs
 ] interface VideoFrame {
-  [RaisesException] constructor(ImageBitmap source, VideoFrameInit init);
+  [CallWith=ScriptState, RaisesException] constructor(ImageBitmap source, VideoFrameInit init);
 
   // TODO(sandersd): Provide a way to find out what pixel formats are supported.
   // TODO(sandersd): Provide a way to convert to a specific pixel format, and to
@@ -51,7 +51,7 @@
 
   // Creates of the copy of this VideoFrame, which needs to be independently
   // destroyed.
-  [RaisesException]
+  [CallWith=ScriptState, RaisesException]
   VideoFrame clone();
 
   // Create an ImageBitmap from the crop region, scaled to the display size.
diff --git a/third_party/blink/renderer/modules/webcodecs/video_frame_handle.cc b/third_party/blink/renderer/modules/webcodecs/video_frame_handle.cc
index 5c8a4c2..893a424 100644
--- a/third_party/blink/renderer/modules/webcodecs/video_frame_handle.cc
+++ b/third_party/blink/renderer/modules/webcodecs/video_frame_handle.cc
@@ -4,11 +4,36 @@
 
 #include "third_party/blink/renderer/modules/webcodecs/video_frame_handle.h"
 
+#include "third_party/blink/renderer/core/execution_context/execution_context.h"
+
 namespace blink {
 
-VideoFrameHandle::VideoFrameHandle(scoped_refptr<media::VideoFrame> frame)
+VideoFrameHandle::VideoFrameHandle(scoped_refptr<media::VideoFrame> frame,
+                                   ExecutionContext* context)
     : frame_(std::move(frame)) {
   DCHECK(frame_);
+  DCHECK(context);
+
+  destruction_auditor_ =
+      VideoFrameLogger::From(*context).GetDestructionAuditor();
+
+  DCHECK(destruction_auditor_);
+}
+
+VideoFrameHandle::VideoFrameHandle(
+    scoped_refptr<media::VideoFrame> frame,
+    scoped_refptr<VideoFrameLogger::VideoFrameDestructionAuditor> reporter)
+    : frame_(std::move(frame)), destruction_auditor_(std::move(reporter)) {
+  DCHECK(frame_);
+  DCHECK(destruction_auditor_);
+}
+
+VideoFrameHandle::~VideoFrameHandle() {
+  // If we still have a valid |destruction_auditor_|, Invalidate() was never
+  // called and corresponding frames never received a call to destroy() before
+  // being garbage collected.
+  if (destruction_auditor_)
+    destruction_auditor_->ReportUndestroyedFrame();
 }
 
 scoped_refptr<media::VideoFrame> VideoFrameHandle::frame() {
@@ -19,6 +44,7 @@
 void VideoFrameHandle::Invalidate() {
   WTF::MutexLocker locker(mutex_);
   frame_.reset();
+  destruction_auditor_.reset();
 }
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/modules/webcodecs/video_frame_handle.h b/third_party/blink/renderer/modules/webcodecs/video_frame_handle.h
index 49a2e995..a865bbc 100644
--- a/third_party/blink/renderer/modules/webcodecs/video_frame_handle.h
+++ b/third_party/blink/renderer/modules/webcodecs/video_frame_handle.h
@@ -8,17 +8,30 @@
 #include "base/memory/scoped_refptr.h"
 #include "media/base/video_frame.h"
 #include "third_party/blink/renderer/modules/modules_export.h"
+#include "third_party/blink/renderer/modules/webcodecs/video_frame_logger.h"
 #include "third_party/blink/renderer/platform/wtf/thread_safe_ref_counted.h"
 #include "third_party/blink/renderer/platform/wtf/threading_primitives.h"
 
 namespace blink {
 
+class ExecutionContext;
+
 // Wrapper class that allows sharing a single |frame_| reference across
 // multiple VideoFrames, which can be invalidated for all frames at once.
+//
+// If Invalidate() is not called before the handle's destructor runs, this means
+// that none of the VideoFrames sharing this handle were destroyed, and they
+// were GC'ed instead. This can lead to stalls, since frames are not released
+// fast enough through the GC to keep a pipeline running smoothly. In that case
+// report an undestroyed frame through |destruction_auditor_|.
 class MODULES_EXPORT VideoFrameHandle
     : public WTF::ThreadSafeRefCounted<VideoFrameHandle> {
  public:
-  explicit VideoFrameHandle(scoped_refptr<media::VideoFrame>);
+  VideoFrameHandle(scoped_refptr<media::VideoFrame>, ExecutionContext*);
+
+  VideoFrameHandle(
+      scoped_refptr<media::VideoFrame>,
+      scoped_refptr<VideoFrameLogger::VideoFrameDestructionAuditor>);
 
   // Returns a copy of |frame_|, which should be re-used throughout the scope
   // of a function call, instead of calling frame() multiple times. Otherwise
@@ -31,10 +44,12 @@
 
  private:
   friend class WTF::ThreadSafeRefCounted<VideoFrameHandle>;
-  ~VideoFrameHandle() = default;
+  ~VideoFrameHandle();
 
   WTF::Mutex mutex_;
   scoped_refptr<media::VideoFrame> frame_;
+  scoped_refptr<VideoFrameLogger::VideoFrameDestructionAuditor>
+      destruction_auditor_;
 };
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/modules/webcodecs/video_frame_logger.cc b/third_party/blink/renderer/modules/webcodecs/video_frame_logger.cc
new file mode 100644
index 0000000..81804e0
--- /dev/null
+++ b/third_party/blink/renderer/modules/webcodecs/video_frame_logger.cc
@@ -0,0 +1,93 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "third_party/blink/renderer/modules/webcodecs/video_frame_logger.h"
+
+#include "third_party/blink/renderer/core/inspector/console_message.h"
+
+namespace blink {
+
+// How frequently we check for leaks.
+constexpr base::TimeDelta kTimerInterval = base::TimeDelta::FromSeconds(10);
+
+// How long we wait before stopping the timer when there is no activity.
+constexpr base::TimeDelta kTimerShutdownDelay =
+    base::TimeDelta::FromSeconds(60);
+
+void VideoFrameLogger::VideoFrameDestructionAuditor::ReportUndestroyedFrame() {
+  were_frames_not_destroyed_ = true;
+}
+
+void VideoFrameLogger::VideoFrameDestructionAuditor::Clear() {
+  were_frames_not_destroyed_ = false;
+}
+
+VideoFrameLogger::VideoFrameLogger(ExecutionContext& context)
+    : Supplement<ExecutionContext>(context),
+      destruction_auditor_(
+          base::MakeRefCounted<VideoFrameDestructionAuditor>()) {
+  timer_ = std::make_unique<TaskRunnerTimer<VideoFrameLogger>>(
+      context.GetTaskRunner(TaskType::kInternalMedia), this,
+      &VideoFrameLogger::LogDestructionErrors);
+}
+
+// static
+VideoFrameLogger& VideoFrameLogger::From(ExecutionContext& context) {
+  VideoFrameLogger* supplement =
+      Supplement<ExecutionContext>::From<VideoFrameLogger>(context);
+  if (!supplement) {
+    supplement = MakeGarbageCollected<VideoFrameLogger>(context);
+    Supplement<ExecutionContext>::ProvideTo(context, supplement);
+  }
+
+  return *supplement;
+}
+
+scoped_refptr<VideoFrameLogger::VideoFrameDestructionAuditor>
+VideoFrameLogger::GetDestructionAuditor() {
+  // We cannot directly log destruction errors: they are detected during
+  // garbage collection, and it would be unsafe to access GC'ed objects from
+  // a GC'ed object's destructor. Instead, start a timer here to periodically
+  // poll for these errors. The timer should stop itself after a period of
+  // inactivity.
+  if (!timer_->IsActive())
+    timer_->StartRepeating(kTimerInterval, FROM_HERE);
+
+  last_auditor_access_ = base::TimeTicks::Now();
+
+  return destruction_auditor_;
+}
+
+void VideoFrameLogger::LogDestructionErrors(TimerBase*) {
+  // If it's been a while since this class was used and there are not other
+  // references to |leak_status_|, stop the timer.
+  if (base::TimeTicks::Now() - last_auditor_access_ > kTimerShutdownDelay &&
+      destruction_auditor_->HasOneRef()) {
+    timer_->Stop();
+  }
+
+  if (!destruction_auditor_->were_frames_not_destroyed())
+    return;
+
+  auto* execution_context = GetSupplementable();
+  if (!execution_context->IsContextDestroyed()) {
+    execution_context->AddConsoleMessage(MakeGarbageCollected<ConsoleMessage>(
+        mojom::blink::ConsoleMessageSource::kJavaScript,
+        mojom::blink::ConsoleMessageLevel::kError,
+        "A VideoFrame was garbage collected without being destroyed. "
+        "Applications should call destroy() on frames when done with them to "
+        "prevent stalls."));
+  }
+
+  destruction_auditor_->Clear();
+}
+
+void VideoFrameLogger::Trace(Visitor* visitor) const {
+  Supplement<ExecutionContext>::Trace(visitor);
+}
+
+// static
+const char VideoFrameLogger::kSupplementName[] = "VideoFrameLogger";
+
+}  // namespace blink
diff --git a/third_party/blink/renderer/modules/webcodecs/video_frame_logger.h b/third_party/blink/renderer/modules/webcodecs/video_frame_logger.h
new file mode 100644
index 0000000..8bfdce0
--- /dev/null
+++ b/third_party/blink/renderer/modules/webcodecs/video_frame_logger.h
@@ -0,0 +1,79 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_WEBCODECS_VIDEO_FRAME_LOGGER_H_
+#define THIRD_PARTY_BLINK_RENDERER_MODULES_WEBCODECS_VIDEO_FRAME_LOGGER_H_
+
+#include "base/memory/scoped_refptr.h"
+#include "media/base/video_frame.h"
+#include "third_party/blink/renderer/core/execution_context/execution_context.h"
+#include "third_party/blink/renderer/modules/modules_export.h"
+#include "third_party/blink/renderer/platform/supplementable.h"
+#include "third_party/blink/renderer/platform/timer.h"
+#include "third_party/blink/renderer/platform/wtf/thread_safe_ref_counted.h"
+#include "third_party/blink/renderer/platform/wtf/threading_primitives.h"
+
+namespace blink {
+
+// This class is used to distribute a VideoFrameDestructionAuditor flag to
+// VideoFrameHandles. If a handle's destructor is run without having received a
+// call to Invalidate(), it will set |destruction_auditor_|. The
+// VideoFrameLogger periodically checks whether or not the flag is set, and
+// outputs an error message to the JS console, reminding developers to call
+// destroy() on their VideoFrames.
+//
+// This class lets us avoid making VideoFrames ExecutionLifeCycleObservers,
+// which could add 1000s of observers per second. It also avoids the use of
+// a pre-finzalizer on VideoFrames, which could have a GC performance impact.
+class MODULES_EXPORT VideoFrameLogger
+    : public GarbageCollected<VideoFrameLogger>,
+      public Supplement<ExecutionContext> {
+ public:
+  // Class that reports when blink::VideoFrames have been garbage collected
+  // without having destroy() called on them. This is a web page application
+  // error which can cause a web page to stall.
+  class VideoFrameDestructionAuditor
+      : public WTF::ThreadSafeRefCounted<VideoFrameDestructionAuditor> {
+   public:
+    void ReportUndestroyedFrame();
+    void Clear();
+
+    bool were_frames_not_destroyed() { return were_frames_not_destroyed_; }
+
+   private:
+    friend class WTF::ThreadSafeRefCounted<VideoFrameDestructionAuditor>;
+    ~VideoFrameDestructionAuditor() = default;
+
+    bool were_frames_not_destroyed_ = false;
+  };
+
+  static const char kSupplementName[];
+
+  static VideoFrameLogger& From(ExecutionContext&);
+
+  explicit VideoFrameLogger(ExecutionContext&);
+  virtual ~VideoFrameLogger() = default;
+
+  // Disallow copy and assign.
+  VideoFrameLogger& operator=(const VideoFrameLogger&) = delete;
+  VideoFrameLogger(const VideoFrameLogger&) = delete;
+
+  // Returns |destruction_auditor_| and starts |timer_| if needed.
+  scoped_refptr<VideoFrameDestructionAuditor> GetDestructionAuditor();
+
+  void Trace(Visitor*) const override;
+
+ private:
+  void LogDestructionErrors(TimerBase*);
+
+  base::TimeTicks last_auditor_access_;
+
+  std::unique_ptr<TimerBase> timer_;
+
+  scoped_refptr<VideoFrameDestructionAuditor> destruction_auditor_;
+};
+
+}  // namespace blink
+
+#endif  // THIRD_PARTY_BLINK_RENDERER_MODULES_WEBCODECS_VIDEO_FRAME_LOGGER_H_
diff --git a/third_party/blink/renderer/modules/webcodecs/video_frame_test.cc b/third_party/blink/renderer/modules/webcodecs/video_frame_test.cc
index cf557a5..569b03d1 100644
--- a/third_party/blink/renderer/modules/webcodecs/video_frame_test.cc
+++ b/third_party/blink/renderer/modules/webcodecs/video_frame_test.cc
@@ -7,6 +7,7 @@
 #include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_testing.h"
 #include "third_party/blink/renderer/modules/webcodecs/video_frame.h"
 #include "third_party/blink/renderer/modules/webcodecs/video_frame_handle.h"
+#include "third_party/blink/renderer/platform/heap/thread_state.h"
 #include "ui/gfx/geometry/rect.h"
 #include "ui/gfx/geometry/size.h"
 
@@ -17,8 +18,9 @@
 class VideoFrameTest : public testing::Test {
  public:
   VideoFrame* CreateBlinkVideoFrame(
-      scoped_refptr<media::VideoFrame> media_frame) {
-    return MakeGarbageCollected<VideoFrame>(std::move(media_frame));
+      scoped_refptr<media::VideoFrame> media_frame,
+      ExecutionContext* context) {
+    return MakeGarbageCollected<VideoFrame>(std::move(media_frame), context);
   }
   VideoFrame* CreateBlinkVideoFrameFromHandle(
       scoped_refptr<VideoFrameHandle> handle) {
@@ -47,11 +49,14 @@
 };
 
 TEST_F(VideoFrameTest, ConstructorAndAttributes) {
+  V8TestingScope scope;
+
   scoped_refptr<media::VideoFrame> media_frame = CreateBlackMediaVideoFrame(
       base::TimeDelta::FromMicroseconds(1000), media::PIXEL_FORMAT_I420,
       gfx::Size(112, 208) /* coded_size */,
       gfx::Size(100, 200) /* visible_size */);
-  VideoFrame* blink_frame = CreateBlinkVideoFrame(media_frame);
+  VideoFrame* blink_frame =
+      CreateBlinkVideoFrame(media_frame, scope.GetExecutionContext());
 
   EXPECT_EQ(1000u, blink_frame->timestamp().value());
   EXPECT_EQ(112u, blink_frame->codedWidth());
@@ -71,9 +76,12 @@
 }
 
 TEST_F(VideoFrameTest, FramesSharingHandleDestruction) {
+  V8TestingScope scope;
+
   scoped_refptr<media::VideoFrame> media_frame =
       CreateDefaultBlackMediaVideoFrame();
-  VideoFrame* blink_frame = CreateBlinkVideoFrame(media_frame);
+  VideoFrame* blink_frame =
+      CreateBlinkVideoFrame(media_frame, scope.GetExecutionContext());
 
   VideoFrame* frame_with_shared_handle =
       CreateBlinkVideoFrameFromHandle(blink_frame->handle());
@@ -88,12 +96,15 @@
 }
 
 TEST_F(VideoFrameTest, FramesNotSharingHandleDestruction) {
+  V8TestingScope scope;
+
   scoped_refptr<media::VideoFrame> media_frame =
       CreateDefaultBlackMediaVideoFrame();
-  VideoFrame* blink_frame = CreateBlinkVideoFrame(media_frame);
+  VideoFrame* blink_frame =
+      CreateBlinkVideoFrame(media_frame, scope.GetExecutionContext());
 
-  auto new_handle =
-      base::MakeRefCounted<VideoFrameHandle>(blink_frame->frame());
+  auto new_handle = base::MakeRefCounted<VideoFrameHandle>(
+      blink_frame->frame(), scope.GetExecutionContext());
 
   VideoFrame* frame_with_new_handle =
       CreateBlinkVideoFrameFromHandle(std::move(new_handle));
@@ -111,9 +122,11 @@
 
   scoped_refptr<media::VideoFrame> media_frame =
       CreateDefaultBlackMediaVideoFrame();
-  VideoFrame* blink_frame = CreateBlinkVideoFrame(media_frame);
+  VideoFrame* blink_frame =
+      CreateBlinkVideoFrame(media_frame, scope.GetExecutionContext());
 
-  VideoFrame* cloned_frame = blink_frame->clone(scope.GetExceptionState());
+  VideoFrame* cloned_frame =
+      blink_frame->clone(scope.GetScriptState(), scope.GetExceptionState());
 
   // The cloned frame should be referencing the same media::VideoFrame.
   EXPECT_EQ(blink_frame->frame(), cloned_frame->frame());
@@ -131,17 +144,55 @@
 
   scoped_refptr<media::VideoFrame> media_frame =
       CreateDefaultBlackMediaVideoFrame();
-  VideoFrame* blink_frame = CreateBlinkVideoFrame(media_frame);
+  VideoFrame* blink_frame =
+      CreateBlinkVideoFrame(media_frame, scope.GetExecutionContext());
 
   blink_frame->destroy();
 
-  VideoFrame* cloned_frame = blink_frame->clone(scope.GetExceptionState());
+  VideoFrame* cloned_frame =
+      blink_frame->clone(scope.GetScriptState(), scope.GetExceptionState());
 
   // No frame should have been created, and there should be an exception.
   EXPECT_EQ(nullptr, cloned_frame);
   EXPECT_TRUE(scope.GetExceptionState().HadException());
 }
 
+TEST_F(VideoFrameTest, LeakedHandlesReportLeaks) {
+  V8TestingScope scope;
+
+  // Create a handle directly instead of a video frame, to avoid dealing with
+  // the GarbageCollector.
+  scoped_refptr<media::VideoFrame> media_frame =
+      CreateDefaultBlackMediaVideoFrame();
+  auto handle = base::MakeRefCounted<VideoFrameHandle>(
+      media_frame, scope.GetExecutionContext());
+
+  // Remove the last reference to the handle without calling Invalidate().
+  handle.reset();
+
+  auto& logger = VideoFrameLogger::From(*scope.GetExecutionContext());
+
+  EXPECT_TRUE(logger.GetDestructionAuditor()->were_frames_not_destroyed());
+}
+
+TEST_F(VideoFrameTest, InvalidatedHandlesDontReportLeaks) {
+  V8TestingScope scope;
+
+  // Create a handle directly instead of a video frame, to avoid dealing with
+  // the GarbageCollector.
+  scoped_refptr<media::VideoFrame> media_frame =
+      CreateDefaultBlackMediaVideoFrame();
+  auto handle = base::MakeRefCounted<VideoFrameHandle>(
+      media_frame, scope.GetExecutionContext());
+
+  handle->Invalidate();
+  handle.reset();
+
+  auto& logger = VideoFrameLogger::From(*scope.GetExecutionContext());
+
+  EXPECT_FALSE(logger.GetDestructionAuditor()->were_frames_not_destroyed());
+}
+
 }  // namespace
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/modules/webcodecs/video_track_reader.cc b/third_party/blink/renderer/modules/webcodecs/video_track_reader.cc
index 52edbaa..65f7a285 100644
--- a/third_party/blink/renderer/modules/webcodecs/video_track_reader.cc
+++ b/third_party/blink/renderer/modules/webcodecs/video_track_reader.cc
@@ -99,8 +99,13 @@
   // We may want to invalidate |media_frames| when constraints change, but it's
   // unclear whether this is a problem for now.
 
+  auto* context = GetExecutionContext();
+  if (!context)
+    return;
+
   callback_->InvokeAndReportException(
-      nullptr, MakeGarbageCollected<VideoFrame>(std::move(media_frame)));
+      nullptr,
+      MakeGarbageCollected<VideoFrame>(std::move(media_frame), context));
 }
 
 void VideoTrackReader::OnReadyStateChanged(
diff --git a/third_party/blink/renderer/modules/webcodecs/video_track_reader_writer_test.cc b/third_party/blink/renderer/modules/webcodecs/video_track_reader_writer_test.cc
index c784aa6b4..c19ffe6 100644
--- a/third_party/blink/renderer/modules/webcodecs/video_track_reader_writer_test.cc
+++ b/third_party/blink/renderer/modules/webcodecs/video_track_reader_writer_test.cc
@@ -46,9 +46,9 @@
   }
 
  protected:
-  VideoFrame* CreateBlackVideoFrame() {
+  VideoFrame* CreateBlackVideoFrame(ExecutionContext* context) {
     return MakeGarbageCollected<VideoFrame>(
-        media::VideoFrame::CreateBlackFrame(gfx::Size(100, 100)));
+        media::VideoFrame::CreateBlackFrame(gfx::Size(100, 100)), context);
   }
 
   void RunIOUntilIdle() const {
@@ -84,7 +84,7 @@
 
   reader->start(GetCallback(read_output_function), ASSERT_NO_EXCEPTION);
 
-  auto* frame = CreateBlackVideoFrame();
+  auto* frame = CreateBlackVideoFrame(scope.GetExecutionContext());
   writer->writable()
       ->getWriter(script_state, ASSERT_NO_EXCEPTION)
       ->write(script_state,
@@ -125,7 +125,7 @@
   auto* writer =
       VideoTrackWriter::Create(script_state, &params, ASSERT_NO_EXCEPTION);
 
-  auto* frame = CreateBlackVideoFrame();
+  auto* frame = CreateBlackVideoFrame(scope.GetExecutionContext());
   writer->writable()
       ->getWriter(script_state, ASSERT_NO_EXCEPTION)
       ->write(script_state,
diff --git a/third_party/blink/renderer/platform/loader/fetch/DEPS b/third_party/blink/renderer/platform/loader/fetch/DEPS
index 6b62d91..2c306ca 100644
--- a/third_party/blink/renderer/platform/loader/fetch/DEPS
+++ b/third_party/blink/renderer/platform/loader/fetch/DEPS
@@ -1,5 +1,6 @@
 include_rules = [
   "+net/base/ip_endpoint.h",
+  "+net/base/schemeful_site.h",
   "+net/dns/public",
   "+services/network/public/cpp/fetch_api_utils.h",
   "+services/network/public/cpp/optional_trust_token_params.h",
diff --git a/third_party/blink/renderer/platform/loader/fetch/resource.cc b/third_party/blink/renderer/platform/loader/fetch/resource.cc
index 3f3e7a2..a019b61 100644
--- a/third_party/blink/renderer/platform/loader/fetch/resource.cc
+++ b/third_party/blink/renderer/platform/loader/fetch/resource.cc
@@ -34,6 +34,7 @@
 #include "base/stl_util.h"
 #include "base/time/default_clock.h"
 #include "build/build_config.h"
+#include "net/base/schemeful_site.h"
 #include "services/network/public/mojom/fetch_api.mojom-blink.h"
 #include "third_party/blink/public/platform/platform.h"
 #include "third_party/blink/public/platform/web_security_origin.h"
@@ -128,8 +129,14 @@
 
 namespace {
 const base::Clock* g_clock_for_testing = nullptr;
+
+String OriginToSchemefulSite(const SecurityOrigin& origin) {
+  net::SchemefulSite site(origin.ToUrlOrigin());
+  return String(site.Serialize().c_str());
 }
 
+}  // namespace
+
 static inline base::Time Now() {
   const base::Clock* clock = g_clock_for_testing
                                  ? g_clock_for_testing
@@ -155,6 +162,13 @@
       response_timestamp_(Now()),
       resource_request_(request),
       overhead_size_(CalculateOverheadSize()) {
+  scoped_refptr<const SecurityOrigin> top_frame_origin =
+      resource_request_.TopFrameOrigin();
+  if (top_frame_origin) {
+    existing_top_frame_sites_in_cache_.insert(
+        OriginToSchemefulSite(*top_frame_origin));
+  }
+
   InstanceCounters::IncrementCounter(InstanceCounters::kResourceCounter);
 
   if (IsMainThread())
@@ -1186,4 +1200,10 @@
   g_clock_for_testing = clock;
 }
 
+bool Resource::AppendTopFrameSiteForMetrics(const SecurityOrigin& origin) {
+  auto result =
+      existing_top_frame_sites_in_cache_.insert(OriginToSchemefulSite(origin));
+  return !result.is_new_entry;
+}
+
 }  // namespace blink
diff --git a/third_party/blink/renderer/platform/loader/fetch/resource.h b/third_party/blink/renderer/platform/loader/fetch/resource.h
index b7f9f71f..6b27f6f 100644
--- a/third_party/blink/renderer/platform/loader/fetch/resource.h
+++ b/third_party/blink/renderer/platform/loader/fetch/resource.h
@@ -403,6 +403,11 @@
     return CalculateOverheadSize();
   }
 
+  // Appends the top-frame site derived from |origin| to
+  // |existing_top_frame_sites_in_cache_| and returns true if the same site
+  // already exists.
+  bool AppendTopFrameSiteForMetrics(const SecurityOrigin& origin);
+
  protected:
   Resource(const ResourceRequestHead&,
            ResourceType,
@@ -541,6 +546,11 @@
 
   WebScopedVirtualTimePauser virtual_time_pauser_;
 
+  // To compute metrics for measuring the efficacy of the
+  // memory cache if it was partitioned by top-frame site (in addition to the
+  // current origin which it is already partitioned by).
+  HashSet<String> existing_top_frame_sites_in_cache_;
+
   DISALLOW_COPY_AND_ASSIGN(Resource);
 };
 
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 25ad130..b2b28a4 100644
--- a/third_party/blink/renderer/platform/loader/fetch/resource_fetcher.cc
+++ b/third_party/blink/renderer/platform/loader/fetch/resource_fetcher.cc
@@ -806,7 +806,8 @@
     const FetchParameters& params,
     const ResourceFactory& factory,
     bool is_static_data,
-    bool in_cached_resources_map) const {
+    bool in_cached_resources_map,
+    bool same_top_frame_site_resource_cached) const {
   if (is_static_data)
     return;
 
@@ -829,6 +830,11 @@
   if (in_cached_resources_map)
     DEFINE_RESOURCE_HISTOGRAM("PerDocument.");
 
+  // Log metrics to evaluate effectiveness of the memory cache if it was
+  // partitioned by the top-frame site.
+  if (same_top_frame_site_resource_cached)
+    DEFINE_RESOURCE_HISTOGRAM("PerTopFrameSite.");
+
   // Async (and defer) scripts may have more cache misses, track them
   // separately. See https://crbug.com/1043679 for context.
   if (params.Defer() != FetchParameters::DeferOption::kNoDefer &&
@@ -1074,6 +1080,7 @@
     }
   }
 
+  bool same_top_frame_site_resource_cached = false;
   if (!is_stale_revalidation && !resource) {
     resource = MatchPreload(params, resource_type);
     if (resource) {
@@ -1087,6 +1094,12 @@
       if (resource) {
         policy = DetermineRevalidationPolicy(resource_type, params, *resource,
                                              is_static_data);
+        scoped_refptr<const SecurityOrigin> top_frame_origin =
+            resource_request.TopFrameOrigin();
+        if (top_frame_origin) {
+          same_top_frame_site_resource_cached =
+              resource->AppendTopFrameSiteForMetrics(*top_frame_origin);
+        }
       }
     }
   }
@@ -1095,7 +1108,8 @@
       MemoryCache::RemoveFragmentIdentifierIfNeeded(params.Url()));
 
   UpdateMemoryCacheStats(resource, policy, params, factory, is_static_data,
-                         in_cached_resources_map);
+                         in_cached_resources_map,
+                         same_top_frame_site_resource_cached);
 
   switch (policy) {
     case RevalidationPolicy::kReload:
diff --git a/third_party/blink/renderer/platform/loader/fetch/resource_fetcher.h b/third_party/blink/renderer/platform/loader/fetch/resource_fetcher.h
index 6ea8adc..07af328 100644
--- a/third_party/blink/renderer/platform/loader/fetch/resource_fetcher.h
+++ b/third_party/blink/renderer/platform/loader/fetch/resource_fetcher.h
@@ -405,7 +405,8 @@
                               const FetchParameters&,
                               const ResourceFactory&,
                               bool is_static_data,
-                              bool in_cached_resources_map) const;
+                              bool in_cached_resources_map,
+                              bool same_top_frame_site_resource_cached) const;
 
   void ScheduleStaleRevalidate(Resource* stale_resource);
   void RevalidateStaleResource(Resource* stale_resource);
diff --git a/third_party/blink/renderer/platform/loader/fetch/resource_fetcher_test.cc b/third_party/blink/renderer/platform/loader/fetch/resource_fetcher_test.cc
index edbd8c3..7053dd6 100644
--- a/third_party/blink/renderer/platform/loader/fetch/resource_fetcher_test.cc
+++ b/third_party/blink/renderer/platform/loader/fetch/resource_fetcher_test.cc
@@ -277,6 +277,88 @@
       "Blink.MemoryCache.RevalidationPolicy.PerDocument.Mock", 1);
   histogram_tester.ExpectTotalCount("Blink.MemoryCache.RevalidationPolicy.Mock",
                                     3);
+  histogram_tester.ExpectBucketCount(
+      "Blink.MemoryCache.RevalidationPolicy.Mock",
+      3 /* RevalidationPolicy::kLoad */, 1);
+  histogram_tester.ExpectBucketCount(
+      "Blink.MemoryCache.RevalidationPolicy.Mock",
+      0 /* RevalidationPolicy::kUse */, 2);
+}
+
+TEST_F(ResourceFetcherTest, MetricsPerTopFrameSite) {
+  blink::HistogramTester histogram_tester;
+
+  KURL url("http://127.0.0.1:8000/foo.html");
+  ResourceResponse response(url);
+  response.SetHttpStatusCode(200);
+  response.SetHttpHeaderField(http_names::kCacheControl, "max-age=3600");
+  platform_->GetURLLoaderMockFactory()->RegisterURL(
+      url, WrappedResourceResponse(response),
+      test::PlatformTestDataPath(kTestResourceFilename));
+
+  ResourceRequestHead request_head(url);
+  scoped_refptr<const SecurityOrigin> origin_a =
+      SecurityOrigin::Create(KURL("https://a.test"));
+  request_head.SetTopFrameOrigin(origin_a);
+  request_head.SetRequestorOrigin(origin_a);
+  FetchParameters fetch_params =
+      FetchParameters::CreateForTest(ResourceRequest(request_head));
+  auto* fetcher_1 = CreateFetcher();
+  Resource* resource_1 = MockResource::Fetch(fetch_params, fetcher_1, nullptr);
+  ASSERT_TRUE(resource_1);
+  platform_->GetURLLoaderMockFactory()->ServeAsynchronousRequests();
+  EXPECT_TRUE(resource_1->IsLoaded());
+  EXPECT_TRUE(GetMemoryCache()->Contains(resource_1));
+
+  auto* fetcher_2 = CreateFetcher();
+  ResourceRequestHead request_head_2(url);
+  scoped_refptr<const SecurityOrigin> origin_b =
+      SecurityOrigin::Create(KURL("https://b.test"));
+  request_head_2.SetTopFrameOrigin(origin_b);
+  request_head_2.SetRequestorOrigin(origin_a);
+  FetchParameters fetch_params_2 =
+      FetchParameters::CreateForTest(ResourceRequest(request_head_2));
+  Resource* resource_2 =
+      MockResource::Fetch(fetch_params_2, fetcher_2, nullptr);
+  EXPECT_EQ(resource_1, resource_2);
+
+  // Test histograms.
+  histogram_tester.ExpectTotalCount(
+      "Blink.MemoryCache.RevalidationPolicy.PerTopFrameSite.Mock", 0);
+
+  histogram_tester.ExpectTotalCount("Blink.MemoryCache.RevalidationPolicy.Mock",
+                                    2);
+
+  histogram_tester.ExpectBucketCount(
+      "Blink.MemoryCache.RevalidationPolicy.Mock",
+      3 /* RevalidationPolicy::kLoad */, 1);
+  histogram_tester.ExpectBucketCount(
+      "Blink.MemoryCache.RevalidationPolicy.Mock",
+      0 /* RevalidationPolicy::kUse */, 1);
+
+  // Now load the same resource with origin_b as top-frame site. The
+  // PerTopFrameSite histogram should be incremented.
+  auto* fetcher_3 = CreateFetcher();
+  ResourceRequestHead request_head_3(url);
+  scoped_refptr<const SecurityOrigin> foo_origin_b =
+      SecurityOrigin::Create(KURL("https://foo.b.test"));
+  request_head_3.SetTopFrameOrigin(foo_origin_b);
+  request_head_3.SetRequestorOrigin(origin_a);
+  FetchParameters fetch_params_3 =
+      FetchParameters::CreateForTest(ResourceRequest(request_head_3));
+  Resource* resource_3 =
+      MockResource::Fetch(fetch_params_2, fetcher_3, nullptr);
+  EXPECT_EQ(resource_1, resource_3);
+  histogram_tester.ExpectTotalCount(
+      "Blink.MemoryCache.RevalidationPolicy.PerTopFrameSite.Mock", 1);
+  histogram_tester.ExpectBucketCount(
+      "Blink.MemoryCache.RevalidationPolicy.PerTopFrameSite.Mock",
+      0 /* RevalidationPolicy::kUse */, 1);
+  histogram_tester.ExpectTotalCount("Blink.MemoryCache.RevalidationPolicy.Mock",
+                                    3);
+  histogram_tester.ExpectBucketCount(
+      "Blink.MemoryCache.RevalidationPolicy.Mock",
+      0 /* RevalidationPolicy::kUse */, 2);
 }
 
 // Verify that the ad bit is copied to WillSendRequest's request when the
diff --git a/third_party/blink/renderer/platform/runtime_enabled_features.json5 b/third_party/blink/renderer/platform/runtime_enabled_features.json5
index e6c2bb0..b942955 100644
--- a/third_party/blink/renderer/platform/runtime_enabled_features.json5
+++ b/third_party/blink/renderer/platform/runtime_enabled_features.json5
@@ -685,11 +685,11 @@
     },
     {
       name: "DecodeJpeg420ImagesToYUV",
-      status: "test",
+      status: "stable",
     },
     {
       name: "DecodeLossyWebPImagesToYUV",
-      status: "test",
+      status: "stable",
     },
     {
       name: "DelayAsyncScriptExecutionUntilFinishedParsing",
@@ -1081,6 +1081,7 @@
       // enabled, we'll typically fall back to legacy code for block children.
       name: "LayoutNGFullPositionForPoint",
       implied_by: ["LayoutNGBlockFragmentation", "LayoutNGFragmentTraversal"],
+      status: "stable",
     },
     {
       name: "LayoutNGGrid",
diff --git a/third_party/blink/tools/blinkpy/presubmit/audit_non_blink_usage.py b/third_party/blink/tools/blinkpy/presubmit/audit_non_blink_usage.py
index d8d0834f..c66ec87 100755
--- a/third_party/blink/tools/blinkpy/presubmit/audit_non_blink_usage.py
+++ b/third_party/blink/tools/blinkpy/presubmit/audit_non_blink_usage.py
@@ -107,8 +107,6 @@
             'base::CancelableOnceClosure',
             'base::CancelableRepeatingCallback',
             'base::CancelableRepeatingClosure',
-            'base::CancelableCallback',
-            'base::CancelableClosure',
 
             # //base/mac/scoped_nsobject.h
             'base::scoped_nsobject',
@@ -717,6 +715,7 @@
         'paths': ['third_party/blink/renderer/core/page/scrolling'],
         'allowed': [
             'cc::ScrollbarLayerBase',
+            'shared_highlighting::.+',
         ],
     },
     {
diff --git a/third_party/blink/web_tests/FlagExpectations/disable-layout-ng b/third_party/blink/web_tests/FlagExpectations/disable-layout-ng
index ab74220..beacc9c 100644
--- a/third_party/blink/web_tests/FlagExpectations/disable-layout-ng
+++ b/third_party/blink/web_tests/FlagExpectations/disable-layout-ng
@@ -23,6 +23,9 @@
 ### editing/selection/mouse/
 crbug.com/591099 editing/selection/mouse/drag_over_text_transform.html [ Crash ]
 
+### editing/selection/select-line-up-down.html
+crbug.com/591099 editing/selection/select-line-up-down.html [ Failure ]
+
 ### external/wpt/css/CSS2/abspos/
 crbug.com/591099 external/wpt/css/CSS2/abspos/hypothetical-box-dynamic.html [ Failure ]
 
diff --git a/third_party/blink/web_tests/TestExpectations b/third_party/blink/web_tests/TestExpectations
index 0179c87..ecbc1977 100644
--- a/third_party/blink/web_tests/TestExpectations
+++ b/third_party/blink/web_tests/TestExpectations
@@ -5033,11 +5033,6 @@
 crbug.com/867532 [ Linux ] external/wpt/workers/modules/dedicated-worker-import-data-url.any.worker.html [ Timeout Pass ]
 crbug.com/867532 [ Linux ] external/wpt/workers/modules/dedicated-worker-import.any.worker.html [ Timeout Pass ]
 
-# These video tests seem to take a screenshot too early.
-crbug.com/963141 media/video-object-fit.html [ Pass Failure ]
-crbug.com/963141 media/video-object-fit-change.html [ Pass Failure ]
-crbug.com/963141 media/video-aspect-ratio.html [ Pass Failure ]
-
 # Updated by sheriff 2020-06-01: this one seem flaky on all platforms now.
 # See also: crbug.com/1083564
 crbug.com/963141 media/controls/video-overlay-cast-light-rendering.html [ Pass Failure ]
diff --git a/third_party/blink/web_tests/VirtualTestSuites b/third_party/blink/web_tests/VirtualTestSuites
index fea00fb..b070aba 100644
--- a/third_party/blink/web_tests/VirtualTestSuites
+++ b/third_party/blink/web_tests/VirtualTestSuites
@@ -98,16 +98,14 @@
   {
     "prefix": "gpu-rasterization",
     "bases": ["images"],
-    "args": ["--enable-gpu-rasterization",
-             "--enable-features=DecodeLossyWebPImagesToYUV",
-             "--enable-features=DecodeJpeg420ImagesToYUV"]
+    "args": ["--enable-gpu-rasterization"]
   },
   {
     "prefix": "gpu-rasterization-disable-yuv",
     "bases": ["images/yuv-decode-eligible"],
     "args": ["--enable-gpu-rasterization",
-             "--disable-features=DecodeLossyWebPImagesToYUV",
-             "--disable-features=DecodeJpeg420ImagesToYUV"]
+             "--disable-blink-features=DecodeLossyWebPImagesToYUV",
+             "--disable-blink-features=DecodeJpeg420ImagesToYUV"]
   },
   {
     "prefix": "exotic-color-space",
diff --git a/third_party/blink/web_tests/accessibility/aria-owns-crash.html b/third_party/blink/web_tests/accessibility/aria-owns-crash.html
new file mode 100644
index 0000000..d0dda5a
--- /dev/null
+++ b/third_party/blink/web_tests/accessibility/aria-owns-crash.html
@@ -0,0 +1,26 @@
+<!DOCTYPE HTML>
+<script src="../resources/testharness.js"></script>
+<script src="../resources/testharnessreport.js"></script>
+
+<dialog>
+  <div aria-owns=>
+    <style>
+      .arbitraryClassName { }
+    </style>
+  </div>
+</dialog>
+
+<script>
+async_test((t) => {
+    let child = document.createElement('div');
+    child.id = 'foo';
+    document.body.appendChild(child);
+
+    setTimeout(() => {
+        document.styleSheets[0].deleteRule(0);
+        document.replaceChild(child, document.documentElement);
+        t.done();
+    });
+}, "Regression test for aria-owns related crash in AXRelationCache::Init");
+
+</script>
diff --git a/third_party/blink/web_tests/android/ChromiumWPTExpectations b/third_party/blink/web_tests/android/ChromiumWPTExpectations
index 12e8e04..c984827d 100644
--- a/third_party/blink/web_tests/android/ChromiumWPTExpectations
+++ b/third_party/blink/web_tests/android/ChromiumWPTExpectations
@@ -3243,7 +3243,7 @@
 crbug.com/1050754 external/wpt/mediasession/mediametadata.html [ Failure Pass ]
 crbug.com/1050754 external/wpt/merchant-validation/complete-method.tentative.https.html [ Failure Pass ]
 crbug.com/1050754 external/wpt/merchant-validation/constructor.tentative.https.html [ Failure Pass ]
-crbug.com/1050754 external/wpt/merchant-validation/constructortentative..http.html [ Failure ]
+crbug.com/1050754 external/wpt/merchant-validation/constructor.tentative.http.html [ Failure ]
 crbug.com/1050754 external/wpt/merchant-validation/onmerchantvalidation-attribute.https.html [ Failure Pass ]
 crbug.com/1050754 external/wpt/mimesniff/mime-types/charset-parameter.window.html [ Failure Pass ]
 crbug.com/1050754 external/wpt/mimesniff/mime-types/parsing.any.html [ Failure Pass ]
diff --git a/third_party/blink/web_tests/android/WeblayerWPTExpectations b/third_party/blink/web_tests/android/WeblayerWPTExpectations
index 7c706b6..eb6c7c9 100644
--- a/third_party/blink/web_tests/android/WeblayerWPTExpectations
+++ b/third_party/blink/web_tests/android/WeblayerWPTExpectations
@@ -3209,7 +3209,7 @@
 crbug.com/1050754 external/wpt/mediasession/setactionhandler.html [ Failure ]
 crbug.com/1050754 external/wpt/merchant-validation/complete-method.tentative.https.html [ Failure ]
 crbug.com/1050754 external/wpt/merchant-validation/constructor.tentative.https.html [ Failure ]
-crbug.com/1050754 external/wpt/merchant-validation/constructortentative..http.html [ Failure ]
+crbug.com/1050754 external/wpt/merchant-validation/constructor.tentative.http.html [ Failure ]
 crbug.com/1050754 external/wpt/merchant-validation/onmerchantvalidation-attribute.https.html [ Failure Pass ]
 crbug.com/1050754 external/wpt/mimesniff/mime-types/charset-parameter.window.html [ Failure Pass ]
 crbug.com/1050754 external/wpt/mimesniff/mime-types/parsing.any.html [ Failure Pass ]
diff --git a/third_party/blink/web_tests/android/WebviewWPTExpectations b/third_party/blink/web_tests/android/WebviewWPTExpectations
index fd2ac5d..63c0d95 100644
--- a/third_party/blink/web_tests/android/WebviewWPTExpectations
+++ b/third_party/blink/web_tests/android/WebviewWPTExpectations
@@ -3479,7 +3479,7 @@
 crbug.com/1050754 external/wpt/mediasession/setactionhandler.html [ Failure ]
 crbug.com/1050754 external/wpt/merchant-validation/complete-method.tentative.https.html [ Failure ]
 crbug.com/1050754 external/wpt/merchant-validation/constructor.tentative.https.html [ Failure ]
-crbug.com/1050754 external/wpt/merchant-validation/constructortentative..http.html [ Failure ]
+crbug.com/1050754 external/wpt/merchant-validation/constructor.tentative.http.html [ Failure ]
 crbug.com/1050754 external/wpt/merchant-validation/onmerchantvalidation-attribute.https.html [ Failure Pass ]
 crbug.com/1050754 external/wpt/mimesniff/mime-types/charset-parameter.window.html [ Failure Pass ]
 crbug.com/1050754 external/wpt/mimesniff/mime-types/parsing.any.html [ Failure Pass ]
diff --git a/third_party/blink/web_tests/editing/selection/click-on-block-image.html b/third_party/blink/web_tests/editing/selection/click-on-block-image.html
index c2d88b0..5ea1b3b 100644
--- a/third_party/blink/web_tests/editing/selection/click-on-block-image.html
+++ b/third_party/blink/web_tests/editing/selection/click-on-block-image.html
@@ -41,8 +41,8 @@
         var elem;
         elem = document.getElementById("myimage");
         
-        runTest(elem.offsetLeft - 10, elem.offsetTop + 10, document.getElementById("test"), 1);
-        runTest(elem.offsetLeft + elem.offsetWidth + 10, elem.offsetTop + 10, document.getElementById("test"), 2);
+        runTest(elem.offsetLeft - 10, elem.offsetTop + 20, document.getElementById("test"), 1);
+        runTest(elem.offsetLeft + elem.offsetWidth + 10, elem.offsetTop + 20, document.getElementById("test"), 2);
     }
 }
 
diff --git a/third_party/blink/web_tests/editing/selection/continuations-with-move-caret-to-boundary.html b/third_party/blink/web_tests/editing/selection/continuations-with-move-caret-to-boundary.html
index a4ce7cc..042c5484 100644
--- a/third_party/blink/web_tests/editing/selection/continuations-with-move-caret-to-boundary.html
+++ b/third_party/blink/web_tests/editing/selection/continuations-with-move-caret-to-boundary.html
@@ -30,7 +30,7 @@
 
 selection_test(
     [kStyle, '<p>AAAAA</p><p>BBBBB</p>'],
-    selection => dragOverBlocks(selection, -15),
+    selection => dragOverBlocks(selection, -5),
     [kStyle,
     isMac
     ? '<p>^AAAAA</p><p>|BBBBB</p>'
diff --git a/third_party/blink/web_tests/editing/selection/offset-from-point.html b/third_party/blink/web_tests/editing/selection/offset-from-point.html
index 2106816..6a8b781 100644
--- a/third_party/blink/web_tests/editing/selection/offset-from-point.html
+++ b/third_party/blink/web_tests/editing/selection/offset-from-point.html
@@ -28,8 +28,6 @@
     var isVertical = writingMode && writingMode[0] == "v";
     var results = [ name ];
     getOffsetFromPoint(element, isVertical, results);
-    if (isVertical) // The last character in vertical is flaky by win/mac/linux
-        results.splice(-1, 1);
     for (var result of results) {
         var div = document.createElement("div");
         div.innerText = result;
diff --git a/third_party/blink/web_tests/editing/selection/select-line-up-down.html b/third_party/blink/web_tests/editing/selection/select-line-up-down.html
new file mode 100644
index 0000000..86f2bad
--- /dev/null
+++ b/third_party/blink/web_tests/editing/selection/select-line-up-down.html
@@ -0,0 +1,100 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script src="../../resources/testharness.js"></script>
+<script src="../../resources/testharnessreport.js"></script>
+<script src="../assert_selection.js"></script>
+<script>
+
+selection_test(
+  [
+    '<div contenteditable>',
+      '<div>line| 1</div>',
+      '<div><span contenteditable="false">line 2</span><br></div>',
+      '<div>line 3</div>',
+    '</div>',
+  ],
+  selection => selection.modify('move', 'forward', 'line'),
+  [
+  '<div contenteditable>',
+      '<div>line 1</div>',
+      '<div><span contenteditable="false">line 2</span>|<br></div>',
+      '<div>line 3</div>',
+    '</div>',
+  ],
+  'Down arrow selection should not cross editing boundaries.');
+
+selection_test(
+  [
+    '<div contenteditable>',
+      '<div>line| 1</div>',
+      '<div>abc<span contenteditable="false">line 2</span><br></div>',
+      '<div>line 3</div>',
+    '</div>',
+  ],
+  selection => selection.modify('move', 'forward', 'line'),
+  [
+  '<div contenteditable>',
+      '<div>line 1</div>',
+      '<div>abc|<span contenteditable="false">line 2</span><br></div>',
+      '<div>line 3</div>',
+    '</div>',
+  ],
+  'Down arrow selection should not cross editing boundaries when content is present before non-editable.');
+
+selection_test(
+  [
+    '<div contenteditable>',
+      '<div>line 1</div>',
+      '<div><span contenteditable="false">line 2</span><br></div>',
+      '<div>line| 3</div>',
+    '</div>',
+  ],
+  selection => selection.modify('move', 'backward', 'line'),
+  [
+  '<div contenteditable>',
+      '<div>line 1</div>',
+      '<div><span contenteditable="false">line 2</span>|<br></div>',
+      '<div>line 3</div>',
+    '</div>',
+  ],
+  'Up arrow selection should not cross editing boundaries.');
+
+selection_test(
+  [
+    '<div contenteditable>',
+      '<div>line 1</div>',
+      '<div>abc<span contenteditable="false">line 2</span><br></div>',
+      '<div>line| 3</div>',
+    '</div>',
+  ],
+  selection => selection.modify('move', 'backward', 'line'),
+  [
+  '<div contenteditable>',
+      '<div>line 1</div>',
+      '<div>abc|<span contenteditable="false">line 2</span><br></div>',
+      '<div>line 3</div>',
+    '</div>',
+  ],
+  'Up arrow selection should not cross editing boundaries when content is present before non-editable.');
+
+selection_test(
+  [
+    '<div contenteditable>',
+      '<div>line 1</div>',
+      '<div><span contenteditable="false">line 2</span>test<br></div>',
+      '<div>line| 3</div>',
+    '</div>',
+  ],
+  selection => selection.modify('move', 'backward', 'line'),
+  [
+  '<div contenteditable>',
+      '<div>line 1</div>',
+      '<div><span contenteditable="false">line 2</span>|test<br></div>',
+      '<div>line 3</div>',
+    '</div>',
+  ],
+  'Up arrow selection should not cross editing boundaries when editable content present around non-editable.');
+
+</script>
+</html>
diff --git a/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_8.json b/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_8.json
index 9faa2802..541812a 100644
--- a/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_8.json
+++ b/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_8.json
@@ -668,6 +668,13 @@
        null,
        {}
       ]
+     ],
+     "svg-unused-filter-on-clippath-mutated-crash.html": [
+      "060b2547de59dfb14835532e52747bee8cc5fdc3",
+      [
+       null,
+       {}
+      ]
      ]
     }
    },
@@ -6372,13 +6379,6 @@
        {}
       ]
      ],
-     "hover-002-manual.html": [
-      "50859c5cfb80f1f82c453adad72643009347d7c2",
-      [
-       null,
-       {}
-      ]
-     ],
      "old-tests": {
       "css3-modsel-159.xml": [
        "3504398dbcf20f70f35c2842b75922cc8e6d7056",
@@ -50736,7 +50736,7 @@
       ]
      ],
      "border-radius-clip-002.htm": [
-      "c6aa0c6a3e10b639673541d7a16e1c7a43ac8fd2",
+      "e81871ee50c4498c3ed3a63672725e2e395b5281",
       [
        null,
        [
@@ -61451,6 +61451,19 @@
        {}
       ]
      ],
+     "flex-aspect-ratio-img-row-014.html": [
+      "9f12b65f8435ef781d2a98170a70eb66574f73e5",
+      [
+       null,
+       [
+        [
+         "/css/css-flexbox/reference/flex-aspect-ratio-img-row-014-ref.html",
+         "=="
+        ]
+       ],
+       {}
+      ]
+     ],
      "flex-base.html": [
       "93401d3fe32716ca14a3f7f3be4f0fa64a7fabf2",
       [
@@ -157239,6 +157252,19 @@
          {}
         ]
        ],
+       "legend-position-relative-2.html": [
+        "3fbdbd5c2065addbbcd66a27de83406c7f1d4aa7",
+        [
+         null,
+         [
+          [
+           "/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-position-relative-2-ref.html",
+           "=="
+          ]
+         ],
+         {}
+        ]
+       ],
        "legend-position-relative.html": [
         "993836126143a8921e31bc8e61bef955eb302503",
         [
@@ -168996,7 +169022,7 @@
     "file": {
      "resources": {
       "echo-content-escaped.py": [
-       "bdbbc0f1ea56591a48a8e06e9a39491a8d49aea6",
+       "2cbaf45c20efdfcba17a27d3aecb3e5c9bee4bfb",
        []
       ]
      }
@@ -171612,6 +171638,14 @@
       "6502444407f59e6ea08da63c8dcdb22978e5ae83",
       []
      ],
+     "frame-src-sandboxed-allowed-expected.txt": [
+      "1102ea6c18da669572590c2617059dcdb516e238",
+      []
+     ],
+     "frame-src-sandboxed-allowed.html.headers": [
+      "ec9e8deb5991e9950c705a1ac17201faa5e9fc9d",
+      []
+     ],
      "support": {
       "frame.html": [
        "50be42958744b8a9213d84847fbf0413ae20f3b6",
@@ -172739,6 +172773,14 @@
      "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391",
      []
     ],
+    "attributes": {
+     "resources": {
+      "secure-non-secure-child.html": [
+       "f6a4682f8aecc1fe2aaacc928836dfbba2b8af09",
+       []
+      ]
+     }
+    },
     "domain": {
      "domain-attribute-host-with-and-without-leading-period.sub.https.html.sub.headers": [
       "77d3d8c0c447c99fa556ea58dee090fadf7ad31d",
@@ -173020,214 +173062,6 @@
         "fea1e1a643b97d4a101d704bd1497376a4997b3c",
         []
        ],
-       "attribute0001-expected": [
-        "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391",
-        []
-       ],
-       "attribute0001-test": [
-        "6199f78cff28e9deb6ea7e929d6d17ddfbf66c3f",
-        []
-       ],
-       "attribute0002-expected": [
-        "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391",
-        []
-       ],
-       "attribute0002-test": [
-        "047a24d9a5018e37269c7d257894db487f12bcaf",
-        []
-       ],
-       "attribute0003-expected": [
-        "b14d4f69b58c3d9cc7ed1f363d42d625e7bdcf8c",
-        []
-       ],
-       "attribute0003-test": [
-        "c944bac478bc34bf48627b634e98b96acf9772af",
-        []
-       ],
-       "attribute0004-expected": [
-        "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391",
-        []
-       ],
-       "attribute0004-test": [
-        "bcfaa7d8384832f4237f19f09b18432e8ded8fcb",
-        []
-       ],
-       "attribute0005-expected": [
-        "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391",
-        []
-       ],
-       "attribute0005-test": [
-        "1671087813f0304b45c1156e2bd80dbe7cc0f8a2",
-        []
-       ],
-       "attribute0006-expected": [
-        "b14d4f69b58c3d9cc7ed1f363d42d625e7bdcf8c",
-        []
-       ],
-       "attribute0006-test": [
-        "39d7589033d9b13e4263605a1b6799438c2120a2",
-        []
-       ],
-       "attribute0007-expected": [
-        "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391",
-        []
-       ],
-       "attribute0007-test": [
-        "f75f46a71d90df2e29ec93f214a717b210d90c38",
-        []
-       ],
-       "attribute0008-expected": [
-        "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391",
-        []
-       ],
-       "attribute0008-test": [
-        "be45b3a2c722804b852aa36070a5523b4f4d272c",
-        []
-       ],
-       "attribute0009-expected": [
-        "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391",
-        []
-       ],
-       "attribute0009-test": [
-        "1a44c2244014a4aca8f455b725828d33f1a7878d",
-        []
-       ],
-       "attribute0010-expected": [
-        "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391",
-        []
-       ],
-       "attribute0010-test": [
-        "ca6220061e86e612c851105bb8a8cfc67f8b93e9",
-        []
-       ],
-       "attribute0011-expected": [
-        "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391",
-        []
-       ],
-       "attribute0011-test": [
-        "3bd4c2e99882076e5482df9692c99fe05b7fb47a",
-        []
-       ],
-       "attribute0012-expected": [
-        "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391",
-        []
-       ],
-       "attribute0012-test": [
-        "6e7b816616391bf3b72e9373fb203003051a8ca4",
-        []
-       ],
-       "attribute0013-expected": [
-        "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391",
-        []
-       ],
-       "attribute0013-test": [
-        "f4814e432a498aa73bb1bb3eab5dbc10fb19d263",
-        []
-       ],
-       "attribute0014-expected": [
-        "b14d4f69b58c3d9cc7ed1f363d42d625e7bdcf8c",
-        []
-       ],
-       "attribute0014-test": [
-        "ef88896aaf7bdc14008b10b79dc628e0d812492e",
-        []
-       ],
-       "attribute0015-expected": [
-        "b14d4f69b58c3d9cc7ed1f363d42d625e7bdcf8c",
-        []
-       ],
-       "attribute0015-test": [
-        "cea7060a9c971d7ee7ef438f34bf51ded374b40f",
-        []
-       ],
-       "attribute0016-expected": [
-        "b14d4f69b58c3d9cc7ed1f363d42d625e7bdcf8c",
-        []
-       ],
-       "attribute0016-test": [
-        "9a5b591a78888796d10441fbf49ff5fe20d7c635",
-        []
-       ],
-       "attribute0017-expected": [
-        "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391",
-        []
-       ],
-       "attribute0017-test": [
-        "a6aeeb34ea7b41779b75f30c116b952ccb2e14b4",
-        []
-       ],
-       "attribute0018-expected": [
-        "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391",
-        []
-       ],
-       "attribute0018-test": [
-        "f9122013443607e641d72640c6ec382cffaa487a",
-        []
-       ],
-       "attribute0019-expected": [
-        "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391",
-        []
-       ],
-       "attribute0019-test": [
-        "a424c6ee68d17dbf01ed4de7a3610bf3ba8aaf44",
-        []
-       ],
-       "attribute0020-expected": [
-        "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391",
-        []
-       ],
-       "attribute0020-test": [
-        "367d2a104f5bbc9e48255189d0dae12ab0b094a3",
-        []
-       ],
-       "attribute0021-expected": [
-        "b14d4f69b58c3d9cc7ed1f363d42d625e7bdcf8c",
-        []
-       ],
-       "attribute0021-test": [
-        "bb76deb3afcf0041286612e755c08077414ed36c",
-        []
-       ],
-       "attribute0022-expected": [
-        "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391",
-        []
-       ],
-       "attribute0022-test": [
-        "ac79c0f9ec9d15abd7cd5fb65e11a2ac3a3c6e3a",
-        []
-       ],
-       "attribute0023-expected": [
-        "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391",
-        []
-       ],
-       "attribute0023-test": [
-        "97f2ac3946bda38f597e013b6505014d07f1636f",
-        []
-       ],
-       "attribute0024-expected": [
-        "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391",
-        []
-       ],
-       "attribute0024-test": [
-        "cb041c56c1c3db9bc6049a1bd4f384ac86eeaeee",
-        []
-       ],
-       "attribute0025-expected": [
-        "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391",
-        []
-       ],
-       "attribute0025-test": [
-        "c430943516d4ec679c63a04ece96aedb3fcf355a",
-        []
-       ],
-       "attribute0026-expected": [
-        "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391",
-        []
-       ],
-       "attribute0026-test": [
-        "7f68322ee2e3710a12f3238ce2af834d1fe15164",
-        []
-       ],
        "charset0001-expected": [
         "8646afc636624f223fe79296a6d2b49747258d52",
         []
@@ -174573,7 +174407,11 @@
       []
      ],
      "cookie-helper.sub.js": [
-      "50dcdfc5ecbb6dd023eef9ce64beab5e277db406",
+      "3f0aac26efe00a04a04dab727ef8438f86e21757",
+      []
+     ],
+     "cookie.py": [
+      "9710b518e21c317dc103722835b334c7843636d8",
       []
      ],
      "drop.py": [
@@ -174593,7 +174431,7 @@
       []
      ],
      "echo-cookie.html": [
-      "a715b8b4294ffdc89b4d1dc6172cea91ccfc8073",
+      "4780447e8baf0a6c69e72ef8b156bbacccf6e525",
       []
      ],
      "echo-json.py": [
@@ -183885,6 +183723,10 @@
        "5fe4eadd958ea1c70d6fd361f3b986639cd4e1db",
        []
       ],
+      "flex-aspect-ratio-img-row-014-ref.html": [
+       "ea36ff403011527bf63d248db2fc40ff24328d91",
+       []
+      ],
       "flex-base-ref.html": [
        "d5c4709094c2d71e6eeb3c702549bba7258e1f56",
        []
@@ -213917,7 +213759,7 @@
       []
      ],
      "progressive-image.py": [
-      "64cc44ee0f2259f54c2c1ab303c57577890acf62",
+      "84e98c84510622c26002ec2bfa593b015ac939a1",
       []
      ],
      "slow-image.py": [
@@ -215499,7 +215341,7 @@
       []
      ],
      "message2.py": [
-      "cfe908406fc1c64bfee94f285d6335f80b5ec722",
+      "8515e7b25eb9e60e74700f51d9d2cdfa062dcae1",
       []
      ],
      "reconnect-fail.py": [
@@ -221375,16 +221217,12 @@
        "f69fa4ff17d9ffe18559c34546139872c6a8e2e2",
        []
       ],
-      "current-work-canvas.xhtml": [
-       "2bb889ab275fcdc7983752fa79e8dc990b38c5d2",
-       []
-      ],
       "gentest.py": [
        "5c223e41fba054c82292f9b459b6665473fb7d82",
        []
       ],
       "gentestutils.py": [
-       "d677f4d33bcc66bec9e271afccca5e36df9ab0e8",
+       "b6861db5f9ef72bf5ed02087411e2c3694865d75",
        []
       ],
       "name2dir-offscreen.yaml": [
@@ -221396,11 +221234,7 @@
        []
       ],
       "spec.yaml": [
-       "d4b1840a69f7f3406f77735350aabcd97fa836d3",
-       []
-      ],
-      "specextract.py": [
-       "c3b4a071eed39912e0fce6f9e150cf3641ed04c0",
+       "34f013fcd713affb8e0cc7e8324de55535f6396d",
        []
       ],
       "templates-offscreen.yaml": [
@@ -226932,6 +226766,10 @@
         "94f4991f2272da61a9a8381d07abb243677d06a9",
         []
        ],
+       "legend-position-relative-2-ref.html": [
+        "da2dd3e1c61cc42e948169c6a36c8947744c7e76",
+        []
+       ],
        "legend-position-relative-ref.html": [
         "fd6c11a00566759fbf1e749d49ad396cf1a7ee08",
         []
@@ -230483,7 +230321,7 @@
           []
          ],
          "moving-between-documents-iframe.py": [
-          "b7b6dac1937c203f10cfbdcad315a6d240d10f32",
+          "dbcfe9b8d0d295074c6aaa950a0a73503e42990d",
           []
          ],
          "slow-flag-setter.py": [
@@ -232661,11 +232499,7 @@
        "d17588a18f053ec2b6b257f2785b0effb553d190",
        []
       ]
-     },
-     "subdomain-flag.www.sub.window-expected.txt": [
-      "977b18cb16e15ae434e565a8079bc5917a0d4f86",
-      []
-     ]
+     }
     },
     "testdriver": {
      "actions": {
@@ -234679,40 +234513,120 @@
      "953611f93037cfebe0459d5f67599b727539ae40",
      []
     ],
+    "detached.tentative.https.window.js.headers": [
+     "4fff9d9fba4c81f953826ffea010a75be626b95d",
+     []
+    ],
+    "iframe.cross-origin.tentative.https.window.js.headers": [
+     "4fff9d9fba4c81f953826ffea010a75be626b95d",
+     []
+    ],
+    "iframe.cross-site.tentative.https.window.js.headers": [
+     "4fff9d9fba4c81f953826ffea010a75be626b95d",
+     []
+    ],
+    "iframe.same-origin.tentative.https.window.js.headers": [
+     "4fff9d9fba4c81f953826ffea010a75be626b95d",
+     []
+    ],
+    "main-frame-and-worker.tentative.https.window.js.headers": [
+     "4fff9d9fba4c81f953826ffea010a75be626b95d",
+     []
+    ],
+    "main-frame.tentative.https.window.js.headers": [
+     "4fff9d9fba4c81f953826ffea010a75be626b95d",
+     []
+    ],
+    "redirect.client.tentative.https.window.js.headers": [
+     "4fff9d9fba4c81f953826ffea010a75be626b95d",
+     []
+    ],
+    "redirect.server.tentative.https.window.js.headers": [
+     "4fff9d9fba4c81f953826ffea010a75be626b95d",
+     []
+    ],
     "resources": {
      "common.js": [
-      "3b246719799d2f963bc5cb4cd12500bba62ecb08",
+      "11b40d7d3d17ff0708c457a43d66b360b7e0bb07",
       []
      ],
      "iframe.redirect.sub.html": [
       "6eaf557422c18e9f0d7a27870102227267af81c1",
       []
      ],
+     "iframe.redirect.sub.html.headers": [
+      "4e798cd9f5d3f756df077a43ce9a1a6f9b41fd28",
+      []
+     ],
      "iframe.secret.sub.html": [
       "55caa347fbfdb2b182bd6d2e1e22088eb78e0d3a",
       []
      ],
+     "iframe.secret.sub.html.headers": [
+      "b227e843ae8e4b9136127c37eed0353c5d21c85c",
+      []
+     ],
      "iframe.sub.html": [
       "96b7b1a83982e2f38bc4e9cc4288a3708611bb30",
       []
      ],
+     "iframe.sub.html.headers": [
+      "b227e843ae8e4b9136127c37eed0353c5d21c85c",
+      []
+     ],
+     "redirect.py": [
+      "1e6dbff8a8478c22d04948d1a358098a2c98470f",
+      []
+     ],
      "window.redirect.sub.html": [
       "b339abc54f7a3e72184b434de85231763b1734c4",
       []
      ],
+     "window.redirect.sub.html.headers": [
+      "4fff9d9fba4c81f953826ffea010a75be626b95d",
+      []
+     ],
      "window.secret.sub.html": [
       "99d9d1251b28e0a91633a0f162ffc6bfc306ec26",
       []
      ],
+     "window.secret.sub.html.headers": [
+      "4fff9d9fba4c81f953826ffea010a75be626b95d",
+      []
+     ],
      "window.sub.html": [
       "c2540943828ce9fd9db463ad4f33c643c6f1eadf",
       []
      ],
+     "window.sub.html.headers": [
+      "4fff9d9fba4c81f953826ffea010a75be626b95d",
+      []
+     ],
      "worker.js": [
-      "bc194a854cd93528930b49ff2a3051e63d4ad43e",
+      "000df1272948ef22b5963978a015b56e70fc8093",
+      []
+     ],
+     "worker.js.headers": [
+      "a2714096617defba2905d164b8da35d3f7b15506",
       []
      ]
-    }
+    },
+    "window-open.cross-origin.tentative.https.window.js.headers": [
+     "4fff9d9fba4c81f953826ffea010a75be626b95d",
+     []
+    ],
+    "window-open.cross-site.tentative.https.window.js.headers": [
+     "4fff9d9fba4c81f953826ffea010a75be626b95d",
+     []
+    ],
+    "window-open.mix.tentative.https.window.js.headers": [
+     "4fff9d9fba4c81f953826ffea010a75be626b95d",
+     []
+    ],
+    "window-open.same-origin.tentative.https.window.js.headers": [
+     "4fff9d9fba4c81f953826ffea010a75be626b95d",
+     []
+    ]
    },
    "media": {
     "1x1-green.png": [
@@ -237652,7 +237566,7 @@
        []
       ],
       "portal-harness.js": [
-       "9761ac9268bce245cdf5335a613127874c0fd976",
+       "fa8c761afb9f924fe94f8b1b19e49270c79d281a",
        []
       ],
       "portal-manipulate-history-with-subframes.sub.html": [
@@ -237693,7 +237607,7 @@
       []
      ],
      "eval-portal.html": [
-      "98c2013915eae38bea2b8722bb8f80378ae894a0",
+      "a473501b014db604f70b4b20c3a55a22e5c40b5e",
       []
      ],
      "focus-page-with-button.html": [
@@ -237717,11 +237631,11 @@
       []
      ],
      "portal-activate-data-portal.html": [
-      "f57e4b196be471783316a6749a58ebd4a5b962a7",
+      "0842ad82efa19432dac85aa29d900fefd6d1a277",
       []
      ],
      "portal-activate-event-portal.html": [
-      "63c2e6e8b92b0af9cdf0e3814133b0fe4b68a169",
+      "6de5aafca78a261f879dd1f88f3eb124b91a621d",
       []
      ],
      "portal-activate-in-handler.html": [
@@ -237729,7 +237643,7 @@
       []
      ],
      "portal-activate-inside-portal.html": [
-      "517c9a47e516124c2602607f5a3b01d3acb0e971",
+      "ff8bead3242fd2334f4e1f263cd66e381c1c69fa",
       []
      ],
      "portal-activate-twice-window-1.html": [
@@ -237741,7 +237655,7 @@
       []
      ],
      "portal-close-window.html": [
-      "6e163f4e86c97f66ea8f3298e36ed62d1ceb4790",
+      "a12af3cd7a9e2f8be033cb2ceeb59eaffdcab659",
       []
      ],
      "portal-embed-and-activate.html": [
@@ -237753,27 +237667,27 @@
       []
      ],
      "portal-host-hidden-after-activation-portal.html": [
-      "75c8b733b5e7a5960ab86db549df437decea700e",
+      "491d184f9720d249e55f470e7032c82f555620c3",
       []
      ],
      "portal-host-post-message-after-activate.html": [
-      "996380f923086e21df847af7da8bd9efd73127b3",
+      "7b03ac0294ced6f2ef6b01fbc91876d82b829b81",
       []
      ],
      "portal-host-post-message-navigate-1.html": [
-      "3b36eaed05e95ad2b251d65598b1950d0f26e37e",
+      "a59144e7e11e8f906897beaad8adc0facdaa413c",
       []
      ],
      "portal-host-post-message-navigate-2.html": [
-      "163c42e655d6aa69a8ba8ccfb8474072eac9d349",
+      "571c4f122e0dccb5204f6576228910f03d34420a",
       []
      ],
      "portal-host-post-message-x-origin.html": [
-      "eb390e8b539d1b901bbe571f0b19f6eaa9c8d0bb",
+      "6cbc7f4b884242930486081081ec937e7deb7948",
       []
      ],
      "portal-host-post-message.html": [
-      "3c49d560f4b7f3b41d463dec1dc8ce621f47c0d3",
+      "1935ee898e915edf2478d3bea36cffb94d654efc",
       []
      ],
      "portal-host.html": [
@@ -237801,7 +237715,7 @@
       []
      ],
      "portal-post-message-portal.html": [
-      "26f62839af5ed8ea7a50535f411780bdf7fd6e03",
+      "e83ae56e08fcb251577168ba8cc8dce0e3100133",
       []
      ],
      "portal-post-message-x-origin-portal.html": [
@@ -237813,7 +237727,7 @@
       []
      ],
      "portals-adopt-predecessor-portal.html": [
-      "48e162b97140e835c7269ce40a859d38665451df",
+      "b838b38be16424e6bd51b483dca27a8445622090",
       []
      ],
      "portals-adopt-predecessor.html": [
@@ -237821,15 +237735,15 @@
       []
      ],
      "portals-nested-portal.html": [
-      "1ac17c03d4cdc6c9a7c3648c61be3909e965741e",
+      "278b32eea06bf71dd951780b12a8715410a83aab",
       []
      ],
      "portals-rendering-portal.html": [
-      "c3fe18ef5345c8d963da76bc9d6445635f310f17",
+      "31b3f4a9909e9bda842997f1c7586e79dceedc2b",
       []
      ],
      "postmessage-referrer.sub.html": [
-      "92aef00380ae4a6180039ad0b10169c81a190441",
+      "c3837dc79d8cb3d0fa86e45a78cdd4a7d37f9d1e",
       []
      ],
      "predecessor-fires-unload-watch-unload.html": [
@@ -237841,11 +237755,11 @@
       []
      ],
      "simple-portal-adopts-predecessor.html": [
-      "b199bdd93b3a03437ebde7abaef9b14ac61b1f76",
+      "b5ea9f029d84dc9c3bfd525820a3c428d0b1abaa",
       []
      ],
      "simple-portal.html": [
-      "29380099af1a3b9bf0990990ecefd8fa632d30c4",
+      "7d7b678cadcb81315ccd4052345c372f04a94fea",
       []
      ],
      "stash-utils.sub.js": [
@@ -239752,7 +239666,7 @@
      []
     ],
     "SyntheticResponse.py": [
-     "944de61c71561d9a96825b9a344bc642a48f262a",
+     "0cce1df3cf6b5377fb4cbe9ed40d0a023c75336b",
      []
     ],
     "__init__.py": [
@@ -241797,7 +241711,7 @@
         []
        ],
        "chunked-encoding-scope.py": [
-        "912f43d00402278d585bd123de5fe11d10ab1c04",
+        "659c4d8cdf24e481408d9ceacfad9ca1d55373a9",
         []
        ],
        "chunked-encoding-worker.js": [
@@ -242564,7 +242478,7 @@
        []
       ],
       "invalid-chunked-encoding-with-flush.py": [
-       "22a696508f44162927d396daa2ffad39780eaff2",
+       "05977c6ab0b5d977cf9490c7240f95f54f4a82d4",
        []
       ],
       "invalid-chunked-encoding.py": [
@@ -243278,6 +243192,10 @@
       "declarative-child-frame.html": [
        "10608b4875e0bd7d0169cf109b62b2b3612a8288",
        []
+      ],
+      "helpers.js": [
+       "70808e8db7b11db236b893cfd7147458154f69ce",
+       []
       ]
      }
     },
@@ -243400,7 +243318,7 @@
      []
     ],
     "README.md": [
-     "4032edf22f34f596d74da5ee0e4019c5dcf1c69c",
+     "0987e90ad00481afb015a92faf1f2d8bf2f55694",
      []
     ],
     "appcache": {
@@ -243475,7 +243393,7 @@
       []
      ],
      "generate-test-sxgs.sh": [
-      "e3988ce683dad77fd2dd8ed0ba5bf94426acb9d4",
+      "9738f7cab19f9175bb0015df818c7d3f7d3f57cb",
       []
      ],
      "inner-url.html": [
@@ -251403,7 +251321,7 @@
       []
      ],
      "requirements.txt": [
-      "7c134b89b9583f9f0584450f20e9665cb80e6445",
+      "77c1ea50e90bc2ccff510173fbc892190b616b1d",
       []
      ],
      "requirements_android_webview.txt": [
@@ -251435,7 +251353,7 @@
       []
      ],
      "requirements_firefox.txt": [
-      "373466dae07e95943d91f330832bf82dc118f0d7",
+      "622c34dcb038347db4f58fa3c69f00ffd0c3e280",
       []
      ],
      "requirements_ie.txt": [
@@ -251950,7 +251868,7 @@
        []
       ],
       "response.py": [
-       "1519ed78f397646559c42fa6322a8c145a14d094",
+       "6e5ee115a55c329b5d457e44e77b9e990a8eadaf",
        []
       ],
       "router.py": [
@@ -253466,7 +253384,7 @@
      []
     ],
     "README.md": [
-     "03b42ab340a2c0cdc774b78f203c80d5eee5539f",
+     "90c13069bacde39c89acea37e1e0005b956be845",
      []
     ],
     "resources": {
@@ -253515,7 +253433,7 @@
       ]
      },
      "generate-test-wbns.sh": [
-      "64a54bca3a408c5af751a59daf8664db62ea7d28",
+      "7100e6a777260261275c54e337b2aebeca1c4fd1",
       []
      ],
      "location": {
@@ -255355,7 +255273,7 @@
     },
     "unload-a-document": {
      "001-1.html": [
-      "75d689e0b3d2e2ce3b7aa56ef33fb05409b78cb6",
+      "c6ef23018b1058eb9de29e9bd35ecbeabf90c77d",
       []
      ],
      "001-2.html": [
@@ -255363,7 +255281,7 @@
       []
      ],
      "002-1.html": [
-      "546de89dfee0782a916bf0ed82328bb77e92956c",
+      "04623ffc473fadaaf48f097994d60751400900b6",
       []
      ],
      "002-2.html": [
@@ -255383,7 +255301,7 @@
       []
      ],
      "005-1.html": [
-      "fd70fc5bddee9af48223f044146b4f69953b7cdc",
+      "1dbcef22bb368e60ba0a1b05b5ee9d46c56892ba",
       []
      ]
     },
@@ -259323,7 +259241,7 @@
       []
      ],
      "echo-method.py": [
-      "7899c184b768cfba8c50c9d6814ff0058d594cc8",
+      "564c3db11f0357a5917c4564a00c47329a3675f8",
       []
      ],
      "empty-div-utf8-html.py": [
@@ -259403,7 +259321,7 @@
       []
      ],
      "inspect-headers.py": [
-      "36ef17488ce5241f21caf48ac44c877bf86fbae8",
+      "72c1a7f1d7a4daae25a49a874cb9c311aa0ed344",
       []
      ],
      "invalid-utf8-html.py": [
@@ -278969,6 +278887,13 @@
        {}
       ]
      ],
+     "frame-src-sandboxed-allowed.html": [
+      "419a14458b759084ec1a9dd3e037a279149fe073",
+      [
+       null,
+       {}
+      ]
+     ],
      "frame-src-self-unique-origin.html": [
       "947b11e063de776b4d9afffb91e1667460d9099f",
       [
@@ -282649,6 +282574,44 @@
     ]
    },
    "cookies": {
+    "attributes": {
+     "invalid.html": [
+      "9e72394940f01bf23df863dae862519e432c685a",
+      [
+       null,
+       {
+        "timeout": "long"
+       }
+      ]
+     ],
+     "path.html": [
+      "ca8d04935f5cd8ee8cb746b4cb4e10f6e99d6c61",
+      [
+       null,
+       {
+        "timeout": "long"
+       }
+      ]
+     ],
+     "secure-non-secure.html": [
+      "55f11f3adb10d002c0bb40c620e1c0ccba8012f5",
+      [
+       null,
+       {
+        "timeout": "long"
+       }
+      ]
+     ],
+     "secure.https.html": [
+      "5e73758c4a070a39812deab3e2b7c61e6f56733e",
+      [
+       null,
+       {
+        "timeout": "long"
+       }
+      ]
+     ]
+    },
     "cookie-enabled-noncookie-frame.html": [
      "539d715ebd5344de4cf02b6485462b31bc167525",
      [
@@ -282687,15 +282650,6 @@
      ]
     },
     "http-state": {
-     "attribute-tests.html": [
-      "5d9330042e18b09a9cf6739eb74ec1c1f1fa5c02",
-      [
-       null,
-       {
-        "timeout": "long"
-       }
-      ]
-     ],
      "charset-tests.html": [
       "5917da19ec4264eed7277858842cd533fcb4135e",
       [
@@ -309344,6 +309298,15 @@
        {}
       ]
      ],
+     "hover-002.html": [
+      "02cee99bf6cd161eb95806854cb12e39504a359e",
+      [
+       null,
+       {
+        "testdriver": true
+       }
+      ]
+     ],
      "i18n": {
       "css3-selectors-lang-001.html": [
        "e88f20a02471e324ee5d5900add484142cbf5ce8",
@@ -378196,6 +378159,15 @@
         }
        ]
       ],
+      "mouseClickCount.html": [
+       "4f02088c5a7c4f17945b0e1028ace6186e8ee0c9",
+       [
+        null,
+        {
+         "testdriver": true
+        }
+       ]
+      ],
       "multiDevice.html": [
        "6bc0fa218d8953093e583622264bdf02b73c78bb",
        [
@@ -379700,6 +379672,27 @@
       {}
      ]
     ],
+    "content-visibility-auto-offscreen.html": [
+     "8356a340dfb0b515b84ee8c8f14827d362305e30",
+     [
+      null,
+      {}
+     ]
+    ],
+    "content-visibility-auto-onscreen.html": [
+     "4d9d06aa537ecbc4a0fa3fa465197b220a533c23",
+     [
+      null,
+      {}
+     ]
+    ],
+    "content-visibility-hidden.html": [
+     "939b1a212233a5be7b0b9611fe07cf062a11ffe0",
+     [
+      null,
+      {}
+     ]
+    ],
     "fixed-position-move.html": [
      "877c2ba4b34615c41a5b21dbf114df69eef04352",
      [
@@ -381187,10 +381180,10 @@
     }
    },
    "measure-memory": {
-    "detached.tentative.window.js": [
-     "c6a133cfe456c7c8488ea76d85b903261de206fb",
+    "detached.tentative.https.window.js": [
+     "179e5e727adfd9b12e82b84b0c39a7c682a6689d",
      [
-      "measure-memory/detached.tentative.window.html",
+      "measure-memory/detached.tentative.https.window.html",
       {
        "script_metadata": [
         [
@@ -381210,10 +381203,10 @@
       }
      ]
     ],
-    "iframe.cross-origin.tentative.window.js": [
-     "a9dccc8d80f9de314f59a05da521621a8038fe0d",
+    "iframe.cross-origin.tentative.https.window.js": [
+     "ac0641cc2621df534faedfe50d22dac5bde3cb15",
      [
-      "measure-memory/iframe.cross-origin.tentative.window.html",
+      "measure-memory/iframe.cross-origin.tentative.https.window.html",
       {
        "script_metadata": [
         [
@@ -381233,10 +381226,10 @@
       }
      ]
     ],
-    "iframe.cross-site.tentative.window.js": [
-     "e40ce59fa4d25741155fe637d1b18fce58a37245",
+    "iframe.cross-site.tentative.https.window.js": [
+     "1b4dfc70b7e10ef4a304513b8b7446ea27df41c6",
      [
-      "measure-memory/iframe.cross-site.tentative.window.html",
+      "measure-memory/iframe.cross-site.tentative.https.window.html",
       {
        "script_metadata": [
         [
@@ -381256,10 +381249,10 @@
       }
      ]
     ],
-    "iframe.same-origin.tentative.window.js": [
-     "7fc02036117a152ffeb945fb4ad32ab2bdf97215",
+    "iframe.same-origin.tentative.https.window.js": [
+     "1d546b27f302ace49618d448cfcb13f668631c08",
      [
-      "measure-memory/iframe.same-origin.tentative.window.html",
+      "measure-memory/iframe.same-origin.tentative.https.window.html",
       {
        "script_metadata": [
         [
@@ -381279,10 +381272,10 @@
       }
      ]
     ],
-    "main-frame-and-worker.tentative.window.js": [
-     "514a4ed067315433c5a368fc7d065b415a4e8229",
+    "main-frame-and-worker.tentative.https.window.js": [
+     "f0b8abf1bc6dca66f57a0bd4f2152f6c479de6f2",
      [
-      "measure-memory/main-frame-and-worker.tentative.window.html",
+      "measure-memory/main-frame-and-worker.tentative.https.window.html",
       {
        "script_metadata": [
         [
@@ -381302,10 +381295,10 @@
       }
      ]
     ],
-    "main-frame.tentative.window.js": [
-     "0a34abb9246f0c218c26cedd99bebbf2f01aeaf0",
+    "main-frame.tentative.https.window.js": [
+     "fd58e9314b0980154a9e828e0212dee2f20309d5",
      [
-      "measure-memory/main-frame.tentative.window.html",
+      "measure-memory/main-frame.tentative.https.window.html",
       {
        "script_metadata": [
         [
@@ -381325,10 +381318,10 @@
       }
      ]
     ],
-    "redirect.client.tentative.window.js": [
-     "e38a325c7122833c0a05bda9b4c8d027a407ead0",
+    "redirect.client.tentative.https.window.js": [
+     "36d9a9d44cd1734572c2b3b930cec7ff0b3eeee2",
      [
-      "measure-memory/redirect.client.tentative.window.html",
+      "measure-memory/redirect.client.tentative.https.window.html",
       {
        "script_metadata": [
         [
@@ -381348,10 +381341,10 @@
       }
      ]
     ],
-    "redirect.server.tentative.window.js": [
-     "740abca167829087fbd8bf5d8373cf4f2646f3f7",
+    "redirect.server.tentative.https.window.js": [
+     "6506730b34cbe681a72a65b290c3c2e5b012f5e5",
      [
-      "measure-memory/redirect.server.tentative.window.html",
+      "measure-memory/redirect.server.tentative.https.window.html",
       {
        "script_metadata": [
         [
@@ -381371,10 +381364,10 @@
       }
      ]
     ],
-    "window-open.cross-origin.tentative.window.js": [
-     "d067b2c175bd995898c7ded32297d5bfa543c57a",
+    "window-open.cross-origin.tentative.https.window.js": [
+     "2e6561ad44bbd8345102e627dbe079ea7f98605e",
      [
-      "measure-memory/window-open.cross-origin.tentative.window.html",
+      "measure-memory/window-open.cross-origin.tentative.https.window.html",
       {
        "script_metadata": [
         [
@@ -381394,10 +381387,10 @@
       }
      ]
     ],
-    "window-open.cross-site.tentative.window.js": [
-     "7fa49f5facc21f73818a726d4547cc0ba5581e30",
+    "window-open.cross-site.tentative.https.window.js": [
+     "f70ad9df32b92640160503550afcbb9a4168943e",
      [
-      "measure-memory/window-open.cross-site.tentative.window.html",
+      "measure-memory/window-open.cross-site.tentative.https.window.html",
       {
        "script_metadata": [
         [
@@ -381417,10 +381410,10 @@
       }
      ]
     ],
-    "window-open.mix.tentative.window.js": [
-     "5bb9d29c61d86c67f654f77827d7dc07c31b2508",
+    "window-open.mix.tentative.https.window.js": [
+     "6a913a88a4876ae096b989658384c8848b14f227",
      [
-      "measure-memory/window-open.mix.tentative.window.html",
+      "measure-memory/window-open.mix.tentative.https.window.html",
       {
        "script_metadata": [
         [
@@ -381440,10 +381433,10 @@
       }
      ]
     ],
-    "window-open.same-origin.tentative.window.js": [
-     "7ec3cc436f1c3a250c18c6bcc369241241b2b081",
+    "window-open.same-origin.tentative.https.window.js": [
+     "5223a97bc7d2fc4ca55fbd5e06d979abe78d2ca1",
      [
-      "measure-memory/window-open.same-origin.tentative.window.html",
+      "measure-memory/window-open.same-origin.tentative.https.window.html",
       {
        "script_metadata": [
         [
@@ -382860,15 +382853,15 @@
       {}
      ]
     ],
-    "constructor.tentative.https.html": [
-     "9fdf78ddb3dea4de72e48d1ae5288c0a9f161d68",
+    "constructor.tentative.http.html": [
+     "8368c79a3b1dea2df26bbc804208002ec97fbf09",
      [
       null,
       {}
      ]
     ],
-    "constructortentative..http.html": [
-     "8368c79a3b1dea2df26bbc804208002ec97fbf09",
+    "constructor.tentative.https.html": [
+     "9fdf78ddb3dea4de72e48d1ae5288c0a9f161d68",
      [
       null,
       {}
@@ -390967,7 +390960,7 @@
      ]
     ],
     "pointerevent_auxclick_is_a_pointerevent.html": [
-     "8c25125a4f0dee674a122cda94d23fab873c8a10",
+     "000d0df764e53f8d1cfa629ebfcccfb768a7a4bf",
      [
       null,
       {
@@ -391021,7 +391014,7 @@
      ]
     ],
     "pointerevent_click_is_a_pointerevent.html": [
-     "ba20919ebe061efedaf38896246fb7aecfecd811",
+     "dfea148898e4eed29f25e9bf04067a6e7e251b25",
      [
       null,
       {
@@ -391046,7 +391039,7 @@
      ]
     ],
     "pointerevent_contextmenu_is_a_pointerevent.html": [
-     "4f5b2434b40054913b094ed2fcb11d4a36390008",
+     "8a820834a3a2bd193604ea668a812204f07aeac4",
      [
       null,
       {
@@ -391994,7 +391987,7 @@
      ]
     ],
     "portals-focus.sub.html": [
-     "168e74aa9c816ef56c4618b34e5fe01370b3cb6c",
+     "3e3045adf90aabdfb7b9a2136fabb48d9f98406c",
      [
       null,
       {
@@ -392025,7 +392018,7 @@
      ]
     ],
     "portals-host-post-message.sub.html": [
-     "aa4893cb904d29087ea5413c90eddf7dc317a216",
+     "d589235ec3bf9befbe8e41dd98d98134fea887a8",
      [
       null,
       {
@@ -392048,7 +392041,7 @@
      ]
     ],
     "portals-post-message.sub.html": [
-     "19803f686969678f72030d6a6ddce4b0d361b275",
+     "d556dd43d84ab413e85055bb14d000bbdb070ec7",
      [
       null,
       {
@@ -407545,21 +407538,21 @@
       ]
      ],
      "declarative-shadow-dom-attachment.tentative.html": [
-      "c4a35d341c1f688e9690851982b6cb6a9ef7fa7f",
+      "b9033f599242237626985f35ac6560527c972b32",
       [
        null,
        {}
       ]
      ],
      "declarative-shadow-dom-basic.tentative.html": [
-      "6e3c16a9d82dfa798fed4c54ecb9561832548d07",
+      "a03743e44ffda00d1d334e58d275eb8bf61ff2a9",
       [
        null,
        {}
       ]
      ],
      "declarative-shadow-dom-opt-in.tentative.html": [
-      "2d6bf5f3f2d90970f109aa4213bc8de79775811c",
+      "d1fd9fc448a220c270dff51117648ccc8ba16607",
       [
        null,
        {}
@@ -407599,13 +407592,6 @@
        null,
        {}
       ]
-     ],
-     "setinnerhtml.tentative.html": [
-      "c65bf04a06c97343025aa1e795a8e440edbe763b",
-      [
-       null,
-       {}
-      ]
      ]
     },
     "event-composed-path-after-dom-mutation.html": [
@@ -428052,7 +428038,7 @@
      ]
     ],
     "video-decoder.any.js": [
-     "e667a5642e76a6bb58cd608ebf2c1428c70b208a",
+     "2dd85ad955b7321167b9809007d1badea5780555",
      [
       "webcodecs/video-decoder.any.html",
       {
@@ -429715,6 +429701,13 @@
       }
      ]
     ],
+    "RTCPeerConnectionIceErrorEvent.html": [
+     "4434cfd28b7eb761df1c11571fa7c50ce5f32bbf",
+     [
+      null,
+      {}
+     ]
+    ],
     "RTCPeerConnectionIceEvent-constructor.html": [
      "447002dca1fa35816fdd24c74dd761c1d48cf028",
      [
@@ -430023,6 +430016,13 @@
      ]
     ],
     "protocol": {
+     "RTCPeerConnection-payloadTypes.html": [
+      "eacbf38a0f6128efdcd597f995bf872f559a882c",
+      [
+       null,
+       {}
+      ]
+     ],
      "bundle.https.html": [
       "61d1ff8ac108297dafe333694ddd1194ff53fe26",
       [
@@ -434363,7 +434363,7 @@
     },
     "unload-a-document": {
      "001.html": [
-      "56e883c6492be7c6a18100ca275864fe3e284526",
+      "52427b5d8d8478033f7f8877916bffaaccb11d6f",
       [
        null,
        {}
@@ -434374,7 +434374,7 @@
       ]
      ],
      "002.html": [
-      "94028e703863132a131f8153e3efe762a1fe8905",
+      "748da64ec7b0ff8397d699df92b96bdb2273a236",
       [
        null,
        {
@@ -434405,7 +434405,7 @@
       ]
      ],
      "005.html": [
-      "81a05f48ead2dea99489ea11f8bfb91b83696733",
+      "588fd76765acd16b3b0ddbb73dbd30bad6f84963",
       [
        null,
        {
diff --git a/third_party/blink/web_tests/external/wpt/FileAPI/file/resources/echo-content-escaped.py b/third_party/blink/web_tests/external/wpt/FileAPI/file/resources/echo-content-escaped.py
index bdbbc0f..2cbaf45 100644
--- a/third_party/blink/web_tests/external/wpt/FileAPI/file/resources/echo-content-escaped.py
+++ b/third_party/blink/web_tests/external/wpt/FileAPI/file/resources/echo-content-escaped.py
@@ -5,9 +5,13 @@
 # As a convenience, CRLF newlines are left as is.
 
 def escape_byte(byte):
-    if b"\0" <= byte <= b"\x1F" or byte >= b"\x7F":
-        return b"\\x%02x" % ord(byte)
-    if byte == b"\\":
+    # Iterating over a binary string gives different types in Py2 & Py3.
+    # Py3: bytes -> int
+    # Py2: str -> str (of length 1), so we convert it to int
+    code = byte if type(byte) is int else ord(byte)
+    if 0 <= code <= 0x1F or code >= 0x7F:
+        return b"\\x%02x" % code
+    if code == ord(b"\\"):
         return b"\\\\"
     return byte
 
diff --git a/third_party/blink/web_tests/external/wpt/css/css-flexbox/flex-aspect-ratio-img-row-014.html b/third_party/blink/web_tests/external/wpt/css/css-flexbox/flex-aspect-ratio-img-row-014.html
new file mode 100644
index 0000000..9f12b65
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-flexbox/flex-aspect-ratio-img-row-014.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<title>CSS Flexible Box Test: Aspect ratio handling of images</title>
+<link rel="author" title="Sergio Villar Senin" href="mailto:svillar@igalia.com" />
+<link rel="help" href="https://drafts.csswg.org/css-flexbox-1/#algo-cross-item" />
+<link rel="match" href="reference/flex-aspect-ratio-img-row-014-ref.html" />
+<meta name="assert" content="Test that we compute the correct aspect-ratio based cross size when a percentage main size is specified" />
+
+<style>
+#reference-overlapped-red {
+    position: absolute;
+    background-color: red;
+    width: 90px;
+    height: 225px;
+    z-index: -1;
+}
+#constrained-flex {
+    display: flex;
+    width: 300px;
+    border: 1px solid black;
+}
+img {
+    min-width: 0;
+    min-height: 0;
+    width: 30%;
+}
+</style>
+
+<p>Test passes if there is <strong>no red</strong> visible on the page.</p>
+
+<div id="reference-overlapped-red"></div>
+<div id="constrained-flex">
+    <img id="test-flex-item-overlapping-green" src="support/20x50-green.png" />
+</div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-flexbox/reference/flex-aspect-ratio-img-row-014-ref.html b/third_party/blink/web_tests/external/wpt/css/css-flexbox/reference/flex-aspect-ratio-img-row-014-ref.html
new file mode 100644
index 0000000..ea36ff40
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-flexbox/reference/flex-aspect-ratio-img-row-014-ref.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<title>CSS Reference</title>
+<link rel="author" title="Sergio Villar Senin" href="mailto:svillar@igalia.com" />
+<style>
+span {
+  display: inline-block;
+  background-color: green;
+  height: 225px;
+  width: 90px;
+}
+
+div {
+  border: 1px solid black;
+  height: 225px;
+  width: 300px;
+}
+</style>
+
+<p>Test passes if there is <strong>no red</strong> visible on the page.</p>
+<div><span></span></div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-paint-api/two-element-custom-property-animation-ref.html b/third_party/blink/web_tests/external/wpt/css/css-paint-api/two-element-custom-property-animation-ref.html
new file mode 100644
index 0000000..6c6d945
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-paint-api/two-element-custom-property-animation-ref.html
@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<html>
+<body>
+<canvas id ="canvas" width="200" height="400"></canvas>
+<script>
+var canvas = document.getElementById('canvas');
+var context = canvas.getContext("2d");
+context.fillStyle = 'green';
+context.fillRect(0, 0, 100, 100);
+context.fillStyle = 'rgb(128, 128, 0)';
+context.fillRect(0, 200, 200, 200);
+</script>
+</body>
+</html>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-paint-api/two-element-custom-property-animation.https.html b/third_party/blink/web_tests/external/wpt/css/css-paint-api/two-element-custom-property-animation.https.html
new file mode 100644
index 0000000..044650d
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-paint-api/two-element-custom-property-animation.https.html
@@ -0,0 +1,87 @@
+<!DOCTYPE html>
+<html class="reftest-wait">
+<link rel="help" href="https://drafts.css-houdini.org/css-paint-api/">
+<link rel="match" href="two-element-custom-property-animation-ref.html">
+<style>
+#footainer {
+  width: 200px;
+  height: 200px;
+}
+.fooanimate {
+  background-image: paint(foo);
+  animation: expand 5s;
+}
+#bartainer {
+  width: 200px;
+  height: 200px;
+}
+.baranimate {
+  background-image: paint(bar);
+  animation: colorChange 5s;
+}
+@keyframes expand {
+  0% { --foo: 0; }
+  0.01% { --foo: 100; }
+  99% { --foo: 100; }
+  100% { --foo: 200; }
+}
+@keyframes colorChange {
+  0% { --bar: rgb(255, 0, 0); }
+  0.01% { --bar: rgb(128, 128, 0); }
+  99% { --bar: rgb(128, 128, 0); }
+  100% { --bar: rgb(0, 255, 0); }
+}
+</style>
+<script src="/common/reftest-wait.js"></script>
+<script src="/common/worklet-reftest.js"></script>
+<body>
+<div id="footainer"></div>
+<div id="bartainer"></div>
+
+<script id="code" type="text/worklet">
+registerPaint('foo', class {
+  static get inputProperties() { return ['--foo']; }
+  paint(ctx, geom, properties) {
+    let fooValue = parseFloat(properties.get('--foo').toString());
+    ctx.fillStyle = 'green';
+    ctx.fillRect(0, 0, fooValue, fooValue);
+  }
+});
+
+registerPaint('bar', class {
+  static get inputProperties() { return ['--bar']; }
+  paint(ctx, geom, properties) {
+    ctx.fillStyle = properties.get('--bar').toString();
+    ctx.fillRect(0, 0, 200, 200);
+  }
+});
+</script>
+
+<script type="text/javascript">
+CSS.registerProperty({
+  name: '--foo',
+  syntax: '<number>',
+  initialValue: '0',
+  inherits: false
+});
+CSS.registerProperty({
+  name: '--bar',
+  syntax: '<color>',
+  initialValue: 'rgb(0, 0, 0)',
+  inherits: false
+});
+</script>
+
+<script>
+var code = document.getElementById('code').textContent;
+var blob = new Blob([code], {type: 'text/javascript'});
+CSS.paintWorklet.addModule(URL.createObjectURL(blob)).then(function() {
+  document.getElementById('footainer').classList.add('fooanimate');
+  document.getElementById('bartainer').classList.add('baranimate');
+  requestAnimationFrame(function() {
+    takeScreenshot();
+  });
+});
+</script>
+</body>
+</html>
diff --git a/third_party/blink/web_tests/external/wpt/css/selectors/focus-visible-001-manual.html b/third_party/blink/web_tests/external/wpt/css/selectors/focus-visible-001.html
similarity index 81%
rename from third_party/blink/web_tests/external/wpt/css/selectors/focus-visible-001-manual.html
rename to third_party/blink/web_tests/external/wpt/css/selectors/focus-visible-001.html
index 3475ba6..2afcea2 100644
--- a/third_party/blink/web_tests/external/wpt/css/selectors/focus-visible-001-manual.html
+++ b/third_party/blink/web_tests/external/wpt/css/selectors/focus-visible-001.html
@@ -7,6 +7,9 @@
   <link rel="help" href="https://drafts.csswg.org/selectors-4/#the-focus-visible-pseudo" />
   <script src="/resources/testharness.js"></script>
   <script src="/resources/testharnessreport.js"></script>
+  <script src="/resources/testdriver.js"></script>
+  <script src="/resources/testdriver-actions.js"></script>
+  <script src="/resources/testdriver-vendor.js"></script>
   <style>
     :focus-visible {
       outline: darkgreen dotted 1px; /* fallback for Edge */
@@ -34,6 +37,9 @@
         assert_equals(getComputedStyle(el).outlineColor, "rgb(0, 100, 0)");
         t.done();
       }));
+      const tab_key = '\ue004';
+      test_driver.send_keys(el, tab_key)
+        .catch(e => t.step_func(() => assert_unreached("Actions sequence failed " + e)));
     }, "Keyboard focus should match :focus-visible");
   </script>
 </body>
diff --git a/third_party/blink/web_tests/external/wpt/element-timing/resources/progressive-image.py b/third_party/blink/web_tests/external/wpt/element-timing/resources/progressive-image.py
index 64cc44e..84e98c8 100644
--- a/third_party/blink/web_tests/external/wpt/element-timing/resources/progressive-image.py
+++ b/third_party/blink/web_tests/external/wpt/element-timing/resources/progressive-image.py
@@ -19,7 +19,6 @@
     # Read from the beginning, |numInitial| bytes.
     first = body[:numInitial]
     response.writer.write_content(first)
-    response.writer.flush()
 
     time.sleep(sleepTime)
 
diff --git a/third_party/blink/web_tests/external/wpt/eventsource/resources/message2.py b/third_party/blink/web_tests/external/wpt/eventsource/resources/message2.py
index cfe90840..8515e7b 100644
--- a/third_party/blink/web_tests/external/wpt/eventsource/resources/message2.py
+++ b/third_party/blink/web_tests/external/wpt/eventsource/resources/message2.py
@@ -4,7 +4,6 @@
     response.headers.set(b'Content-Type', b'text/event-stream')
     response.headers.set(b'Cache-Control', b'no-cache')
 
-    response.explicit_flush = True
     response.write_status_headers()
 
     while True:
@@ -31,5 +30,4 @@
         response.writer.write(u"data:end")
         response.writer.write(u"\n\n")
 
-        response.writer.flush()
         time.sleep(2)
diff --git a/third_party/blink/web_tests/external/wpt/html/canvas/tools/current-work-canvas.xhtml b/third_party/blink/web_tests/external/wpt/html/canvas/tools/current-work-canvas.xhtml
deleted file mode 100644
index 2bb889ab..0000000
--- a/third_party/blink/web_tests/external/wpt/html/canvas/tools/current-work-canvas.xhtml
+++ /dev/null
@@ -1,4576 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?><html class="split" lang="en-US-x-hixie" xmlns="http://www.w3.org/1999/xhtml"><head><meta charset="utf-8"/><meta content="width=device-width, initial-scale=1, shrink-to-fit=no" name="viewport"/><title>HTML Standard</title><meta content="#3c790a" name="theme-color"/><link href="https://resources.whatwg.org/standard.css" rel="stylesheet"/><link href="https://resources.whatwg.org/logo.svg" rel="icon"/><style>
-   .status { min-height: 0.6em; font: 1em sans-serif; width: 9em; padding: 0.3em; position: absolute; z-index: 8; right: 0.3em; background: #EEE; color: black; box-shadow: 0 0 3px #999; overflow: hidden; margin: -2em 0 0 0; border-collapse: initial; border-spacing: initial; }
-   .status:hover { z-index: 9; }
-   .status:focus-within { z-index: 9; }
-   .status.wrapped &gt; :not(input) { display: none; }
-   .status &gt; input { position: absolute; left: 0; top: 0; width: 1em; height: 1em; border: none; background: transparent; padding: 0; margin: 0; }
-   .status &gt; p { font-size: 0.6em; margin: 0; padding: 0; }
-   .status &gt; p + p { padding-top: 0.5em; }
-   .status &gt; p &gt; strong { margin-left: 1.5em; }
-   .status &gt; .support { display: block; }
-   .status &gt; .support &gt; span { padding: 0.2em 0; display: block; display: table; }
-   .status &gt; .support &gt; span.partial { color: #666666; filter: grayscale(50%); }
-   .status &gt; .support &gt; span.no { color: #CCCCCC; filter: grayscale(100%); }
-   .status &gt; .support &gt; span.no::before { opacity: 0.5; }
-   .status &gt; .support &gt; span:first-of-type { padding-top: 0.5em; }
-   .status &gt; .support &gt; span &gt; span { padding: 0 0.5em; display: table-cell; vertical-align: top; }
-   .status &gt; .support &gt; span &gt; span:first-child { width: 100%; }
-   .status &gt; .support &gt; span &gt; span:last-child { width: 100%; white-space: pre; padding: 0; }
-   .status &gt; .support &gt; span::before { content: ' '; display: table-cell; min-width: 1.5em; height: 1.5em; background: no-repeat center center; background-size: contain; text-align: right; font-size: 0.75em; font-weight: bold; }
-   .status &gt; .support &gt; .and_chr::before { background-image: url(https://resources.whatwg.org/browser-logos/chrome.svg); }
-   .status &gt; .support &gt; .and_ff::before { background-image: url(https://resources.whatwg.org/browser-logos/firefox.png); }
-   .status &gt; .support &gt; .and_uc::before { background-image: url(https://resources.whatwg.org/browser-logos/uc.png); } /* UC Browser for Android */
-   .status &gt; .support &gt; .android::before { background-image: url(https://resources.whatwg.org/browser-logos/android.svg); }
-   .status &gt; .support &gt; .bb::before { background-image: url(https://resources.whatwg.org/browser-logos/bb.jpg); } /* Blackberry Browser */
-   .status &gt; .support &gt; .chrome::before { background-image: url(https://resources.whatwg.org/browser-logos/chrome.svg); }
-   .status &gt; .support &gt; .edge::before { background-image: url(https://resources.whatwg.org/browser-logos/edge.svg); }
-   .status &gt; .support &gt; .firefox::before { background-image: url(https://resources.whatwg.org/browser-logos/firefox.png); }
-   .status &gt; .support &gt; .ie::before { background-image: url(https://resources.whatwg.org/browser-logos/ie.png); }
-   .status &gt; .support &gt; .ie_mob::before { background-image: url(https://resources.whatwg.org/browser-logos/ie-mobile.svg); }
-   .status &gt; .support &gt; .ios_saf::before { background-image: url(https://resources.whatwg.org/browser-logos/safari-ios.svg); }
-   .status &gt; .support &gt; .op_mini::before { background-image: url(https://resources.whatwg.org/browser-logos/opera-mini.png); }
-   .status &gt; .support &gt; .op_mob::before { background-image: url(https://resources.whatwg.org/browser-logos/opera.png); }
-   .status &gt; .support &gt; .opera::before { background-image: url(https://resources.whatwg.org/browser-logos/opera.png); }
-   .status &gt; .support &gt; .safari::before { background-image: url(https://resources.whatwg.org/browser-logos/safari.png); }
-   .status &gt; .support &gt; .samsung::before { background-image: url(https://resources.whatwg.org/browser-logos/samsung.png); }
-   .status &gt; .caniuse { text-align: right; font-style: italic; width: 100%; }
-   .status &gt; .caniuse + p { margin-top: 0.5em; border-top: 1px solid silver; }
-
-   @media (max-width: 767px) {
-     .status { right: -9em; }
-   }
-  </style><style>
-   [hidden] { display: none; }
-
-   .bad, .bad *:not(.X\58X) { color: gray; border-color: gray; background: transparent; }
-
-   .fingerprint { position: absolute; right: 0; z-index: 5; }
-   @media (max-width: 767px) {
-     .fingerprint { max-width: 35px; }
-   }
-
-   .applies .yes, .yesno .yes { background: yellow; }
-   .yesno .yes, .yesno .no { text-align: center; }
-
-   .applies thead th &gt; * { display: block; }
-   .applies thead code { display: block; }
-   .applies td { text-align: center; }
-
-   .matrix, .matrix td { border: hidden; text-align: right; }
-   .matrix { margin-left: 2em; }
-
-   .vertical-summary-table tr &gt; th[rowspan=&quot;2&quot;]:first-child + th,
-   .vertical-summary-table tr &gt; td[rowspan=&quot;2&quot;]:first-child + td { border-bottom: hidden; }
-
-   .dice-example { border-collapse: collapse; border-style: hidden solid solid hidden; border-width: thin; margin-left: 3em; }
-   .dice-example caption { width: 30em; font-size: smaller; font-style: italic; padding: 0.75em 0; text-align: left; }
-   .dice-example td, .dice-example th { border: solid thin; width: 1.35em; height: 1.05em; text-align: center; padding: 0; }
-
-   td.eg { border-width: thin; text-align: center; }
-
-   #table-example-1 { border: solid thin; border-collapse: collapse; margin-left: 3em; }
-   #table-example-1 caption { padding-bottom: 0.5em; }
-   #table-example-1 thead, #table-example-1 tbody { border: none; }
-   #table-example-1 th, #table-example-1 td { border: solid thin; }
-   #table-example-1 th { font-weight: normal; }
-   #table-example-1 td { border-style: none solid; vertical-align: top; }
-   #table-example-1 th { padding: 0.5em; vertical-align: middle; text-align: center; }
-   #table-example-1 tbody tr:first-child td { padding-top: 0.5em; }
-   #table-example-1 tbody tr:last-child td { padding-bottom: 1.5em; }
-   #table-example-1 tbody td:first-child { padding-left: 2.5em; padding-right: 0; width: 9em; }
-   #table-example-1 tbody td:first-child::after { content: leader(&quot;. &quot;); }
-   #table-example-1 tbody td { padding-left: 2em; padding-right: 2em; }
-   #table-example-1 tbody td:first-child + td { width: 10em; }
-   #table-example-1 tbody td:first-child + td ~ td { width: 2.5em; }
-   #table-example-1 tbody td:first-child + td + td + td ~ td { width: 1.25em; }
-
-   .apple-table-examples { border: none; border-collapse: separate; border-spacing: 1.5em 0em; width: 40em; margin-left: 3em; }
-   .apple-table-examples * { font-family: &quot;Times&quot;, serif; }
-   .apple-table-examples td, .apple-table-examples th { border: none; white-space: nowrap; padding-top: 0; padding-bottom: 0; }
-   .apple-table-examples tbody th:first-child { border-left: none; width: 100%; }
-   .apple-table-examples thead th:first-child ~ th { font-size: smaller; font-weight: bolder; border-bottom: solid 2px; text-align: center; }
-   .apple-table-examples tbody th::after, .apple-table-examples tfoot th::after { content: leader(&quot;. &quot;) }
-   .apple-table-examples tbody th, .apple-table-examples tfoot th { font: inherit; text-align: left; }
-   .apple-table-examples td { text-align: right; vertical-align: top; }
-   .apple-table-examples.e1 tbody tr:last-child td { border-bottom: solid 1px; }
-   .apple-table-examples.e1 tbody + tbody tr:last-child td { border-bottom: double 3px; }
-   .apple-table-examples.e2 th[scope=row] { padding-left: 1em; }
-   .apple-table-examples sup { line-height: 0; }
-
-   .three-column-nowrap tr &gt; td:first-child,
-   .three-column-nowrap tr &gt; td:first-child + td,
-   .three-column-nowrap tr &gt; td:first-child + td + td { white-space: nowrap; }
-
-   .details-example img { vertical-align: top; }
-
-   .parse-error-table td &gt; p:first-child { margin-top: 0; }
-
-   #named-character-references-table {
-     white-space: nowrap;
-     font-size: 0.6em;
-     column-width: 30em;
-     column-gap: 1em;
-     -webkit-column-width: 30em;
-     -webkit-column-gap: 1em;
-   }
-   #named-character-references-table &gt; table &gt; tbody &gt; tr &gt; td:first-child + td,
-   #named-character-references-table &gt; table &gt; tbody &gt; tr &gt; td:last-child { text-align: center; }
-   #named-character-references-table &gt; table &gt; tbody &gt; tr &gt; td:last-child:hover &gt; span { position: absolute; top: auto; left: auto; margin-left: 0.5em; line-height: 1.2; font-size: 5em; border: outset; padding: 0.25em 0.5em; background: white; width: 1.25em; height: auto; text-align: center; }
-   #named-character-references-table &gt; table &gt; tbody &gt; tr#entity-CounterClockwiseContourIntegral &gt; td:first-child { font-size: 0.5em; }
-
-   .glyph.control { color: red; }
-
-   #table-example-1 * { font-family: &quot;Essays1743&quot;, serif; line-height: 1.01em; }
-   @font-face {
-     font-family: 'Essays1743';
-     src: url('/fonts/Essays1743.ttf');
-   }
-   @font-face {
-     font-family: 'Essays1743';
-     font-weight: bold;
-     src: url('/fonts/Essays1743-Bold.ttf');
-   }
-   @font-face {
-     font-family: 'Essays1743';
-     font-style: italic;
-     src: url('/fonts/Essays1743-Italic.ttf');
-   }
-   @font-face {
-     font-family: 'Essays1743';
-     font-style: italic;
-     font-weight: bold;
-     src: url('/fonts/Essays1743-BoldItalic.ttf');
-   }
-
-   @media (max-width: 767px) {
-     #abstractimg { width: 100%; }
-   }
-   #abstractimg, #abstractimg text { font: inherit; }
-   #abstractimg rect { fill: #424242; }
-   #abstractimg text { fill: #ffffff; font-size: 18px }
-   #abstractimg .top { word-spacing: 50px; text-anchor: middle; }
-   #abstractimg .left, #abstractimg .bottom { word-spacing: 12px; }
-   #abstractimg .right { font-size: 25px; }
-  </style></head><body><header class="head with-buttons" id="head">
-   <a class="logo" href="https://whatwg.org/"><img alt="WHATWG" height="100" src="https://resources.whatwg.org/logo.svg" width="100"/></a>
-   <hgroup><h1 class="allcaps">HTML</h1><h2 class="no-num no-toc" id="living-standard">Living Standard — Last Updated <span class="pubdate">31 August 2017</span></h2></hgroup>
-   
-   
-
-   
-  <p class="copyright">Parts of this specification are © Copyright 2004-2014 Apple Inc., Mozilla Foundation, and Opera Software ASA. You are granted a license to use, reproduce and create derivative works of this document.</p></header><h4 id="the-canvas-element"><span class="secno">4.12.5</span> The <dfn id="canvas"><code>canvas</code></dfn> element<a class="self-link" href="#the-canvas-element"/></h4><div class="status"><input onclick="toggleStatus(this)" type="button" value="⋰"/><p class="support"><strong>Support:</strong> canvas<span class="and_chr yes"><span>Chrome for Android</span> <span>59+</span></span><span class="chrome yes"><span>Chrome</span> <span>4+</span></span><span class="and_uc yes"><span>UC Browser for Android</span> <span>11.4+</span></span><span class="ios_saf yes"><span>iOS Safari</span> <span>3.2+</span></span><span class="firefox yes"><span>Firefox</span> <span>3.6+</span></span><span class="ie yes"><span>IE</span> <span>9+</span></span><span class="samsung yes"><span>Samsung Internet</span> <span>4+</span></span><span class="op_mini partial"><span>Opera Mini (limited)</span> <span>all+</span></span><span class="safari yes"><span>Safari</span> <span>4+</span></span><span class="android yes"><span>Android Browser</span> <span>3+</span></span><span class="opera yes"><span>Opera</span> <span>9+</span></span><span class="edge yes"><span>Edge</span> <span>12+</span></span></p><p class="caniuse">Source: <a href="https://caniuse.com/#feat=canvas">caniuse.com</a></p></div>
-
-  <dl class="element"><dt><a href="https://html.spec.whatwg.org/multipage/dom.html#concept-element-categories" id="the-canvas-element:concept-element-categories">Categories</a>:</dt><dd><a href="https://html.spec.whatwg.org/multipage/dom.html#flow-content-2" id="the-canvas-element:flow-content-2">Flow content</a>.</dd><dd><a href="https://html.spec.whatwg.org/multipage/dom.html#phrasing-content-2" id="the-canvas-element:phrasing-content-2">Phrasing content</a>.</dd><dd><a href="https://html.spec.whatwg.org/multipage/dom.html#embedded-content-category" id="the-canvas-element:embedded-content-category">Embedded content</a>.</dd><dd><a href="https://html.spec.whatwg.org/multipage/dom.html#palpable-content-2" id="the-canvas-element:palpable-content-2">Palpable content</a>.</dd><dt><a href="https://html.spec.whatwg.org/multipage/dom.html#concept-element-contexts" id="the-canvas-element:concept-element-contexts">Contexts in which this element can be used</a>:</dt><dd>Where <a href="https://html.spec.whatwg.org/multipage/dom.html#embedded-content-category" id="the-canvas-element:embedded-content-category-2">embedded content</a> is expected.</dd><dt><a href="https://html.spec.whatwg.org/multipage/dom.html#concept-element-content-model" id="the-canvas-element:concept-element-content-model">Content model</a>:</dt><dd><a href="https://html.spec.whatwg.org/multipage/dom.html#transparent" id="the-canvas-element:transparent">Transparent</a>, but with no <a href="https://html.spec.whatwg.org/multipage/dom.html#interactive-content-2" id="the-canvas-element:interactive-content-2">interactive content</a> descendants except
-   for <code id="the-canvas-element:the-a-element"><a href="https://html.spec.whatwg.org/multipage/text-level-semantics.html#the-a-element">a</a></code> elements, <code id="the-canvas-element:the-img-element"><a href="https://html.spec.whatwg.org/multipage/embedded-content.html#the-img-element">img</a></code> elements with
-   <code id="the-canvas-element:attr-hyperlink-usemap"><a href="https://html.spec.whatwg.org/multipage/image-maps.html#attr-hyperlink-usemap">usemap</a></code> attributes, <code id="the-canvas-element:the-button-element"><a href="https://html.spec.whatwg.org/multipage/form-elements.html#the-button-element">button</a></code> elements,
-   <code id="the-canvas-element:the-input-element"><a href="https://html.spec.whatwg.org/multipage/input.html#the-input-element">input</a></code> elements whose <code id="the-canvas-element:attr-input-type"><a href="https://html.spec.whatwg.org/multipage/input.html#attr-input-type">type</a></code> attribute are in
-   the <a href="https://html.spec.whatwg.org/multipage/input.html#checkbox-state-(type=checkbox)" id="the-canvas-element:checkbox-state-(type=checkbox)">Checkbox</a> or <a href="https://html.spec.whatwg.org/multipage/input.html#radio-button-state-(type=radio)" id="the-canvas-element:radio-button-state-(type=radio)">Radio Button</a> states, <code id="the-canvas-element:the-input-element-2"><a href="https://html.spec.whatwg.org/multipage/input.html#the-input-element">input</a></code> elements that are
-   <a href="https://html.spec.whatwg.org/multipage/forms.html#concept-button" id="the-canvas-element:concept-button">buttons</a>, <code id="the-canvas-element:the-select-element"><a href="https://html.spec.whatwg.org/multipage/form-elements.html#the-select-element">select</a></code> elements with a <code id="the-canvas-element:attr-select-multiple"><a href="https://html.spec.whatwg.org/multipage/form-elements.html#attr-select-multiple">multiple</a></code> attribute or a <a href="https://html.spec.whatwg.org/multipage/form-elements.html#concept-select-size" id="the-canvas-element:concept-select-size">display size</a> greater than 1, and elements that would not be
-   <a href="https://html.spec.whatwg.org/multipage/dom.html#interactive-content-2" id="the-canvas-element:interactive-content-2-2">interactive content</a> except for having the <code id="the-canvas-element:attr-tabindex"><a href="https://html.spec.whatwg.org/multipage/interaction.html#attr-tabindex">tabindex</a></code> attribute specified.</dd><dt><a href="https://html.spec.whatwg.org/multipage/dom.html#concept-element-tag-omission" id="the-canvas-element:concept-element-tag-omission">Tag omission in text/html</a>:</dt><dd>Neither tag is omissible.</dd><dt><a href="https://html.spec.whatwg.org/multipage/dom.html#concept-element-attributes" id="the-canvas-element:concept-element-attributes">Content attributes</a>:</dt><dd><a href="https://html.spec.whatwg.org/multipage/dom.html#global-attributes" id="the-canvas-element:global-attributes">Global attributes</a></dd><dd><code id="the-canvas-element:attr-canvas-width"><a href="#attr-canvas-width">width</a></code> — Horizontal dimension</dd><dd><code id="the-canvas-element:attr-canvas-height"><a href="#attr-canvas-height">height</a></code> — Vertical dimension</dd><dt><a href="https://html.spec.whatwg.org/multipage/dom.html#concept-element-dom" id="the-canvas-element:concept-element-dom">DOM interface</a>:</dt><dd>
-    <pre class="idl">typedef (<a href="#canvasrenderingcontext2d" id="the-canvas-element:canvasrenderingcontext2d">CanvasRenderingContext2D</a> or <a data-x-internal="webglrenderingcontext" href="https://www.khronos.org/registry/webgl/specs/latest/1.0/#WebGLRenderingContext" id="the-canvas-element:webglrenderingcontext">WebGLRenderingContext</a>) <dfn id="renderingcontext">RenderingContext</dfn>;
-
-[Exposed=Window,
- <a href="https://html.spec.whatwg.org/multipage/dom.html#htmlconstructor" id="the-canvas-element:htmlconstructor">HTMLConstructor</a>]
-interface <dfn id="htmlcanvaselement">HTMLCanvasElement</dfn> : <a href="https://html.spec.whatwg.org/multipage/dom.html#htmlelement" id="the-canvas-element:htmlelement">HTMLElement</a> {
-  [<a href="https://html.spec.whatwg.org/multipage/custom-elements.html#cereactions" id="the-canvas-element:cereactions">CEReactions</a>] attribute unsigned long <a href="#dom-canvas-width" id="the-canvas-element:dom-canvas-width">width</a>;
-  [<a href="https://html.spec.whatwg.org/multipage/custom-elements.html#cereactions" id="the-canvas-element:cereactions-2">CEReactions</a>] attribute unsigned long <a href="#dom-canvas-height" id="the-canvas-element:dom-canvas-height">height</a>;
-
-  <a href="#renderingcontext" id="the-canvas-element:renderingcontext">RenderingContext</a>? <a href="#dom-canvas-getcontext-2" id="the-canvas-element:dom-canvas-getcontext-2">getContext</a>(DOMString contextId, any... arguments);
-
-  USVString <a href="#dom-canvas-todataurl-2" id="the-canvas-element:dom-canvas-todataurl-2">toDataURL</a>(optional DOMString type, optional any quality);
-  void <a href="#dom-canvas-toblob-2" id="the-canvas-element:dom-canvas-toblob-2">toBlob</a>(<a href="#blobcallback" id="the-canvas-element:blobcallback">BlobCallback</a> _callback, optional DOMString type, optional any quality);
-  <a href="#offscreencanvas" id="the-canvas-element:offscreencanvas">OffscreenCanvas</a> <a href="#dom-canvas-transfercontroltooffscreen-2" id="the-canvas-element:dom-canvas-transfercontroltooffscreen-2">transferControlToOffscreen</a>();
-};
-
-callback <dfn id="blobcallback">BlobCallback</dfn> = void (<a data-x-internal="blob" href="https://w3c.github.io/FileAPI/#blob" id="the-canvas-element:blob">Blob</a>? blob);</pre>
-   </dd></dl>
-
-  <p>The <code id="the-canvas-element:the-canvas-element"><a href="#the-canvas-element">canvas</a></code> element provides scripts with a resolution-dependent bitmap canvas,
-  which can be used for rendering graphs, game graphics, art, or other visual images on the fly.</p>
-
-  <p>Authors should not use the <code id="the-canvas-element:the-canvas-element-2"><a href="#the-canvas-element">canvas</a></code> element in a document when a more suitable
-  element is available. For example, it is inappropriate to use a <code id="the-canvas-element:the-canvas-element-3"><a href="#the-canvas-element">canvas</a></code> element to
-  render a page heading: if the desired presentation of the heading is graphically intense, it
-  should be marked up using appropriate elements (typically <code id="the-canvas-element:the-h1,-h2,-h3,-h4,-h5,-and-h6-elements"><a href="https://html.spec.whatwg.org/multipage/sections.html#the-h1,-h2,-h3,-h4,-h5,-and-h6-elements">h1</a></code>) and then styled using
-  CSS and supporting technologies such as Web Components.</p>
-
-  <p>When authors use the <code id="the-canvas-element:the-canvas-element-4"><a href="#the-canvas-element">canvas</a></code> element, they must also provide content that, when
-  presented to the user, conveys essentially the same function or purpose as the
-  <code id="the-canvas-element:the-canvas-element-5"><a href="#the-canvas-element">canvas</a></code>'s bitmap. This content may be placed as content of the <code id="the-canvas-element:the-canvas-element-6"><a href="#the-canvas-element">canvas</a></code>
-  element. The contents of the <code id="the-canvas-element:the-canvas-element-7"><a href="#the-canvas-element">canvas</a></code> element, if any, are the element's <a href="https://html.spec.whatwg.org/multipage/dom.html#fallback-content" id="the-canvas-element:fallback-content">fallback
-  content</a>.</p>
-
-  <hr/>
-
-  <p>In interactive visual media, if <a href="https://html.spec.whatwg.org/multipage/webappapis.html#concept-n-script" id="the-canvas-element:concept-n-script">scripting is enabled</a> for
-  the <code id="the-canvas-element:the-canvas-element-8"><a href="#the-canvas-element">canvas</a></code> element, and if support for <code id="the-canvas-element:the-canvas-element-9"><a href="#the-canvas-element">canvas</a></code> elements has been enabled,
-  then the <code id="the-canvas-element:the-canvas-element-10"><a href="#the-canvas-element">canvas</a></code> element <a href="https://html.spec.whatwg.org/multipage/dom.html#represents" id="the-canvas-element:represents">represents</a> <a href="https://html.spec.whatwg.org/multipage/dom.html#embedded-content-category" id="the-canvas-element:embedded-content-category-3">embedded content</a>
-  consisting of a dynamically created image, the element's bitmap.</p>
-
-  <p>In non-interactive, static, visual media, if the <code id="the-canvas-element:the-canvas-element-11"><a href="#the-canvas-element">canvas</a></code> element has been
-  previously associated with a rendering context (e.g. if the page was viewed in an interactive
-  visual medium and is now being printed, or if some script that ran during the page layout process
-  painted on the element), then the <code id="the-canvas-element:the-canvas-element-12"><a href="#the-canvas-element">canvas</a></code> element <a href="https://html.spec.whatwg.org/multipage/dom.html#represents" id="the-canvas-element:represents-2">represents</a>
-  <a href="https://html.spec.whatwg.org/multipage/dom.html#embedded-content-category" id="the-canvas-element:embedded-content-category-4">embedded content</a> with the element's current bitmap and size. Otherwise, the element
-  represents its <a href="https://html.spec.whatwg.org/multipage/dom.html#fallback-content" id="the-canvas-element:fallback-content-2">fallback content</a> instead.</p>
-
-  <p>In non-visual media, and in visual media if <a href="https://html.spec.whatwg.org/multipage/webappapis.html#concept-n-noscript" id="the-canvas-element:concept-n-noscript">scripting is
-  disabled</a> for the <code id="the-canvas-element:the-canvas-element-13"><a href="#the-canvas-element">canvas</a></code> element or if support for <code id="the-canvas-element:the-canvas-element-14"><a href="#the-canvas-element">canvas</a></code> elements
-  has been disabled, the <code id="the-canvas-element:the-canvas-element-15"><a href="#the-canvas-element">canvas</a></code> element <a href="https://html.spec.whatwg.org/multipage/dom.html#represents" id="the-canvas-element:represents-3">represents</a> its <a href="https://html.spec.whatwg.org/multipage/dom.html#fallback-content" id="the-canvas-element:fallback-content-3">fallback
-  content</a> instead.</p>
-
-  
-  <p>When a <code id="the-canvas-element:the-canvas-element-16"><a href="#the-canvas-element">canvas</a></code> element <a href="https://html.spec.whatwg.org/multipage/dom.html#represents" id="the-canvas-element:represents-4">represents</a> <a href="https://html.spec.whatwg.org/multipage/dom.html#embedded-content-category" id="the-canvas-element:embedded-content-category-5">embedded content</a>, the
-  user can still focus descendants of the <code id="the-canvas-element:the-canvas-element-17"><a href="#the-canvas-element">canvas</a></code> element (in the <a href="https://html.spec.whatwg.org/multipage/dom.html#fallback-content" id="the-canvas-element:fallback-content-4">fallback
-  content</a>). When an element is <a href="https://html.spec.whatwg.org/multipage/interaction.html#focused" id="the-canvas-element:focused">focused</a>, it is the target of keyboard interaction
-  events (even though the element itself is not visible). This allows authors to make an interactive
-  canvas keyboard-accessible: authors should have a one-to-one mapping of interactive regions to <i id="the-canvas-element:focusable-area"><a href="https://html.spec.whatwg.org/multipage/interaction.html#focusable-area">focusable areas</a></i> in the <a href="https://html.spec.whatwg.org/multipage/dom.html#fallback-content" id="the-canvas-element:fallback-content-5">fallback content</a>. (Focus has no
-  effect on mouse interaction events.) <a href="https://html.spec.whatwg.org/multipage/references.html#refsUIEVENTS">[UIEVENTS]</a></p> 
-
-  <p>An element whose nearest <code id="the-canvas-element:the-canvas-element-18"><a href="#the-canvas-element">canvas</a></code> element ancestor is <a href="https://html.spec.whatwg.org/multipage/rendering.html#being-rendered" id="the-canvas-element:being-rendered">being rendered</a>
-  and <a href="https://html.spec.whatwg.org/multipage/dom.html#represents" id="the-canvas-element:represents-5">represents</a> <a href="https://html.spec.whatwg.org/multipage/dom.html#embedded-content-category" id="the-canvas-element:embedded-content-category-6">embedded content</a> is an element that is <dfn id="being-used-as-relevant-canvas-fallback-content">being used as
-  relevant canvas fallback content</dfn>.</p>
-
-  <hr/>
-
-  <p>The <code id="the-canvas-element:the-canvas-element-19"><a href="#the-canvas-element">canvas</a></code> element has two attributes to control the size of the element's bitmap:
-  <dfn id="attr-canvas-width"><code>width</code></dfn> and <dfn id="attr-canvas-height"><code>height</code></dfn>. These attributes, when specified, must have
-  values that are <a href="https://html.spec.whatwg.org/multipage/common-microsyntaxes.html#valid-non-negative-integer" id="the-canvas-element:valid-non-negative-integer">valid non-negative integers</a>. The <a href="https://html.spec.whatwg.org/multipage/common-microsyntaxes.html#rules-for-parsing-non-negative-integers" id="the-canvas-element:rules-for-parsing-non-negative-integers">rules for parsing non-negative integers</a> must be used to obtain their
-  numeric values. If an attribute is missing, or if parsing its value returns an error, then the
-  default value must be used instead. The <code id="the-canvas-element:attr-canvas-width-2"><a href="#attr-canvas-width">width</a></code>
-  attribute defaults to 300, and the <code id="the-canvas-element:attr-canvas-height-2"><a href="#attr-canvas-height">height</a></code> attribute
-  defaults to 150.</p>
-
-  <p>The <a data-x-internal="intrinsic-dimensions" href="https://drafts.csswg.org/css2/conform.html#intrinsic" id="the-canvas-element:intrinsic-dimensions">intrinsic dimensions</a> of the <code id="the-canvas-element:the-canvas-element-20"><a href="#the-canvas-element">canvas</a></code> element when it
-  <a href="https://html.spec.whatwg.org/multipage/dom.html#represents" id="the-canvas-element:represents-6">represents</a> <a href="https://html.spec.whatwg.org/multipage/dom.html#embedded-content-category" id="the-canvas-element:embedded-content-category-7">embedded content</a> are equal to the dimensions of the
-  element's bitmap.</p>
-
-  <p>The user agent must use a square pixel density consisting of one pixel of image data per
-  coordinate space unit for the bitmaps of a <code id="the-canvas-element:the-canvas-element-21"><a href="#the-canvas-element">canvas</a></code> and its rendering contexts.</p>
-
-  <p class="note">A <code id="the-canvas-element:the-canvas-element-22"><a href="#the-canvas-element">canvas</a></code> element can be sized arbitrarily by a style sheet, its
-  bitmap is then subject to the <a data-x-internal="'object-fit'" href="https://drafts.csswg.org/css-images/#the-object-fit" id="the-canvas-element:'object-fit'">'object-fit'</a> CSS property.</p>
-
-  
-
-  <hr/>
-
-  <p>The bitmaps of <code id="the-canvas-element:the-canvas-element-23"><a href="#the-canvas-element">canvas</a></code> elements, the bitmaps of <code id="the-canvas-element:imagebitmap"><a href="https://html.spec.whatwg.org/multipage/imagebitmap-and-animations.html#imagebitmap">ImageBitmap</a></code> objects,
-  as well as some of the bitmaps of rendering contexts, such as those described in the sections on
-  the <code id="the-canvas-element:canvasrenderingcontext2d-2"><a href="#canvasrenderingcontext2d">CanvasRenderingContext2D</a></code> and <code id="the-canvas-element:imagebitmaprenderingcontext"><a href="#imagebitmaprenderingcontext">ImageBitmapRenderingContext</a></code> objects
-  below, have an <dfn id="concept-canvas-origin-clean">origin-clean</dfn> flag, which can be
-  set to true or false. Initially, when the <code id="the-canvas-element:the-canvas-element-24"><a href="#the-canvas-element">canvas</a></code> element or <code id="the-canvas-element:imagebitmap-2"><a href="https://html.spec.whatwg.org/multipage/imagebitmap-and-animations.html#imagebitmap">ImageBitmap</a></code>
-  object is created, its bitmap's <a href="#concept-canvas-origin-clean" id="the-canvas-element:concept-canvas-origin-clean">origin-clean</a>
-  flag must be set to true.</p>
-
-  <p>A <code id="the-canvas-element:the-canvas-element-25"><a href="#the-canvas-element">canvas</a></code> element can have a rendering context bound to it. Initially, it does not
-  have a bound rendering context. To keep track of whether it has a rendering context or not, and
-  what kind of rendering context it is, a <code id="the-canvas-element:the-canvas-element-26"><a href="#the-canvas-element">canvas</a></code> also has a <dfn id="concept-canvas-context-mode">canvas context mode</dfn>, which is initially <dfn id="concept-canvas-none">none</dfn> but can be changed to either <dfn id="concept-canvas-placeholder">placeholder</dfn>, <dfn id="concept-canvas-2d">2d</dfn>, <dfn id="concept-canvas-bitmaprenderer">bitmaprenderer</dfn>, or <dfn id="concept-canvas-webgl">webgl</dfn> by algorithms defined in this specification.</p>
-
-  <p>When its <a href="#concept-canvas-context-mode" id="the-canvas-element:concept-canvas-context-mode">canvas context mode</a> is <a href="#concept-canvas-none" id="the-canvas-element:concept-canvas-none">none</a>, a <code id="the-canvas-element:the-canvas-element-27"><a href="#the-canvas-element">canvas</a></code> element has no rendering context,
-  and its bitmap must be fully transparent black with an <a href="https://html.spec.whatwg.org/multipage/infrastructure.html#intrinsic-width" id="the-canvas-element:intrinsic-width">intrinsic width</a> equal to the
-  numeric value of the element's <code id="the-canvas-element:attr-canvas-width-3"><a href="#attr-canvas-width">width</a></code> attribute and an
-  <a href="https://html.spec.whatwg.org/multipage/infrastructure.html#intrinsic-height" id="the-canvas-element:intrinsic-height">intrinsic height</a> equal to the numeric value of the element's <code id="the-canvas-element:attr-canvas-height-3"><a href="#attr-canvas-height">height</a></code> attribute, those values being interpreted in <a data-x-internal="'px'" href="https://drafts.csswg.org/css-values/#px" id="the-canvas-element:'px'">CSS pixels</a>, and being updated as the attributes are set, changed, or
-  removed.</p>
-
-  <p>When its <a href="#concept-canvas-context-mode" id="the-canvas-element:concept-canvas-context-mode-2">canvas context mode</a> is <a href="#concept-canvas-placeholder" id="the-canvas-element:concept-canvas-placeholder">placeholder</a>, a <code id="the-canvas-element:the-canvas-element-28"><a href="#the-canvas-element">canvas</a></code> element has no
-  rendering context. It serves as a placeholder for an <code id="the-canvas-element:offscreencanvas-2"><a href="#offscreencanvas">OffscreenCanvas</a></code> object, and
-  the content of the <code id="the-canvas-element:the-canvas-element-29"><a href="#the-canvas-element">canvas</a></code> element is updated by calling the <code id="the-canvas-element:offscreencontext-commit"><a href="#offscreencontext-commit">commit()</a></code> method of the <code id="the-canvas-element:offscreencanvas-3"><a href="#offscreencanvas">OffscreenCanvas</a></code>
-  object's rendering context.</p>
-
-  <p>When a <code id="the-canvas-element:the-canvas-element-30"><a href="#the-canvas-element">canvas</a></code> element represents <a href="https://html.spec.whatwg.org/multipage/dom.html#embedded-content-category" id="the-canvas-element:embedded-content-category-8">embedded content</a>, it provides a
-  <a data-x-internal="paint-source" href="https://drafts.csswg.org/css-images-4/#paint-source" id="the-canvas-element:paint-source">paint source</a> whose width is the element's <a href="https://html.spec.whatwg.org/multipage/infrastructure.html#intrinsic-width" id="the-canvas-element:intrinsic-width-2">intrinsic width</a>, whose height
-  is the element's <a href="https://html.spec.whatwg.org/multipage/infrastructure.html#intrinsic-height" id="the-canvas-element:intrinsic-height-2">intrinsic height</a>, and whose appearance is the element's bitmap.</p>
-
-  <p>Whenever the <code id="the-canvas-element:attr-canvas-width-4"><a href="#attr-canvas-width">width</a></code> and <code id="the-canvas-element:attr-canvas-height-4"><a href="#attr-canvas-height">height</a></code> content attributes are set, removed, changed, or
-  redundantly set to the value they already have, then the user agent must perform the action
-  from the row of the following table that corresponds to the <code id="the-canvas-element:the-canvas-element-31"><a href="#the-canvas-element">canvas</a></code> element's <a href="#concept-canvas-context-mode" id="the-canvas-element:concept-canvas-context-mode-3">context mode</a>.</p>
-
-  <table><thead><tr><th>
-      <p><a href="#concept-canvas-context-mode" id="the-canvas-element:concept-canvas-context-mode-4">Context Mode</a></p>
-     </th><th>
-      <p>Action</p>
-
-   </th></tr></thead><tbody><tr><th>
-      <p><a href="#concept-canvas-2d" id="the-canvas-element:concept-canvas-2d">2d</a></p>
-     </th><td>
-      <p>Follow the steps to <a href="#concept-canvas-set-bitmap-dimensions" id="the-canvas-element:concept-canvas-set-bitmap-dimensions">set bitmap
-      dimensions</a> to the numeric values of the <code id="the-canvas-element:attr-canvas-width-5"><a href="#attr-canvas-width">width</a></code>
-      and <code id="the-canvas-element:attr-canvas-height-5"><a href="#attr-canvas-height">height</a></code> content attributes.</p>
-
-    </td></tr><tr><th>
-      <p><a href="#concept-canvas-webgl" id="the-canvas-element:concept-canvas-webgl">webgl</a></p>
-     </th><td>
-      <p>Follow the behavior defined in the WebGL specification. <a href="https://html.spec.whatwg.org/multipage/references.html#refsWEBGL">[WEBGL]</a></p>
-
-    </td></tr><tr><th>
-      <p><a href="#concept-canvas-bitmaprenderer" id="the-canvas-element:concept-canvas-bitmaprenderer">bitmaprenderer</a></p>
-     </th><td>
-      <p>If the context's <a href="#concept-imagebitmaprenderingcontext-bitmap-mode" id="the-canvas-element:concept-imagebitmaprenderingcontext-bitmap-mode">bitmap
-      mode</a> is set to <a href="#concept-imagebitmaprenderingcontext-blank" id="the-canvas-element:concept-imagebitmaprenderingcontext-blank">blank</a>,
-      run the steps to <a href="#set-an-imagebitmaprenderingcontext's-output-bitmap" id="the-canvas-element:set-an-imagebitmaprenderingcontext's-output-bitmap">set an <code>ImageBitmapRenderingContext</code>'s output bitmap</a>,
-      passing the <code id="the-canvas-element:the-canvas-element-32"><a href="#the-canvas-element">canvas</a></code> element's rendering context.</p>
-
-    </td></tr><tr><th>
-      <p><a href="#concept-canvas-placeholder" id="the-canvas-element:concept-canvas-placeholder-2">placeholder</a></p>
-     </th><td>
-      <p>Do nothing.</p>
-
-    </td></tr><tr><th>
-      <p><a href="#concept-canvas-none" id="the-canvas-element:concept-canvas-none-2">none</a></p>
-     </th><td>
-      <p>Do nothing.</p>
-  </td></tr></tbody></table>
-
-  <p>The <dfn id="dom-canvas-width"><code>width</code></dfn> and <dfn id="dom-canvas-height"><code>height</code></dfn> IDL attributes must <a href="https://html.spec.whatwg.org/multipage/common-dom-interfaces.html#reflect" id="the-canvas-element:reflect">reflect</a> the
-  respective content attributes of the same name, with the same defaults.</p>
-
-  
-
-  <hr/>
-
-  
-  <dl class="domintro"><dt><var>context</var> = <var>canvas</var> . <code id="dom-canvas-getcontext"><a href="#dom-canvas-getcontext-2">getContext</a></code>(<var>contextId</var> [, ... ] )</dt><dd>
-
-    <p>Returns an object that exposes an API for drawing on the canvas. The first argument
-    specifies the desired API, either &quot;<code id="the-canvas-element:canvas-context-2d"><a href="#canvas-context-2d">2d</a></code>&quot;, &quot;<code id="the-canvas-element:canvas-context-bitmaprenderer"><a href="#canvas-context-bitmaprenderer">bitmaprenderer</a></code>&quot; or &quot;<code id="the-canvas-element:canvas-context-webgl"><a href="#canvas-context-webgl">webgl</a></code>&quot;. Subsequent arguments are handled by that API.</p>
-
-    <p>This specification defines the &quot;<code id="the-canvas-element:canvas-context-2d-2"><a href="#canvas-context-2d">2d</a></code>&quot; and &quot;<code id="the-canvas-element:canvas-context-bitmaprenderer-2"><a href="#canvas-context-bitmaprenderer">bitmaprenderer</a></code>&quot; contexts below. There is also a
-    specification that defines a &quot;<code id="the-canvas-element:canvas-context-webgl-2"><a href="#canvas-context-webgl">webgl</a></code>&quot; context.
-    <a href="https://html.spec.whatwg.org/multipage/references.html#refsWEBGL">[WEBGL]</a></p>
-
-    <p>Returns null if the given context ID is not supported, or if the canvas has already been
-    initialized with another context type (e.g. trying to get a &quot;<code id="the-canvas-element:canvas-context-2d-3"><a href="#canvas-context-2d">2d</a></code>&quot; context after getting a &quot;<code id="the-canvas-element:canvas-context-webgl-3"><a href="#canvas-context-webgl">webgl</a></code>&quot; context).</p>
-
-   </dd></dl>
-
-  
-
-  <p>The <dfn id="dom-canvas-getcontext-2"><code>getContext(<var>contextId</var>,
-  <var>arguments...</var>)</code></dfn> method of the <code id="the-canvas-element:the-canvas-element-33"><a href="#the-canvas-element">canvas</a></code> element, when invoked,
-  must run the steps in the cell of the following table whose column header describes the
-  <code id="the-canvas-element:the-canvas-element-34"><a href="#the-canvas-element">canvas</a></code> element's <a href="#concept-canvas-context-mode" id="the-canvas-element:concept-canvas-context-mode-5">canvas context
-  mode</a> and whose row header describes the method's first argument.</p>
-
-  <table><thead><tr><td>
-     </td><th><a href="#concept-canvas-none" id="the-canvas-element:concept-canvas-none-3">none</a>
-     </th><th><a href="#concept-canvas-2d" id="the-canvas-element:concept-canvas-2d-2">2d</a>
-     </th><th><a href="#concept-canvas-bitmaprenderer" id="the-canvas-element:concept-canvas-bitmaprenderer-2">bitmaprenderer</a>
-     </th><th><a href="#concept-canvas-webgl" id="the-canvas-element:concept-canvas-webgl-2">webgl</a>
-     </th><th><a href="#concept-canvas-placeholder" id="the-canvas-element:concept-canvas-placeholder-3">placeholder</a>
-   </th></tr></thead><tbody><tr><th>&quot;<dfn id="canvas-context-2d"><code>2d</code></dfn>&quot;
-     </th><td>
-
-      Follow the <a href="#2d-context-creation-algorithm" id="the-canvas-element:2d-context-creation-algorithm">2D context creation algorithm</a> defined in the section below, passing
-      it the <code id="the-canvas-element:the-canvas-element-35"><a href="#the-canvas-element">canvas</a></code> element and the method's <var>arguments...</var>, to obtain a
-      <code id="the-canvas-element:canvasrenderingcontext2d-3"><a href="#canvasrenderingcontext2d">CanvasRenderingContext2D</a></code> object; if this does not throw an exception, then
-      set the <code id="the-canvas-element:the-canvas-element-36"><a href="#the-canvas-element">canvas</a></code> element's <a href="#concept-canvas-context-mode" id="the-canvas-element:concept-canvas-context-mode-6">context
-      mode</a> to <a href="#concept-canvas-2d" id="the-canvas-element:concept-canvas-2d-3">2d</a>, and return the
-      <code id="the-canvas-element:canvasrenderingcontext2d-4"><a href="#canvasrenderingcontext2d">CanvasRenderingContext2D</a></code> object.
-
-     </td><td>
-      Return the same object as was returned the last time the method was invoked with this same
-      first argument.
-     </td><td>
-      Return null.
-     </td><td>
-      Return null.
-     </td><td>
-      Throw an <a data-x-internal="invalidstateerror" href="https://heycam.github.io/webidl/#invalidstateerror" id="the-canvas-element:invalidstateerror">&quot;<code>InvalidStateError</code>&quot;</a> <code id="the-canvas-element:domexception"><a data-x-internal="domexception" href="https://heycam.github.io/webidl/#dfn-DOMException">DOMException</a></code>.
-
-    </td></tr><tr><th>&quot;<dfn id="canvas-context-bitmaprenderer"><code>bitmaprenderer</code></dfn>&quot;
-     </th><td>
-
-      Follow the <a href="#imagebitmaprenderingcontext-creation-algorithm" id="the-canvas-element:imagebitmaprenderingcontext-creation-algorithm"><code>ImageBitmapRenderingContext</code> creation algorithm</a> defined
-      in the section below, passing it the <code id="the-canvas-element:the-canvas-element-37"><a href="#the-canvas-element">canvas</a></code> element and the method's
-      <var>arguments...</var>, to obtain an <code id="the-canvas-element:imagebitmaprenderingcontext-2"><a href="#imagebitmaprenderingcontext">ImageBitmapRenderingContext</a></code> object; then
-      set the <code id="the-canvas-element:the-canvas-element-38"><a href="#the-canvas-element">canvas</a></code> element's <a href="#concept-canvas-context-mode" id="the-canvas-element:concept-canvas-context-mode-7">context
-      mode</a> to <a href="#concept-canvas-bitmaprenderer" id="the-canvas-element:concept-canvas-bitmaprenderer-3">bitmaprenderer</a>, and return the
-      <code id="the-canvas-element:imagebitmaprenderingcontext-3"><a href="#imagebitmaprenderingcontext">ImageBitmapRenderingContext</a></code> object.
-
-     </td><td>
-      Return null.
-     </td><td>
-      Return the same object as was returned the last time the method was invoked with this same
-      first argument.
-     </td><td>
-      Return null.
-     </td><td>
-      Throw an <a data-x-internal="invalidstateerror" href="https://heycam.github.io/webidl/#invalidstateerror" id="the-canvas-element:invalidstateerror-2">&quot;<code>InvalidStateError</code>&quot;</a> <code id="the-canvas-element:domexception-2"><a data-x-internal="domexception" href="https://heycam.github.io/webidl/#dfn-DOMException">DOMException</a></code>.
-
-    </td></tr><tr><th>&quot;<dfn id="canvas-context-webgl"><code>webgl</code></dfn>&quot;, if the user agent supports the WebGL feature in its current configuration
-     </th><td>
-
-      Follow the instructions given in the WebGL specification's <i>Context Creation</i> section to
-      obtain either a <code id="the-canvas-element:webglrenderingcontext-2"><a data-x-internal="webglrenderingcontext" href="https://www.khronos.org/registry/webgl/specs/latest/1.0/#WebGLRenderingContext">WebGLRenderingContext</a></code> or null; if the returned value is null,
-      then return null and abort these steps, otherwise, set the <code id="the-canvas-element:the-canvas-element-39"><a href="#the-canvas-element">canvas</a></code> element's
-      <a href="#concept-canvas-context-mode" id="the-canvas-element:concept-canvas-context-mode-8">context mode</a> to <a href="#concept-canvas-webgl" id="the-canvas-element:concept-canvas-webgl-3">webgl</a>, and return the <code id="the-canvas-element:webglrenderingcontext-3"><a data-x-internal="webglrenderingcontext" href="https://www.khronos.org/registry/webgl/specs/latest/1.0/#WebGLRenderingContext">WebGLRenderingContext</a></code>
-      object <a href="https://html.spec.whatwg.org/multipage/references.html#refsWEBGL">[WEBGL]</a>
-
-     </td><td>
-      Return null.
-     </td><td>
-      Return null.
-     </td><td>
-      Return the same object as was returned the last time the method was invoked with this same
-      first argument.
-     </td><td>
-      Throw an <a data-x-internal="invalidstateerror" href="https://heycam.github.io/webidl/#invalidstateerror" id="the-canvas-element:invalidstateerror-3">&quot;<code>InvalidStateError</code>&quot;</a> <code id="the-canvas-element:domexception-3"><a data-x-internal="domexception" href="https://heycam.github.io/webidl/#dfn-DOMException">DOMException</a></code>.
-
-    </td></tr><tr><th>An unsupported value*
-     </th><td>
-      Return null.
-     </td><td>
-      Return null.
-     </td><td>
-      Return null.
-     </td><td>
-      Return null.
-     </td><td>
-      Throw an <a data-x-internal="invalidstateerror" href="https://heycam.github.io/webidl/#invalidstateerror" id="the-canvas-element:invalidstateerror-4">&quot;<code>InvalidStateError</code>&quot;</a> <code id="the-canvas-element:domexception-4"><a data-x-internal="domexception" href="https://heycam.github.io/webidl/#dfn-DOMException">DOMException</a></code>.
-
-  </td></tr></tbody></table>
-
-  <p class="tablenote"><small>* For example, the &quot;<code id="the-canvas-element:canvas-context-webgl-4"><a href="#canvas-context-webgl">webgl</a></code>&quot;
-  value in the case of a user agent having exhausted the graphics hardware's abilities and having no
-  software fallback implementation.</small></p>
-
-  <hr/>
-
-  
-
-  <dl class="domintro"><dt><var>url</var> = <var>canvas</var> . <code id="dom-canvas-todataurl"><a href="#dom-canvas-todataurl-2">toDataURL</a></code>( [ <var>type</var> [, <var>quality</var> ] ] )</dt><dd>
-
-    <p>Returns a <a data-x-internal="data-protocol" href="https://tools.ietf.org/html/rfc2397#section-2" id="the-canvas-element:data-protocol"><code>data:</code> URL</a> for the image in the
-    canvas.</p>
-
-    <p>The first argument, if provided, controls the type of the image to be returned (e.g. PNG or
-    JPEG). The default is &quot;<code id="the-canvas-element:image/png"><a href="https://html.spec.whatwg.org/multipage/indices.html#image/png">image/png</a></code>&quot;; that type is also used if the given type isn't
-    supported. The second argument applies if the type is an image format that supports variable
-    quality (such as &quot;<code id="the-canvas-element:image/jpeg"><a href="https://html.spec.whatwg.org/multipage/indices.html#image/jpeg">image/jpeg</a></code>&quot;), and is a number in the range 0.0 to 1.0 inclusive
-    indicating the desired quality level for the resulting image.</p>
-
-    <p>When trying to use types other than &quot;<code id="the-canvas-element:image/png-2"><a href="https://html.spec.whatwg.org/multipage/indices.html#image/png">image/png</a></code>&quot;, authors can check if the image
-    was really returned in the requested format by checking to see if the returned string starts
-    with one of the exact strings &quot;<code>data:image/png,</code>&quot; or &quot;<code>data:image/png;</code>&quot;. If it does, the image is PNG, and thus the requested type was
-    not supported. (The one exception to this is if the canvas has either no height or no width, in
-    which case the result might simply be &quot;<code>data:,</code>&quot;.)</p>
-
-   </dd><dt><var>canvas</var> . <code id="dom-canvas-toblob"><a href="#dom-canvas-toblob-2">toBlob</a></code>(<var>callback</var> [, <var>type</var> [, quality ] ] )</dt><dd>
-
-    <p>Creates a <code id="the-canvas-element:blob-2"><a data-x-internal="blob" href="https://w3c.github.io/FileAPI/#blob">Blob</a></code> object representing a file containing the image in the canvas,
-    and invokes a callback with a handle to that object.</p>
-
-    <p>The second argument, if provided, controls the type of the image to be returned (e.g. PNG or
-    JPEG). The default is &quot;<code id="the-canvas-element:image/png-3"><a href="https://html.spec.whatwg.org/multipage/indices.html#image/png">image/png</a></code>&quot;; that type is also used if the given type isn't
-    supported. The third argument applies if the type is an image format that supports variable
-    quality (such as &quot;<code id="the-canvas-element:image/jpeg-2"><a href="https://html.spec.whatwg.org/multipage/indices.html#image/jpeg">image/jpeg</a></code>&quot;), and is a number in the range 0.0 to 1.0 inclusive
-    indicating the desired quality level for the resulting image.</p>
-
-   </dd><dt><var>canvas</var> . <code id="dom-canvas-transfercontroltooffscreen"><a href="#dom-canvas-transfercontroltooffscreen-2">transferControlToOffscreen</a></code>()</dt><dd>
-    <p>Returns a newly created <code id="the-canvas-element:offscreencanvas-4"><a href="#offscreencanvas">OffscreenCanvas</a></code> object that uses the
-    <code id="the-canvas-element:the-canvas-element-40"><a href="#the-canvas-element">canvas</a></code> element as a placeholder. Once the <code id="the-canvas-element:the-canvas-element-41"><a href="#the-canvas-element">canvas</a></code> element has become a
-    placeholder for an <code id="the-canvas-element:offscreencanvas-5"><a href="#offscreencanvas">OffscreenCanvas</a></code> object, its intrinsic size can no longer be
-    changed, and it cannot have a rendering context. The content of the placeholder canvas is
-    updated by calling the <code id="the-canvas-element:offscreencontext-commit-2"><a href="#offscreencontext-commit">commit()</a></code> method of the
-    <code id="the-canvas-element:offscreencanvas-6"><a href="#offscreencanvas">OffscreenCanvas</a></code> object's rendering context.
-    </p>
-   </dd></dl>
-
-  
-
-  <p>The <dfn id="dom-canvas-todataurl-2"><code>toDataURL(<var>type</var>,
-  <var>quality</var>)</code></dfn> method, when invoked, must run these steps:</p>
-
-  <ol><li><p>If this <code id="the-canvas-element:the-canvas-element-42"><a href="#the-canvas-element">canvas</a></code> element's bitmap's <a href="#concept-canvas-origin-clean" id="the-canvas-element:concept-canvas-origin-clean-2">origin-clean</a> flag is set to false, then throw a
-   <a data-x-internal="securityerror" href="https://heycam.github.io/webidl/#securityerror" id="the-canvas-element:securityerror">&quot;<code>SecurityError</code>&quot;</a> <code id="the-canvas-element:domexception-5"><a data-x-internal="domexception" href="https://heycam.github.io/webidl/#dfn-DOMException">DOMException</a></code> and abort these steps.</p>
-
-
-   </li><li><p>If this <code id="the-canvas-element:the-canvas-element-43"><a href="#the-canvas-element">canvas</a></code> element's bitmap has no pixels (i.e. either its horizontal
-   dimension or its vertical dimension is zero) then return the string &quot;<code>data:,</code>&quot; and abort these steps. (This is the shortest <a data-x-internal="data-protocol" href="https://tools.ietf.org/html/rfc2397#section-2" id="the-canvas-element:data-protocol-2"><code>data:</code> URL</a>; it represents the empty string in a <code>text/plain</code> resource.)</p></li><li><p>Let <var>file</var> be <a href="#a-serialisation-of-the-bitmap-as-a-file" id="the-canvas-element:a-serialisation-of-the-bitmap-as-a-file">a
-   serialization of this <code>canvas</code> element's bitmap as a file</a>, passing
-   <var>type</var> and <var>quality</var> if they were given.</p></li><li><p>If <var>file</var> is null then return &quot;<code>data:,</code>&quot;.</p></li><li><p>Return a <a data-x-internal="data-protocol" href="https://tools.ietf.org/html/rfc2397#section-2" id="the-canvas-element:data-protocol-3"><code>data:</code> URL</a> representing
-   <var>file</var>. <a href="https://html.spec.whatwg.org/multipage/references.html#refsRFC2397">[RFC2397]</a></p>
-
-   
-
-  </li></ol>
-
-  <p>The <dfn id="dom-canvas-toblob-2"><code>toBlob(<var>callback</var>, <var>type</var>,
-  <var>quality</var>)</code></dfn> method, when invoked, must run these steps:</p>
-
-  <ol><li><p>If this <code id="the-canvas-element:the-canvas-element-44"><a href="#the-canvas-element">canvas</a></code> element's bitmap's <a href="#concept-canvas-origin-clean" id="the-canvas-element:concept-canvas-origin-clean-3">origin-clean</a> flag is set to false, then throw a
-   <a data-x-internal="securityerror" href="https://heycam.github.io/webidl/#securityerror" id="the-canvas-element:securityerror-2">&quot;<code>SecurityError</code>&quot;</a> <code id="the-canvas-element:domexception-6"><a data-x-internal="domexception" href="https://heycam.github.io/webidl/#dfn-DOMException">DOMException</a></code> and abort these steps.</p>
-
-
-   </li><li>
-    <p>If this <code id="the-canvas-element:the-canvas-element-45"><a href="#the-canvas-element">canvas</a></code> element's bitmap has no pixels (i.e. either its horizontal
-    dimension or its vertical dimension is zero) then let <var>result</var> be null.</p>
-
-    <p>Otherwise, let <var>result</var> be a <code id="the-canvas-element:blob-3"><a data-x-internal="blob" href="https://w3c.github.io/FileAPI/#blob">Blob</a></code> object representing <a href="#a-serialisation-of-the-bitmap-as-a-file" id="the-canvas-element:a-serialisation-of-the-bitmap-as-a-file-2">a serialization of this <code>canvas</code> element's
-    bitmap as a file</a>, passing <var>type</var> and <var>quality</var> if they were given. <a href="https://html.spec.whatwg.org/multipage/references.html#refsFILEAPI">[FILEAPI]</a></p>
-   </li><li><p>Return, but continue running these steps <a href="https://html.spec.whatwg.org/multipage/infrastructure.html#in-parallel" id="the-canvas-element:in-parallel">in parallel</a>.</p></li><li><p><a href="https://html.spec.whatwg.org/multipage/webappapis.html#queue-a-task" id="the-canvas-element:queue-a-task">Queue a task</a> to <a data-x-internal="es-invoking-callback-functions" href="https://heycam.github.io/webidl/#invoke-a-callback-function" id="the-canvas-element:es-invoking-callback-functions">invoke</a>
-   the <code id="the-canvas-element:blobcallback-2"><a href="#blobcallback">BlobCallback</a></code> <var>callback</var> with <var>result</var> as its argument. The
-   <a href="https://html.spec.whatwg.org/multipage/webappapis.html#task-source" id="the-canvas-element:task-source">task source</a> for this task is the
-   <dfn id="canvas-blob-serialisation-task-source">canvas blob serialization task
-   source</dfn>.</p></li></ol>
-
-  <p>The <dfn id="dom-canvas-transfercontroltooffscreen-2"><code>transferControlToOffscreen()</code></dfn> method,
-  when invoked, must run these steps:</p>
-
-  <ol><li><p>If this <code id="the-canvas-element:the-canvas-element-46"><a href="#the-canvas-element">canvas</a></code> element's <a href="#concept-canvas-context-mode" id="the-canvas-element:concept-canvas-context-mode-9">context
-   mode</a> is not set to <a href="#concept-canvas-none" id="the-canvas-element:concept-canvas-none-4">none</a>, throw an
-   <a data-x-internal="invalidstateerror" href="https://heycam.github.io/webidl/#invalidstateerror" id="the-canvas-element:invalidstateerror-5">&quot;<code>InvalidStateError</code>&quot;</a> <code id="the-canvas-element:domexception-7"><a data-x-internal="domexception" href="https://heycam.github.io/webidl/#dfn-DOMException">DOMException</a></code> and abort these
-   steps.</p></li><li><p>Let <var>offscreenCanvas</var> be a new <code id="the-canvas-element:offscreencanvas-7"><a href="#offscreencanvas">OffscreenCanvas</a></code> object with its
-   width and height equal to the values of the <code id="the-canvas-element:attr-canvas-width-6"><a href="#attr-canvas-width">width</a></code>
-   and <code id="the-canvas-element:attr-canvas-height-6"><a href="#attr-canvas-height">height</a></code> content attributes of this
-   <code id="the-canvas-element:the-canvas-element-47"><a href="#the-canvas-element">canvas</a></code> element.</p></li><li><p>Set the <a href="#offscreencanvas-placeholder" id="the-canvas-element:offscreencanvas-placeholder">placeholder <code>canvas</code>
-   element</a> of <var>offscreenCanvas</var> to be a weak reference to this <code id="the-canvas-element:the-canvas-element-48"><a href="#the-canvas-element">canvas</a></code>
-   element.</p></li><li><p>Set this <code id="the-canvas-element:the-canvas-element-49"><a href="#the-canvas-element">canvas</a></code> element's <a href="#concept-canvas-context-mode" id="the-canvas-element:concept-canvas-context-mode-10">context
-   mode</a> to <a href="#concept-canvas-placeholder" id="the-canvas-element:concept-canvas-placeholder-4">placeholder</a>.</p></li><li><p>Return <var>offscreenCanvas</var>.</p></li></ol>
-
-  
-
-  
-
-  <h5 id="2dcontext"><span class="secno">4.12.5.1</span> The 2D rendering context<a class="self-link" href="#2dcontext"/></h5>
-
-  
-
-  <pre class="idl">typedef (<a href="https://html.spec.whatwg.org/multipage/embedded-content.html#htmlimageelement" id="2dcontext:htmlimageelement">HTMLImageElement</a> or
-         <a data-x-internal="svgimageelement" href="https://www.w3.org/TR/SVG11/struct.html#InterfaceSVGImageElement" id="2dcontext:svgimageelement">SVGImageElement</a>) <dfn id="htmlorsvgimageelement">HTMLOrSVGImageElement</dfn>;
-
-typedef (<a href="#htmlorsvgimageelement" id="2dcontext:htmlorsvgimageelement">HTMLOrSVGImageElement</a> or
-         <a href="https://html.spec.whatwg.org/multipage/media.html#htmlvideoelement" id="2dcontext:htmlvideoelement">HTMLVideoElement</a> or
-         <a href="#htmlcanvaselement" id="2dcontext:htmlcanvaselement">HTMLCanvasElement</a> or
-         <a href="https://html.spec.whatwg.org/multipage/imagebitmap-and-animations.html#imagebitmap" id="2dcontext:imagebitmap">ImageBitmap</a> or
-         <a href="#offscreencanvas" id="2dcontext:offscreencanvas">OffscreenCanvas</a>) <dfn id="canvasimagesource">CanvasImageSource</dfn>;
-
-enum <dfn id="canvasfillrule">CanvasFillRule</dfn> { &quot;<a href="#dom-context-2d-fillrule-nonzero" id="2dcontext:dom-context-2d-fillrule-nonzero">nonzero</a>&quot;, &quot;<a href="#dom-context-2d-fillrule-evenodd" id="2dcontext:dom-context-2d-fillrule-evenodd">evenodd</a>&quot; };
-
-dictionary <dfn id="canvasrenderingcontext2dsettings">CanvasRenderingContext2DSettings</dfn> {
-  boolean <a href="#dom-canvasrenderingcontext2dsettings-alpha" id="2dcontext:dom-canvasrenderingcontext2dsettings-alpha">alpha</a> = true;
-};
-
-enum <dfn id="imagesmoothingquality">ImageSmoothingQuality</dfn> { &quot;<a href="#dom-context-2d-imagesmoothingquality-low" id="2dcontext:dom-context-2d-imagesmoothingquality-low">low</a>&quot;, &quot;<a href="#dom-context-2d-imagesmoothingquality-medium" id="2dcontext:dom-context-2d-imagesmoothingquality-medium">medium</a>&quot;, &quot;<a href="#dom-context-2d-imagesmoothingquality-high" id="2dcontext:dom-context-2d-imagesmoothingquality-high">high</a>&quot; };
-
-interface <dfn id="canvasrenderingcontext2d">CanvasRenderingContext2D</dfn> {
-  // back-reference to the canvas
-  readonly attribute <a href="#htmlcanvaselement" id="2dcontext:htmlcanvaselement-2">HTMLCanvasElement</a> <a href="#dom-context-2d-canvas-2" id="2dcontext:dom-context-2d-canvas-2">canvas</a>;
-};
-<a href="#canvasrenderingcontext2d" id="2dcontext:canvasrenderingcontext2d">CanvasRenderingContext2D</a> implements <a href="#canvasstate" id="2dcontext:canvasstate">CanvasState</a>;
-<a href="#canvasrenderingcontext2d" id="2dcontext:canvasrenderingcontext2d-2">CanvasRenderingContext2D</a> implements <a href="#canvastransform" id="2dcontext:canvastransform">CanvasTransform</a>;
-<a href="#canvasrenderingcontext2d" id="2dcontext:canvasrenderingcontext2d-3">CanvasRenderingContext2D</a> implements <a href="#canvascompositing" id="2dcontext:canvascompositing">CanvasCompositing</a>;
-<a href="#canvasrenderingcontext2d" id="2dcontext:canvasrenderingcontext2d-4">CanvasRenderingContext2D</a> implements <a href="#canvasimagesmoothing" id="2dcontext:canvasimagesmoothing">CanvasImageSmoothing</a>;
-<a href="#canvasrenderingcontext2d" id="2dcontext:canvasrenderingcontext2d-5">CanvasRenderingContext2D</a> implements <a href="#canvasfillstrokestyles" id="2dcontext:canvasfillstrokestyles">CanvasFillStrokeStyles</a>;
-<a href="#canvasrenderingcontext2d" id="2dcontext:canvasrenderingcontext2d-6">CanvasRenderingContext2D</a> implements <a href="#canvasshadowstyles" id="2dcontext:canvasshadowstyles">CanvasShadowStyles</a>;
-<a href="#canvasrenderingcontext2d" id="2dcontext:canvasrenderingcontext2d-7">CanvasRenderingContext2D</a> implements <a href="#canvasfilters" id="2dcontext:canvasfilters">CanvasFilters</a>;
-<a href="#canvasrenderingcontext2d" id="2dcontext:canvasrenderingcontext2d-8">CanvasRenderingContext2D</a> implements <a href="#canvasrect" id="2dcontext:canvasrect">CanvasRect</a>;
-<a href="#canvasrenderingcontext2d" id="2dcontext:canvasrenderingcontext2d-9">CanvasRenderingContext2D</a> implements <a href="#canvasdrawpath" id="2dcontext:canvasdrawpath">CanvasDrawPath</a>;
-<a href="#canvasrenderingcontext2d" id="2dcontext:canvasrenderingcontext2d-10">CanvasRenderingContext2D</a> implements <a href="#canvasuserinterface" id="2dcontext:canvasuserinterface">CanvasUserInterface</a>;
-<a href="#canvasrenderingcontext2d" id="2dcontext:canvasrenderingcontext2d-11">CanvasRenderingContext2D</a> implements <a href="#canvastext" id="2dcontext:canvastext">CanvasText</a>;
-<a href="#canvasrenderingcontext2d" id="2dcontext:canvasrenderingcontext2d-12">CanvasRenderingContext2D</a> implements <a href="#canvasdrawimage" id="2dcontext:canvasdrawimage">CanvasDrawImage</a>;
-<a href="#canvasrenderingcontext2d" id="2dcontext:canvasrenderingcontext2d-13">CanvasRenderingContext2D</a> implements <a href="#canvasimagedata" id="2dcontext:canvasimagedata">CanvasImageData</a>;
-<a href="#canvasrenderingcontext2d" id="2dcontext:canvasrenderingcontext2d-14">CanvasRenderingContext2D</a> implements <a href="#canvaspathdrawingstyles" id="2dcontext:canvaspathdrawingstyles">CanvasPathDrawingStyles</a>;
-<a href="#canvasrenderingcontext2d" id="2dcontext:canvasrenderingcontext2d-15">CanvasRenderingContext2D</a> implements <a href="#canvastextdrawingstyles" id="2dcontext:canvastextdrawingstyles">CanvasTextDrawingStyles</a>;
-<a href="#canvasrenderingcontext2d" id="2dcontext:canvasrenderingcontext2d-16">CanvasRenderingContext2D</a> implements <a href="#canvaspath" id="2dcontext:canvaspath">CanvasPath</a>;
-
-[NoInterfaceObject, Exposed=(Window,Worker)]
-interface <dfn id="canvasstate">CanvasState</dfn> {
-  // state
-  void <a href="#dom-context-2d-save-2" id="2dcontext:dom-context-2d-save-2">save</a>(); // push state on state stack
-  void <a href="#dom-context-2d-restore-2" id="2dcontext:dom-context-2d-restore-2">restore</a>(); // pop state stack and restore state
-};
-
-[NoInterfaceObject, Exposed=(Window,Worker)]
-interface <dfn id="canvastransform">CanvasTransform</dfn> {
-  // transformations (default transform is the identity matrix)
-  void <a href="#dom-context-2d-scale-2" id="2dcontext:dom-context-2d-scale-2">scale</a>(unrestricted double x, unrestricted double y);
-  void <a href="#dom-context-2d-rotate-2" id="2dcontext:dom-context-2d-rotate-2">rotate</a>(unrestricted double angle);
-  void <a href="#dom-context-2d-translate-2" id="2dcontext:dom-context-2d-translate-2">translate</a>(unrestricted double x, unrestricted double y);
-  void <a href="#dom-context-2d-transform-2" id="2dcontext:dom-context-2d-transform-2">transform</a>(unrestricted double a, unrestricted double b, unrestricted double c, unrestricted double d, unrestricted double e, unrestricted double f);
-
-  [NewObject] <a data-x-internal="dommatrix" href="https://drafts.fxtf.org/geometry/#dommatrix" id="2dcontext:dommatrix">DOMMatrix</a> <a href="#dom-context-2d-gettransform-2" id="2dcontext:dom-context-2d-gettransform-2">getTransform</a>();
-  void <a href="#dom-context-2d-settransform-2" id="2dcontext:dom-context-2d-settransform-2">setTransform</a>(unrestricted double a, unrestricted double b, unrestricted double c, unrestricted double d, unrestricted double e, unrestricted double f);
-  void <a href="#dom-context-2d-settransform-2" id="2dcontext:dom-context-2d-settransform-2-2">setTransform</a>(optional <a data-x-internal="dommatrix2dinit" href="https://drafts.fxtf.org/geometry/#dictdef-dommatrix2dinit" id="2dcontext:dommatrix2dinit">DOMMatrix2DInit</a> transform);
-  void <a href="#dom-context-2d-resettransform-2" id="2dcontext:dom-context-2d-resettransform-2">resetTransform</a>();
-
-};
-
-[NoInterfaceObject, Exposed=(Window,Worker)]
-interface <dfn id="canvascompositing">CanvasCompositing</dfn> {
-  // compositing
-  attribute unrestricted double <a href="#dom-context-2d-globalalpha-2" id="2dcontext:dom-context-2d-globalalpha-2">globalAlpha</a>; // (default 1.0)
-  attribute DOMString <a href="#dom-context-2d-globalcompositeoperation-2" id="2dcontext:dom-context-2d-globalcompositeoperation-2">globalCompositeOperation</a>; // (default source-over)
-};
-
-[NoInterfaceObject, Exposed=(Window,Worker)]
-interface <dfn id="canvasimagesmoothing">CanvasImageSmoothing</dfn> {
-  // image smoothing
-  attribute boolean <a href="#dom-context-2d-imagesmoothingenabled-2" id="2dcontext:dom-context-2d-imagesmoothingenabled-2">imageSmoothingEnabled</a>; // (default true)
-  attribute <a href="#imagesmoothingquality" id="2dcontext:imagesmoothingquality">ImageSmoothingQuality</a> <a href="#dom-context-2d-imagesmoothingquality-2" id="2dcontext:dom-context-2d-imagesmoothingquality-2">imageSmoothingQuality</a>; // (default low)
-
-};
-
-[NoInterfaceObject, Exposed=(Window,Worker)]
-interface <dfn id="canvasfillstrokestyles">CanvasFillStrokeStyles</dfn> {
-  // colors and styles (see also the <a href="#canvaspathdrawingstyles" id="2dcontext:canvaspathdrawingstyles-2">CanvasPathDrawingStyles</a> and <a href="#canvastextdrawingstyles" id="2dcontext:canvastextdrawingstyles-2">CanvasTextDrawingStyles</a> interfaces)
-  attribute (DOMString or CanvasGradient or CanvasPattern) <a href="#dom-context-2d-strokestyle-2" id="2dcontext:dom-context-2d-strokestyle-2">strokeStyle</a>; // (default black)
-  attribute (DOMString or CanvasGradient or CanvasPattern) <a href="#dom-context-2d-fillstyle-2" id="2dcontext:dom-context-2d-fillstyle-2">fillStyle</a>; // (default black)
-  <a href="#canvasgradient" id="2dcontext:canvasgradient">CanvasGradient</a> <a href="#dom-context-2d-createlineargradient-2" id="2dcontext:dom-context-2d-createlineargradient-2">createLinearGradient</a>(double x0, double y0, double x1, double y1);
-  <a href="#canvasgradient" id="2dcontext:canvasgradient-2">CanvasGradient</a> <a href="#dom-context-2d-createradialgradient-2" id="2dcontext:dom-context-2d-createradialgradient-2">createRadialGradient</a>(double x0, double y0, double r0, double x1, double y1, double r1);
-  <a href="#canvaspattern" id="2dcontext:canvaspattern">CanvasPattern</a>? <a href="#dom-context-2d-createpattern-2" id="2dcontext:dom-context-2d-createpattern-2">createPattern</a>(<a href="#canvasimagesource" id="2dcontext:canvasimagesource">CanvasImageSource</a> image, [TreatNullAs=EmptyString] DOMString repetition);
-
-};
-
-[NoInterfaceObject, Exposed=(Window,Worker)]
-interface <dfn id="canvasshadowstyles">CanvasShadowStyles</dfn> {
-  // shadows
-  attribute unrestricted double <a href="#dom-context-2d-shadowoffsetx-2" id="2dcontext:dom-context-2d-shadowoffsetx-2">shadowOffsetX</a>; // (default 0)
-  attribute unrestricted double <a href="#dom-context-2d-shadowoffsety-2" id="2dcontext:dom-context-2d-shadowoffsety-2">shadowOffsetY</a>; // (default 0)
-  attribute unrestricted double <a href="#dom-context-2d-shadowblur-2" id="2dcontext:dom-context-2d-shadowblur-2">shadowBlur</a>; // (default 0)
-  attribute DOMString <a href="#dom-context-2d-shadowcolor-2" id="2dcontext:dom-context-2d-shadowcolor-2">shadowColor</a>; // (default transparent black)
-};
-
-[NoInterfaceObject, Exposed=(Window,Worker)]
-interface <dfn id="canvasfilters">CanvasFilters</dfn> {
-  // filters
-  attribute DOMString <a href="#dom-context-2d-filter" id="2dcontext:dom-context-2d-filter">filter</a>; // (default &quot;none&quot;)
-};
-
-[NoInterfaceObject, Exposed=(Window,Worker)]
-interface <dfn id="canvasrect">CanvasRect</dfn> {
-  // rects
-  void <a href="#dom-context-2d-clearrect-2" id="2dcontext:dom-context-2d-clearrect-2">clearRect</a>(unrestricted double x, unrestricted double y, unrestricted double w, unrestricted double h);
-  void <a href="#dom-context-2d-fillrect-2" id="2dcontext:dom-context-2d-fillrect-2">fillRect</a>(unrestricted double x, unrestricted double y, unrestricted double w, unrestricted double h);
-  void <a href="#dom-context-2d-strokerect-2" id="2dcontext:dom-context-2d-strokerect-2">strokeRect</a>(unrestricted double x, unrestricted double y, unrestricted double w, unrestricted double h);
-};
-
-[NoInterfaceObject, Exposed=(Window,Worker)]
-interface <dfn id="canvasdrawpath">CanvasDrawPath</dfn> {
-  // path API (see also <a href="#canvaspath" id="2dcontext:canvaspath-2">CanvasPath</a>)
-  void <a href="#dom-context-2d-beginpath-2" id="2dcontext:dom-context-2d-beginpath-2">beginPath</a>();
-  void <a href="#dom-context-2d-fill-2" id="2dcontext:dom-context-2d-fill-2">fill</a>(optional <a href="#canvasfillrule" id="2dcontext:canvasfillrule">CanvasFillRule</a> fillRule = &quot;<a href="#dom-context-2d-fillrule-nonzero" id="2dcontext:dom-context-2d-fillrule-nonzero-2">nonzero</a>&quot;);
-  void <a href="#dom-context-2d-fill-2" id="2dcontext:dom-context-2d-fill-2-2">fill</a>(<a href="#path2d" id="2dcontext:path2d">Path2D</a> path, optional <a href="#canvasfillrule" id="2dcontext:canvasfillrule-2">CanvasFillRule</a> fillRule = &quot;<a href="#dom-context-2d-fillrule-nonzero" id="2dcontext:dom-context-2d-fillrule-nonzero-3">nonzero</a>&quot;);
-  void <a href="#dom-context-2d-stroke-2" id="2dcontext:dom-context-2d-stroke-2">stroke</a>();
-  void <a href="#dom-context-2d-stroke-2" id="2dcontext:dom-context-2d-stroke-2-2">stroke</a>(<a href="#path2d" id="2dcontext:path2d-2">Path2D</a> path);
-  void <a href="#dom-context-2d-clip-2" id="2dcontext:dom-context-2d-clip-2">clip</a>(optional <a href="#canvasfillrule" id="2dcontext:canvasfillrule-3">CanvasFillRule</a> fillRule = &quot;<a href="#dom-context-2d-fillrule-nonzero" id="2dcontext:dom-context-2d-fillrule-nonzero-4">nonzero</a>&quot;);
-  void <a href="#dom-context-2d-clip-2" id="2dcontext:dom-context-2d-clip-2-2">clip</a>(<a href="#path2d" id="2dcontext:path2d-3">Path2D</a> path, optional <a href="#canvasfillrule" id="2dcontext:canvasfillrule-4">CanvasFillRule</a> fillRule = &quot;<a href="#dom-context-2d-fillrule-nonzero" id="2dcontext:dom-context-2d-fillrule-nonzero-5">nonzero</a>&quot;);
-  void <a href="#dom-context-2d-resetclip-2" id="2dcontext:dom-context-2d-resetclip-2">resetClip</a>();
-  boolean <a href="#dom-context-2d-ispointinpath-2" id="2dcontext:dom-context-2d-ispointinpath-2">isPointInPath</a>(unrestricted double x, unrestricted double y, optional <a href="#canvasfillrule" id="2dcontext:canvasfillrule-5">CanvasFillRule</a> fillRule = &quot;<a href="#dom-context-2d-fillrule-nonzero" id="2dcontext:dom-context-2d-fillrule-nonzero-6">nonzero</a>&quot;);
-  boolean <a href="#dom-context-2d-ispointinpath-2" id="2dcontext:dom-context-2d-ispointinpath-2-2">isPointInPath</a>(<a href="#path2d" id="2dcontext:path2d-4">Path2D</a> path, unrestricted double x, unrestricted double y, optional <a href="#canvasfillrule" id="2dcontext:canvasfillrule-6">CanvasFillRule</a> fillRule = &quot;<a href="#dom-context-2d-fillrule-nonzero" id="2dcontext:dom-context-2d-fillrule-nonzero-7">nonzero</a>&quot;);
-  boolean <a href="#dom-context-2d-ispointinstroke-2" id="2dcontext:dom-context-2d-ispointinstroke-2">isPointInStroke</a>(unrestricted double x, unrestricted double y);
-  boolean <a href="#dom-context-2d-ispointinstroke-2" id="2dcontext:dom-context-2d-ispointinstroke-2-2">isPointInStroke</a>(<a href="#path2d" id="2dcontext:path2d-5">Path2D</a> path, unrestricted double x, unrestricted double y);
-};
-
-[Exposed=Window,
- NoInterfaceObject]
-interface <dfn id="canvasuserinterface">CanvasUserInterface</dfn> {
-  void <a href="#dom-context-2d-drawfocusifneeded-2" id="2dcontext:dom-context-2d-drawfocusifneeded-2">drawFocusIfNeeded</a>(<a data-x-internal="element" href="https://dom.spec.whatwg.org/#interface-element" id="2dcontext:element">Element</a> element);
-  void <a href="#dom-context-2d-drawfocusifneeded-2" id="2dcontext:dom-context-2d-drawfocusifneeded-2-2">drawFocusIfNeeded</a>(<a href="#path2d" id="2dcontext:path2d-6">Path2D</a> path, <a data-x-internal="element" href="https://dom.spec.whatwg.org/#interface-element" id="2dcontext:element-2">Element</a> element);
-  void <a href="#dom-context-2d-scrollpathintoview-2" id="2dcontext:dom-context-2d-scrollpathintoview-2">scrollPathIntoView</a>();
-  void <a href="#dom-context-2d-scrollpathintoview-2" id="2dcontext:dom-context-2d-scrollpathintoview-2-2">scrollPathIntoView</a>(<a href="#path2d" id="2dcontext:path2d-7">Path2D</a> path);
-};
-
-[Exposed=Window,
- NoInterfaceObject]
-interface <dfn id="canvastext">CanvasText</dfn> {
-  // text (see also the <a href="#canvaspathdrawingstyles" id="2dcontext:canvaspathdrawingstyles-3">CanvasPathDrawingStyles</a> and <a href="#canvastextdrawingstyles" id="2dcontext:canvastextdrawingstyles-3">CanvasTextDrawingStyles</a> interfaces)
-  void <a href="#dom-context-2d-filltext-2" id="2dcontext:dom-context-2d-filltext-2">fillText</a>(DOMString text, unrestricted double x, unrestricted double y, optional unrestricted double maxWidth);
-  void <a href="#dom-context-2d-stroketext-2" id="2dcontext:dom-context-2d-stroketext-2">strokeText</a>(DOMString text, unrestricted double x, unrestricted double y, optional unrestricted double maxWidth);
-  <a href="#textmetrics" id="2dcontext:textmetrics">TextMetrics</a> <a href="#dom-context-2d-measuretext-2" id="2dcontext:dom-context-2d-measuretext-2">measureText</a>(DOMString text);
-};
-
-[NoInterfaceObject, Exposed=(Window,Worker)]
-interface <dfn id="canvasdrawimage">CanvasDrawImage</dfn> {
-  // drawing images
-  void <a href="#dom-context-2d-drawimage" id="2dcontext:dom-context-2d-drawimage">drawImage</a>(<a href="#canvasimagesource" id="2dcontext:canvasimagesource-2">CanvasImageSource</a> image, unrestricted double dx, unrestricted double dy);
-  void <a href="#dom-context-2d-drawimage" id="2dcontext:dom-context-2d-drawimage-2">drawImage</a>(<a href="#canvasimagesource" id="2dcontext:canvasimagesource-3">CanvasImageSource</a> image, unrestricted double dx, unrestricted double dy, unrestricted double dw, unrestricted double dh);
-  void <a href="#dom-context-2d-drawimage" id="2dcontext:dom-context-2d-drawimage-3">drawImage</a>(<a href="#canvasimagesource" id="2dcontext:canvasimagesource-4">CanvasImageSource</a> image, unrestricted double sx, unrestricted double sy, unrestricted double sw, unrestricted double sh, unrestricted double dx, unrestricted double dy, unrestricted double dw, unrestricted double dh);
-};
-
-[NoInterfaceObject, Exposed=(Window,Worker)]
-interface <dfn id="canvasimagedata">CanvasImageData</dfn> {
-  // <a href="#pixel-manipulation" id="2dcontext:pixel-manipulation">pixel manipulation</a>
-  <a href="#imagedata" id="2dcontext:imagedata">ImageData</a> <a href="#dom-context-2d-createimagedata-2" id="2dcontext:dom-context-2d-createimagedata-2">createImageData</a>(long sw, long sh);
-  <a href="#imagedata" id="2dcontext:imagedata-2">ImageData</a> <a href="#dom-context-2d-createimagedata-2" id="2dcontext:dom-context-2d-createimagedata-2-2">createImageData</a>(<a href="#imagedata" id="2dcontext:imagedata-3">ImageData</a> imagedata);
-  <a href="#imagedata" id="2dcontext:imagedata-4">ImageData</a> <a href="#dom-context-2d-getimagedata-2" id="2dcontext:dom-context-2d-getimagedata-2">getImageData</a>(long sx, long sy, long sw, long sh);
-  void <a href="#dom-context-2d-putimagedata-2" id="2dcontext:dom-context-2d-putimagedata-2">putImageData</a>(<a href="#imagedata" id="2dcontext:imagedata-5">ImageData</a> imagedata, long dx, long dy);
-  void <a href="#dom-context-2d-putimagedata-2" id="2dcontext:dom-context-2d-putimagedata-2-2">putImageData</a>(<a href="#imagedata" id="2dcontext:imagedata-6">ImageData</a> imagedata, long dx, long dy, long dirtyX, long dirtyY, long dirtyWidth, long dirtyHeight);
-};
-
-enum <dfn id="canvaslinecap">CanvasLineCap</dfn> { &quot;butt&quot;, &quot;round&quot;, &quot;square&quot; };
-enum <dfn id="canvaslinejoin">CanvasLineJoin</dfn> { &quot;round&quot;, &quot;bevel&quot;, &quot;miter&quot; };
-enum <dfn id="canvastextalign">CanvasTextAlign</dfn> { &quot;<a href="#dom-context-2d-textalign-start" id="2dcontext:dom-context-2d-textalign-start">start</a>&quot;, &quot;<a href="#dom-context-2d-textalign-end" id="2dcontext:dom-context-2d-textalign-end">end</a>&quot;, &quot;<a href="#dom-context-2d-textalign-left" id="2dcontext:dom-context-2d-textalign-left">left</a>&quot;, &quot;<a href="#dom-context-2d-textalign-right" id="2dcontext:dom-context-2d-textalign-right">right</a>&quot;, &quot;<a href="#dom-context-2d-textalign-center" id="2dcontext:dom-context-2d-textalign-center">center</a>&quot; };
-enum <dfn id="canvastextbaseline">CanvasTextBaseline</dfn> { &quot;<a href="#dom-context-2d-textbaseline-top" id="2dcontext:dom-context-2d-textbaseline-top">top</a>&quot;, &quot;<a href="#dom-context-2d-textbaseline-hanging" id="2dcontext:dom-context-2d-textbaseline-hanging">hanging</a>&quot;, &quot;<a href="#dom-context-2d-textbaseline-middle" id="2dcontext:dom-context-2d-textbaseline-middle">middle</a>&quot;, &quot;<a href="#dom-context-2d-textbaseline-alphabetic" id="2dcontext:dom-context-2d-textbaseline-alphabetic">alphabetic</a>&quot;, &quot;<a href="#dom-context-2d-textbaseline-ideographic" id="2dcontext:dom-context-2d-textbaseline-ideographic">ideographic</a>&quot;, &quot;<a href="#dom-context-2d-textbaseline-bottom" id="2dcontext:dom-context-2d-textbaseline-bottom">bottom</a>&quot; };
-enum <dfn id="canvasdirection">CanvasDirection</dfn> { &quot;<a href="#dom-context-2d-direction-ltr" id="2dcontext:dom-context-2d-direction-ltr">ltr</a>&quot;, &quot;<a href="#dom-context-2d-direction-rtl" id="2dcontext:dom-context-2d-direction-rtl">rtl</a>&quot;, &quot;<a href="#dom-context-2d-direction-inherit" id="2dcontext:dom-context-2d-direction-inherit">inherit</a>&quot; };
-
-[NoInterfaceObject, Exposed=(Window,Worker)]
-interface <dfn id="canvaspathdrawingstyles">CanvasPathDrawingStyles</dfn> {
-  // line caps/joins
-  attribute unrestricted double <a href="#dom-context-2d-linewidth-2" id="2dcontext:dom-context-2d-linewidth-2">lineWidth</a>; // (default 1)
-  attribute <a href="#canvaslinecap" id="2dcontext:canvaslinecap">CanvasLineCap</a> <a href="#dom-context-2d-linecap-2" id="2dcontext:dom-context-2d-linecap-2">lineCap</a>; // (default &quot;butt&quot;)
-  attribute <a href="#canvaslinejoin" id="2dcontext:canvaslinejoin">CanvasLineJoin</a> <a href="#dom-context-2d-linejoin-2" id="2dcontext:dom-context-2d-linejoin-2">lineJoin</a>; // (default &quot;miter&quot;)
-  attribute unrestricted double <a href="#dom-context-2d-miterlimit-2" id="2dcontext:dom-context-2d-miterlimit-2">miterLimit</a>; // (default 10)
-
-  // dashed lines
-  void <a href="#dom-context-2d-setlinedash-2" id="2dcontext:dom-context-2d-setlinedash-2">setLineDash</a>(sequence&lt;unrestricted double&gt; segments); // default empty
-  sequence&lt;unrestricted double&gt; <a href="#dom-context-2d-getlinedash-2" id="2dcontext:dom-context-2d-getlinedash-2">getLineDash</a>();
-  attribute unrestricted double <a href="#dom-context-2d-linedashoffset-2" id="2dcontext:dom-context-2d-linedashoffset-2">lineDashOffset</a>;
-};
-
-[Exposed=Window,
- NoInterfaceObject]
-interface <dfn id="canvastextdrawingstyles">CanvasTextDrawingStyles</dfn> {
-  // text
-  attribute DOMString <a href="#dom-context-2d-font-2" id="2dcontext:dom-context-2d-font-2">font</a>; // (default 10px sans-serif)
-  attribute <a href="#canvastextalign" id="2dcontext:canvastextalign">CanvasTextAlign</a> <a href="#dom-context-2d-textalign-2" id="2dcontext:dom-context-2d-textalign-2">textAlign</a>; // (default: &quot;start&quot;)
-  attribute <a href="#canvastextbaseline" id="2dcontext:canvastextbaseline">CanvasTextBaseline</a> <a href="#dom-context-2d-textbaseline-2" id="2dcontext:dom-context-2d-textbaseline-2">textBaseline</a>; // (default: &quot;alphabetic&quot;)
-  attribute <a href="#canvasdirection" id="2dcontext:canvasdirection">CanvasDirection</a> <a href="#dom-context-2d-direction-2" id="2dcontext:dom-context-2d-direction-2">direction</a>; // (default: &quot;inherit&quot;)
-};
-
-[NoInterfaceObject, Exposed=(Window,Worker)]
-interface <dfn id="canvaspath">CanvasPath</dfn> {
-  // shared path API methods
-  void <a href="#dom-context-2d-closepath-2" id="2dcontext:dom-context-2d-closepath-2">closePath</a>();
-  void <a href="#dom-context-2d-moveto-2" id="2dcontext:dom-context-2d-moveto-2">moveTo</a>(unrestricted double x, unrestricted double y);
-  void <a href="#dom-context-2d-lineto-2" id="2dcontext:dom-context-2d-lineto-2">lineTo</a>(unrestricted double x, unrestricted double y);
-  void <a href="#dom-context-2d-quadraticcurveto-2" id="2dcontext:dom-context-2d-quadraticcurveto-2">quadraticCurveTo</a>(unrestricted double cpx, unrestricted double cpy, unrestricted double x, unrestricted double y);
-  void <a href="#dom-context-2d-beziercurveto-2" id="2dcontext:dom-context-2d-beziercurveto-2">bezierCurveTo</a>(unrestricted double cp1x, unrestricted double cp1y, unrestricted double cp2x, unrestricted double cp2y, unrestricted double x, unrestricted double y);
-  void <a href="#dom-context-2d-arcto-2" id="2dcontext:dom-context-2d-arcto-2">arcTo</a>(unrestricted double x1, unrestricted double y1, unrestricted double x2, unrestricted double y2, unrestricted double radius); 
-  void <a href="#dom-context-2d-arcto-2" id="2dcontext:dom-context-2d-arcto-2-2">arcTo</a>(unrestricted double x1, unrestricted double y1, unrestricted double x2, unrestricted double y2, unrestricted double radiusX, unrestricted double radiusY, unrestricted double rotation); 
-  void <a href="#dom-context-2d-rect-2" id="2dcontext:dom-context-2d-rect-2">rect</a>(unrestricted double x, unrestricted double y, unrestricted double w, unrestricted double h);
-  void <a href="#dom-context-2d-arc-2" id="2dcontext:dom-context-2d-arc-2">arc</a>(unrestricted double x, unrestricted double y, unrestricted double radius, unrestricted double startAngle, unrestricted double endAngle, optional boolean anticlockwise = false); 
-  void <a href="#dom-context-2d-ellipse-2" id="2dcontext:dom-context-2d-ellipse-2">ellipse</a>(unrestricted double x, unrestricted double y, unrestricted double radiusX, unrestricted double radiusY, unrestricted double rotation, unrestricted double startAngle, unrestricted double endAngle, optional boolean anticlockwise = false); 
-};
-
-[Exposed=(Window,Worker)]
-interface <dfn id="canvasgradient">CanvasGradient</dfn> {
-  // opaque object
-  void <a href="#dom-canvasgradient-addcolorstop-2" id="2dcontext:dom-canvasgradient-addcolorstop-2">addColorStop</a>(double offset, DOMString color);
-};
-
-[Exposed=(Window,Worker)]
-interface <dfn id="canvaspattern">CanvasPattern</dfn> {
-  // opaque object
-  void <a href="#dom-canvaspattern-settransform-2" id="2dcontext:dom-canvaspattern-settransform-2">setTransform</a>(optional <a data-x-internal="dommatrix2dinit" href="https://drafts.fxtf.org/geometry/#dictdef-dommatrix2dinit" id="2dcontext:dommatrix2dinit-2">DOMMatrix2DInit</a> transform);
-};
-
-[Exposed=Window]
-interface <dfn id="textmetrics">TextMetrics</dfn> {
-  // x-direction
-  readonly attribute double <a href="#dom-textmetrics-width-2" id="2dcontext:dom-textmetrics-width-2">width</a>; // advance width
-  readonly attribute double <a href="#dom-textmetrics-actualboundingboxleft-2" id="2dcontext:dom-textmetrics-actualboundingboxleft-2">actualBoundingBoxLeft</a>;
-  readonly attribute double <a href="#dom-textmetrics-actualboundingboxright-2" id="2dcontext:dom-textmetrics-actualboundingboxright-2">actualBoundingBoxRight</a>;
-
-  // y-direction
-  readonly attribute double <a href="#dom-textmetrics-fontboundingboxascent-2" id="2dcontext:dom-textmetrics-fontboundingboxascent-2">fontBoundingBoxAscent</a>;
-  readonly attribute double <a href="#dom-textmetrics-fontboundingboxdescent-2" id="2dcontext:dom-textmetrics-fontboundingboxdescent-2">fontBoundingBoxDescent</a>;
-  readonly attribute double <a href="#dom-textmetrics-actualboundingboxascent-2" id="2dcontext:dom-textmetrics-actualboundingboxascent-2">actualBoundingBoxAscent</a>;
-  readonly attribute double <a href="#dom-textmetrics-actualboundingboxdescent-2" id="2dcontext:dom-textmetrics-actualboundingboxdescent-2">actualBoundingBoxDescent</a>;
-  readonly attribute double <a href="#dom-textmetrics-emheightascent-2" id="2dcontext:dom-textmetrics-emheightascent-2">emHeightAscent</a>;
-  readonly attribute double <a href="#dom-textmetrics-emheightdescent-2" id="2dcontext:dom-textmetrics-emheightdescent-2">emHeightDescent</a>;
-  readonly attribute double <a href="#dom-textmetrics-hangingbaseline-2" id="2dcontext:dom-textmetrics-hangingbaseline-2">hangingBaseline</a>;
-  readonly attribute double <a href="#dom-textmetrics-alphabeticbaseline-2" id="2dcontext:dom-textmetrics-alphabeticbaseline-2">alphabeticBaseline</a>;
-  readonly attribute double <a href="#dom-textmetrics-ideographicbaseline-2" id="2dcontext:dom-textmetrics-ideographicbaseline-2">ideographicBaseline</a>;
-};
-
-[<a href="#dom-imagedata" id="2dcontext:dom-imagedata">Constructor</a>(unsigned long sw, unsigned long sh),
- <a href="#dom-imagedata" id="2dcontext:dom-imagedata-2">Constructor</a>(<a data-x-internal="idl-uint8clampedarray" href="https://heycam.github.io/webidl/#idl-Uint8ClampedArray" id="2dcontext:idl-uint8clampedarray">Uint8ClampedArray</a> data, unsigned long sw, optional unsigned long sh),
- Exposed=(Window,Worker),
- <a href="https://html.spec.whatwg.org/multipage/structured-data.html#serializable" id="2dcontext:serializable">Serializable</a>]
-interface <dfn id="imagedata">ImageData</dfn> {
-  readonly attribute unsigned long <a href="#dom-imagedata-width-2" id="2dcontext:dom-imagedata-width-2">width</a>;
-  readonly attribute unsigned long <a href="#dom-imagedata-height-2" id="2dcontext:dom-imagedata-height-2">height</a>;
-  readonly attribute <a data-x-internal="idl-uint8clampedarray" href="https://heycam.github.io/webidl/#idl-Uint8ClampedArray" id="2dcontext:idl-uint8clampedarray-2">Uint8ClampedArray</a> <a href="#dom-imagedata-data-2" id="2dcontext:dom-imagedata-data-2">data</a>;
-};
-
-[<a href="#dom-path2d" id="2dcontext:dom-path2d">Constructor</a>,
- <a href="#dom-path2d-copy" id="2dcontext:dom-path2d-copy">Constructor</a>(<a href="#path2d" id="2dcontext:path2d-8">Path2D</a> path),
- <a href="#dom-path2d-merge" id="2dcontext:dom-path2d-merge">Constructor</a>(sequence&lt;<a href="#path2d" id="2dcontext:path2d-9">Path2D</a>&gt; paths, optional <a href="#canvasfillrule" id="2dcontext:canvasfillrule-7">CanvasFillRule</a> fillRule = &quot;<a href="#dom-context-2d-fillrule-nonzero" id="2dcontext:dom-context-2d-fillrule-nonzero-8">nonzero</a>&quot;),
- <a href="#dom-path2d-withdata" id="2dcontext:dom-path2d-withdata">Constructor</a>(DOMString d),
- Exposed=(Window,Worker)]
-interface <dfn id="path2d">Path2D</dfn> {
-  void <a href="#dom-path2d-addpath-2" id="2dcontext:dom-path2d-addpath-2">addPath</a>(<a href="#path2d" id="2dcontext:path2d-10">Path2D</a> path, optional <a data-x-internal="dommatrix2dinit" href="https://drafts.fxtf.org/geometry/#dictdef-dommatrix2dinit" id="2dcontext:dommatrix2dinit-3">DOMMatrix2DInit</a> transform);
-};
-<a href="#path2d" id="2dcontext:path2d-11">Path2D</a> implements <a href="#canvaspath" id="2dcontext:canvaspath-3">CanvasPath</a>;</pre>
-
- 
-
-  <p class="note">To maintain compatibility with existing Web content, user agents need to
-  enumerate methods defined in <code id="2dcontext:canvasuserinterface-2"><a href="#canvasuserinterface">CanvasUserInterface</a></code> immediately after the <code id="2dcontext:dom-context-2d-stroke-2-3"><a href="#dom-context-2d-stroke-2">stroke()</a></code> method on <code id="2dcontext:canvasrenderingcontext2d-17"><a href="#canvasrenderingcontext2d">CanvasRenderingContext2D</a></code>
-  objects.</p>
-
-  <dl class="domintro"><dt><var>context</var> = <var>canvas</var> . <code id="2dcontext:dom-canvas-getcontext-2"><a href="#dom-canvas-getcontext-2">getContext</a></code>('2d' [, { [ <code id="2dcontext:dom-canvasrenderingcontext2dsettings-alpha-2"><a href="#dom-canvasrenderingcontext2dsettings-alpha">alpha</a></code>: false ] } ] )</dt><dd>
-
-    <p>Returns a <code id="2dcontext:canvasrenderingcontext2d-18"><a href="#canvasrenderingcontext2d">CanvasRenderingContext2D</a></code> object that is permanently bound to a
-    particular <code id="2dcontext:the-canvas-element"><a href="#the-canvas-element">canvas</a></code> element.</p>
-
-    <p>If the <code id="2dcontext:dom-canvasrenderingcontext2dsettings-alpha-3"><a href="#dom-canvasrenderingcontext2dsettings-alpha">alpha</a></code> setting is
-    provided and set to false, then the canvas is forced to always be opaque.</p>
-
-   </dd><dt><var>context</var> . <code id="dom-context-2d-canvas"><a href="#dom-context-2d-canvas-2">canvas</a></code></dt><dd>
-
-    <p>Returns the <code id="2dcontext:the-canvas-element-2"><a href="#the-canvas-element">canvas</a></code> element.</p>
-
-   </dd></dl>
-
-  
-
-  <p>A <code id="2dcontext:canvasrenderingcontext2d-19"><a href="#canvasrenderingcontext2d">CanvasRenderingContext2D</a></code> object has an <dfn id="output-bitmap">output bitmap</dfn> that
-  is initialized when the object is created.</p>
-
-
-  <p>The <a href="#output-bitmap" id="2dcontext:output-bitmap">output bitmap</a> has an <a href="#concept-canvas-origin-clean" id="2dcontext:concept-canvas-origin-clean">origin-clean</a> flag, which can be set to true or false.
-  Initially, when one of these bitmaps is created, its <a href="#concept-canvas-origin-clean" id="2dcontext:concept-canvas-origin-clean-2">origin-clean</a> flag must be set to true.</p>
-
-
-  <p>The <code id="2dcontext:canvasrenderingcontext2d-20"><a href="#canvasrenderingcontext2d">CanvasRenderingContext2D</a></code> object also has an <dfn id="concept-canvas-alpha">alpha</dfn> flag, which can be set to true or false. Initially,
-  when the context is created, its <a href="#concept-canvas-alpha" id="2dcontext:concept-canvas-alpha">alpha</a> flag must be
-  set to true. When a <code id="2dcontext:canvasrenderingcontext2d-21"><a href="#canvasrenderingcontext2d">CanvasRenderingContext2D</a></code> object has its <a href="#concept-canvas-alpha" id="2dcontext:concept-canvas-alpha-2">alpha</a> flag set to false, then its alpha channel must be
-  fixed to 1.0 (fully opaque) for all pixels, and attempts to change the alpha component of any
-  pixel must be silently ignored.</p>
-
-  <p class="note">Thus, the bitmap of such a context starts off as fully-opaque black instead of
-  fully-transparent black; <code id="2dcontext:dom-context-2d-clearrect-2-2"><a href="#dom-context-2d-clearrect-2">clearRect()</a></code> always
-  results in fully-opaque black pixels, every fourth byte from <code id="2dcontext:dom-context-2d-getimagedata-2-2"><a href="#dom-context-2d-getimagedata-2">getImageData()</a></code> is always 255, the <code id="2dcontext:dom-context-2d-putimagedata-2-3"><a href="#dom-context-2d-putimagedata-2">putImageData()</a></code> method effectively ignores every
-  fourth byte in its input, and so on. However, the alpha component of styles and images drawn
-  onto the canvas are still honoured up to the point where they would impact the <a href="#output-bitmap" id="2dcontext:output-bitmap-2">output
-  bitmap</a>'s alpha channel; for instance, drawing a 50% transparent white square on a freshly
-  created <a href="#output-bitmap" id="2dcontext:output-bitmap-3">output bitmap</a> with its <a href="#concept-canvas-alpha" id="2dcontext:concept-canvas-alpha-3">alpha</a>
-  flag set to false will result in a fully-opaque gray square.</p>
-
-  <hr/>
-
-  <p>The <code id="2dcontext:canvasrenderingcontext2d-22"><a href="#canvasrenderingcontext2d">CanvasRenderingContext2D</a></code> 2D rendering context represents a flat linear
-  Cartesian surface whose origin (0,0) is at the top left corner, with the coordinate space having
-  <var>x</var> values increasing when going right, and <var>y</var> values increasing when going
-  down. The <var>x</var>-coordinate of the right-most edge is equal to the width of the rendering
-  context's <a href="#output-bitmap" id="2dcontext:output-bitmap-4">output bitmap</a> in <a data-x-internal="'px'" href="https://drafts.csswg.org/css-values/#px" id="2dcontext:'px'">CSS pixels</a>; similarly, the
-  <var>y</var>-coordinate of the bottom-most edge is equal to the height of the rendering context's
-  <a href="#output-bitmap" id="2dcontext:output-bitmap-5">output bitmap</a> in <a data-x-internal="'px'" href="https://drafts.csswg.org/css-values/#px" id="2dcontext:'px'-2">CSS pixels</a>.</p>
-
-  <p>The size of the coordinate space does not necessarily represent the size of the actual bitmaps
-  that the user agent will use internally or during rendering. On high-definition displays, for
-  instance, the user agent may internally use bitmaps with two device pixels per unit in the
-  coordinate space, so that the rendering remains at high quality throughout. Anti-aliasing can
-  similarly be implemented using over-sampling with bitmaps of a higher resolution than the final
-  image on the display.</p>
-
-  <hr/>
-
-  <p>The <dfn id="2d-context-creation-algorithm">2D context creation algorithm</dfn>, which is passed a <var>target</var> (a
-  <code id="2dcontext:the-canvas-element-3"><a href="#the-canvas-element">canvas</a></code> element) and optionally some arguments, consists of running the following
-  steps:</p>
-
-  <ol><li><p>If the algorithm was passed some arguments, then let <var>arg</var> be the first such
-   argument. Otherwise, let <var>arg</var> be undefined.</p></li><li><p>Let <var>settings</var> be the result of <a href="#coerce-context-arguments-for-2d" id="2dcontext:coerce-context-arguments-for-2d">coercing the <var>arg</var> context arguments for 2D</a>.</p></li><li><p>Create a new <code id="2dcontext:canvasrenderingcontext2d-23"><a href="#canvasrenderingcontext2d">CanvasRenderingContext2D</a></code> object.</p></li><li><p>Initialize its <code id="2dcontext:dom-context-2d-canvas-2-2"><a href="#dom-context-2d-canvas-2">canvas</a></code> attribute to point to
-   <var>target</var>.</p></li><li><p>Let the new <code id="2dcontext:canvasrenderingcontext2d-24"><a href="#canvasrenderingcontext2d">CanvasRenderingContext2D</a></code> object's <a href="#output-bitmap" id="2dcontext:output-bitmap-6">output bitmap</a> be
-   the same bitmap as <var>target</var>'s bitmap (so that they are shared).</p></li><li><p><a href="#concept-canvas-set-bitmap-dimensions" id="2dcontext:concept-canvas-set-bitmap-dimensions">Set bitmap dimensions</a> to the
-   numeric values of <var>target</var>'s <code id="2dcontext:attr-canvas-width"><a href="#attr-canvas-width">width</a></code> and
-   <code id="2dcontext:attr-canvas-height"><a href="#attr-canvas-height">height</a></code> content attributes.</p></li><li>
-
-    <p>Process each of the members of <var>settings</var> as follows:</p>
-
-    <dl><dt><dfn id="dom-canvasrenderingcontext2dsettings-alpha"><code>alpha</code></dfn></dt><dd>If false, then set the new <code id="2dcontext:canvasrenderingcontext2d-25"><a href="#canvasrenderingcontext2d">CanvasRenderingContext2D</a></code> object's <a href="#concept-canvas-alpha" id="2dcontext:concept-canvas-alpha-4">alpha</a> flag to false.</dd></dl>
-
-   </li><li><p>Return the new <code id="2dcontext:canvasrenderingcontext2d-26"><a href="#canvasrenderingcontext2d">CanvasRenderingContext2D</a></code> object.</p></li></ol>
-
-  <hr/>
-
-  <hr/>
-
-  <p>When a user agent is required to <dfn id="coerce-context-arguments-for-2d">coerce context arguments for 2D</dfn>, it must run these
-  steps:</p>
-
-  <ol><li><p>Let <var>input</var> be the argument to coerce.</p></li><li><p>Let <var>jsval</var> be the result of <a data-x-internal="concept-idl-convert" href="https://heycam.github.io/webidl/#es-type-mapping" id="2dcontext:concept-idl-convert">converting</a>
-   <var>input</var> to a JavaScript value. (This can throw an exception.)</p></li><li><p>Let <var>dict</var> be the result of <a data-x-internal="concept-idl-convert" href="https://heycam.github.io/webidl/#es-type-mapping" id="2dcontext:concept-idl-convert-2">converting</a>
-   <var>jsval</var> to the dictionary type <code id="2dcontext:canvasrenderingcontext2dsettings"><a href="#canvasrenderingcontext2dsettings">CanvasRenderingContext2DSettings</a></code>. (This can
-   throw an exception.)</p></li><li><p>Return <var>dict</var>.</p></li></ol>
-
-  <hr/>
-
-  <p>When the user agent is to <dfn id="concept-canvas-set-bitmap-dimensions">set bitmap
-  dimensions</dfn> to <var>width</var> and <var>height</var>, it must run these steps:</p>
-
-  <ol><li><p><a href="#reset-the-rendering-context-to-its-default-state" id="2dcontext:reset-the-rendering-context-to-its-default-state">Reset the rendering context to its default state</a>.</p></li><li><p>Resize the <a href="#output-bitmap" id="2dcontext:output-bitmap-7">output bitmap</a> to the new <var>width</var> and <var>height</var>
-   and clear it to fully transparent black.</p></li><li><p>Let <var>canvas</var> be the <code id="2dcontext:the-canvas-element-4"><a href="#the-canvas-element">canvas</a></code> element to which the rendering
-   context's <code id="2dcontext:dom-context-2d-canvas-2-3"><a href="#dom-context-2d-canvas-2">canvas</a></code> attribute was initialized.</p></li><li><p>If the numeric value of <var>canvas</var>'s <code id="2dcontext:attr-canvas-width-2"><a href="#attr-canvas-width">width</a></code>
-   content attribute differs from <var>width</var>, then set <var>canvas</var>'s <code id="2dcontext:attr-canvas-width-3"><a href="#attr-canvas-width">width</a></code> content attribute to the shortest possible string
-   representing <var>width</var> as a <a href="https://html.spec.whatwg.org/multipage/common-microsyntaxes.html#valid-non-negative-integer" id="2dcontext:valid-non-negative-integer">valid non-negative integer</a>.</p></li><li><p>If the numeric value of <var>canvas</var>'s <code id="2dcontext:attr-canvas-height-2"><a href="#attr-canvas-height">height</a></code>
-   content attribute differs from <var>height</var>, then set <var>canvas</var>'s <code id="2dcontext:attr-canvas-height-3"><a href="#attr-canvas-height">height</a></code> content attribute to the shortest possible string
-   representing <var>height</var> as a <a href="https://html.spec.whatwg.org/multipage/common-microsyntaxes.html#valid-non-negative-integer" id="2dcontext:valid-non-negative-integer-2">valid non-negative integer</a>.</p></li></ol>
-
-  <div class="example">
-   <p>Only one square appears to be drawn in the following example:</p>
-   <pre>// canvas is a reference to a &lt;canvas&gt; element
-var context = canvas.getContext('2d');
-context.fillRect(0,0,50,50);
-canvas.setAttribute('width', '300'); // clears the canvas
-context.fillRect(0,100,50,50);
-canvas.width = canvas.width; // clears the canvas
-context.fillRect(100,0,50,50); // only this square remains</pre>
-  </div>
-
-  <hr/>
-
-  <p>When the user agent is to run the <dfn id="concept-canvas-unbinding-steps">unbinding
-  steps</dfn> for a rendering context, it must run these steps:</p>
-
-  <ol><li><p><a href="#reset-the-rendering-context-to-its-default-state" id="2dcontext:reset-the-rendering-context-to-its-default-state-2">Reset the rendering context to its default state</a>.</p></li><li><p>Clear the <code id="2dcontext:canvasrenderingcontext2d-27"><a href="#canvasrenderingcontext2d">CanvasRenderingContext2D</a></code> object's <a href="#output-bitmap" id="2dcontext:output-bitmap-8">output bitmap</a> to a
-   transparent black.</p></li><li><p>Set the <code id="2dcontext:canvasrenderingcontext2d-28"><a href="#canvasrenderingcontext2d">CanvasRenderingContext2D</a></code> object's <a href="#concept-canvas-origin-clean" id="2dcontext:concept-canvas-origin-clean-3">origin-clean</a> flag to true.</p></li><li><p>Let the <code id="2dcontext:canvasrenderingcontext2d-29"><a href="#canvasrenderingcontext2d">CanvasRenderingContext2D</a></code> object have no <a href="#output-bitmap" id="2dcontext:output-bitmap-9">output
-   bitmap</a>.</p></li></ol>
-
-  <p>When the user agent is to run the <dfn id="concept-canvas-binding-steps">binding
-  steps</dfn> to bind the rendering context to the <code id="2dcontext:the-canvas-element-5"><a href="#the-canvas-element">canvas</a></code> element <var>target</var>, it
-  must run these steps:</p>
-
-  <ol><li><p><a href="#reset-the-rendering-context-to-its-default-state" id="2dcontext:reset-the-rendering-context-to-its-default-state-3">Reset the rendering context to its default state</a>.</p></li><li><p>Resize the <code id="2dcontext:canvasrenderingcontext2d-30"><a href="#canvasrenderingcontext2d">CanvasRenderingContext2D</a></code> object's <a href="#output-bitmap" id="2dcontext:output-bitmap-10">output bitmap</a> to
-   the dimensions of <var>target</var>'s bitmap and clear it to fully transparent black.</p></li><li><p>Set the <code id="2dcontext:canvasrenderingcontext2d-31"><a href="#canvasrenderingcontext2d">CanvasRenderingContext2D</a></code> object's <a href="#concept-canvas-origin-clean" id="2dcontext:concept-canvas-origin-clean-4">origin-clean</a> flag to true.</p></li><li><p>Let the <code id="2dcontext:canvasrenderingcontext2d-32"><a href="#canvasrenderingcontext2d">CanvasRenderingContext2D</a></code> object's <a href="#output-bitmap" id="2dcontext:output-bitmap-11">output bitmap</a> be <var>target</var>'s bitmap.</p></li></ol>
-
-  <hr/>
-
-  <p>The <dfn id="dom-context-2d-canvas-2"><code>canvas</code></dfn> attribute must return the
-  value it was initialized to when the object was created.</p>
-
-  <hr/>
-
-  <p id="canvasrenderingcontext2d-currentcolor">Whenever the CSS value <code>currentColor</code> is used as a color in the <code id="2dcontext:canvasrenderingcontext2d-33"><a href="#canvasrenderingcontext2d">CanvasRenderingContext2D</a></code>
-  API, the <a data-x-internal="computed-value" href="https://drafts.csswg.org/css-cascade/#computed-value" id="2dcontext:computed-value">computed value</a> of the <code>currentColor</code> keyword is
-  the <a data-x-internal="computed-value" href="https://drafts.csswg.org/css-cascade/#computed-value" id="2dcontext:computed-value-2">computed value</a> of the <a data-x-internal="'color'" href="https://drafts.csswg.org/css-color/#the-color-property" id="2dcontext:'color'">'color'</a> property on the <code id="2dcontext:the-canvas-element-6"><a href="#the-canvas-element">canvas</a></code>
-  element at the time that the color is specified (e.g. when the appropriate attribute is set, or
-  when the method is called; not when the color is rendered or otherwise used). If the computed
-  value of the <a data-x-internal="'color'" href="https://drafts.csswg.org/css-color/#the-color-property" id="2dcontext:'color'-2">'color'</a> property is undefined for a particular case (e.g. because the element is
-  not in a document), then the <a data-x-internal="computed-value" href="https://drafts.csswg.org/css-cascade/#computed-value" id="2dcontext:computed-value-3">computed value</a> of the <a data-x-internal="'color'" href="https://drafts.csswg.org/css-color/#the-color-property" id="2dcontext:'color'-3">'color'</a> property
-  for the purposes of determining the computed value of the <code>currentColor</code>
-  keyword is fully opaque black. <a href="https://html.spec.whatwg.org/multipage/references.html#refsCSSCOLOR">[CSSCOLOR]</a></p>
-
-  <p>In the case of <code id="2dcontext:dom-canvasgradient-addcolorstop-2-2"><a href="#dom-canvasgradient-addcolorstop-2">addColorStop()</a></code> on
-  <code id="2dcontext:canvasgradient-3"><a href="#canvasgradient">CanvasGradient</a></code>, the &quot;<a data-x-internal="computed-value" href="https://drafts.csswg.org/css-cascade/#computed-value" id="2dcontext:computed-value-4">computed value</a> of the <a data-x-internal="'color'" href="https://drafts.csswg.org/css-color/#the-color-property" id="2dcontext:'color'-4">'color'</a>
-  property&quot; for the purposes of determining the <a data-x-internal="computed-value" href="https://drafts.csswg.org/css-cascade/#computed-value" id="2dcontext:computed-value-5">computed value</a> of the <code>currentColor</code> keyword is always fully opaque black (there is no associated
-  element). <a href="https://html.spec.whatwg.org/multipage/references.html#refsCSSCOLOR">[CSSCOLOR]</a></p>
-
-  <p class="note">This is because <code id="2dcontext:canvasgradient-4"><a href="#canvasgradient">CanvasGradient</a></code> objects are
-  <code id="2dcontext:the-canvas-element-7"><a href="#the-canvas-element">canvas</a></code>-neutral — a <code id="2dcontext:canvasgradient-5"><a href="#canvasgradient">CanvasGradient</a></code> object created by one
-  <code id="2dcontext:the-canvas-element-8"><a href="#the-canvas-element">canvas</a></code> can be used by another, and there is therefore no way to know which is the
-  &quot;element in question&quot; at the time that the color is specified.</p>
-
-  <p class="note">Similar concerns exist with font-related properties; the rules for those are
-  described in detail in the relevant section below.</p>
-
-  
-
-  <hr/>
-
-  <p>The <code id="2dcontext:canvasfillrule-8"><a href="#canvasfillrule">CanvasFillRule</a></code> enumeration is used to select the <dfn id="fill-rule">fill rule</dfn>
-  algorithm by which to determine if a point is inside or outside a path.</p>
-
-  <p>The value &quot;<dfn id="dom-context-2d-fillrule-nonzero"><code>nonzero</code></dfn>&quot; value
-  indicates the non-zero winding rule, wherein
-
-     a point is considered to be outside a shape if the number of times a half-infinite straight
-     line drawn from that point crosses the shape's path going in one direction is equal to the
-     number of times it crosses the path going in the other direction.
-
-  </p>
-
-
-  <p>The &quot;<dfn id="dom-context-2d-fillrule-evenodd"><code>evenodd</code></dfn>&quot; value indicates
-  the even-odd rule, wherein
-
-     a point is considered to be outside a shape if the number of times a half-infinite straight
-     line drawn from that point crosses the shape's path is even.
-
-  </p>
-
-  <p>If a point is not outside a shape, it is inside the shape.</p>
-
-
-  <hr/>
-
-  <p>The <code id="2dcontext:imagesmoothingquality-2"><a href="#imagesmoothingquality">ImageSmoothingQuality</a></code> enumeration is used to express a preference for the
-  interpolation quality to use when smoothing images.</p>
-
-  <p>The &quot;<dfn id="dom-context-2d-imagesmoothingquality-low"><code>low</code></dfn>&quot; value
-  indicates a preference for a low level of image interpolation quality. Low-quality image
-  interpolation may be more computationally efficient than higher settings.</p>
-
-  <p>The &quot;<dfn id="dom-context-2d-imagesmoothingquality-medium"><code>medium</code></dfn>&quot; value
-  indicates a preference for a medium level of image interpolation quality.</p>
-
-  <p>The &quot;<dfn id="dom-context-2d-imagesmoothingquality-high"><code>high</code></dfn>&quot; value
-  indicates a preference for a high level of image interpolation quality. High-quality image
-  interpolation may be more computationally expensive than lower settings.</p>
-
-  <p class="note">Bilinear scaling is an example of a relatively fast, lower-quality image-smoothing
-  algorithm. Bicubic or Lanczos scaling are examples of image-smoothing algorithms that produce
-  higher-quality output. This specification does not mandate that specific interpolation algorithms
-  be used.</p>
-
-
-  <h6 id="implementation-notes"><span class="secno">4.12.5.1.1</span> Implementation notes<a class="self-link" href="#implementation-notes"/></h6>
-
-  <p><i>This section is non-normative.</i></p>
-
-  <p>The <a href="#output-bitmap" id="implementation-notes:output-bitmap">output bitmap</a>, when it is not directly displayed by the user agent,
-  implementations can, instead of updating this bitmap, merely remember the sequence of drawing
-  operations that have been applied to it until such time as the bitmap's actual data is needed
-  (for example because of a call to <code id="implementation-notes:dom-context-2d-drawimage"><a href="#dom-context-2d-drawimage">drawImage()</a></code>, or
-  the <code id="implementation-notes:dom-createimagebitmap-2"><a href="https://html.spec.whatwg.org/multipage/imagebitmap-and-animations.html#dom-createimagebitmap-2">createImageBitmap()</a></code> factory method). In many
-  cases, this will be more memory efficient.</p>
-
-  <p>The bitmap of a <code id="implementation-notes:the-canvas-element"><a href="#the-canvas-element">canvas</a></code> element is the one bitmap that's pretty much always going
-  to be needed in practice. The <a href="#output-bitmap" id="implementation-notes:output-bitmap-2">output bitmap</a> of a rendering context, when it has one,
-  is always just an alias to a <code id="implementation-notes:the-canvas-element-2"><a href="#the-canvas-element">canvas</a></code> element's bitmap.</p>
-
-  <p>Additional bitmaps are sometimes needed, e.g. to enable fast drawing when the canvas is being
-  painted at a different size than its <a data-x-internal="intrinsic-dimensions" href="https://drafts.csswg.org/css2/conform.html#intrinsic" id="implementation-notes:intrinsic-dimensions">intrinsic size</a>,
-  or to enable double buffering so that graphics updates, like page scrolling for example, can be
-  processed concurrently while canvas draw commands are being executed.</p>
-
-  <h6 id="the-canvas-state"><span class="secno">4.12.5.1.2</span> The canvas state<a class="self-link" href="#the-canvas-state"/></h6>
-
-  <p>Objects that implement the <code id="the-canvas-state:canvasstate"><a href="#canvasstate">CanvasState</a></code> interface maintain a stack of drawing
-  states. <dfn id="drawing-state">Drawing states</dfn> consist of:</p>
-
-  <ul class="brief"><li>The current <a href="#transformations" id="the-canvas-state:transformations">transformation matrix</a>.</li><li>The current <a href="#clipping-region" id="the-canvas-state:clipping-region">clipping region</a>.</li><li>The current values of the following attributes: <code id="the-canvas-state:dom-context-2d-strokestyle-2"><a href="#dom-context-2d-strokestyle-2">strokeStyle</a></code>, <code id="the-canvas-state:dom-context-2d-fillstyle-2"><a href="#dom-context-2d-fillstyle-2">fillStyle</a></code>, <code id="the-canvas-state:dom-context-2d-globalalpha-2"><a href="#dom-context-2d-globalalpha-2">globalAlpha</a></code>, <code id="the-canvas-state:dom-context-2d-linewidth-2"><a href="#dom-context-2d-linewidth-2">lineWidth</a></code>, <code id="the-canvas-state:dom-context-2d-linecap-2"><a href="#dom-context-2d-linecap-2">lineCap</a></code>, <code id="the-canvas-state:dom-context-2d-linejoin-2"><a href="#dom-context-2d-linejoin-2">lineJoin</a></code>, <code id="the-canvas-state:dom-context-2d-miterlimit-2"><a href="#dom-context-2d-miterlimit-2">miterLimit</a></code>, <code id="the-canvas-state:dom-context-2d-linedashoffset-2"><a href="#dom-context-2d-linedashoffset-2">lineDashOffset</a></code>, <code id="the-canvas-state:dom-context-2d-shadowoffsetx-2"><a href="#dom-context-2d-shadowoffsetx-2">shadowOffsetX</a></code>, <code id="the-canvas-state:dom-context-2d-shadowoffsety-2"><a href="#dom-context-2d-shadowoffsety-2">shadowOffsetY</a></code>, <code id="the-canvas-state:dom-context-2d-shadowblur-2"><a href="#dom-context-2d-shadowblur-2">shadowBlur</a></code>, <code id="the-canvas-state:dom-context-2d-shadowcolor-2"><a href="#dom-context-2d-shadowcolor-2">shadowColor</a></code>, <code id="the-canvas-state:dom-context-2d-filter"><a href="#dom-context-2d-filter">filter</a></code>, <code id="the-canvas-state:dom-context-2d-globalcompositeoperation-2"><a href="#dom-context-2d-globalcompositeoperation-2">globalCompositeOperation</a></code>, <code id="the-canvas-state:dom-context-2d-font-2"><a href="#dom-context-2d-font-2">font</a></code>, <code id="the-canvas-state:dom-context-2d-textalign-2"><a href="#dom-context-2d-textalign-2">textAlign</a></code>, <code id="the-canvas-state:dom-context-2d-textbaseline-2"><a href="#dom-context-2d-textbaseline-2">textBaseline</a></code>, <code id="the-canvas-state:dom-context-2d-direction-2"><a href="#dom-context-2d-direction-2">direction</a></code>, <code id="the-canvas-state:dom-context-2d-imagesmoothingenabled-2"><a href="#dom-context-2d-imagesmoothingenabled-2">imageSmoothingEnabled</a></code>, <code id="the-canvas-state:dom-context-2d-imagesmoothingquality-2"><a href="#dom-context-2d-imagesmoothingquality-2">imageSmoothingQuality</a></code>.</li><li>The current <a href="#dash-list" id="the-canvas-state:dash-list">dash list</a>.</li></ul>
-
-  <p class="note">The <a href="#current-default-path" id="the-canvas-state:current-default-path">current default path</a> and the rendering context's bitmaps are not
-  part of the drawing state. The <a href="#current-default-path" id="the-canvas-state:current-default-path-2">current default path</a> is persistent, and can only be
-  reset using the <code id="the-canvas-state:dom-context-2d-beginpath-2"><a href="#dom-context-2d-beginpath-2">beginPath()</a></code> method. The bitmaps
-  depend on whether and how the rendering context is bound to a <code id="the-canvas-state:the-canvas-element"><a href="#the-canvas-element">canvas</a></code> element.</p>
-
-  <dl class="domintro"><dt><var>context</var> . <code id="dom-context-2d-save"><a href="#dom-context-2d-save-2">save</a></code>()</dt><dd>
-
-    <p>Pushes the current state onto the stack.</p>
-
-   </dd><dt><var>context</var> . <code id="dom-context-2d-restore"><a href="#dom-context-2d-restore-2">restore</a></code>()</dt><dd>
-
-    <p>Pops the top state on the stack, restoring the context to that state.</p>
-
-   </dd></dl>
-
-  
-
-  <p>The <dfn id="dom-context-2d-save-2"><code>save()</code></dfn> method, when invoked, must push
-  a copy of the current drawing state onto the drawing state stack.</p>
-
-  <p>The <dfn id="dom-context-2d-restore-2"><code>restore()</code></dfn> method, when invoked,
-  must pop the top entry in the drawing state stack, and reset the drawing state it describes. If
-  there is no saved state, then the method must do nothing.</p>
-
-  <p>When the user agent is to <dfn id="reset-the-rendering-context-to-its-default-state">reset the rendering context to its default state</dfn>, it must
-  clear the drawing state stack and everything that <a href="#drawing-state" id="the-canvas-state:drawing-state">drawing state</a> consists of to
-  initial values.</p>
-
-  
-
-  
-
-
-  <h6 id="line-styles"><span class="secno">4.12.5.1.3</span> Line styles<a class="self-link" href="#line-styles"/></h6>
-
-  <dl class="domintro"><dt><var>context</var> . <code id="dom-context-2d-linewidth"><a href="#dom-context-2d-linewidth-2">lineWidth</a></code> [ = <var>value</var> ]</dt><dt><var>styles</var> . <code id="line-styles:dom-context-2d-linewidth-2"><a href="#dom-context-2d-linewidth-2">lineWidth</a></code> [ = <var>value</var> ]</dt><dd>
-
-    <p>Returns the current line width.</p>
-
-    <p>Can be set, to change the line width. Values that are not finite values greater than zero are
-    ignored.</p>
-
-   </dd><dt><var>context</var> . <code id="dom-context-2d-linecap"><a href="#dom-context-2d-linecap-2">lineCap</a></code> [ = <var>value</var> ]</dt><dt><var>styles</var> . <code id="line-styles:dom-context-2d-linecap-2"><a href="#dom-context-2d-linecap-2">lineCap</a></code> [ = <var>value</var> ]</dt><dd>
-
-    <p>Returns the current line cap style.</p>
-
-    <p>Can be set, to change the line cap style.</p>
-
-    <p>The possible line cap styles are &quot;<code>butt</code>&quot;, &quot;<code>round</code>&quot;, and &quot;<code>square</code>&quot;. Other values are ignored.</p>
-
-   </dd><dt><var>context</var> . <code id="dom-context-2d-linejoin"><a href="#dom-context-2d-linejoin-2">lineJoin</a></code> [ = <var>value</var> ]</dt><dt><var>styles</var> . <code id="line-styles:dom-context-2d-linejoin-2"><a href="#dom-context-2d-linejoin-2">lineJoin</a></code> [ = <var>value</var> ]</dt><dd>
-
-    <p>Returns the current line join style.</p>
-
-    <p>Can be set, to change the line join style.</p>
-
-    <p>The possible line join styles are &quot;<code>bevel</code>&quot;, &quot;<code>round</code>&quot;, and &quot;<code>miter</code>&quot;. Other values are ignored.</p>
-
-   </dd><dt><var>context</var> . <code id="dom-context-2d-miterlimit"><a href="#dom-context-2d-miterlimit-2">miterLimit</a></code> [ = <var>value</var> ]</dt><dt><var>styles</var> . <code id="line-styles:dom-context-2d-miterlimit-2"><a href="#dom-context-2d-miterlimit-2">miterLimit</a></code> [ = <var>value</var> ]</dt><dd>
-
-    <p>Returns the current miter limit ratio.</p>
-
-    <p>Can be set, to change the miter limit ratio. Values that are not finite values greater than
-    zero are ignored.</p>
-
-   </dd><dt><var>context</var> . <code id="dom-context-2d-setlinedash"><a href="#dom-context-2d-setlinedash-2">setLineDash</a></code>(<var>segments</var>)</dt><dt><var>styles</var> . <code id="line-styles:dom-context-2d-setlinedash-2"><a href="#dom-context-2d-setlinedash-2">setLineDash</a></code>(<var>segments</var>)</dt><dd>
-
-    <p>Sets the current line dash pattern (as used when stroking). The argument is a list of
-    distances for which to alternately have the line on and the line off.</p>
-
-   </dd><dt><var>segments</var> = <var>context</var> . <code id="dom-context-2d-getlinedash"><a href="#dom-context-2d-getlinedash-2">getLineDash</a></code>()</dt><dt><var>segments</var> = <var>styles</var> . <code id="line-styles:dom-context-2d-getlinedash-2"><a href="#dom-context-2d-getlinedash-2">getLineDash</a></code>()</dt><dd>
-
-    <p>Returns a copy of the current line dash pattern. The array returned will always have an even
-    number of entries (i.e. the pattern is normalized).</p>
-
-   </dd><dt><var>context</var> . <code id="dom-context-2d-linedashoffset"><a href="#dom-context-2d-linedashoffset-2">lineDashOffset</a></code></dt><dt><var>styles</var> . <code id="line-styles:dom-context-2d-linedashoffset-2"><a href="#dom-context-2d-linedashoffset-2">lineDashOffset</a></code></dt><dd>
-
-    <p>Returns the phase offset (in the same units as the line dash pattern).</p>
-
-    <p>Can be set, to change the phase offset. Values that are not finite values are ignored.</p>
-
-   </dd></dl>
-
-  
-
-  <p>Objects that implement the <code id="line-styles:canvaspathdrawingstyles"><a href="#canvaspathdrawingstyles">CanvasPathDrawingStyles</a></code> interface have attributes and
-  methods (defined in this section) that control how lines are treated by the object.</p>
-
-  <p>The <dfn id="dom-context-2d-linewidth-2"><code>lineWidth</code></dfn> attribute gives the
-  width of lines, in coordinate space units. On getting, it must return the current value. On
-  setting, zero, negative, infinite, and NaN values must be ignored, leaving the value unchanged;
-  other values must change the current value to the new value.</p>
-
-  <p>When the object implementing the <code id="line-styles:canvaspathdrawingstyles-2"><a href="#canvaspathdrawingstyles">CanvasPathDrawingStyles</a></code> interface is created, the
-  <code id="line-styles:dom-context-2d-linewidth-2-2"><a href="#dom-context-2d-linewidth-2">lineWidth</a></code> attribute must initially have the value
-  1.0.</p>
-
-  <hr/>
-
-  <p>The <dfn id="dom-context-2d-linecap-2"><code>lineCap</code></dfn> attribute defines the type
-  of endings that UAs will place on the end of lines. The three valid values are &quot;<code>butt</code>&quot;, &quot;<code>round</code>&quot;, and &quot;<code>square</code>&quot;.</p>
-
-  <p>On getting, it must return the current value. On setting, the current value must be changed
-  to the new value.</p>
-
-  <p>When the object implementing the <code id="line-styles:canvaspathdrawingstyles-3"><a href="#canvaspathdrawingstyles">CanvasPathDrawingStyles</a></code> interface is created, the
-  <code id="line-styles:dom-context-2d-linecap-2-2"><a href="#dom-context-2d-linecap-2">lineCap</a></code> attribute must initially have the value
-  &quot;<code>butt</code>&quot;.</p>
-
-  <hr/>
-
-  <p>The <dfn id="dom-context-2d-linejoin-2"><code>lineJoin</code></dfn> attribute defines the type
-  of corners that UAs will place where two lines meet. The three valid values are
-  &quot;<code>bevel</code>&quot;, &quot;<code>round</code>&quot;, and &quot;<code>miter</code>&quot;.</p>
-
-  <p>On getting, it must return the current value. On setting, the current value must be changed
-  to the new value.</p>
-
-  <p>When the object implementing the <code id="line-styles:canvaspathdrawingstyles-4"><a href="#canvaspathdrawingstyles">CanvasPathDrawingStyles</a></code> interface is created, the
-  <code id="line-styles:dom-context-2d-linejoin-2-2"><a href="#dom-context-2d-linejoin-2">lineJoin</a></code> attribute must initially have the value
-  &quot;<code>miter</code>&quot;.</p>
-
-  <hr/>
-
-  <p>When the <code id="line-styles:dom-context-2d-linejoin-2-3"><a href="#dom-context-2d-linejoin-2">lineJoin</a></code> attribute has the value &quot;<code>miter</code>&quot;, strokes use the miter limit ratio to decide how to render joins. The
-  miter limit ratio can be explicitly set using the <dfn id="dom-context-2d-miterlimit-2"><code>miterLimit</code></dfn> attribute. On getting, it must return
-  the current value. On setting, zero, negative, infinite, and NaN values must be ignored, leaving
-  the value unchanged; other values must change the current value to the new value.</p>
-  
-
-  <p>When the object implementing the <code id="line-styles:canvaspathdrawingstyles-5"><a href="#canvaspathdrawingstyles">CanvasPathDrawingStyles</a></code> interface is created, the
-  <code id="line-styles:dom-context-2d-miterlimit-2-2"><a href="#dom-context-2d-miterlimit-2">miterLimit</a></code> attribute must initially have the value
-  10.0.</p>
-
-  <hr/>
-
-  <p>Each <code id="line-styles:canvaspathdrawingstyles-6"><a href="#canvaspathdrawingstyles">CanvasPathDrawingStyles</a></code> object has a <dfn id="dash-list">dash list</dfn>, which is either
-  empty or consists of an even number of non-negative numbers. Initially, the <a href="#dash-list" id="line-styles:dash-list">dash list</a>
-  must be empty.</p>
-
-  <p>The <dfn id="dom-context-2d-setlinedash-2"><code>setLineDash()</code></dfn> method, when
-  invoked, must run these steps:</p>
-
-  <ol><li><p>Let <var>a</var> be the argument.</p></li><li><p>If any value in <var>a</var> is not finite (e.g. an Infinity or a NaN value), or
-   if any value is negative (less than zero), then abort these steps (without throwing an exception;
-   user agents could show a message on a developer console, though, as that would be helpful for
-   debugging).</p></li><li><p>If the number of elements in <var>a</var> is odd, then let <var>a</var>
-   be the concatenation of two copies of <var>a</var>.</p></li><li><p>Let the object's <a href="#dash-list" id="line-styles:dash-list-2">dash list</a> be <var>a</var>.</p></li></ol>
-
-  <p>When the <dfn id="dom-context-2d-getlinedash-2"><code>getLineDash()</code></dfn> method is
-  invoked, it must return a sequence whose values are the values of the object's <a href="#dash-list" id="line-styles:dash-list-3">dash
-  list</a>, in the same order.</p>
-
-  <p>It is sometimes useful to change the &quot;phase&quot; of the dash pattern, e.g. to achieve a &quot;marching
-  ants&quot; effect. The phase can be set using the <dfn id="dom-context-2d-linedashoffset-2"><code>lineDashOffset</code></dfn> attribute. On getting, it must
-  return the current value. On setting, infinite and NaN values must be ignored, leaving the value
-  unchanged; other values must change the current value to the new value.</p>
-
-  <p>When the object implementing the <code id="line-styles:canvaspathdrawingstyles-7"><a href="#canvaspathdrawingstyles">CanvasPathDrawingStyles</a></code> interface is created, the
-  <code id="line-styles:dom-context-2d-linedashoffset-2-2"><a href="#dom-context-2d-linedashoffset-2">lineDashOffset</a></code> attribute must initially have
-  the value 0.0.</p>
-
-  <hr/>
-
-  <p>When a user agent is to <dfn id="trace-a-path">trace a path</dfn>, given an object <var>style</var>
-  that implements the <code id="line-styles:canvaspathdrawingstyles-8"><a href="#canvaspathdrawingstyles">CanvasPathDrawingStyles</a></code> interface, it must run the following
-  algorithm. This algorithm returns a new <a href="#concept-path" id="line-styles:concept-path">path</a>.</p>
-
-  <ol><li><p>Let <var>path</var> be a copy of the path being traced.</p></li><li><p>Prune all zero-length <a href="#line-segments" id="line-styles:line-segments">line segments</a> from <var>path</var>.</p></li><li><p>Remove from <var>path</var> any subpaths containing no lines (i.e. subpaths with
-   just one point).</p></li><li><p>Replace each point in each subpath of <var>path</var> other than the first point
-   and the last point of each subpath by a <i>join</i> that joins the line leading to that point to
-   the line leading out of that point, such that the subpaths all consist of two points (a starting
-   point with a line leading out of it, and an ending point with a line leading into it), one or
-   more lines (connecting the points and the joins), and zero or more joins (each connecting one
-   line to another), connected together such that each subpath is a series of one or more lines with
-   a join between each one and a point on each end.</p></li><li><p>Add a straight closing line to each closed subpath in <var>path</var> connecting
-   the last point and the first point of that subpath; change the last point to a join (from the
-   previously last line to the newly added closing line), and change the first point to a join (from
-   the newly added closing line to the first line).</p>
-
-   </li><li><p>If the <var>styles</var> <a href="#dash-list" id="line-styles:dash-list-4">dash list</a> is empty, then jump to the step
-   labeled <i>convert</i>.</p></li><li><p>Let <var>pattern width</var> be the concatenation of all the entries of the <var>styles</var> <a href="#dash-list" id="line-styles:dash-list-5">dash list</a>, in coordinate space units.</p>
-
-   </li><li><p>For each subpath <var>subpath</var> in <var>path</var>, run the
-   following substeps. These substeps mutate the subpaths in <var>path</var> <i>in
-   vivo</i>.</p>
-
-    <ol><li><p>Let <var>subpath width</var> be the length of all the lines of <var>subpath</var>, in coordinate space units.</p>
-
-     </li><li><p>Let <var>offset</var> be the value of the <var>styles</var> <code id="line-styles:dom-context-2d-linedashoffset-2-3"><a href="#dom-context-2d-linedashoffset-2">lineDashOffset</a></code>, in coordinate space
-     units.</p></li><li>
-
-      <p>While <var>offset</var> is greater than <var>pattern width</var>,
-      decrement it by <var>pattern width</var>.</p>
-
-      <p>While <var>offset</var> is less than zero, increment it by <var>pattern
-      width</var>.</p>
-
-     </li><li><p>Define <var>L</var> to be a linear coordinate line defined along all lines in
-     <var>subpath</var>, such that the start of the first line in the subpath is defined
-     as coordinate 0, and the end of the last line in the subpath is defined as coordinate <var>subpath width</var>.</p></li><li><p>Let <var>position</var> be zero minus <var>offset</var>.</p></li><li><p>Let <var>index</var> be 0.</p></li><li><p>Let <var>current state</var> be <i>off</i> (the other states being <i>on</i>
-     and <i>zero-on</i>).</p></li><li><p><i>Dash on</i>: Let <var>segment length</var> be
-     the value of the <var>styles</var> <a href="#dash-list" id="line-styles:dash-list-6">dash
-     list</a>'s <var>index</var>th entry.</p></li><li><p>Increment <var>position</var> by <var>segment length</var>.</p></li><li><p>If <var>position</var> is greater than <var>subpath width</var>,
-     then end these substeps for this subpath and start them again for the next subpath; if there
-     are no more subpaths, then jump to the step labeled <i>convert</i> instead.</p></li><li><p>If <var>segment length</var> is non-zero, then let <var>current state</var> be
-     <i>on</i>.</p></li><li><p>Increment <var>index</var> by one.</p></li><li><p><i>Dash off</i>: Let <var>segment
-     length</var> be the value of the <var>styles</var> <a href="#dash-list" id="line-styles:dash-list-7">dash list</a>'s <var>index</var>th entry.</p></li><li><p>Let <var>start</var> be the offset <var>position</var> on <var>L</var>.</p></li><li><p>Increment <var>position</var> by <var>segment length</var>.</p></li><li><p>If <var>position</var> is less than zero, then jump to the step labeled
-     <i>post-cut</i>.</p></li><li><p>If <var>start</var> is less than zero, then let <var>start</var> be
-     zero.</p></li><li><p>If <var>position</var> is greater than <var>subpath width</var>,
-     then let <var>end</var> be the offset <var>subpath width</var> on <var>L</var>. Otherwise, let <var>end</var> be the offset <var>position</var> on <var>L</var>.</p></li><li>
-
-      <p>Jump to the first appropriate step:</p>
-
-      <dl class="switch"><dt>If <var>segment length</var> is zero and <var>current state</var> is
-       <i>off</i></dt><dd>
-
-        <p>Do nothing, just continue to the next step.</p>
-
-       </dd><dt>If <var>current state</var> is <i>off</i></dt><dd>
-
-        <p>Cut the line on which <var>end</var> finds itself short at <var>end</var> and place a point there, cutting the subpath that it was in in two;
-        remove all line segments, joins, points, and subpaths that are between <var>start</var> and <var>end</var>; and finally place a single point at <var>start</var> with no lines connecting to it.</p>
-
-        <p>The point has a <i>directionality</i> for the purposes of drawing line caps (see below).
-        The directionality is the direction that the original line had at that point (i.e. when <var>L</var> was defined above).</p>
-
-       </dd><dt>Otherwise</dt><dd>
-
-        <p>Cut the line on which <var>start</var> finds itself into two at <var>start</var> and place a point there, cutting the subpath that it was in in two, and
-        similarly cut the line on which <var>end</var> finds itself short at <var>end</var> and place a point there, cutting the subpath that <em>it</em> was in in
-        two, and then remove all line segments, joins, points, and subpaths that are between <var>start</var> and <var>end</var>.</p>
-
-        <p>If <var>start</var> and <var>end</var> are the same point, then this
-        results in just the line being cut in two and two points being inserted there, with nothing
-        being removed, unless a join also happens to be at that point, in which case the join must
-        be removed.</p>
-
-       </dd></dl>
-
-     </li><li><p><i>Post-cut</i>: If <var>position</var> is greater than <var>subpath width</var>, then jump to the step labeled <i>convert</i>.</p></li><li><p>If <var>segment length</var> is greater than zero, then let
-     <var>positioned-at-on-dash</var> be false.</p></li><li><p>Increment <var>index</var> by one. If it is equal to the number of entries in
-     the <var>styles</var> <a href="#dash-list" id="line-styles:dash-list-8">dash list</a>, then let <var>index</var> be
-     0.</p></li><li><p>Return to the step labeled <i>dash on</i>.</p></li></ol>
-
-   </li><li>
-
-    <p><i>Convert</i>: This is the step that converts the path to a new path that represents its
-    stroke.</p>
-
-    <p>Create a new <a href="#concept-path" id="line-styles:concept-path-2">path</a> that describes the edge of the areas
-    that would be covered if a straight line of length equal to the <var>styles</var>
-    <code id="line-styles:dom-context-2d-linewidth-2-3"><a href="#dom-context-2d-linewidth-2">lineWidth</a></code> was swept along each subpath in <var>path</var> while being kept at an angle such that the line is orthogonal to the path
-    being swept, replacing each point with the end cap necessary to satisfy the <var>styles</var> <code id="line-styles:dom-context-2d-linecap-2-3"><a href="#dom-context-2d-linecap-2">lineCap</a></code> attribute as
-    described previously and elaborated below, and replacing each join with the join necessary to
-    satisfy the <var>styles</var> <code id="line-styles:dom-context-2d-linejoin-2-4"><a href="#dom-context-2d-linejoin-2">lineJoin</a></code>
-    type, as defined below.</p>
-
-    <p><strong>Caps</strong>: Each point has a flat edge perpendicular to the direction of the line
-    coming out of it. This is then augmented according to the value of the <var>styles</var> <code id="line-styles:dom-context-2d-linecap-2-4"><a href="#dom-context-2d-linecap-2">lineCap</a></code>. The &quot;<code>butt</code>&quot; value means that no additional line cap is added. The &quot;<code>round</code>&quot; value means that a semi-circle with the diameter equal to the <var>styles</var> <code id="line-styles:dom-context-2d-linewidth-2-4"><a href="#dom-context-2d-linewidth-2">lineWidth</a></code> width must
-    additionally be placed on to the line coming out of each point. The &quot;<code>square</code>&quot; value means that a rectangle with the length of the <var>styles</var> <code id="line-styles:dom-context-2d-linewidth-2-5"><a href="#dom-context-2d-linewidth-2">lineWidth</a></code> width and the
-    width of half the <var>styles</var> <code id="line-styles:dom-context-2d-linewidth-2-6"><a href="#dom-context-2d-linewidth-2">lineWidth</a></code> width, placed flat against the edge
-    perpendicular to the direction of the line coming out of the point, must be added at each
-    point.</p>
-
-    <p>Points with no lines coming out of them must have two caps placed back-to-back as if it was
-    really two points connected to each other by an infinitesimally short straight line in the
-    direction of the point's <i>directionality</i> (as defined above).</p>
-
-    <p><strong>Joins</strong>: In addition to the point where a join occurs, two additional points
-    are relevant to each join, one for each line: the two corners found half the line width away
-    from the join point, one perpendicular to each line, each on the side furthest from the other
-    line.</p>
-
-    <p>A triangle connecting these two opposite corners with a straight line, with the third point
-    of the triangle being the join point, must be added at all joins. The <code id="line-styles:dom-context-2d-linejoin-2-5"><a href="#dom-context-2d-linejoin-2">lineJoin</a></code> attribute controls whether anything else is
-    rendered. The three aforementioned values have the following meanings:</p>
-
-    <p>The &quot;<code>bevel</code>&quot; value means that this is all that is rendered at
-    joins.</p>
-
-    <p>The &quot;<code>round</code>&quot; value means that an arc connecting the two aforementioned
-    corners of the join, abutting (and not overlapping) the aforementioned triangle, with the
-    diameter equal to the line width and the origin at the point of the join, must be added at
-    joins.</p>
-
-    <p>The &quot;<code>miter</code>&quot; value means that a second triangle must (if it can given
-    the miter length) be added at the join, with one line being the line between the two
-    aforementioned corners, abutting the first triangle, and the other two being continuations of
-    the outside edges of the two joining lines, as long as required to intersect without going over
-    the miter length.</p>
-
-    <p>The miter length is the distance from the point where the join occurs to the intersection of
-    the line edges on the outside of the join. The miter limit ratio is the maximum allowed ratio of
-    the miter length to half the line width. If the miter length would cause the miter limit ratio
-    (as set by the <var>style</var> <code id="line-styles:dom-context-2d-miterlimit-2-3"><a href="#dom-context-2d-miterlimit-2">miterLimit</a></code> attribute) to be exceeded, then this second
-    triangle must not be added.</p> 
-
-
-
-    <p>The subpaths in the newly created path must be oriented such that for any point, the number
-    of times a half-infinite straight line drawn from that point crosses a subpath is even if and
-    only if the number of times a half-infinite straight line drawn from that same point crosses a
-    subpath going in one direction is equal to the number of times it crosses a subpath going in the
-    other direction.</p>
-
-   </li><li><p>Return the newly created path.</p></li></ol>
-
-
-
-  
-
-
-  <h6 id="text-styles"><span class="secno">4.12.5.1.4</span> Text styles<a class="self-link" href="#text-styles"/></h6>
-
-  <dl class="domintro"><dt><var>context</var> . <code id="dom-context-2d-font"><a href="#dom-context-2d-font-2">font</a></code> [ = <var>value</var> ]</dt><dt><var>styles</var> . <code id="text-styles:dom-context-2d-font-2"><a href="#dom-context-2d-font-2">font</a></code> [ = <var>value</var> ]</dt><dd>
-
-    <p>Returns the current font settings.</p>
-
-    <p>Can be set, to change the font. The syntax is the same as for the CSS <a data-x-internal="'font'" href="https://drafts.csswg.org/css-fonts/#font-prop" id="text-styles:'font'">'font'</a>
-    property; values that cannot be parsed as CSS font values are ignored.</p>
-
-    <p>Relative keywords and lengths are computed relative to the font of the <code id="text-styles:the-canvas-element"><a href="#the-canvas-element">canvas</a></code>
-    element.</p>
-
-   </dd><dt><var>context</var> . <code id="dom-context-2d-textalign"><a href="#dom-context-2d-textalign-2">textAlign</a></code> [ = <var>value</var> ]</dt><dt><var>styles</var> . <code id="text-styles:dom-context-2d-textalign-2"><a href="#dom-context-2d-textalign-2">textAlign</a></code> [ = <var>value</var> ]</dt><dd>
-
-    <p>Returns the current text alignment settings.</p>
-
-    <p>Can be set, to change the alignment. The possible values are and their meanings are given
-    below. Other values are ignored. The default is &quot;<code>start</code>&quot;.</p>
-
-   </dd><dt><var>context</var> . <code id="dom-context-2d-textbaseline"><a href="#dom-context-2d-textbaseline-2">textBaseline</a></code> [ = <var>value</var> ]</dt><dt><var>styles</var> . <code id="text-styles:dom-context-2d-textbaseline-2"><a href="#dom-context-2d-textbaseline-2">textBaseline</a></code> [ = <var>value</var> ]</dt><dd>
-
-    <p>Returns the current baseline alignment settings.</p>
-
-    <p>Can be set, to change the baseline alignment. The possible values and their meanings are
-    given below. Other values are ignored. The default is &quot;<code id="text-styles:dom-context-2d-textbaseline-alphabetic"><a href="#dom-context-2d-textbaseline-alphabetic">alphabetic</a></code>&quot;.</p>
-
-   </dd><dt><var>context</var> . <code id="dom-context-2d-direction"><a href="#dom-context-2d-direction-2">direction</a></code> [ = <var>value</var> ]</dt><dt><var>styles</var> . <code id="text-styles:dom-context-2d-direction-2"><a href="#dom-context-2d-direction-2">direction</a></code> [ = <var>value</var> ]</dt><dd>
-
-    <p>Returns the current directionality.</p>
-
-    <p>Can be set, to change the directionality. The possible values and their meanings are given
-    below. Other values are ignored. The default is &quot;<code id="text-styles:dom-context-2d-direction-inherit"><a href="#dom-context-2d-direction-inherit">inherit</a></code>&quot;.</p>
-
-   </dd></dl>
-
-  
-
-  <p>Objects that implement the <code id="text-styles:canvastextdrawingstyles"><a href="#canvastextdrawingstyles">CanvasTextDrawingStyles</a></code> interface have attributes
-  (defined in this section) that control how text is laid out (rasterized or outlined) by the
-  object. Such objects can also have a <dfn id="font-style-source-object">font style source object</dfn>. For
-  <code id="text-styles:canvasrenderingcontext2d"><a href="#canvasrenderingcontext2d">CanvasRenderingContext2D</a></code> objects, this is the <code id="text-styles:the-canvas-element-2"><a href="#the-canvas-element">canvas</a></code> element
-  referenced by the context's canvas property.</p>
-
-  
-
-  <p>The <dfn id="dom-context-2d-font-2"><code>font</code></dfn> IDL attribute, on setting, must
-  be <a data-x-internal="parse-something-according-to-a-css-grammar" href="https://drafts.csswg.org/css-syntax/#parse-grammar" id="text-styles:parse-something-according-to-a-css-grammar">parsed as a CSS &lt;'font'&gt;
-  value</a> (but without supporting property-independent style sheet syntax like 'inherit'), and
-  the resulting font must be assigned to the context, with the <a data-x-internal="'line-height'" href="https://drafts.csswg.org/css2/visudet.html#propdef-line-height" id="text-styles:'line-height'">'line-height'</a> component
-  forced to 'normal', with the <a data-x-internal="'font-size'" href="https://drafts.csswg.org/css-fonts/#font-size-prop" id="text-styles:'font-size'">'font-size'</a> component converted to <a data-x-internal="'px'" href="https://drafts.csswg.org/css-values/#px" id="text-styles:'px'">CSS pixels</a>, and with system fonts being computed to explicit values. If the
-  new value is syntactically incorrect (including using property-independent style sheet syntax like
-  'inherit' or 'initial'), then it must be ignored, without assigning a new font value. <a href="https://html.spec.whatwg.org/multipage/references.html#refsCSS">[CSS]</a></p>
-
-  <p>Font family names must be interpreted in the context of the <a href="#font-style-source-object" id="text-styles:font-style-source-object">font style source
-  object</a> when the font is to be used; any fonts embedded using <code>@font-face</code> or loaded using <code id="text-styles:fontface"><a href="https://html.spec.whatwg.org/multipage/infrastructure.html#fontface">FontFace</a></code> objects that are visible to the
-  <a href="#font-style-source-object" id="text-styles:font-style-source-object-2">font style source object</a> must therefore be available once they are loaded. (Each <a href="#font-style-source-object" id="text-styles:font-style-source-object-3">font style source
-  object</a> has a <a data-x-internal="font-source" href="https://drafts.csswg.org/css-font-loading/#font-source" id="text-styles:font-source">font source</a>, which determines what fonts are available.) If a font
-  is used before it is fully loaded, or if the <a href="#font-style-source-object" id="text-styles:font-style-source-object-4">font style source object</a> does not have
-  that font in scope at the time the font is to be used, then it must be treated as if it was an
-  unknown font, falling back to another as described by the relevant CSS specifications. <a href="https://html.spec.whatwg.org/multipage/references.html#refsCSSFONTS">[CSSFONTS]</a> <a href="https://html.spec.whatwg.org/multipage/references.html#refsCSSFONTLOAD">[CSSFONTLOAD]</a></p>
-
-  <p>On getting, the <code id="text-styles:dom-context-2d-font-2-2"><a href="#dom-context-2d-font-2">font</a></code> attribute must return the <a data-x-internal="serializing-a-css-value" href="https://drafts.csswg.org/cssom/#serialize-a-css-value" id="text-styles:serializing-a-css-value">serialized form</a> of the current font of the context (with
-  no <a data-x-internal="'line-height'" href="https://drafts.csswg.org/css2/visudet.html#propdef-line-height" id="text-styles:'line-height'-2">'line-height'</a> component). <a href="https://html.spec.whatwg.org/multipage/references.html#refsCSSOM">[CSSOM]</a></p>
-
-  <div class="example">
-
-   <p>For example, after the following statement:</p>
-
-   <pre>context.font = 'italic 400 12px/2 Unknown Font, sans-serif';</pre>
-
-   <p>...the expression <code>context.font</code> would evaluate to the string &quot;<code>italic 12px &quot;Unknown Font&quot;, sans-serif</code>&quot;. The &quot;400&quot;
-   font-weight doesn't appear because that is the default value. The line-height doesn't appear
-   because it is forced to &quot;normal&quot;, the default value.</p>
-
-  </div>
-
-  <p>When the object implementing the <code id="text-styles:canvastextdrawingstyles-2"><a href="#canvastextdrawingstyles">CanvasTextDrawingStyles</a></code> interface is created, the
-  font of the context must be set to 10px sans-serif. When the <a data-x-internal="'font-size'" href="https://drafts.csswg.org/css-fonts/#font-size-prop" id="text-styles:'font-size'-2">'font-size'</a> component is
-  set to lengths using percentages, <a data-x-internal="'em'" href="https://drafts.csswg.org/css-values/#em" id="text-styles:'em'">'em'</a> or <a data-x-internal="'ex'" href="https://drafts.csswg.org/css-values/#ex" id="text-styles:'ex'">'ex'</a> units, or the 'larger' or
-  'smaller' keywords, these must be interpreted relative to the <a data-x-internal="computed-value" href="https://drafts.csswg.org/css-cascade/#computed-value" id="text-styles:computed-value">computed value</a> of the
-  <a data-x-internal="'font-size'" href="https://drafts.csswg.org/css-fonts/#font-size-prop" id="text-styles:'font-size'-3">'font-size'</a> property of the <a href="#font-style-source-object" id="text-styles:font-style-source-object-5">font style source object</a> at the time that
-  the attribute is set, if it is an element. When the <a data-x-internal="'font-weight'" href="https://drafts.csswg.org/css-fonts/#font-weight-prop" id="text-styles:'font-weight'">'font-weight'</a> component is set to
-  the relative values 'bolder' and 'lighter', these must be interpreted relative to the
-  <a data-x-internal="computed-value" href="https://drafts.csswg.org/css-cascade/#computed-value" id="text-styles:computed-value-2">computed value</a> of the <a data-x-internal="'font-weight'" href="https://drafts.csswg.org/css-fonts/#font-weight-prop" id="text-styles:'font-weight'-2">'font-weight'</a> property of the <a href="#font-style-source-object" id="text-styles:font-style-source-object-6">font style
-  source object</a> at the time that the attribute is set, if it is an element. If the <a data-x-internal="computed-value" href="https://drafts.csswg.org/css-cascade/#computed-value" id="text-styles:computed-value-3">computed values</a> are undefined for a particular case (e.g. because
-  the <a href="#font-style-source-object" id="text-styles:font-style-source-object-7">font style source object</a> is not an element or is not <a href="https://html.spec.whatwg.org/multipage/rendering.html#being-rendered" id="text-styles:being-rendered">being
-  rendered</a>), then the relative keywords must be interpreted relative to the normal-weight
-  10px sans-serif default.</p>
-
-  <p>The <dfn id="dom-context-2d-textalign-2"><code>textAlign</code></dfn> IDL attribute, on
-  getting, must return the current value. On setting, the current value must be changed to the new
-  value. When the object implementing the <code id="text-styles:canvastextdrawingstyles-3"><a href="#canvastextdrawingstyles">CanvasTextDrawingStyles</a></code> interface is
-  created, the <code id="text-styles:dom-context-2d-textalign-2-2"><a href="#dom-context-2d-textalign-2">textAlign</a></code> attribute must initially
-  have the value <code id="text-styles:dom-context-2d-textalign-start"><a href="#dom-context-2d-textalign-start">start</a></code>.</p>
-
-  <p>The <dfn id="dom-context-2d-textbaseline-2"><code>textBaseline</code></dfn> IDL attribute, on
-  getting, must return the current value. On setting, the current value must be changed to the new
-  value. When the object implementing the <code id="text-styles:canvastextdrawingstyles-4"><a href="#canvastextdrawingstyles">CanvasTextDrawingStyles</a></code> interface is
-  created, the <code id="text-styles:dom-context-2d-textbaseline-2-2"><a href="#dom-context-2d-textbaseline-2">textBaseline</a></code> attribute must
-  initially have the value <code id="text-styles:dom-context-2d-textbaseline-alphabetic-2"><a href="#dom-context-2d-textbaseline-alphabetic">alphabetic</a></code>.</p>
-
-  <p>The <dfn id="dom-context-2d-direction-2"><code>direction</code></dfn> IDL attribute, on
-  getting, must return the current value. On setting, the current value must be changed to the new
-  value. When the object implementing the <code id="text-styles:canvastextdrawingstyles-5"><a href="#canvastextdrawingstyles">CanvasTextDrawingStyles</a></code> interface is
-  created, the <code id="text-styles:dom-context-2d-direction-2-2"><a href="#dom-context-2d-direction-2">direction</a></code> attribute must initially
-  have the value &quot;<code id="text-styles:dom-context-2d-direction-inherit-2"><a href="#dom-context-2d-direction-inherit">inherit</a></code>&quot;.</p>
-
-  
-
-  <p>The <code id="text-styles:dom-context-2d-textalign-2-3"><a href="#dom-context-2d-textalign-2">textAlign</a></code> attribute's allowed keywords are
-  as follows:</p>
-
-  <dl><dt><dfn id="dom-context-2d-textalign-start"><code>start</code></dfn>
-   </dt><dd><p>Align to the start edge of the text (left side in left-to-right text, right side in
-   right-to-left text).</p></dd><dt><dfn id="dom-context-2d-textalign-end"><code>end</code></dfn>
-   </dt><dd><p>Align to the end edge of the text (right side in left-to-right text, left side in
-   right-to-left text).</p></dd><dt><dfn id="dom-context-2d-textalign-left"><code>left</code></dfn>
-   </dt><dd><p>Align to the left.</p></dd><dt><dfn id="dom-context-2d-textalign-right"><code>right</code></dfn>
-   </dt><dd><p>Align to the right.</p></dd><dt><dfn id="dom-context-2d-textalign-center"><code>center</code></dfn>
-   </dt><dd><p>Align to the center.</p></dd></dl>
-
-  <p>The <code id="text-styles:dom-context-2d-textbaseline-2-3"><a href="#dom-context-2d-textbaseline-2">textBaseline</a></code>
-  attribute's allowed keywords correspond to alignment points in the
-  font:</p>
-
-  <p><img alt="The top of the em square is roughly at the top of the glyphs in a font, the hanging baseline is where some glyphs like आ are anchored, the middle is half-way between the top of the em square and the bottom of the em square, the alphabetic baseline is where characters like Á, ÿ, f, and Ω are anchored, the ideographic baseline is where glyphs like 私 and 達 are anchored, and the bottom of the em square is roughly at the bottom of the glyphs in a font. The top and bottom of the bounding box can be far from these baselines, due to glyphs extending far outside the em square." height="300" src="https://html.spec.whatwg.org/images/baselines.png" width="738"/></p>
-
-  <p>The keywords map to these alignment points as follows:</p>
-
-  <dl><dt><dfn id="dom-context-2d-textbaseline-top"><code>top</code></dfn>
-   </dt><dd>The top of the em square</dd><dt><dfn id="dom-context-2d-textbaseline-hanging"><code>hanging</code></dfn>
-   </dt><dd>The hanging baseline</dd><dt><dfn id="dom-context-2d-textbaseline-middle"><code>middle</code></dfn>
-   </dt><dd>The middle of the em square</dd><dt><dfn id="dom-context-2d-textbaseline-alphabetic"><code>alphabetic</code></dfn>
-   </dt><dd>The alphabetic baseline</dd><dt><dfn id="dom-context-2d-textbaseline-ideographic"><code>ideographic</code></dfn>
-   </dt><dd>The ideographic baseline</dd><dt><dfn id="dom-context-2d-textbaseline-bottom"><code>bottom</code></dfn>
-   </dt><dd>The bottom of the em square</dd></dl>
-
-  <p>The <code id="text-styles:dom-context-2d-direction-2-3"><a href="#dom-context-2d-direction-2">direction</a></code> attribute's allowed keywords are
-  as follows:</p>
-
-  <dl><dt><dfn id="dom-context-2d-direction-ltr"><code>ltr</code></dfn>
-
-   </dt><dd><p>Treat input to the <a href="#text-preparation-algorithm" id="text-styles:text-preparation-algorithm">text preparation algorithm</a> as left-to-right text.</p></dd><dt><dfn id="dom-context-2d-direction-rtl"><code>rtl</code></dfn>
-
-   </dt><dd><p>Treat input to the <a href="#text-preparation-algorithm" id="text-styles:text-preparation-algorithm-2">text preparation algorithm</a> as right-to-left text.</p></dd><dt><dfn id="dom-context-2d-direction-inherit"><code>inherit</code></dfn>
-
-   </dt><dd><p>Default to the directionality of the <code id="text-styles:the-canvas-element-3"><a href="#the-canvas-element">canvas</a></code> element or <code id="text-styles:document"><a href="https://html.spec.whatwg.org/multipage/dom.html#document">Document</a></code>
-   as appropriate.</p></dd></dl>
-
-  <p>The <dfn id="text-preparation-algorithm">text preparation algorithm</dfn> is as follows. It takes as input a string <var>text
-  </var>, a <code id="text-styles:canvastextdrawingstyles-6"><a href="#canvastextdrawingstyles">CanvasTextDrawingStyles</a></code> object <var>target</var>, and an optional length
-  <var>maxWidth</var>. It returns an array of glyph shapes, each positioned on a common coordinate
-  space, a <var>physical alignment</var> whose value is one of <i>left</i>, <i>right</i>, and
-  <i>center</i>, and an <a data-x-internal="inline-box" href="https://drafts.csswg.org/css2/visuren.html#inline-box" id="text-styles:inline-box">inline box</a>. (Most callers of this algorithm ignore the
-  <var>physical alignment</var> and the <a data-x-internal="inline-box" href="https://drafts.csswg.org/css2/visuren.html#inline-box" id="text-styles:inline-box-2">inline box</a>.)</p>
-
-  <ol><li><p>If <var>maxWidth</var> was provided but is less than or equal to zero or equal to NaN,
-   then return an empty array.</p></li><li><p>Replace all <a data-x-internal="space-characters" href="https://infra.spec.whatwg.org/#ascii-whitespace" id="text-styles:space-characters">ASCII whitespace</a> in <var>text</var> with U+0020 SPACE
-   characters.</p></li><li><p>Let <var>font</var> be the current font of <var>target</var>, as given
-   by that object's <code id="text-styles:dom-context-2d-font-2-3"><a href="#dom-context-2d-font-2">font</a></code> attribute.</p></li><li>
-
-    <p>Apply the appropriate step from the following list to determine the value of <var>direction</var>:</p>
-
-    <dl class="switch"><dt>If the <var>target</var> object's <code id="text-styles:dom-context-2d-direction-2-4"><a href="#dom-context-2d-direction-2">direction</a></code> attribute has the value &quot;<code id="text-styles:dom-context-2d-direction-ltr"><a href="#dom-context-2d-direction-ltr">ltr</a></code>&quot;</dt><dd>Let <var>direction</var> be '<a href="https://html.spec.whatwg.org/multipage/dom.html#concept-ltr" id="text-styles:concept-ltr">ltr</a>'.</dd><dt>If the <var>target</var> object's <code id="text-styles:dom-context-2d-direction-2-5"><a href="#dom-context-2d-direction-2">direction</a></code> attribute has the value &quot;<code id="text-styles:dom-context-2d-direction-rtl"><a href="#dom-context-2d-direction-rtl">rtl</a></code>&quot;</dt><dd>Let <var>direction</var> be '<a href="https://html.spec.whatwg.org/multipage/dom.html#concept-rtl" id="text-styles:concept-rtl">rtl</a>'.</dd><dt>If the <var>target</var> object's <a href="#font-style-source-object" id="text-styles:font-style-source-object-8">font style source object</a> is an
-     element</dt><dd>Let <var>direction</var> be <a href="https://html.spec.whatwg.org/multipage/dom.html#the-directionality" id="text-styles:the-directionality">the directionality</a> of the <var>target</var> object's <a href="#font-style-source-object" id="text-styles:font-style-source-object-9">font style source object</a>.</dd><dt>If the <var>target</var> object's <a href="#font-style-source-object" id="text-styles:font-style-source-object-10">font style source object</a> is a
-     <code id="text-styles:document-2"><a href="https://html.spec.whatwg.org/multipage/dom.html#document">Document</a></code> with a non-null <a data-x-internal="document-element" href="https://dom.spec.whatwg.org/#document-element" id="text-styles:document-element">document element</a></dt><dd>Let <var>direction</var> be <a href="https://html.spec.whatwg.org/multipage/dom.html#the-directionality" id="text-styles:the-directionality-2">the directionality</a> of the <var>target</var>
-     object's <a href="#font-style-source-object" id="text-styles:font-style-source-object-11">font style source object</a>'s <a data-x-internal="document-element" href="https://dom.spec.whatwg.org/#document-element" id="text-styles:document-element-2">document element</a>.</dd><dt>Otherwise</dt><dd>Let <var>direction</var> be '<a href="https://html.spec.whatwg.org/multipage/dom.html#concept-ltr" id="text-styles:concept-ltr-2">ltr</a>'.</dd></dl>
-
-   </li><li><p>Form a hypothetical infinitely-wide CSS <a data-x-internal="line-box" href="https://drafts.csswg.org/css2/visuren.html#line-box" id="text-styles:line-box">line box</a> containing a single
-   <a data-x-internal="inline-box" href="https://drafts.csswg.org/css2/visuren.html#inline-box" id="text-styles:inline-box-3">inline box</a> containing the text <var>text</var>, with all the properties at their
-   initial values except the <a data-x-internal="'font'" href="https://drafts.csswg.org/css-fonts/#font-prop" id="text-styles:'font'-2">'font'</a> property of the <a data-x-internal="inline-box" href="https://drafts.csswg.org/css2/visuren.html#inline-box" id="text-styles:inline-box-4">inline box</a> set to
-   <var>font</var>, the <a data-x-internal="'direction'" href="https://drafts.csswg.org/css-writing-modes/#direction" id="text-styles:'direction'">'direction'</a> property of the <a data-x-internal="inline-box" href="https://drafts.csswg.org/css2/visuren.html#inline-box" id="text-styles:inline-box-5">inline box</a> set to
-   <var>direction</var>, and the <a data-x-internal="'white-space'" href="https://drafts.csswg.org/css-text/#white-space-property" id="text-styles:'white-space'">'white-space'</a> property set to 'pre'. <a href="https://html.spec.whatwg.org/multipage/references.html#refsCSS">[CSS]</a></p></li><li><p>If <var>maxWidth</var> was provided and the hypothetical width of the
-   <a data-x-internal="inline-box" href="https://drafts.csswg.org/css2/visuren.html#inline-box" id="text-styles:inline-box-6">inline box</a> in the hypothetical <a data-x-internal="line-box" href="https://drafts.csswg.org/css2/visuren.html#line-box" id="text-styles:line-box-2">line box</a> is greater than
-   <var>maxWidth</var> <a data-x-internal="'px'" href="https://drafts.csswg.org/css-values/#px" id="text-styles:'px'-2">CSS pixels</a>, then change <var>font</var> to have a
-   more condensed font (if one is available or if a reasonably readable one can be synthesized by
-   applying a horizontal scale factor to the font) or a smaller font, and return to the previous
-   step.</p></li><li>
-
-    <p>The <var>anchor point</var> is a point on the <a data-x-internal="inline-box" href="https://drafts.csswg.org/css2/visuren.html#inline-box" id="text-styles:inline-box-7">inline box</a>, and the <var>physical
-    alignment</var> is one of the values <i>left</i>, <i>right</i>, and <i>center</i>. These
-    variables are determined by the <code id="text-styles:dom-context-2d-textalign-2-4"><a href="#dom-context-2d-textalign-2">textAlign</a></code> and
-    <code id="text-styles:dom-context-2d-textbaseline-2-4"><a href="#dom-context-2d-textbaseline-2">textBaseline</a></code> values as follows:</p>
-
-    <p>Horizontal position:</p>
-
-    <dl><dt>If <code id="text-styles:dom-context-2d-textalign-2-5"><a href="#dom-context-2d-textalign-2">textAlign</a></code> is <code id="text-styles:dom-context-2d-textalign-left"><a href="#dom-context-2d-textalign-left">left</a></code></dt><dt>If <code id="text-styles:dom-context-2d-textalign-2-6"><a href="#dom-context-2d-textalign-2">textAlign</a></code> is <code id="text-styles:dom-context-2d-textalign-start-2"><a href="#dom-context-2d-textalign-start">start</a></code> and <var>direction</var> is
-     'ltr'</dt><dt>If <code id="text-styles:dom-context-2d-textalign-2-7"><a href="#dom-context-2d-textalign-2">textAlign</a></code> is <code id="text-styles:dom-context-2d-textalign-end"><a href="#dom-context-2d-textalign-end">end</a></code> and <var>direction</var> is 'rtl'</dt><dd>Let the <var>anchor point</var>'s horizontal position be the left edge of the
-     <a data-x-internal="inline-box" href="https://drafts.csswg.org/css2/visuren.html#inline-box" id="text-styles:inline-box-8">inline box</a>, and let <var>physical alignment</var> be <i>left</i>.</dd><dt>If <code id="text-styles:dom-context-2d-textalign-2-8"><a href="#dom-context-2d-textalign-2">textAlign</a></code> is <code id="text-styles:dom-context-2d-textalign-right"><a href="#dom-context-2d-textalign-right">right</a></code></dt><dt>If <code id="text-styles:dom-context-2d-textalign-2-9"><a href="#dom-context-2d-textalign-2">textAlign</a></code> is <code id="text-styles:dom-context-2d-textalign-end-2"><a href="#dom-context-2d-textalign-end">end</a></code> and <var>direction</var> is 'ltr'</dt><dt>If <code id="text-styles:dom-context-2d-textalign-2-10"><a href="#dom-context-2d-textalign-2">textAlign</a></code> is <code id="text-styles:dom-context-2d-textalign-start-3"><a href="#dom-context-2d-textalign-start">start</a></code> and <var>direction</var> is
-     'rtl'</dt><dd>Let the <var>anchor point</var>'s horizontal position be the right edge of the
-     <a data-x-internal="inline-box" href="https://drafts.csswg.org/css2/visuren.html#inline-box" id="text-styles:inline-box-9">inline box</a>, and let <var>physical alignment</var> be <i>right</i>.</dd><dt>If <code id="text-styles:dom-context-2d-textalign-2-11"><a href="#dom-context-2d-textalign-2">textAlign</a></code> is <code id="text-styles:dom-context-2d-textalign-center"><a href="#dom-context-2d-textalign-center">center</a></code></dt><dd>Let the <var>anchor point</var>'s horizontal position be half way between the left
-     and right edges of the <a data-x-internal="inline-box" href="https://drafts.csswg.org/css2/visuren.html#inline-box" id="text-styles:inline-box-10">inline box</a>, and let <var>physical alignment</var> be
-     <i>center</i>.</dd></dl>
-
-    <p>Vertical position:</p>
-
-    <dl><dt>If <code id="text-styles:dom-context-2d-textbaseline-2-5"><a href="#dom-context-2d-textbaseline-2">textBaseline</a></code> is <code id="text-styles:dom-context-2d-textbaseline-top"><a href="#dom-context-2d-textbaseline-top">top</a></code></dt><dd>Let the <var>anchor point</var>'s vertical position be the top of the em box of
-     the first available font of the <a data-x-internal="inline-box" href="https://drafts.csswg.org/css2/visuren.html#inline-box" id="text-styles:inline-box-11">inline box</a>.</dd><dt>If <code id="text-styles:dom-context-2d-textbaseline-2-6"><a href="#dom-context-2d-textbaseline-2">textBaseline</a></code> is <code id="text-styles:dom-context-2d-textbaseline-hanging"><a href="#dom-context-2d-textbaseline-hanging">hanging</a></code></dt><dd>Let the <var>anchor point</var>'s vertical position be the hanging baseline of the
-     first available font of the <a data-x-internal="inline-box" href="https://drafts.csswg.org/css2/visuren.html#inline-box" id="text-styles:inline-box-12">inline box</a>.</dd><dt>If <code id="text-styles:dom-context-2d-textbaseline-2-7"><a href="#dom-context-2d-textbaseline-2">textBaseline</a></code> is <code id="text-styles:dom-context-2d-textbaseline-middle"><a href="#dom-context-2d-textbaseline-middle">middle</a></code></dt><dd>Let the <var>anchor point</var>'s vertical position be half way between the bottom
-     and the top of the em box of the first available font of the <a data-x-internal="inline-box" href="https://drafts.csswg.org/css2/visuren.html#inline-box" id="text-styles:inline-box-13">inline box</a>.</dd><dt>If <code id="text-styles:dom-context-2d-textbaseline-2-8"><a href="#dom-context-2d-textbaseline-2">textBaseline</a></code> is <code id="text-styles:dom-context-2d-textbaseline-alphabetic-3"><a href="#dom-context-2d-textbaseline-alphabetic">alphabetic</a></code></dt><dd>Let the <var>anchor point</var>'s vertical position be the alphabetic baseline of
-     the first available font of the <a data-x-internal="inline-box" href="https://drafts.csswg.org/css2/visuren.html#inline-box" id="text-styles:inline-box-14">inline box</a>.</dd><dt>If <code id="text-styles:dom-context-2d-textbaseline-2-9"><a href="#dom-context-2d-textbaseline-2">textBaseline</a></code> is <code id="text-styles:dom-context-2d-textbaseline-ideographic"><a href="#dom-context-2d-textbaseline-ideographic">ideographic</a></code></dt><dd>Let the <var>anchor point</var>'s vertical position be the ideographic baseline of
-     the first available font of the <a data-x-internal="inline-box" href="https://drafts.csswg.org/css2/visuren.html#inline-box" id="text-styles:inline-box-15">inline box</a>.</dd><dt>If <code id="text-styles:dom-context-2d-textbaseline-2-10"><a href="#dom-context-2d-textbaseline-2">textBaseline</a></code> is <code id="text-styles:dom-context-2d-textbaseline-bottom"><a href="#dom-context-2d-textbaseline-bottom">bottom</a></code></dt><dd>Let the <var>anchor point</var>'s vertical position be the bottom of the em box of
-     the first available font of the <a data-x-internal="inline-box" href="https://drafts.csswg.org/css2/visuren.html#inline-box" id="text-styles:inline-box-16">inline box</a>.</dd></dl>
-
-   </li><li>
-
-    <p>Let <var>result</var> be an array constructed by iterating over each glyph in the
-    <a data-x-internal="inline-box" href="https://drafts.csswg.org/css2/visuren.html#inline-box" id="text-styles:inline-box-17">inline box</a> from left to right (if any), adding to the array, for each glyph, the
-    shape of the glyph as it is in the <a data-x-internal="inline-box" href="https://drafts.csswg.org/css2/visuren.html#inline-box" id="text-styles:inline-box-18">inline box</a>, positioned on a coordinate space
-    using <a data-x-internal="'px'" href="https://drafts.csswg.org/css-values/#px" id="text-styles:'px'-3">CSS pixels</a> with its origin is at the <var>anchor
-    point</var>.</p>
-
-   </li><li><p>Return <var>result</var>, <var>physical alignment</var>, and the inline
-   box.</p></li></ol>
-
-
-  <h6 id="building-paths"><span class="secno">4.12.5.1.5</span> Building paths<a class="self-link" href="#building-paths"/></h6>
-
-  <p>Objects that implement the <code id="building-paths:canvaspath"><a href="#canvaspath">CanvasPath</a></code> interface have a <a href="#concept-path" id="building-paths:concept-path">path</a>. A <dfn id="concept-path">path</dfn> has a list of zero or
-  more subpaths. Each subpath consists of a list of one or more points, connected by straight or
-  curved <dfn id="line-segments">line segments</dfn>, and a flag indicating whether the subpath is closed or not. A
-  closed subpath is one where the last point of the subpath is connected to the first point of the
-  subpath by a straight line. Subpaths with only one point are ignored when painting the path.</p>
-
-  <p><a href="#concept-path" id="building-paths:concept-path-2">Paths</a> have a <dfn id="need-new-subpath">need new subpath</dfn> flag. When this
-  flag is set, certain APIs create a new subpath rather than extending the previous one. When a
-  <a href="#concept-path" id="building-paths:concept-path-3">path</a> is created, its <a href="#need-new-subpath" id="building-paths:need-new-subpath">need new subpath</a> flag must be
-  set.</p>
-
-  <p>When an object implementing the <code id="building-paths:canvaspath-2"><a href="#canvaspath">CanvasPath</a></code> interface is created, its <a href="#concept-path" id="building-paths:concept-path-4">path</a> must be initialized to zero subpaths.</p>
-
-  <dl class="domintro"><dt><var>context</var> . <code id="dom-context-2d-moveto"><a href="#dom-context-2d-moveto-2">moveTo</a></code>(<var>x</var>, <var>y</var>)</dt><dt><var>path</var> . <code id="building-paths:dom-context-2d-moveto-2"><a href="#dom-context-2d-moveto-2">moveTo</a></code>(<var>x</var>, <var>y</var>)</dt><dd>
-
-    <p>Creates a new subpath with the given point.</p>
-
-   </dd><dt><var>context</var> . <code id="dom-context-2d-closepath"><a href="#dom-context-2d-closepath-2">closePath</a></code>()</dt><dt><var>path</var> . <code id="building-paths:dom-context-2d-closepath-2"><a href="#dom-context-2d-closepath-2">closePath</a></code>()</dt><dd>
-
-    <p>Marks the current subpath as closed, and starts a new subpath with a point the same as the
-    start and end of the newly closed subpath.</p>
-
-   </dd><dt><var>context</var> . <code id="dom-context-2d-lineto"><a href="#dom-context-2d-lineto-2">lineTo</a></code>(<var>x</var>, <var>y</var>)</dt><dt><var>path</var> . <code id="building-paths:dom-context-2d-lineto-2"><a href="#dom-context-2d-lineto-2">lineTo</a></code>(<var>x</var>, <var>y</var>)</dt><dd>
-
-    <p>Adds the given point to the current subpath, connected to the previous one by a straight
-    line.</p>
-
-   </dd><dt><var>context</var> . <code id="dom-context-2d-quadraticcurveto"><a href="#dom-context-2d-quadraticcurveto-2">quadraticCurveTo</a></code>(<var>cpx</var>, <var>cpy</var>, <var>x</var>, <var>y</var>)</dt><dt><var>path</var> . <code id="building-paths:dom-context-2d-quadraticcurveto-2"><a href="#dom-context-2d-quadraticcurveto-2">quadraticCurveTo</a></code>(<var>cpx</var>, <var>cpy</var>, <var>x</var>, <var>y</var>)</dt><dd>
-
-    <p>Adds the given point to the current subpath, connected to the previous one by a quadratic
-    Bézier curve with the given control point.</p>
-
-   </dd><dt><var>context</var> . <code id="dom-context-2d-beziercurveto"><a href="#dom-context-2d-beziercurveto-2">bezierCurveTo</a></code>(<var>cp1x</var>, <var>cp1y</var>, <var>cp2x</var>, <var>cp2y</var>, <var>x</var>, <var>y</var>)</dt><dt><var>path</var> . <code id="building-paths:dom-context-2d-beziercurveto-2"><a href="#dom-context-2d-beziercurveto-2">bezierCurveTo</a></code>(<var>cp1x</var>, <var>cp1y</var>, <var>cp2x</var>, <var>cp2y</var>, <var>x</var>, <var>y</var>)</dt><dd>
-
-    <p>Adds the given point to the current subpath, connected to the previous one by a cubic
-    Bézier curve with the given control points.</p>
-
-   </dd><dt><var>context</var> . <code id="dom-context-2d-arcto"><a href="#dom-context-2d-arcto-2">arcTo</a></code>(<var>x1</var>, <var>y1</var>, <var>x2</var>, <var>y2</var>, <var>radiusX</var> [, <var>radiusY</var>, <var>rotation</var> ] )</dt><dt><var>path</var> . <code id="building-paths:dom-context-2d-arcto-2"><a href="#dom-context-2d-arcto-2">arcTo</a></code>(<var>x1</var>, <var>y1</var>, <var>x2</var>, <var>y2</var>, <var>radiusX</var> [, <var>radiusY</var>, <var>rotation</var> ] )</dt><dd>
-
-    <p>Adds an arc with the given control points and radius to the current subpath, connected to the
-    previous point by a straight line.</p>
-
-    <p>If two radii are provided, then the first controls the width of the arc's ellipse, and the
-    second controls the height. If only one is provided, or if they are the same, then the arc is
-    from a circle. In the case of an ellipse, the rotation argument controls the clockwise
-    inclination of the ellipse relative to the x-axis.</p>
-
-    <p>Throws an <a data-x-internal="indexsizeerror" href="https://heycam.github.io/webidl/#indexsizeerror" id="building-paths:indexsizeerror">&quot;<code>IndexSizeError</code>&quot;</a> <code id="building-paths:domexception"><a data-x-internal="domexception" href="https://heycam.github.io/webidl/#dfn-DOMException">DOMException</a></code> if the given
-    radius is negative.</p>
-
-    <figure class="diagrams">
-     
-     <img alt="" height="254" src="https://html.spec.whatwg.org/images/arcTo1.png" width="357"/>
-     <img alt="" height="310" src="https://html.spec.whatwg.org/images/arcTo2.png" width="468"/>
-     <img alt="" height="233" src="https://html.spec.whatwg.org/images/arcTo3.png" width="513"/>
-    </figure>
-
-
-
-   </dd><dt><var>context</var> . <code id="dom-context-2d-arc"><a href="#dom-context-2d-arc-2">arc</a></code>(<var>x</var>, <var>y</var>, <var>radius</var>, <var>startAngle</var>, <var>endAngle</var> [, <var>anticlockwise</var> ] )</dt><dt><var>path</var> . <code id="building-paths:dom-context-2d-arc-2"><a href="#dom-context-2d-arc-2">arc</a></code>(<var>x</var>, <var>y</var>, <var>radius</var>, <var>startAngle</var>, <var>endAngle</var> [, <var>anticlockwise</var> ] )</dt><dd>
-
-    <p>Adds points to the subpath such that the arc described by the circumference of the circle
-    described by the arguments, starting at the given start angle and ending at the given end angle,
-    going in the given direction (defaulting to clockwise), is added to the path, connected to the
-    previous point by a straight line.</p>
-
-    <p>Throws an <a data-x-internal="indexsizeerror" href="https://heycam.github.io/webidl/#indexsizeerror" id="building-paths:indexsizeerror-2">&quot;<code>IndexSizeError</code>&quot;</a> <code id="building-paths:domexception-2"><a data-x-internal="domexception" href="https://heycam.github.io/webidl/#dfn-DOMException">DOMException</a></code> if the given
-    radius is negative.</p>
-
-    <figure class="diagrams">
-     
-     <img alt="" height="255" src="https://html.spec.whatwg.org/images/arc1.png" width="590"/>
-    </figure>
-
-
-
-   </dd><dt><var>context</var> . <code id="dom-context-2d-ellipse"><a href="#dom-context-2d-ellipse-2">ellipse</a></code>(<var>x</var>, <var>y</var>, <var>radiusX</var>, <var>radiusY</var>, <var>rotation</var>, <var>startAngle</var>, <var>endAngle</var> [, <var>anticlockwise</var>] )</dt><dt><var>path</var> . <code id="building-paths:dom-context-2d-ellipse-2"><a href="#dom-context-2d-ellipse-2">ellipse</a></code>(<var>x</var>, <var>y</var>, <var>radiusX</var>, <var>radiusY</var>, <var>rotation</var>, <var>startAngle</var>, <var>endAngle</var> [, <var>anticlockwise</var>] )</dt><dd>
-
-    <p>Adds points to the subpath such that the arc described by the circumference of the ellipse
-    described by the arguments, starting at the given start angle and ending at the given end angle,
-    going in the given direction (defaulting to clockwise), is added to the path, connected to the
-    previous point by a straight line.</p>
-
-    <p>Throws an <a data-x-internal="indexsizeerror" href="https://heycam.github.io/webidl/#indexsizeerror" id="building-paths:indexsizeerror-3">&quot;<code>IndexSizeError</code>&quot;</a> <code id="building-paths:domexception-3"><a data-x-internal="domexception" href="https://heycam.github.io/webidl/#dfn-DOMException">DOMException</a></code> if the given
-    radius is negative.</p>
-
-   </dd><dt><var>context</var> . <code id="dom-context-2d-rect"><a href="#dom-context-2d-rect-2">rect</a></code>(<var>x</var>, <var>y</var>, <var>w</var>, <var>h</var>)</dt><dt><var>path</var> . <code id="building-paths:dom-context-2d-rect-2"><a href="#dom-context-2d-rect-2">rect</a></code>(<var>x</var>, <var>y</var>, <var>w</var>, <var>h</var>)</dt><dd>
-
-    <p>Adds a new closed subpath to the path, representing the given rectangle.</p>
-
-   </dd></dl>
-
-  
-
-  <p>The following methods allow authors to manipulate the <a href="#concept-path" id="building-paths:concept-path-5">paths</a>
-  of objects implementing the <code id="building-paths:canvaspath-3"><a href="#canvaspath">CanvasPath</a></code> interface.</p>
-
-  <p>For objects implementing the <code id="building-paths:canvasdrawpath"><a href="#canvasdrawpath">CanvasDrawPath</a></code> and <code id="building-paths:canvastransform"><a href="#canvastransform">CanvasTransform</a></code>
-  interfaces, the points passed to the methods, and the resulting lines added to <a href="#current-default-path" id="building-paths:current-default-path">current
-  default path</a> by these methods, must be transformed according to the <a href="#transformations" id="building-paths:transformations">current transformation matrix</a> before being added to
-  the path.</p>
-
-  <p>The <dfn id="dom-context-2d-moveto-2"><code>moveTo(<var>x</var>, <var>y</var>)</code></dfn>
-  method, when invoked, must run these steps:</p>
-
-  <ol><li><p>If either of the arguments are infinite or NaN, then abort these steps.</p></li><li><p>Create a new subpath with the specified point as its first (and only) point.</p></li></ol>
-
-  <p>When the user agent is to <dfn id="ensure-there-is-a-subpath">ensure there is a subpath</dfn> for a coordinate (<var>x</var>,
-  <var>y</var>) on a <a href="#concept-path" id="building-paths:concept-path-6">path</a>, the user agent must check to see if
-  the <a href="#concept-path" id="building-paths:concept-path-7">path</a> has its <a href="#need-new-subpath" id="building-paths:need-new-subpath-2">need new subpath</a> flag set. If it
-  does, then the user agent must create a new subpath with the point (<var>x</var>, <var>y</var>) as
-  its first (and only) point, as if the <code id="building-paths:dom-context-2d-moveto-2-2"><a href="#dom-context-2d-moveto-2">moveTo()</a></code> method
-  had been called, and must then unset the <a href="#concept-path" id="building-paths:concept-path-8">path</a>'s <a href="#need-new-subpath" id="building-paths:need-new-subpath-3">need new
-  subpath</a> flag.</p>
-
-
-  <p>The <dfn id="dom-context-2d-closepath-2"><code>closePath()</code></dfn> method, when invoked,
-  must do nothing if the object's path has no subpaths. Otherwise, it must mark the last subpath as
-  closed, create a new subpath whose first point is the same as the previous subpath's first point,
-  and finally add this new subpath to the path.</p>
-
-  <p class="note">If the last subpath had more than one point in its list of points, then this is
-  equivalent to adding a straight line connecting the last point back to the first point, thus
-  &quot;closing&quot; the shape, and then repeating the last (possibly implied) <code id="building-paths:dom-context-2d-moveto-2-3"><a href="#dom-context-2d-moveto-2">moveTo()</a></code> call.</p>
-
-
-  <p>New points and the lines connecting them are added to subpaths using the methods described
-  below. In all cases, the methods only modify the last subpath in the object's path.</p>
-
-
-  <p>The <dfn id="dom-context-2d-lineto-2"><code>lineTo(<var>x</var>, <var>y</var>)</code></dfn>
-  method, when invoked, must run these steps:</p>
-
-  <ol><li><p>If either of the arguments are infinite or NaN, then abort these steps.</p></li><li><p>If the object's path has no subpaths, then <a href="#ensure-there-is-a-subpath" id="building-paths:ensure-there-is-a-subpath">ensure there is a subpath</a> for
-   <span>(<var>x</var>, <var>y</var>)</span>.</p></li><li><p>Otherwise, connect the last point in the subpath to the given point (<var>x</var>,
-   <var>y</var>) using a straight line, and then add the given point (<var>x</var>, <var>y</var>) to
-   the subpath.</p></li></ol>
-
-  <p>The <dfn id="dom-context-2d-quadraticcurveto-2"><code>quadraticCurveTo(<var>cpx</var>,
-  <var>cpy</var>, <var>x</var>, <var>y</var>)</code></dfn> method, when invoked, must run these
-  steps:</p>
-
-  <ol><li><p>If any of the arguments are infinite or NaN, then abort these steps.</p></li><li><p><a href="#ensure-there-is-a-subpath" id="building-paths:ensure-there-is-a-subpath-2">Ensure there is a subpath</a> for <span>(<var>cpx</var>,
-   <var>cpy</var>)</span></p></li><li><p>Connect the last point in the subpath to the given point (<var>x</var>, <var>y</var>)
-   using a quadratic Bézier curve with control point (<var>cpx</var>, <var>cpy</var>). <a href="https://html.spec.whatwg.org/multipage/references.html#refsBEZIER">[BEZIER]</a></p></li><li><p>Add the given point (<var>x</var>, <var>y</var>) to the subpath.</p></li></ol>
-
-  <p>The <dfn id="dom-context-2d-beziercurveto-2"><code>bezierCurveTo(<var>cp1x</var>,
-  <var>cp1y</var>, <var>cp2x</var>, <var>cp2y</var>, <var>x</var>, <var>y</var>)</code></dfn>
-  method, when invoked, must run these steps:</p>
-
-  <ol><li><p>If any of the arguments are infinite or NaN, then abort these steps.</p></li><li><p><a href="#ensure-there-is-a-subpath" id="building-paths:ensure-there-is-a-subpath-3">Ensure there is a subpath</a> for <span>(<var>cp1x</var>,
-   <var>cp1y</var>)</span>.</p></li><li><p>Connect the last point in the subpath to the given point (<var>x</var>, <var>y</var>)
-   using a cubic Bézier curve with control points (<var>cp1x</var>, <var>cp1y</var>) and
-   (<var>cp2x</var>, <var>cp2y</var>). <a href="https://html.spec.whatwg.org/multipage/references.html#refsBEZIER">[BEZIER]</a></p></li><li><p>Add the point (<var>x</var>, <var>y</var>) to the subpath.</p></li></ol>
-
-  <hr/>
-
-  <p>The <dfn id="dom-context-2d-arcto-2"><code>arcTo(<var>x1</var>, <var>y1</var>, <var>x2</var>,
-  <var>y2</var>, <var>radiusX</var>, <var>radiusY</var>, <var>rotation</var>)</code></dfn> method,
-  when invoked, must run these steps:</p>
-
-  <ol><li><p>If any of the arguments are infinite or NaN, then abort these steps.</p></li><li><p><a href="#ensure-there-is-a-subpath" id="building-paths:ensure-there-is-a-subpath-4">Ensure there is a subpath</a> for <span>(<var>x1</var>,
-   <var>y1</var>)</span>.</p></li><li><p>If either <var>radiusX</var> or <var>radiusY</var> are negative, then throw an
-   <a data-x-internal="indexsizeerror" href="https://heycam.github.io/webidl/#indexsizeerror" id="building-paths:indexsizeerror-4">&quot;<code>IndexSizeError</code>&quot;</a> <code id="building-paths:domexception-4"><a data-x-internal="domexception" href="https://heycam.github.io/webidl/#dfn-DOMException">DOMException</a></code>.</p></li><li><p>If <var>radiusY</var> is omitted, then set <var>radiusY</var> to
-   <var>radiusX</var>.</p></li><li><p>Let the point (<var>x0</var>, <var>y0</var>) be the last point in the subpath, transformed
-   by the inverse of the <a href="#transformations" id="building-paths:transformations-2">current transformation
-   matrix</a> (so that it is in the same coordinate system as the points passed to the
-   method).</p></li><li><p>If the point (<var>x0</var>, <var>y0</var>) is equal to the point (<var>x1</var>,
-   <var>y1</var>), or if the point (<var>x1</var>, <var>y1</var>) is equal to the point
-   (<var>x2</var>, <var>y2</var>), or if both <var>radiusX</var> and <var>radiusY</var> are zero,
-   then add the point (<var>x1</var>, <var>y1</var>) to the subpath, and connect that point to the
-   previous point (<var>x0</var>, <var>y0</var>) by a straight line.</p></li><li><p>Otherwise, if the points (<var>x0</var>, <var>y0</var>), (<var>x1</var>, <var>y1</var>),
-   and (<var>x2</var>, <var>y2</var>) all lie on a single straight line, then add the point
-   (<var>x1</var>, <var>y1</var>) to the subpath, and connect that point to the previous point
-   (<var>x0</var>, <var>y0</var>) by a straight line.</p></li><li><p>Otherwise, let <var>The Arc</var> be the shortest arc given by circumference of the
-   ellipse that has radius <var>radiusX</var> on the major axis and radius <var>radiusY</var> on the
-   minor axis, and whose semi-major axis is rotated <var>rotation</var> radians clockwise from the
-   positive x-axis, and that has one point tangent to the half-infinite line that crosses the point
-   (<var>x0</var>, <var>y0</var>) and ends at the point (<var>x1</var>, <var>y1</var>), and that has
-   a different point tangent to the half-infinite line that ends at the point (<var>x1</var>,
-   <var>y1</var>) and crosses the point (<var>x2</var>, <var>y2</var>). The points at which this
-   ellipse touches these two lines are called the start and end tangent points respectively. Connect
-   the point (<var>x0</var>, <var>y0</var>) to the start tangent point by a straight line, adding
-   the start tangent point to the subpath, and then connect the start tangent point to the end
-   tangent point by <var>The Arc</var>, adding the end tangent point to the subpath.</p></li></ol>
-
-  <hr/>
-
-  <p>The <dfn id="dom-context-2d-arc-2"><code>arc(<var>x</var>, <var>y</var>,
-  <var>radius</var>, <var>startAngle</var>, <var>endAngle</var>, <var>anticlockwise</var>)</code></dfn> and <dfn id="dom-context-2d-ellipse-2"><code>ellipse(<var>x</var>, <var>y</var>, <var>radiusX</var>, <var>radiusY</var>, <var>rotation</var>, <var>startAngle</var>, <var>endAngle</var>, <var>anticlockwise</var>)</code></dfn> methods draw arcs.</p>
-
-  <p>The <code id="building-paths:dom-context-2d-arc-2-2"><a href="#dom-context-2d-arc-2">arc()</a></code> method is equivalent to the <code id="building-paths:dom-context-2d-ellipse-2-2"><a href="#dom-context-2d-ellipse-2">ellipse()</a></code> method in the case where the two radii are equal.
-  When the <code id="building-paths:dom-context-2d-arc-2-3"><a href="#dom-context-2d-arc-2">arc()</a></code> method is invoked, it must act as if the
-  <code id="building-paths:dom-context-2d-ellipse-2-3"><a href="#dom-context-2d-ellipse-2">ellipse()</a></code> method had been invoked with the <var>radiusX</var> and <var>radiusY</var> arguments set to the value of the <var>radius</var> argument, the <var>rotation</var> argument set to zero, and the
-  other arguments set to the same values as their identically named arguments on the <code id="building-paths:dom-context-2d-arc-2-4"><a href="#dom-context-2d-arc-2">arc()</a></code> method.</p>
-
-  <p>The <code id="building-paths:dom-context-2d-ellipse-2-4"><a href="#dom-context-2d-ellipse-2">ellipse()</a></code> method, when invoked, must run these
-  steps:</p>
-
-  <ol><li><p>If any of the arguments are infinite or NaN, then abort these steps.</p></li><li><p>If either <var>radiusX</var> or <var>radiusY</var> are negative, then throw an
-   <a data-x-internal="indexsizeerror" href="https://heycam.github.io/webidl/#indexsizeerror" id="building-paths:indexsizeerror-5">&quot;<code>IndexSizeError</code>&quot;</a> <code id="building-paths:domexception-5"><a data-x-internal="domexception" href="https://heycam.github.io/webidl/#dfn-DOMException">DOMException</a></code>.</p></li><li><p>If the object's path has any subpaths, then add a straight line from the last point in the
-   subpath to the start point of the arc.</p></li><li>
-    <p>Add the start and end points of the arc to the subpath, and connect them with an arc. The arc
-    and its start and end points are defined as follows:</p>
-
-    <p>Consider an ellipse that has its origin at (<var>x</var>, <var>y</var>), that has a
-    major-axis radius <var>radiusX</var> and a minor-axis radius <var>radiusY</var>, and that is
-    rotated about its origin such that its semi-major axis is inclined <var>rotation</var> radians
-    clockwise from the x-axis.</p>
-
-    <p>If <var>anticlockwise</var> is false and <span><var>endAngle</var>-<var>startAngle</var></span> is equal to or greater than <span>2π</span>, or, if <var>anticlockwise</var> is <em>true</em> and <span><var>startAngle</var>-<var>endAngle</var></span> is equal to or greater than <span>2π</span>, then the arc is the whole circumference of this ellipse, and the point
-    at <var>startAngle</var> along this circle's circumference, measured in radians clockwise from
-    the ellipse's semi-major axis, acts as both the start point and the end point.</p>
-
-    <p>Otherwise, the points at <var>startAngle</var> and <var>endAngle</var> along this circle's
-    circumference, measured in radians clockwise from the ellipse's semi-major axis, are the start
-    and end points respectively, and the arc is the path along the circumference of this ellipse
-    from the start point to the end point, going anti-clockwise if <var>anticlockwise</var> is true,
-    and clockwise otherwise. Since the points are on the ellipse, as opposed to being simply angles
-    from zero, the arc can never cover an angle greater than <span>2π</span>
-    radians.</p>
-
-    <p class="note">Even if the arc covers the entire circumference of the ellipse and there are no
-    other points in the subpath, the path is not closed unless the <code id="building-paths:dom-context-2d-closepath-2-2"><a href="#dom-context-2d-closepath-2">closePath()</a></code> method is appropriately invoked.</p>
-   </li></ol>
-
-  <hr/>
-
-  <p>The <dfn id="dom-context-2d-rect-2"><code>rect(<var>x</var>, <var>y</var>, <var>w</var>,
-  <var>h</var>)</code></dfn> method, when invoked, must run these steps:</p>
-
-  <ol><li><p>If any of the arguments are infinite or NaN, then abort these steps.</p></li><li><p>Create a new subpath containing just the four points (<var>x</var>, <var>y</var>),
-   (<var>x</var>+<var>w</var>, <var>y</var>), (<var>x</var>+<var>w</var>,
-   <var>y</var>+<var>h</var>), (<var>x</var>, <var>y</var>+<var>h</var>), in that order, with those
-   four points connected by straight lines.</p></li><li><p>Mark the subpath as closed.</p></li><li><p>Create a new subpath with the point (<var>x</var>, <var>y</var>) as the only point in the
-   subpath.</p></li></ol>
-
-  
-
-  
-
-
-
-  <h6 id="path2d-objects"><span class="secno">4.12.5.1.6</span> <code id="path2d-objects:path2d"><a href="#path2d">Path2D</a></code> objects<a class="self-link" href="#path2d-objects"/></h6>
-
-  <p><code id="path2d-objects:path2d-2"><a href="#path2d">Path2D</a></code> objects can be used to declare paths that are then later used on
-  objects implementing the <code id="path2d-objects:canvasdrawpath"><a href="#canvasdrawpath">CanvasDrawPath</a></code> interface. In addition to many of the APIs
-  described in earlier sections, <code id="path2d-objects:path2d-3"><a href="#path2d">Path2D</a></code> objects have methods to combine paths, and to
-  add text to paths.</p>
-
-  <dl class="domintro"><dt><var>path</var> = new <code id="path2d-objects:dom-path2d"><a href="#dom-path2d">Path2D</a></code>()</dt><dd>
-
-    <p>Creates a new empty <code id="path2d-objects:path2d-4"><a href="#path2d">Path2D</a></code> object.</p>
-
-   </dd><dt><var>path</var> = new <code id="path2d-objects:dom-path2d-copy"><a href="#dom-path2d-copy">Path2D</a></code>(<var>path</var>)</dt><dd>
-
-    <p>Creates a new <code id="path2d-objects:path2d-5"><a href="#path2d">Path2D</a></code> object that is a copy of the argument.</p>
-
-   </dd><dt><var>path</var> = new <code id="path2d-objects:dom-path2d-merge"><a href="#dom-path2d-merge">Path2D</a></code>(<var>paths</var> [, <var>fillRule</var> ] )</dt><dd>
-
-    <p>Creates a new <code id="path2d-objects:path2d-6"><a href="#path2d">Path2D</a></code> object that describes a path that outlines the given <var>paths</var>, using the given fill rule.</p>
-
-   </dd><dt><var>path</var> = new <code id="path2d-objects:dom-path2d-withdata"><a href="#dom-path2d-withdata">Path2D</a></code>(<var>d</var>)</dt><dd>
-
-    <p>Creates a new path with the path described by the argument, interpreted as SVG path data. <a href="https://html.spec.whatwg.org/multipage/references.html#refsSVG">[SVG]</a></p>
-
-   </dd><dt><var>path</var> . <code id="dom-path2d-addpath"><a href="#dom-path2d-addpath-2">addPath</a></code>(<var>path</var> [, <var>transform</var> ] )</dt><dd>
-
-    <p>Adds to the path the path given by the argument.</p>
-
-   </dd></dl>
-
-  
-
-  <p>The <dfn id="dom-path2d"><code>Path2D()</code></dfn> constructor, when invoked, must return a
-  newly created <code id="path2d-objects:path2d-7"><a href="#path2d">Path2D</a></code> object.</p>
-
-  <hr/>
-
-  <p>The <dfn id="dom-path2d-copy"><code>Path2D(<var>path</var>)</code></dfn>
-  constructor, when invoked, must return a newly created <code id="path2d-objects:path2d-8"><a href="#path2d">Path2D</a></code> object, to which the
-  subpaths of the argument are added. (In other words, it returns a copy of the argument.)</p>
-
-  <hr/>
-
-  <p>The <dfn id="dom-path2d-merge"><code>Path2D(<var>paths</var>,
-  <var>fillRule</var>)</code></dfn> constructor, when invoked, must run these steps:</p>
-
-  <ol><li>
-
-    <p>Run the appropriate step from the following list, based on the constructor's second
-    argument:</p>
-
-    <dl class="switch"><dt>If it is &quot;nonzero&quot;</dt><dd>
-
-      <p>Let <var>merged path</var> be a <a href="#concept-path" id="path2d-objects:concept-path">path</a> that
-      consists of a set of non-overlapping subpaths that exactly outline the points from which, in
-      any of the <a href="#concept-path" id="path2d-objects:concept-path-2">paths</a> provided in the constructor's first
-      argument, the number of times a half-infinite straight line drawn from that point crosses a
-      subpath going in one direction is not equal to the number of times it crosses a subpath going
-      in the other direction.</p>
-
-     </dd><dt>If it is &quot;evenodd&quot;</dt><dd>
-
-      <p>Let <var>merged path</var> be a <a href="#concept-path" id="path2d-objects:concept-path-3">path</a> that
-      consists of a set of non-overlapping subpaths that exactly outline the points from which, in
-      any of the <a href="#concept-path" id="path2d-objects:concept-path-4">paths</a> provided in the constructor's first
-      argument, the number of times a half-infinite straight line drawn from that point crosses that
-      path is odd.</p>
-
-     </dd></dl>
-
-    <p>The subpaths in <var>merged path</var> must be oriented such that for any point,
-    the number of times a half-infinite straight line drawn from that point crosses a subpath is
-    even if and only if the number of times a half-infinite straight line drawn from that same point
-    crosses a subpath going in one direction is equal to the number of times it crosses a subpath
-    going in the other direction.</p>
-
-   </li><li><p>Add all the subpaths in <var>merged path</var> to the <code id="path2d-objects:path2d-9"><a href="#path2d">Path2D</a></code>
-   object.</p></li><li><p>Set the <code id="path2d-objects:path2d-10"><a href="#path2d">Path2D</a></code> object's <a href="#need-new-subpath" id="path2d-objects:need-new-subpath">need new subpath</a> flag.</p></li></ol>
-
-  <hr/>
-
-  <p>The <dfn id="dom-path2d-withdata"><code>Path2D(<var>d</var>)</code></dfn>
-  constructor, when invoked, must run these steps:</p>
-
-  <ol><li>
-
-    <p>Parse and interpret the <var>d</var> argument according to the SVG specification's
-    rules for path data, thus obtaining an SVG path. <a href="https://html.spec.whatwg.org/multipage/references.html#refsSVG">[SVG]</a></p>
-
-    <p class="note">The resulting path could be empty. SVG defines error handling rules for parsing
-    and applying path data.</p>
-
-   </li><li><p>Let (<var>x</var>, <var>y</var>) be the last point in the SVG
-   path.</p></li><li><p>Create a new <code id="path2d-objects:path2d-11"><a href="#path2d">Path2D</a></code> object and add all the subpaths in the SVG path, if any,
-   to that <code id="path2d-objects:path2d-12"><a href="#path2d">Path2D</a></code> object. </p>
-
-   </li><li><p>Create a new subpath in the <code id="path2d-objects:path2d-13"><a href="#path2d">Path2D</a></code> object with (<var>x</var>, <var>y</var>) as the only point in the subpath.</p></li><li><p>Return the <code id="path2d-objects:path2d-14"><a href="#path2d">Path2D</a></code> object as the constructed object.</p></li></ol>
-
-  <hr/>
-
-  <p>The <dfn id="dom-path2d-addpath-2"><code>addPath(<var>b</var>,
-  <var>transform</var>)</code></dfn> method, when invoked on a <code id="path2d-objects:path2d-15"><a href="#path2d">Path2D</a></code> object
-  <var>a</var>, must run these steps:</p>
-
-  <ol><li><p>If the <code id="path2d-objects:path2d-16"><a href="#path2d">Path2D</a></code> object <var>b</var> has no subpaths, then abort these
-   steps.</p></li><li><p>Create a copy of all the subpaths in <var>b</var>. Let this copy be known as <var>c</var>.</p></li><li><p>Let <var>matrix</var> be the result of <a data-x-internal="create-a-dommatrix-from-a-dictionary" href="https://drafts.fxtf.org/geometry/#create-a-dommatrix-from-the-dictionary" id="path2d-objects:create-a-dommatrix-from-a-dictionary">creating a <code>DOMMatrix</code> from a dictionary</a>
-   <var>transform</var>, with <var>ignore3D</var> set to true.</p></li><li><p>Transform all the coordinates and lines in <var>c</var> by the transform matrix
-   <var>matrix</var>.</p></li><li><p>Let (<var>x</var>, <var>y</var>) be the last point in the last subpath
-   of <var>c</var>.</p></li><li><p>Add all the subpaths in <var>c</var> to <var>a</var>.</p></li><li><p>Create a new subpath in <var>a</var> with (<var>x</var>, <var>y</var>) as the only point in the subpath.</p></li></ol>
-
-  
-
-
-  <h6 id="transformations"><span class="secno">4.12.5.1.7</span> <dfn>Transformations</dfn><a class="self-link" href="#transformations"/></h6><div class="status"><input onclick="toggleStatus(this)" type="button" value="⋰"/><p class="bugs"><strong>Spec bugs:</strong> <a href="https://www.w3.org/Bugs/Public/show_bug.cgi?id=28333" title="Show on example how a,b,c,d,e,f affect the point position">28333</a></p></div>
-
-  <p>Objects that implement the <code id="transformations:canvastransform"><a href="#canvastransform">CanvasTransform</a></code> interface have a <dfn id="current-transformation-matrix">current
-  transformation matrix</dfn>, as well as methods (described in this section) to manipulate it. When
-  an object implementing the <code id="transformations:canvastransform-2"><a href="#canvastransform">CanvasTransform</a></code> interface is created, its transformation
-  matrix must be initialized to the identity transform.</p>
-
-  <p>The <a href="#current-transformation-matrix" id="transformations:current-transformation-matrix">current transformation matrix</a> is applied to coordinates when creating the
-  <a href="#current-default-path" id="transformations:current-default-path">current default path</a>, and when painting text, shapes, and <code id="transformations:path2d"><a href="#path2d">Path2D</a></code>
-  objects, on objects implementing the <code id="transformations:canvastransform-3"><a href="#canvastransform">CanvasTransform</a></code> interface.</p>
-  
-
-  <p class="note">Most of the API uses <code id="transformations:dommatrix"><a data-x-internal="dommatrix" href="https://drafts.fxtf.org/geometry/#dommatrix">DOMMatrix</a></code> objects rather than this API. This API
-  remains mostly for historical reasons.</p>
-
-  
-
-  <p>The transformations must be performed in reverse order.</p>
-
-  <p class="note">For instance, if a scale transformation that doubles the width is applied to the
-  canvas, followed by a rotation transformation that rotates drawing operations by a quarter turn,
-  and a rectangle twice as wide as it is tall is then drawn on the canvas, the actual result will be
-  a square.</p> 
-
-  
-
-  <dl class="domintro"><dt><var>context</var> . <code id="dom-context-2d-scale"><a href="#dom-context-2d-scale-2">scale</a></code>(<var>x</var>, <var>y</var>)</dt><dd>
-
-    <p>Changes the <a href="#current-transformation-matrix" id="transformations:current-transformation-matrix-2">current transformation matrix</a> to apply a scaling transformation
-    with the given characteristics.</p>
-
-   </dd><dt><var>context</var> . <code id="dom-context-2d-rotate"><a href="#dom-context-2d-rotate-2">rotate</a></code>(<var>angle</var>)</dt><dd>
-
-    <p>Changes the <a href="#current-transformation-matrix" id="transformations:current-transformation-matrix-3">current transformation matrix</a> to apply a rotation transformation
-    with the given characteristics. The angle is in radians.</p>
-
-   </dd><dt><var>context</var> . <code id="dom-context-2d-translate"><a href="#dom-context-2d-translate-2">translate</a></code>(<var>x</var>, <var>y</var>)</dt><dd>
-
-    <p>Changes the <a href="#current-transformation-matrix" id="transformations:current-transformation-matrix-4">current transformation matrix</a> to apply a translation transformation
-    with the given characteristics.</p>
-
-   </dd><dt><var>context</var> . <code id="dom-context-2d-transform"><a href="#dom-context-2d-transform-2">transform</a></code>(<var>a</var>, <var>b</var>, <var>c</var>, <var>d</var>, <var>e</var>, <var>f</var>)</dt><dd>
-
-    <p>Changes the <a href="#current-transformation-matrix" id="transformations:current-transformation-matrix-5">current transformation matrix</a> to apply the matrix given by the
-    arguments as described below.</p>
-
-   </dd><dt><var>matrix</var> = <var>context</var> . <code id="dom-context-2d-gettransform"><a href="#dom-context-2d-gettransform-2">getTransform</a></code>()</dt><dd>
-
-    <p>Returns a copy of the <a href="#current-transformation-matrix" id="transformations:current-transformation-matrix-6">current transformation matrix</a>, as a newly created
-    <code id="transformations:dommatrix-2"><a data-x-internal="dommatrix" href="https://drafts.fxtf.org/geometry/#dommatrix">DOMMatrix</a></code> object.</p>
-
-   </dd><dt><var>context</var> . <code id="dom-context-2d-settransform"><a href="#dom-context-2d-settransform-2">setTransform</a></code>(<var>a</var>, <var>b</var>, <var>c</var>, <var>d</var>, <var>e</var>, <var>f</var>)</dt><dd>
-
-    <p>Changes the <a href="#current-transformation-matrix" id="transformations:current-transformation-matrix-7">current transformation matrix</a> <em>to</em> the matrix given by the
-    arguments as described below.</p>
-
-   </dd><dt><var>context</var> . <code id="transformations:dom-context-2d-settransform-2"><a href="#dom-context-2d-settransform-2">setTransform</a></code>(<var>transform</var>)</dt><dd>
-
-    <p>Changes the <a href="#current-transformation-matrix" id="transformations:current-transformation-matrix-8">current transformation matrix</a> <em>to</em> the matrix represented by
-    the passed <code id="transformations:dommatrix2dinit"><a data-x-internal="dommatrix2dinit" href="https://drafts.fxtf.org/geometry/#dictdef-dommatrix2dinit">DOMMatrix2DInit</a></code> dictionary.</p>
-
-   </dd><dt><var>context</var> . <code id="dom-context-2d-resettransform"><a href="#dom-context-2d-resettransform-2">resetTransform</a></code>()</dt><dd>
-
-    <p>Changes the <a href="#current-transformation-matrix" id="transformations:current-transformation-matrix-9">current transformation matrix</a> to the identity transform.</p>
-
-   </dd></dl>
-
-  
-
-  <p>The <dfn id="dom-context-2d-scale-2"><code>scale(<var>x</var>, <var>y</var>)</code></dfn>
-  method, when invoked, must run these steps:</p>
-
-  <ol><li><p>If either of the arguments are infinite or NaN, then abort these steps.</p></li><li><p>Add the scaling transformation described by the arguments to the <a href="#current-transformation-matrix" id="transformations:current-transformation-matrix-10">current
-   transformation matrix</a>. The <var>x</var> argument represents the scale factor in the
-   horizontal direction and the <var>y</var> argument represents the scale factor in the vertical
-   direction. The factors are multiples.</p></li></ol>
-
-  <p>The <dfn id="dom-context-2d-rotate-2"><code>rotate(<var>angle</var>)</code></dfn> method,
-  when invoked, must run these steps:</p>
-
-  <ol><li><p>If <var>angle</var> is infinite or NaN, then abort these steps.</p></li><li><p>Add the rotation transformation described by the argument to the <a href="#current-transformation-matrix" id="transformations:current-transformation-matrix-11">current
-   transformation matrix</a>. The <var>angle</var> argument represents a clockwise rotation angle
-   expressed in radians.</p></li></ol>
-
-  <p>The <dfn id="dom-context-2d-translate-2"><code>translate(<var>x</var>,
-  <var>y</var>)</code></dfn> method, when invoked, must run these steps:</p>
-
-  <ol><li><p>If either of the arguments are infinite or NaN, then abort these steps.</p></li><li><p>Add the translation transformation described by the arguments to the <a href="#current-transformation-matrix" id="transformations:current-transformation-matrix-12">current
-   transformation matrix</a>. The <var>x</var> argument represents the translation distance in
-   the horizontal direction and the <var>y</var> argument represents the translation distance in the
-   vertical direction. The arguments are in coordinate space units.</p></li></ol>
-
-  <p>The <dfn id="dom-context-2d-transform-2"><code>transform(<var>a</var>, <var>b</var>,
-  <var>c</var>, <var>d</var>, <var>e</var>, <var>f</var>)</code></dfn> method, when invoked, must
-  run these steps:</p>
-
-  <ol><li><p>If any of the arguments are infinite or NaN, then abort these steps.</p></li><li><p>Replace the <a href="#current-transformation-matrix" id="transformations:current-transformation-matrix-13">current transformation matrix</a> with the result of multiplying the
-   current transformation matrix with the matrix described by:</p></li></ol>
-
-  
-
-  <table class="matrix"><tbody><tr><td><var>a</var></td><td><var>c</var></td><td><var>e</var></td></tr><tr><td><var>b</var></td><td><var>d</var></td><td><var>f</var></td></tr><tr><td>0</td><td>0</td><td>1</td></tr></tbody></table>
-
-  <p class="note">The arguments <var>a</var>, <var>b</var>, <var>c</var>, <var>d</var>,
-  <var>e</var>, and <var>f</var> are sometimes called <var>m11</var>, <var>m12</var>,
-  <var>m21</var>, <var>m22</var>, <var>dx</var>, and <var>dy</var> or <var>m11</var>,
-  <var>m21</var>, <var>m12</var>, <var>m22</var>, <var>dx</var>, and <var>dy</var>. Care ought to be
-  taken in particular with the order of the second and third arguments (<var>b</var> and
-  <var>c</var>) as their order varies from API to API and APIs sometimes use the notation
-  <var>m12</var>/<var>m21</var> and sometimes <var>m21</var>/<var>m12</var> for those positions.</p>
-
-  
-
-  <p>The <dfn id="dom-context-2d-gettransform-2"><code>getTransform()</code></dfn> method, when
-  invoked, must return a newly created <code id="transformations:dommatrix-3"><a data-x-internal="dommatrix" href="https://drafts.fxtf.org/geometry/#dommatrix">DOMMatrix</a></code> representing a copy of the
-  <a href="#current-transformation-matrix" id="transformations:current-transformation-matrix-14">current transformation matrix</a> matrix of the context.</p>
-
-  <p class="note">This returned object is not live, so updating it will not affect the
-  <a href="#current-transformation-matrix" id="transformations:current-transformation-matrix-15">current transformation matrix</a>, and updating the <a href="#current-transformation-matrix" id="transformations:current-transformation-matrix-16">current transformation
-  matrix</a> will not affect an already returned <code id="transformations:dommatrix-4"><a data-x-internal="dommatrix" href="https://drafts.fxtf.org/geometry/#dommatrix">DOMMatrix</a></code>.</p>
-
-  <p>The <dfn id="dom-context-2d-settransform-2"><code>setTransform(<var>a</var>, <var>b</var>,
-  <var>c</var>, <var>d</var>, <var>e</var>, <var>f</var>)</code></dfn> method, when invoked, must
-  run these steps:</p>
-
-  <ol><li><p>If any of the arguments are infinite or NaN, then abort these steps.</p></li><li><p>Reset the <a href="#current-transformation-matrix" id="transformations:current-transformation-matrix-17">current transformation matrix</a> to the identity matrix.</p></li><li><p>Invoke the <code><a href="#dom-context-2d-transform-2" id="transformations:dom-context-2d-transform-2">transform</a>(<var>a</var>, <var>b</var>, <var>c</var>,
-   <var>d</var>, <var>e</var>, <var>f</var>)</code> method with the same arguments.</p></li></ol>
-
-  <p>The <dfn><code>setTransform(<var>transform</var>)</code></dfn> method, when invoked,
-  must reset the <a href="#current-transformation-matrix" id="transformations:current-transformation-matrix-18">current transformation matrix</a> to the value represented by the result
-  of <a data-x-internal="create-a-dommatrix-from-a-dictionary" href="https://drafts.fxtf.org/geometry/#create-a-dommatrix-from-the-dictionary" id="transformations:create-a-dommatrix-from-a-dictionary">creating a <code>DOMMatrix</code> from a
-  dictionary</a> <var>transform</var>, with <var>ignore3D</var> set to true.</p>
-
-  <p>The <dfn id="dom-context-2d-resettransform-2"><code>resetTransform()</code></dfn> method,
-  when invoked, must reset the <a href="#current-transformation-matrix" id="transformations:current-transformation-matrix-19">current transformation matrix</a> to the identity
-  matrix.</p>
-
-  
-
-
-
-  <h6 id="image-sources-for-2d-rendering-contexts"><span class="secno">4.12.5.1.8</span> Image sources for 2D rendering contexts<a class="self-link" href="#image-sources-for-2d-rendering-contexts"/></h6>
-
-  <p>Some methods on the <code id="image-sources-for-2d-rendering-contexts:canvasdrawimage"><a href="#canvasdrawimage">CanvasDrawImage</a></code> and <code id="image-sources-for-2d-rendering-contexts:canvasfillstrokestyles"><a href="#canvasfillstrokestyles">CanvasFillStrokeStyles</a></code>
-  interfaces take the union type <code id="image-sources-for-2d-rendering-contexts:canvasimagesource"><a href="#canvasimagesource">CanvasImageSource</a></code> as an argument.</p>
-
-  <p>This union type allows objects implementing any of the following interfaces to be used as image
-  sources:</p>
-
-  <ul><li><code id="image-sources-for-2d-rendering-contexts:htmlorsvgimageelement"><a href="#htmlorsvgimageelement">HTMLOrSVGImageElement</a></code> (<code id="image-sources-for-2d-rendering-contexts:the-img-element"><a href="https://html.spec.whatwg.org/multipage/embedded-content.html#the-img-element">img</a></code> or <a data-x-internal="svg-image" href="https://www.w3.org/TR/SVG11/struct.html#ImageElement" id="image-sources-for-2d-rendering-contexts:svg-image">SVG <code>image</code></a>
-   elements)</li><li><code id="image-sources-for-2d-rendering-contexts:htmlvideoelement"><a href="https://html.spec.whatwg.org/multipage/media.html#htmlvideoelement">HTMLVideoElement</a></code> (<code id="image-sources-for-2d-rendering-contexts:the-video-element"><a href="https://html.spec.whatwg.org/multipage/media.html#the-video-element">video</a></code> elements)</li><li><code id="image-sources-for-2d-rendering-contexts:htmlcanvaselement"><a href="#htmlcanvaselement">HTMLCanvasElement</a></code> (<code id="image-sources-for-2d-rendering-contexts:the-canvas-element"><a href="#the-canvas-element">canvas</a></code> elements)</li><li><code id="image-sources-for-2d-rendering-contexts:imagebitmap"><a href="https://html.spec.whatwg.org/multipage/imagebitmap-and-animations.html#imagebitmap">ImageBitmap</a></code></li></ul>
-
-  <p class="note">Although not formally specified as such, <a data-x-internal="svg-image" href="https://www.w3.org/TR/SVG11/struct.html#ImageElement" id="image-sources-for-2d-rendering-contexts:svg-image-2">SVG <code>image</code></a>
-  elements are expected to be implemented nearly identical to <code id="image-sources-for-2d-rendering-contexts:the-img-element-2"><a href="https://html.spec.whatwg.org/multipage/embedded-content.html#the-img-element">img</a></code> elements. That is,
-  <a data-x-internal="svg-image" href="https://www.w3.org/TR/SVG11/struct.html#ImageElement" id="image-sources-for-2d-rendering-contexts:svg-image-3">SVG <code>image</code></a> elements share the fundamental concepts and features of
-  <code id="image-sources-for-2d-rendering-contexts:the-img-element-3"><a href="https://html.spec.whatwg.org/multipage/embedded-content.html#the-img-element">img</a></code> elements.</p>
-
-  <p class="note">The <code id="image-sources-for-2d-rendering-contexts:imagebitmap-2"><a href="https://html.spec.whatwg.org/multipage/imagebitmap-and-animations.html#imagebitmap">ImageBitmap</a></code> interface can be created from a number of other
-  image-representing types, including <code id="image-sources-for-2d-rendering-contexts:imagedata"><a href="#imagedata">ImageData</a></code>.</p>
-
-  <p>When a user agent is required to <dfn id="check-the-usability-of-the-image-argument">check the usability of the <var>image</var>
-  argument</dfn>, where <var>image</var> is a <code id="image-sources-for-2d-rendering-contexts:canvasimagesource-2"><a href="#canvasimagesource">CanvasImageSource</a></code> object, the
-  user agent must run these steps, which return either <i>good</i>, <i>bad</i>, or
-  <i>aborted</i>:</p>
-
-  <ol><li><p>If <var>image</var> is an <code id="image-sources-for-2d-rendering-contexts:htmlorsvgimageelement-2"><a href="#htmlorsvgimageelement">HTMLOrSVGImageElement</a></code> object that is in the <a href="https://html.spec.whatwg.org/multipage/images.html#img-error" id="image-sources-for-2d-rendering-contexts:img-error">broken</a> state, then throw an
-   <a data-x-internal="invalidstateerror" href="https://heycam.github.io/webidl/#invalidstateerror" id="image-sources-for-2d-rendering-contexts:invalidstateerror">&quot;<code>InvalidStateError</code>&quot;</a> <code id="image-sources-for-2d-rendering-contexts:domexception"><a data-x-internal="domexception" href="https://heycam.github.io/webidl/#dfn-DOMException">DOMException</a></code>, return <i>aborted</i>,
-   and abort these steps.</p></li><li><p>If <var>image</var> is an <code id="image-sources-for-2d-rendering-contexts:htmlorsvgimageelement-3"><a href="#htmlorsvgimageelement">HTMLOrSVGImageElement</a></code> object that is not <a href="https://html.spec.whatwg.org/multipage/images.html#img-good" id="image-sources-for-2d-rendering-contexts:img-good">fully decodable</a>, or if <var>image</var> is an
-   <code id="image-sources-for-2d-rendering-contexts:htmlvideoelement-2"><a href="https://html.spec.whatwg.org/multipage/media.html#htmlvideoelement">HTMLVideoElement</a></code> object whose <code id="image-sources-for-2d-rendering-contexts:dom-media-readystate-2"><a href="https://html.spec.whatwg.org/multipage/media.html#dom-media-readystate-2">readyState</a></code>
-   attribute is either <code id="image-sources-for-2d-rendering-contexts:dom-media-have_nothing"><a href="https://html.spec.whatwg.org/multipage/media.html#dom-media-have_nothing">HAVE_NOTHING</a></code> or <code id="image-sources-for-2d-rendering-contexts:dom-media-have_metadata"><a href="https://html.spec.whatwg.org/multipage/media.html#dom-media-have_metadata">HAVE_METADATA</a></code>, then return <i>bad</i> and abort these
-   steps.</p></li><li><p>If <var>image</var> is an <code id="image-sources-for-2d-rendering-contexts:htmlorsvgimageelement-4"><a href="#htmlorsvgimageelement">HTMLOrSVGImageElement</a></code> object with an
-   <a href="https://html.spec.whatwg.org/multipage/infrastructure.html#intrinsic-width" id="image-sources-for-2d-rendering-contexts:intrinsic-width">intrinsic width</a> or <a href="https://html.spec.whatwg.org/multipage/infrastructure.html#intrinsic-height" id="image-sources-for-2d-rendering-contexts:intrinsic-height">intrinsic height</a> (or both) equal to zero, then
-   return <i>bad</i> and abort these steps.</p></li><li><p>If <var>image</var> is an <code id="image-sources-for-2d-rendering-contexts:htmlcanvaselement-2"><a href="#htmlcanvaselement">HTMLCanvasElement</a></code> object with either a horizontal
-   dimension or a vertical dimension equal to zero, then return <i>bad</i> and abort these
-   steps.</p></li><li><p>If <var>image</var> is an <code id="image-sources-for-2d-rendering-contexts:imagebitmap-3"><a href="https://html.spec.whatwg.org/multipage/imagebitmap-and-animations.html#imagebitmap">ImageBitmap</a></code> object with its
-   <a href="https://html.spec.whatwg.org/multipage/structured-data.html#detached" id="image-sources-for-2d-rendering-contexts:detached">[[Detached]]</a> internal slot value set to true, then throw an
-   <a data-x-internal="invalidstateerror" href="https://heycam.github.io/webidl/#invalidstateerror" id="image-sources-for-2d-rendering-contexts:invalidstateerror-2">&quot;<code>InvalidStateError</code>&quot;</a> <code id="image-sources-for-2d-rendering-contexts:domexception-2"><a data-x-internal="domexception" href="https://heycam.github.io/webidl/#dfn-DOMException">DOMException</a></code>, return <i>aborted</i>,
-   and abort these steps.</p></li><li><p>Return <i>good</i>.</p></li></ol>
-
-  <p>When a <code id="image-sources-for-2d-rendering-contexts:canvasimagesource-3"><a href="#canvasimagesource">CanvasImageSource</a></code> object represents an <code id="image-sources-for-2d-rendering-contexts:htmlorsvgimageelement-5"><a href="#htmlorsvgimageelement">HTMLOrSVGImageElement</a></code>,
-  the element's image must be used as the source image.</p>
-
-  <p>Specifically, when a <code id="image-sources-for-2d-rendering-contexts:canvasimagesource-4"><a href="#canvasimagesource">CanvasImageSource</a></code> object represents an animated image in an
-  <code id="image-sources-for-2d-rendering-contexts:htmlorsvgimageelement-6"><a href="#htmlorsvgimageelement">HTMLOrSVGImageElement</a></code>, the user agent must use the default image of the animation
-  (the one that the format defines is to be used when animation is not supported or is disabled),
-  or, if there is no such image, the first frame of the animation, when rendering the image for
-  <code id="image-sources-for-2d-rendering-contexts:canvasrenderingcontext2d"><a href="#canvasrenderingcontext2d">CanvasRenderingContext2D</a></code> APIs.</p>
-
-  <p>When a <code id="image-sources-for-2d-rendering-contexts:canvasimagesource-5"><a href="#canvasimagesource">CanvasImageSource</a></code> object represents an <code id="image-sources-for-2d-rendering-contexts:htmlvideoelement-3"><a href="https://html.spec.whatwg.org/multipage/media.html#htmlvideoelement">HTMLVideoElement</a></code>, then
-  the frame at the <a href="https://html.spec.whatwg.org/multipage/media.html#current-playback-position" id="image-sources-for-2d-rendering-contexts:current-playback-position">current playback position</a> when the method with the argument is
-  invoked must be used as the source image when rendering the image for
-  <code id="image-sources-for-2d-rendering-contexts:canvasrenderingcontext2d-2"><a href="#canvasrenderingcontext2d">CanvasRenderingContext2D</a></code> APIs, and the source image's dimensions must be the <a href="https://html.spec.whatwg.org/multipage/media.html#concept-video-intrinsic-width" id="image-sources-for-2d-rendering-contexts:concept-video-intrinsic-width">intrinsic width</a> and <a href="https://html.spec.whatwg.org/multipage/media.html#concept-video-intrinsic-height" id="image-sources-for-2d-rendering-contexts:concept-video-intrinsic-height">intrinsic height</a> of the <a href="https://html.spec.whatwg.org/multipage/media.html#media-resource" id="image-sources-for-2d-rendering-contexts:media-resource">media resource</a>
-  (i.e. after any aspect-ratio correction has been applied).</p>
-
-  <p>When a <code id="image-sources-for-2d-rendering-contexts:canvasimagesource-6"><a href="#canvasimagesource">CanvasImageSource</a></code> object represents an <code id="image-sources-for-2d-rendering-contexts:htmlcanvaselement-3"><a href="#htmlcanvaselement">HTMLCanvasElement</a></code>, the
-  element's bitmap must be used as the source image.</p>
-
-  <p>When a <code id="image-sources-for-2d-rendering-contexts:canvasimagesource-7"><a href="#canvasimagesource">CanvasImageSource</a></code> object represents an element that is <a href="https://html.spec.whatwg.org/multipage/rendering.html#being-rendered" id="image-sources-for-2d-rendering-contexts:being-rendered">being
-  rendered</a> and that element has been resized, the original image data of the source image
-  must be used, not the image as it is rendered (e.g. <code id="image-sources-for-2d-rendering-contexts:attr-dim-width"><a href="https://html.spec.whatwg.org/multipage/embedded-content-other.html#attr-dim-width">width</a></code> and
-  <code id="image-sources-for-2d-rendering-contexts:attr-dim-height"><a href="https://html.spec.whatwg.org/multipage/embedded-content-other.html#attr-dim-height">height</a></code> attributes on the source element have no effect on how
-  the object is interpreted when rendering the image for <code id="image-sources-for-2d-rendering-contexts:canvasrenderingcontext2d-3"><a href="#canvasrenderingcontext2d">CanvasRenderingContext2D</a></code>
-  APIs).</p>
-
-  <p>When a <code id="image-sources-for-2d-rendering-contexts:canvasimagesource-8"><a href="#canvasimagesource">CanvasImageSource</a></code> object represents an <code id="image-sources-for-2d-rendering-contexts:imagebitmap-4"><a href="https://html.spec.whatwg.org/multipage/imagebitmap-and-animations.html#imagebitmap">ImageBitmap</a></code>, the
-  object's bitmap image data must be used as the source image.</p>
-
-  <p><dfn id="the-image-argument-is-not-origin-clean">The <var>image argument</var> is not origin-clean</dfn> if it is an
-  <code id="image-sources-for-2d-rendering-contexts:htmlorsvgimageelement-7"><a href="#htmlorsvgimageelement">HTMLOrSVGImageElement</a></code> or <code id="image-sources-for-2d-rendering-contexts:htmlvideoelement-4"><a href="https://html.spec.whatwg.org/multipage/media.html#htmlvideoelement">HTMLVideoElement</a></code> whose <a href="https://html.spec.whatwg.org/multipage/origin.html#concept-origin" id="image-sources-for-2d-rendering-contexts:concept-origin">origin</a> is
-  not the <a href="https://html.spec.whatwg.org/multipage/origin.html#same-origin" id="image-sources-for-2d-rendering-contexts:same-origin">same</a> as the <a href="https://html.spec.whatwg.org/multipage/webappapis.html#concept-settings-object-origin" id="image-sources-for-2d-rendering-contexts:concept-settings-object-origin">origin</a> specified by the <a href="https://html.spec.whatwg.org/multipage/webappapis.html#entry-settings-object" id="image-sources-for-2d-rendering-contexts:entry-settings-object">entry settings
-  object</a>, or if it is an <code id="image-sources-for-2d-rendering-contexts:htmlcanvaselement-4"><a href="#htmlcanvaselement">HTMLCanvasElement</a></code> whose bitmap's <a href="#concept-canvas-origin-clean" id="image-sources-for-2d-rendering-contexts:concept-canvas-origin-clean">origin-clean</a> flag is false.</p>
-
-
-
-  <h6 id="fill-and-stroke-styles"><span class="secno">4.12.5.1.9</span> Fill and stroke styles<a class="self-link" href="#fill-and-stroke-styles"/></h6>
-
-  <dl class="domintro"><dt><var>context</var> . <code id="dom-context-2d-fillstyle"><a href="#dom-context-2d-fillstyle-2">fillStyle</a></code> [ = <var>value</var> ]</dt><dd>
-
-    <p>Returns the current style used for filling shapes.</p>
-
-    <p>Can be set, to change the fill style.</p>
-
-    <p>The style can be either a string containing a CSS color, or a <code id="fill-and-stroke-styles:canvasgradient"><a href="#canvasgradient">CanvasGradient</a></code> or
-    <code id="fill-and-stroke-styles:canvaspattern"><a href="#canvaspattern">CanvasPattern</a></code> object. Invalid values are ignored.</p>
-
-   </dd><dt><var>context</var> . <code id="dom-context-2d-strokestyle"><a href="#dom-context-2d-strokestyle-2">strokeStyle</a></code> [ = <var>value</var> ]</dt><dd>
-
-    <p>Returns the current style used for stroking shapes.</p>
-
-    <p>Can be set, to change the stroke style.</p>
-
-    <p>The style can be either a string containing a CSS color, or a <code id="fill-and-stroke-styles:canvasgradient-2"><a href="#canvasgradient">CanvasGradient</a></code> or
-    <code id="fill-and-stroke-styles:canvaspattern-2"><a href="#canvaspattern">CanvasPattern</a></code> object. Invalid values are ignored.</p>
-
-   </dd></dl>
-
-  
-
-  
-
-  <p>Objects that implement the <code id="fill-and-stroke-styles:canvasfillstrokestyles"><a href="#canvasfillstrokestyles">CanvasFillStrokeStyles</a></code> interface have attributes and
-  methods (defined in this section) that control how shapes are treated by the object.</p>
-
-  <p>The <dfn id="dom-context-2d-fillstyle-2"><code>fillStyle</code></dfn> attribute represents the
-  color or style to use inside shapes, and the <dfn id="dom-context-2d-strokestyle-2"><code>strokeStyle</code></dfn> attribute represents the color
-  or style to use for the lines around the shapes.</p>
-
-  <p>Both attributes can be either strings, <code id="fill-and-stroke-styles:canvasgradient-3"><a href="#canvasgradient">CanvasGradient</a></code>s, or
-  <code id="fill-and-stroke-styles:canvaspattern-3"><a href="#canvaspattern">CanvasPattern</a></code>s. On setting, strings must be <a href="https://html.spec.whatwg.org/multipage/infrastructure.html#parsed-as-a-css-color-value" id="fill-and-stroke-styles:parsed-as-a-css-color-value">parsed as CSS &lt;color&gt; values</a> and the color assigned, and
-  <code id="fill-and-stroke-styles:canvasgradient-4"><a href="#canvasgradient">CanvasGradient</a></code> and <code id="fill-and-stroke-styles:canvaspattern-4"><a href="#canvaspattern">CanvasPattern</a></code> objects must be assigned themselves. <a href="https://html.spec.whatwg.org/multipage/references.html#refsCSSCOLOR">[CSSCOLOR]</a> If the value is a string but cannot be <a href="https://html.spec.whatwg.org/multipage/infrastructure.html#parsed-as-a-css-color-value" id="fill-and-stroke-styles:parsed-as-a-css-color-value-2">parsed as a CSS
-  &lt;color&gt; value</a>, then it must be ignored, and the attribute must retain its previous
-  value.
-
-  If the new value is a <code id="fill-and-stroke-styles:canvaspattern-5"><a href="#canvaspattern">CanvasPattern</a></code> object that is marked as <a href="#concept-canvas-pattern-not-origin-clean" id="fill-and-stroke-styles:concept-canvas-pattern-not-origin-clean">not origin-clean</a>, then the
-  <code id="fill-and-stroke-styles:canvasrenderingcontext2d"><a href="#canvasrenderingcontext2d">CanvasRenderingContext2D</a></code>'s <a href="#concept-canvas-origin-clean" id="fill-and-stroke-styles:concept-canvas-origin-clean">origin-clean</a> flag must be set to false.
-
-  </p>
-
-  <p>When set to a <code id="fill-and-stroke-styles:canvaspattern-6"><a href="#canvaspattern">CanvasPattern</a></code> or <code id="fill-and-stroke-styles:canvasgradient-5"><a href="#canvasgradient">CanvasGradient</a></code> object, the assignment
-  is <a href="https://html.spec.whatwg.org/multipage/infrastructure.html#live" id="fill-and-stroke-styles:live">live</a>, meaning that changes made to the object after the assignment do affect
-  subsequent stroking or filling of shapes.</p>
-
-  <p>On getting, if the value is a color, then the <a href="#serialisation-of-a-color" id="fill-and-stroke-styles:serialisation-of-a-color">serialization of the color</a> must be returned. Otherwise, if it is not a color but a
-  <code id="fill-and-stroke-styles:canvasgradient-6"><a href="#canvasgradient">CanvasGradient</a></code> or <code id="fill-and-stroke-styles:canvaspattern-7"><a href="#canvaspattern">CanvasPattern</a></code>, then the respective object must be
-  returned. (Such objects are opaque and therefore only useful for assigning to other attributes or
-  for comparison to other gradients or patterns.)</p>
-
-  <p>The <dfn id="serialisation-of-a-color">serialization of a color</dfn> for a color
-  value is a string, computed as follows: if it has alpha equal to 1.0, then the string is a
-  lowercase six-digit hex value, prefixed with a &quot;#&quot; character (U+0023 NUMBER SIGN), with the first
-  two digits representing the red component, the next two digits representing the green component,
-  and the last two digits representing the blue component, the digits being <a data-x-internal="lowercase-ascii-hex-digits" href="https://infra.spec.whatwg.org/#ascii-lower-hex-digit" id="fill-and-stroke-styles:lowercase-ascii-hex-digits">ASCII lower hex digits</a>. Otherwise, the color value has alpha less than
-  1.0, and the string is the color value in the CSS <code>rgba()</code>
-  functional-notation format: the literal string &quot;<code>rgba</code>&quot; (U+0072 U+0067 U+0062
-  U+0061) followed by a U+0028 LEFT PARENTHESIS, a base-ten integer in the range 0-255 representing
-  the red component (using <a data-x-internal="ascii-digits" href="https://infra.spec.whatwg.org/#ascii-digit" id="fill-and-stroke-styles:ascii-digits">ASCII digits</a> in the shortest form possible), a literal
-  U+002C COMMA and U+0020 SPACE, an integer for the green component, a comma and a space, an integer
-  for the blue component, another comma and space, a U+0030 DIGIT ZERO, if the alpha value is
-  greater than zero then a U+002E FULL STOP (representing the decimal point), if the alpha value is
-  greater than zero then one or more <a data-x-internal="ascii-digits" href="https://infra.spec.whatwg.org/#ascii-digit" id="fill-and-stroke-styles:ascii-digits-2">ASCII digits</a> representing the fractional part of
-  the alpha, and finally a U+0029
-  RIGHT PARENTHESIS. User agents must express the fractional part of the alpha value, if any, with
-  the level of precision necessary for the alpha value, when reparsed, to be interpreted as the same
-  alpha value.</p>
-  
-
-  <p>When the context is created, the <code id="fill-and-stroke-styles:dom-context-2d-fillstyle-2"><a href="#dom-context-2d-fillstyle-2">fillStyle</a></code> and <code id="fill-and-stroke-styles:dom-context-2d-strokestyle-2"><a href="#dom-context-2d-strokestyle-2">strokeStyle</a></code> attributes
-  must initially have the string value <code>#000000</code>.</p>
-
-  <p>When the value is a color, it must not be affected by the transformation matrix when used to
-  draw on bitmaps.</p> 
-
-  
-
-  <hr/>
-
-  <p>There are two types of gradients, linear gradients and radial gradients, both represented by
-  objects implementing the opaque <code id="fill-and-stroke-styles:canvasgradient-7"><a href="#canvasgradient">CanvasGradient</a></code> interface.</p>
-
-  <p id="interpolation">Once a gradient has been created (see below), stops are placed along it to
-  define how the colors are distributed along the gradient. The color of the
-  gradient at each stop is the color specified for that stop. Between each such stop, the colors and
-  the alpha component must be linearly interpolated over the RGBA space without premultiplying the
-  alpha value to find the color to use at that offset. Before the first stop, the color must be the
-  color of the first stop. After the last stop, the color must be the color of the last stop. When
-  there are no stops, the gradient is transparent black.</p>
-
-  <dl class="domintro"><dt><var>gradient</var> . <code id="dom-canvasgradient-addcolorstop"><a href="#dom-canvasgradient-addcolorstop-2">addColorStop</a></code>(<var>offset</var>, <var>color</var>)</dt><dd>
-
-    <p>Adds a color stop with the given color to the gradient at the given offset. 0.0 is the offset
-    at one end of the gradient, 1.0 is the offset at the other end.</p>
-
-    <p>Throws an <a data-x-internal="indexsizeerror" href="https://heycam.github.io/webidl/#indexsizeerror" id="fill-and-stroke-styles:indexsizeerror">&quot;<code>IndexSizeError</code>&quot;</a> <code id="fill-and-stroke-styles:domexception"><a data-x-internal="domexception" href="https://heycam.github.io/webidl/#dfn-DOMException">DOMException</a></code> if the offset
-    is out of range. Throws a <a data-x-internal="syntaxerror" href="https://heycam.github.io/webidl/#syntaxerror" id="fill-and-stroke-styles:syntaxerror">&quot;<code>SyntaxError</code>&quot;</a> <code id="fill-and-stroke-styles:domexception-2"><a data-x-internal="domexception" href="https://heycam.github.io/webidl/#dfn-DOMException">DOMException</a></code> if
-    the color cannot be parsed.</p>
-
-   </dd><dt><var>gradient</var> = <var>context</var> . <code id="dom-context-2d-createlineargradient"><a href="#dom-context-2d-createlineargradient-2">createLinearGradient</a></code>(<var>x0</var>, <var>y0</var>, <var>x1</var>, <var>y1</var>)</dt><dd>
-
-    <p>Returns a <code id="fill-and-stroke-styles:canvasgradient-8"><a href="#canvasgradient">CanvasGradient</a></code> object that represents a
-    linear gradient that paints along the line given by the
-    coordinates represented by the arguments.</p>
-
-   </dd><dt><var>gradient</var> = <var>context</var> . <code id="dom-context-2d-createradialgradient"><a href="#dom-context-2d-createradialgradient-2">createRadialGradient</a></code>(<var>x0</var>, <var>y0</var>, <var>r0</var>, <var>x1</var>, <var>y1</var>, <var>r1</var>)</dt><dd>
-
-    <p>Returns a <code id="fill-and-stroke-styles:canvasgradient-9"><a href="#canvasgradient">CanvasGradient</a></code> object that represents a
-    radial gradient that paints along the cone given by the circles
-    represented by the arguments.</p>
-
-    <p>If either of the radii are negative, throws an
-    <a data-x-internal="indexsizeerror" href="https://heycam.github.io/webidl/#indexsizeerror" id="fill-and-stroke-styles:indexsizeerror-2">&quot;<code>IndexSizeError</code>&quot;</a> <code id="fill-and-stroke-styles:domexception-3"><a data-x-internal="domexception" href="https://heycam.github.io/webidl/#dfn-DOMException">DOMException</a></code> exception.</p>
-
-   </dd></dl>
-
-  
-
-  <p>The <dfn id="dom-canvasgradient-addcolorstop-2"><code>addColorStop(<var>offset</var>,
-  <var>color</var>)</code></dfn> method on the <code id="fill-and-stroke-styles:canvasgradient-10"><a href="#canvasgradient">CanvasGradient</a></code> interface adds a new stop
-  to a gradient. If the <var>offset</var> is less than 0 or greater than 1 then an
-  <a data-x-internal="indexsizeerror" href="https://heycam.github.io/webidl/#indexsizeerror" id="fill-and-stroke-styles:indexsizeerror-3">&quot;<code>IndexSizeError</code>&quot;</a> <code id="fill-and-stroke-styles:domexception-4"><a data-x-internal="domexception" href="https://heycam.github.io/webidl/#dfn-DOMException">DOMException</a></code> must be thrown. If the
-  <var>color</var> cannot be <a href="https://html.spec.whatwg.org/multipage/infrastructure.html#parsed-as-a-css-color-value" id="fill-and-stroke-styles:parsed-as-a-css-color-value-3">parsed as a CSS &lt;color&gt; value</a>, then a
-  <a data-x-internal="syntaxerror" href="https://heycam.github.io/webidl/#syntaxerror" id="fill-and-stroke-styles:syntaxerror-2">&quot;<code>SyntaxError</code>&quot;</a> <code id="fill-and-stroke-styles:domexception-5"><a data-x-internal="domexception" href="https://heycam.github.io/webidl/#dfn-DOMException">DOMException</a></code> must be thrown. Otherwise, the
-  gradient must have a new stop placed, at offset <var>offset</var> relative to the whole gradient,
-  and with the color obtained by <a href="https://html.spec.whatwg.org/multipage/infrastructure.html#parsed-as-a-css-color-value" id="fill-and-stroke-styles:parsed-as-a-css-color-value-4">parsing
-  <var>color</var> as a CSS &lt;color&gt; value</a>. If multiple stops are added at the same
-  offset on a gradient, then they must be placed in the order added, with the first one closest to
-  the start of the gradient, and each subsequent one infinitesimally further along towards the end
-  point (in effect causing all but the first and last stop added at each point to be ignored).</p>
-
-  <p>The <dfn id="dom-context-2d-createlineargradient-2"><code>createLinearGradient(<var>x0</var>,
-  <var>y0</var>, <var>x1</var>, <var>y1</var>)</code></dfn> method takes four arguments that
-  represent the start point (<var>x0</var>, <var>y0</var>) and end point (<var>x1</var>,
-  <var>y1</var>) of the gradient. The method, when invoked, must return a linear
-  <code id="fill-and-stroke-styles:canvasgradient-11"><a href="#canvasgradient">CanvasGradient</a></code> initialized with the specified line.</p>
-
-  <p>Linear gradients must be rendered such that all points on a line perpendicular to the line that
-  crosses the start and end points have the color at the point where those two lines cross (with the
-  colors coming from the <a href="#interpolation">interpolation and extrapolation</a> described
-  above). The points in the linear gradient must be transformed as described by the <a href="#transformations" id="fill-and-stroke-styles:transformations">current transformation matrix</a> when rendering.</p>
-
-  <p>If <var>x0</var> = <var>x1</var> and <span><var>y0</var> = <var>y1</var></span>, then the linear
-  gradient must paint nothing.</p>
-
-  <p>The <dfn id="dom-context-2d-createradialgradient-2"><code>createRadialGradient(<var>x0</var>,
-  <var>y0</var>, <var>r0</var>, <var>x1</var>, <var>y1</var>, <var>r1</var>)</code></dfn> method
-  takes six arguments, the first three representing the start circle with origin (<var>x0</var>,
-  <var>y0</var>) and radius <var>r0</var>, and the last three representing the end circle with
-  origin (<var>x1</var>, <var>y1</var>) and radius <var>r1</var>. The values are in coordinate space
-  units. If either of <var>r0</var> or <var>r1</var> are negative, then an
-  <a data-x-internal="indexsizeerror" href="https://heycam.github.io/webidl/#indexsizeerror" id="fill-and-stroke-styles:indexsizeerror-4">&quot;<code>IndexSizeError</code>&quot;</a> <code id="fill-and-stroke-styles:domexception-6"><a data-x-internal="domexception" href="https://heycam.github.io/webidl/#dfn-DOMException">DOMException</a></code> must be thrown. Otherwise,
-  the method, when invoked, must return a radial <code id="fill-and-stroke-styles:canvasgradient-12"><a href="#canvasgradient">CanvasGradient</a></code> initialized with the
-  two specified circles.</p>
-
-  <p>Radial gradients must be rendered by following these steps:</p>
-
-  <ol><li><p>If <var>x<sub>0</sub></var> = <var>x<sub>1</sub></var> and <var>y<sub>0</sub></var> = <var>y<sub>1</sub></var> and <var>r<sub>0</sub></var> = <var>r<sub>1</sub></var>, then the radial gradient must
-   paint nothing. Abort these steps.</p></li><li>
-
-    <p>Let <span>x(<var>ω</var>) = (<var>x<sub>1</sub></var>-<var>x<sub>0</sub></var>)<var>ω</var> + <var>x<sub>0</sub></var></span></p>
-
-    <p>Let <span>y(<var>ω</var>) = (<var>y<sub>1</sub></var>-<var>y<sub>0</sub></var>)<var>ω</var> + <var>y<sub>0</sub></var></span></p>
-
-    <p>Let <span>r(<var>ω</var>) = (<var>r<sub>1</sub></var>-<var>r<sub>0</sub></var>)<var>ω</var> + <var>r<sub>0</sub></var></span></p>
-
-    <p>Let the color at <var>ω</var> be the color at that position on the gradient
-    (with the colors coming from the <a href="#interpolation">interpolation and extrapolation</a>
-    described above).</p>
-
-   </li><li><p>For all values of <var>ω</var> where <span>r(<var>ω</var>) &gt; 0</span>, starting with the value of <var>ω</var> nearest to positive infinity and ending with the value of <var>ω</var> nearest to negative infinity, draw the circumference of the circle with
-   radius <span>r(<var>ω</var>)</span> at position (<span>x(<var>ω</var>)</span>, <span>y(<var>ω</var>)</span>), with the
-   color at <var>ω</var>, but only painting on the parts of the bitmap that have not
-   yet been painted on by earlier circles in this step for this rendering of the gradient.</p></li></ol>
-
-  <p class="note">This effectively creates a cone, touched by the two circles defined in the
-  creation of the gradient, with the part of the cone before the start circle (0.0) using the color
-  of the first offset, the part of the cone after the end circle (1.0) using the color of the last
-  offset, and areas outside the cone untouched by the gradient (transparent black).</p>
-
-  <p>The resulting radial gradient must then be transformed as described by the <a href="#transformations" id="fill-and-stroke-styles:transformations-2">current transformation matrix</a> when rendering.</p>
-
-  <p>Gradients must be painted only where the relevant stroking or filling effects requires that
-  they be drawn.</p>
-
-  
-
-  <hr/>
-
-  <p>Patterns are represented by objects implementing the opaque <code id="fill-and-stroke-styles:canvaspattern-8"><a href="#canvaspattern">CanvasPattern</a></code>
-  interface.</p>
-
-  <dl class="domintro"><dt><var>pattern</var> = <var>context</var> . <code id="dom-context-2d-createpattern"><a href="#dom-context-2d-createpattern-2">createPattern</a></code>(<var>image</var>, <var>repetition</var>)</dt><dd>
-
-    <p>Returns a <code id="fill-and-stroke-styles:canvaspattern-9"><a href="#canvaspattern">CanvasPattern</a></code> object that uses the given image and repeats in the
-    direction(s) given by the <var>repetition</var> argument.</p>
-
-    <p>The allowed values for <var>repetition</var> are <code>repeat</code> (both
-    directions), <code>repeat-x</code> (horizontal only), <code>repeat-y</code>
-    (vertical only), and <code>no-repeat</code> (neither). If the <var>repetition</var> argument is empty, the value <code>repeat</code> is used.</p>
-
-    <p>If the image isn't yet fully decoded, then nothing is drawn. If the image is a canvas with no
-    data, throws an <a data-x-internal="invalidstateerror" href="https://heycam.github.io/webidl/#invalidstateerror" id="fill-and-stroke-styles:invalidstateerror">&quot;<code>InvalidStateError</code>&quot;</a> <code id="fill-and-stroke-styles:domexception-7"><a data-x-internal="domexception" href="https://heycam.github.io/webidl/#dfn-DOMException">DOMException</a></code>.</p>
-
-   </dd><dt><var>pattern</var> . <code id="dom-canvaspattern-settransform"><a href="#dom-canvaspattern-settransform-2">setTransform</a></code>(<var>transform</var>)</dt><dd>
-
-    <p>Sets the transformation matrix that will be used when rendering the pattern during a fill or
-    stroke painting operation.</p>
-
-   </dd></dl>
-
-  
-
-  <p>The <dfn id="dom-context-2d-createpattern-2"><code>createPattern(<var>image</var>,
-  <var>repetition</var>)</code></dfn> method, when invoked, must run these steps:</p>
-
-  <ol><li><p>Let <var>image</var> be the first argument and <var>repetition</var> be
-   the second argument.</p></li><li><p><a href="#check-the-usability-of-the-image-argument" id="fill-and-stroke-styles:check-the-usability-of-the-image-argument">Check the usability of the <var>image</var> argument</a>. If this
-   returns <i>aborted</i>, then an exception has been thrown and the method doesn't return anything;
-   abort these steps. If it returns <i>bad</i>, then return null and abort these steps. Otherwise it
-   returns <i>good</i>; continue with these steps.</p></li><li><p>If <var>repetition</var> is the empty string, then set it to &quot;<code>repeat</code>&quot;.</p>
-
-   </li><li><p>If <var>repetition</var> is not a <a href="https://html.spec.whatwg.org/multipage/infrastructure.html#case-sensitive" id="fill-and-stroke-styles:case-sensitive">case-sensitive</a> match for one of
-   &quot;<code>repeat</code>&quot;, &quot;<code>repeat-x</code>&quot;, &quot;<code>repeat-y</code>&quot;, or &quot;<code>no-repeat</code>&quot;, then throw a
-   <a data-x-internal="syntaxerror" href="https://heycam.github.io/webidl/#syntaxerror" id="fill-and-stroke-styles:syntaxerror-3">&quot;<code>SyntaxError</code>&quot;</a> <code id="fill-and-stroke-styles:domexception-8"><a data-x-internal="domexception" href="https://heycam.github.io/webidl/#dfn-DOMException">DOMException</a></code> and abort these steps.</p></li><li><p>Create a new <code id="fill-and-stroke-styles:canvaspattern-10"><a href="#canvaspattern">CanvasPattern</a></code> object with the image <var>image</var>
-   and the repetition behavior given by <var>repetition</var>.</p></li><li><p>If <a href="#the-image-argument-is-not-origin-clean" id="fill-and-stroke-styles:the-image-argument-is-not-origin-clean">the <var>image argument</var> is not origin-clean</a>, then mark the
-   <code id="fill-and-stroke-styles:canvaspattern-11"><a href="#canvaspattern">CanvasPattern</a></code> object as <dfn id="concept-canvas-pattern-not-origin-clean">not
-   origin-clean</dfn>.</p></li><li><p>Return the <code id="fill-and-stroke-styles:canvaspattern-12"><a href="#canvaspattern">CanvasPattern</a></code> object.</p></li></ol>
-
-  <p>Modifying the <var>image</var> used when creating a <code id="fill-and-stroke-styles:canvaspattern-13"><a href="#canvaspattern">CanvasPattern</a></code> object
-  after calling the <code id="fill-and-stroke-styles:dom-context-2d-createpattern-2"><a href="#dom-context-2d-createpattern-2">createPattern()</a></code> method must
-  not affect the pattern(s) rendered by the <code id="fill-and-stroke-styles:canvaspattern-14"><a href="#canvaspattern">CanvasPattern</a></code> object.</p>
-
-  <p>Patterns have a transformation matrix, which controls how the pattern is used when it is
-  painted. Initially, a pattern's transformation matrix must be the identity transform.</p>
-
-  <p>The <dfn id="dom-canvaspattern-settransform-2"><code>setTransform(<var>transform</var>)</code></dfn> method,
-  when invoked, must reset the pattern's transformation matrix to the value represented by the
-  result of <a data-x-internal="create-a-dommatrix-from-a-dictionary" href="https://drafts.fxtf.org/geometry/#create-a-dommatrix-from-the-dictionary" id="fill-and-stroke-styles:create-a-dommatrix-from-a-dictionary">creating a <code>DOMMatrix</code>
-  from a dictionary</a> <var>transform</var>, with <var>ignore3D</var> set to true.</p>
-
-  <p>When a pattern is to be rendered within an area, the user agent must run the following steps to
-  determine what is rendered:</p>
-
-  <ol><li><p>Create an infinite transparent black bitmap.</p></li><li>
-
-    <p>Place a copy of the image on the bitmap, anchored such that its top left corner is at the
-    origin of the coordinate space, with one coordinate space unit per <a data-x-internal="'px'" href="https://drafts.csswg.org/css-values/#px" id="fill-and-stroke-styles:'px'">CSS
-    pixel</a> of the image, then place repeated copies of this image horizontally to the left and
-    right, if the repetition behavior is &quot;<code>repeat-x</code>&quot;, or vertically up and
-    down, if the repetition behavior is &quot;<code>repeat-y</code>&quot;, or in all four
-    directions all over the bitmap, if the repetition behavior is &quot;<code>repeat</code>&quot;.</p>
-
-    <p>If the original image data is a bitmap image, then the value painted at a point in the area
-    of the repetitions is computed by filtering the original image data. When scaling up, if the
-    <code id="fill-and-stroke-styles:dom-context-2d-imagesmoothingenabled-2"><a href="#dom-context-2d-imagesmoothingenabled-2">imageSmoothingEnabled</a></code> attribute is
-    set to false, then the image must be rendered using nearest-neighbor interpolation. Otherwise,
-    the user agent may use any filtering algorithm (for example bilinear interpolation or
-    nearest-neighbor). User agents which support multiple filtering algorithms may use the value of
-    the <code id="fill-and-stroke-styles:dom-context-2d-imagesmoothingquality-2"><a href="#dom-context-2d-imagesmoothingquality-2">imageSmoothingQuality</a></code> attribute
-    to guide the choice of filtering algorithm. When such a filtering algorithm requires a pixel
-    value from outside the original image data, it must instead use the value from wrapping the
-    pixel's coordinates to the original image's dimensions. (That is, the filter uses 'repeat'
-    behavior, regardless of the value of the pattern's repetition behavior.)</p> 
-
-   </li><li><p>Transform the resulting bitmap according to the pattern's transformation matrix.</p></li><li><p>Transform the resulting bitmap again, this time according to the <a href="#transformations" id="fill-and-stroke-styles:transformations-3">current transformation matrix</a>.</p></li><li><p>Replace any part of the image outside the area in which the pattern is to be rendered with
-   transparent black.</p></li><li><p>The resulting bitmap is what is to be rendered, with the same origin and same
-   scale.</p></li></ol>
-
-  <hr/>
-
-  <p>If a radial gradient or repeated pattern is used when the transformation matrix is singular,
-  then the resulting style must be transparent black (otherwise the gradient or pattern would be
-  collapsed to a point or line, leaving the other pixels undefined). Linear gradients and solid
-  colors always define all points even with singular transformation matrices.</p>
-
-  
-
-
-
-
-  <h6 id="drawing-rectangles-to-the-bitmap"><span class="secno">4.12.5.1.10</span> Drawing rectangles to the bitmap<a class="self-link" href="#drawing-rectangles-to-the-bitmap"/></h6>
-
-  <p>Objects that implement the <code id="drawing-rectangles-to-the-bitmap:canvasrect"><a href="#canvasrect">CanvasRect</a></code> interface provide the following methods for
-  immediately drawing rectangles to the bitmap. The methods each take four arguments; the first two
-  give the <var>x</var> and <var>y</var> coordinates of the top left of the rectangle, and the
-  second two give the width <var>w</var> and height <var>h</var> of the rectangle, respectively.</p>
-
-  
-
-  <p>The <a href="#transformations" id="drawing-rectangles-to-the-bitmap:transformations">current transformation matrix</a> must be
-  applied to the following four coordinates, which form the path that must then be closed to get the
-  specified rectangle: <span>(<var>x</var>, <var>y</var>)</span>, <span>(<var>x</var>+<var>w</var>, <var>y</var>)</span>, <span>(<var>x</var>+<var>w</var>, <var>y</var>+<var>h</var>)</span>, <span>(<var>x</var>, <var>y</var>+<var>h</var>)</span>.</p>
-
-  <p>Shapes are painted without affecting the <a href="#current-default-path" id="drawing-rectangles-to-the-bitmap:current-default-path">current default path</a>, and are subject to
-  the <a href="#clipping-region" id="drawing-rectangles-to-the-bitmap:clipping-region">clipping region</a>, and, with the exception of <code id="drawing-rectangles-to-the-bitmap:dom-context-2d-clearrect-2"><a href="#dom-context-2d-clearrect-2">clearRect()</a></code>, also <a href="#shadows" id="drawing-rectangles-to-the-bitmap:shadows">shadow
-  effects</a>, <a href="#dom-context-2d-globalalpha-2" id="drawing-rectangles-to-the-bitmap:dom-context-2d-globalalpha-2">global alpha</a>, and <a href="#dom-context-2d-globalcompositeoperation-2" id="drawing-rectangles-to-the-bitmap:dom-context-2d-globalcompositeoperation-2">global composition operators</a>.</p>
-
-  
-
-  <dl class="domintro"><dt><var>context</var> . <code id="dom-context-2d-clearrect"><a href="#dom-context-2d-clearrect-2">clearRect</a></code>(<var>x</var>, <var>y</var>, <var>w</var>, <var>h</var>)</dt><dd>
-
-    <p>Clears all pixels on the bitmap in the given rectangle to transparent black.</p>
-
-   </dd><dt><var>context</var> . <code id="dom-context-2d-fillrect"><a href="#dom-context-2d-fillrect-2">fillRect</a></code>(<var>x</var>, <var>y</var>, <var>w</var>, <var>h</var>)</dt><dd>
-
-    <p>Paints the given rectangle onto the bitmap, using the current fill style.</p>
-
-   </dd><dt><var>context</var> . <code id="dom-context-2d-strokerect"><a href="#dom-context-2d-strokerect-2">strokeRect</a></code>(<var>x</var>, <var>y</var>, <var>w</var>, <var>h</var>)</dt><dd>
-
-    <p>Paints the box that outlines the given rectangle onto the bitmap, using the current stroke
-    style.</p>
-
-   </dd></dl>
-
-  
-
-  <p>The <dfn id="dom-context-2d-clearrect-2"><code>clearRect(<var>x</var>, <var>y</var>,
-  <var>w</var>, <var>h</var>)</code></dfn> method, when invoked, must run these steps:</p>
-
-  <ol><li><p>If any of the arguments are infinite or NaN, then abort these steps.</p></li><li><p>Let <var>pixels</var> be the set of pixels in the specified rectangle that also
-   intersect the current <a href="#clipping-region" id="drawing-rectangles-to-the-bitmap:clipping-region-2">clipping region</a>.</p></li><li><p>Clear the pixels in <var>pixels</var> to a fully transparent black, erasing any
-   previous image.</p></li></ol>
-
-  <p class="note">If either height or width are zero, this method has no effect, since the set of
-  pixels would be empty.</p>
-
-  <p>The <dfn id="dom-context-2d-fillrect-2"><code>fillRect(<var>x</var>, <var>y</var>,
-  <var>w</var>, <var>h</var>)</code></dfn> method, when invoked, must must run these steps:</p>
-
-  <ol><li><p>If any of the arguments are infinite or NaN, then abort these steps.</p></li><li><p>If either <var>w</var> or <var>h</var> are zero, then abort these steps.</p></li><li><p>Paint the specified rectangular area using the <code id="drawing-rectangles-to-the-bitmap:dom-context-2d-fillstyle-2"><a href="#dom-context-2d-fillstyle-2">fillStyle</a></code>.</p>
-  </li></ol>
-
-  <p>The <dfn id="dom-context-2d-strokerect-2"><code>strokeRect(<var>x</var>, <var>y</var>,
-  <var>w</var>, <var>h</var>)</code></dfn> method, when invoked, must run these steps:</p>
-
-  <ol><li><p>If any of the arguments are infinite or NaN, then abort these steps.</p></li><li><p>Take the result of <a href="#trace-a-path" id="drawing-rectangles-to-the-bitmap:trace-a-path">tracing the path</a> described below,
-   using the <code id="drawing-rectangles-to-the-bitmap:canvaspathdrawingstyles"><a href="#canvaspathdrawingstyles">CanvasPathDrawingStyles</a></code> interface's line styles, and fill it with the
-   <code id="drawing-rectangles-to-the-bitmap:dom-context-2d-strokestyle-2"><a href="#dom-context-2d-strokestyle-2">strokeStyle</a></code>.</p></li></ol>
-
-  <p>If both <var>w</var> and <var>h</var> are zero, the path has a single subpath
-  with just one point (<var>x</var>, <var>y</var>), and no lines, and this method
-  thus has no effect (the <a href="#trace-a-path" id="drawing-rectangles-to-the-bitmap:trace-a-path-2">trace a path</a> algorithm returns an empty path in that
-  case).</p>
-
-  <p>If just one of either <var>w</var> or <var>h</var> is zero, then the path has
-  a single subpath consisting of two points, with coordinates (<var>x</var>, <var>y</var>) and (<var>x</var>+<var>w</var>, <var>y</var>+<var>h</var>), in that order, connected by a single straight line.</p>
-
-  <p>Otherwise, the path has a single subpath consisting of four points, with coordinates (<span><var>x</var></span>, <var>y</var>), (<span><var>x</var>+<var>w</var></span>, <var>y</var>), (<var>x</var>+<var>w</var>,
-  <var>y</var>+<var>h</var>), and (<var>x</var>, <var>y</var>+<var>h</var>),
-  connected to each other in that order by straight lines.</p>
-
-  
-
-
-
-  <h6 id="drawing-text-to-the-bitmap"><span class="secno">4.12.5.1.11</span> Drawing text to the bitmap<a class="self-link" href="#drawing-text-to-the-bitmap"/></h6><div class="status"><input onclick="toggleStatus(this)" type="button" value="⋰"/><p class="support"><strong>Support:</strong> canvas-text<span class="and_chr yes"><span>Chrome for Android</span> <span>59+</span></span><span class="chrome yes"><span>Chrome</span> <span>4+</span></span><span class="and_uc yes"><span>UC Browser for Android</span> <span>11.4+</span></span><span class="ios_saf yes"><span>iOS Safari</span> <span>3.2+</span></span><span class="firefox yes"><span>Firefox</span> <span>3.5+</span></span><span class="ie yes"><span>IE</span> <span>9+</span></span><span class="samsung yes"><span>Samsung Internet</span> <span>4+</span></span><span class="op_mini no"><span>Opera Mini</span> <span>None</span></span><span class="safari yes"><span>Safari</span> <span>4+</span></span><span class="android yes"><span>Android Browser</span> <span>2.1+</span></span><span class="opera yes"><span>Opera</span> <span>10.5+</span></span><span class="edge yes"><span>Edge</span> <span>12+</span></span></p><p class="caniuse">Source: <a href="https://caniuse.com/#feat=canvas-text">caniuse.com</a></p></div>
-
-  <dl class="domintro" id="text-0"><dt><var>context</var> . <code id="dom-context-2d-filltext"><a href="#dom-context-2d-filltext-2">fillText</a></code>(<var>text</var>, <var>x</var>, <var>y</var> [, <var>maxWidth</var> ] )</dt><dt><var>context</var> . <code id="dom-context-2d-stroketext"><a href="#dom-context-2d-stroketext-2">strokeText</a></code>(<var>text</var>, <var>x</var>, <var>y</var> [, <var>maxWidth</var> ] )</dt><dd>
-
-    <p>Fills or strokes (respectively) the given text at the given position. If a maximum width is
-    provided, the text will be scaled to fit that width if necessary.</p>
-
-   </dd><dt><var>metrics</var> = <var>context</var> . <code id="dom-context-2d-measuretext"><a href="#dom-context-2d-measuretext-2">measureText</a></code>(<var>text</var>)</dt><dd>
-
-    <p>Returns a <code id="drawing-text-to-the-bitmap:textmetrics"><a href="#textmetrics">TextMetrics</a></code> object with the metrics of the given text in the current
-    font.</p>
-
-   </dd><dt><var>metrics</var> . <code id="dom-textmetrics-width"><a href="#dom-textmetrics-width-2">width</a></code></dt><dt><var>metrics</var> . <code id="dom-textmetrics-actualboundingboxleft"><a href="#dom-textmetrics-actualboundingboxleft-2">actualBoundingBoxLeft</a></code></dt><dt><var>metrics</var> . <code id="dom-textmetrics-actualboundingboxright"><a href="#dom-textmetrics-actualboundingboxright-2">actualBoundingBoxRight</a></code></dt><dt><var>metrics</var> . <code id="dom-textmetrics-fontboundingboxascent"><a href="#dom-textmetrics-fontboundingboxascent-2">fontBoundingBoxAscent</a></code></dt><dt><var>metrics</var> . <code id="dom-textmetrics-fontboundingboxdescent"><a href="#dom-textmetrics-fontboundingboxdescent-2">fontBoundingBoxDescent</a></code></dt><dt><var>metrics</var> . <code id="dom-textmetrics-actualboundingboxascent"><a href="#dom-textmetrics-actualboundingboxascent-2">actualBoundingBoxAscent</a></code></dt><dt><var>metrics</var> . <code id="dom-textmetrics-actualboundingboxdescent"><a href="#dom-textmetrics-actualboundingboxdescent-2">actualBoundingBoxDescent</a></code></dt><dt><var>metrics</var> . <code id="dom-textmetrics-emheightascent"><a href="#dom-textmetrics-emheightascent-2">emHeightAscent</a></code></dt><dt><var>metrics</var> . <code id="dom-textmetrics-emheightdescent"><a href="#dom-textmetrics-emheightdescent-2">emHeightDescent</a></code></dt><dt><var>metrics</var> . <code id="dom-textmetrics-hangingbaseline"><a href="#dom-textmetrics-hangingbaseline-2">hangingBaseline</a></code></dt><dt><var>metrics</var> . <code id="dom-textmetrics-alphabeticbaseline"><a href="#dom-textmetrics-alphabeticbaseline-2">alphabeticBaseline</a></code></dt><dt><var>metrics</var> . <code id="dom-textmetrics-ideographicbaseline"><a href="#dom-textmetrics-ideographicbaseline-2">ideographicBaseline</a></code></dt><dd>
-
-    <p>Returns the measurement described below.</p>
-
-   </dd></dl>
-
-  
-
-  <p>Objects that implement the <code id="drawing-text-to-the-bitmap:canvastext"><a href="#canvastext">CanvasText</a></code> interface provide the following methods for
-  rendering text.</p>
-
-  <p>The <dfn id="dom-context-2d-filltext-2"><code>fillText()</code></dfn> and <dfn id="dom-context-2d-stroketext-2"><code>strokeText()</code></dfn> methods take three or four arguments,
-  <var>text</var>, <var>x</var>, <var>y</var>, and optionally <var>maxWidth</var>, and render the
-  given <var>text</var> at the given (<var>x</var>, <var>y</var>) coordinates ensuring that the text
-  isn't wider than <var>maxWidth</var> if specified, using the current <code id="drawing-text-to-the-bitmap:dom-context-2d-font-2"><a href="#dom-context-2d-font-2">font</a></code>, <code id="drawing-text-to-the-bitmap:dom-context-2d-textalign-2"><a href="#dom-context-2d-textalign-2">textAlign</a></code>, and <code id="drawing-text-to-the-bitmap:dom-context-2d-textbaseline-2"><a href="#dom-context-2d-textbaseline-2">textBaseline</a></code> values. Specifically, when the methods
-  are invoked, the user agent must run these steps:</p>
-
-  <ol><li><p>If any of the arguments are infinite or NaN, then abort these steps.</p></li><li><p>Run the <a href="#text-preparation-algorithm" id="drawing-text-to-the-bitmap:text-preparation-algorithm">text preparation algorithm</a>, passing it <var>text</var>, the object
-   implementing the <code id="drawing-text-to-the-bitmap:canvastext-2"><a href="#canvastext">CanvasText</a></code> interface, and, if the <var>maxWidth</var> argument was
-   provided, that argument. Let <var>glyphs</var> be the result.</p>
-
-   </li><li><p>Move all the shapes in <var>glyphs</var> to the right by <var>x</var>
-   <a data-x-internal="'px'" href="https://drafts.csswg.org/css-values/#px" id="drawing-text-to-the-bitmap:'px'">CSS pixels</a> and down by <var>y</var> <a data-x-internal="'px'" href="https://drafts.csswg.org/css-values/#px" id="drawing-text-to-the-bitmap:'px'-2">CSS
-   pixels</a>.</p></li><li>
-
-    <p>Paint the shapes given in <var>glyphs</var>, as transformed by the <a href="#transformations" id="drawing-text-to-the-bitmap:transformations">current transformation matrix</a>, with each <a data-x-internal="'px'" href="https://drafts.csswg.org/css-values/#px" id="drawing-text-to-the-bitmap:'px'-3">CSS pixel</a> in the coordinate space of <var>glyphs</var> mapped to one
-    coordinate space unit.</p>
-
-    <p>For <code id="drawing-text-to-the-bitmap:dom-context-2d-filltext-2"><a href="#dom-context-2d-filltext-2">fillText()</a></code>, <code id="drawing-text-to-the-bitmap:dom-context-2d-fillstyle-2"><a href="#dom-context-2d-fillstyle-2">fillStyle</a></code> must be applied to the shapes and <code id="drawing-text-to-the-bitmap:dom-context-2d-strokestyle-2"><a href="#dom-context-2d-strokestyle-2">strokeStyle</a></code> must be ignored. For <code id="drawing-text-to-the-bitmap:dom-context-2d-stroketext-2"><a href="#dom-context-2d-stroketext-2">strokeText()</a></code>, the reverse holds: <code id="drawing-text-to-the-bitmap:dom-context-2d-strokestyle-2-2"><a href="#dom-context-2d-strokestyle-2">strokeStyle</a></code> must be applied to the result of <a href="#trace-a-path" id="drawing-text-to-the-bitmap:trace-a-path">tracing</a> the shapes using the object implementing the
-    <code id="drawing-text-to-the-bitmap:canvastext-3"><a href="#canvastext">CanvasText</a></code> interface for the line styles, and <code id="drawing-text-to-the-bitmap:dom-context-2d-fillstyle-2-2"><a href="#dom-context-2d-fillstyle-2">fillStyle</a></code> must be ignored.</p>
-
-    <p>These shapes are painted without affecting the current path, and are subject to <a href="#shadows" id="drawing-text-to-the-bitmap:shadows">shadow effects</a>, <a href="#dom-context-2d-globalalpha-2" id="drawing-text-to-the-bitmap:dom-context-2d-globalalpha-2">global
-    alpha</a>, the <a href="#clipping-region" id="drawing-text-to-the-bitmap:clipping-region">clipping region</a>, and <a href="#dom-context-2d-globalcompositeoperation-2" id="drawing-text-to-the-bitmap:dom-context-2d-globalcompositeoperation-2">global composition operators</a>.</p>
-
-   </li></ol>
-
-
-
-  <p>The <dfn id="dom-context-2d-measuretext-2"><code>measureText()</code></dfn> method takes one
-  argument, <var>text</var>. When the method is invoked, the user agent must run the
-  <a href="#text-preparation-algorithm" id="drawing-text-to-the-bitmap:text-preparation-algorithm-2">text preparation algorithm</a>, passing it <var>text</var> and the object implementing
-  the <code id="drawing-text-to-the-bitmap:canvastext-4"><a href="#canvastext">CanvasText</a></code> interface, and then using the returned <a data-x-internal="inline-box" href="https://drafts.csswg.org/css2/visuren.html#inline-box" id="drawing-text-to-the-bitmap:inline-box">inline box</a> must
-  create a new <code id="drawing-text-to-the-bitmap:textmetrics-2"><a href="#textmetrics">TextMetrics</a></code> object with its attributes set as described in the following
-  list.
-
-  If doing these measurements requires using a font that has an <a href="https://html.spec.whatwg.org/multipage/origin.html#concept-origin" id="drawing-text-to-the-bitmap:concept-origin">origin</a> that is not the
-  <a href="https://html.spec.whatwg.org/multipage/origin.html#same-origin" id="drawing-text-to-the-bitmap:same-origin">same</a> as that of the <code id="drawing-text-to-the-bitmap:document"><a href="https://html.spec.whatwg.org/multipage/dom.html#document">Document</a></code> object that owns the
-  <code id="drawing-text-to-the-bitmap:the-canvas-element"><a href="#the-canvas-element">canvas</a></code> element (even if &quot;using a font&quot; means just checking if that font has a
-  particular glyph in it before falling back to another font), then the method, when invoked, must
-  throw a <a data-x-internal="securityerror" href="https://heycam.github.io/webidl/#securityerror" id="drawing-text-to-the-bitmap:securityerror">&quot;<code>SecurityError</code>&quot;</a> <code id="drawing-text-to-the-bitmap:domexception"><a data-x-internal="domexception" href="https://heycam.github.io/webidl/#dfn-DOMException">DOMException</a></code>.
-
-  Otherwise, it must return the new <code id="drawing-text-to-the-bitmap:textmetrics-3"><a href="#textmetrics">TextMetrics</a></code> object.
-  <a href="https://html.spec.whatwg.org/multipage/references.html#refsCSS">[CSS]</a>
-  <a class="fingerprint" href="https://html.spec.whatwg.org/multipage/introduction.html#fingerprinting-vector" id="drawing-text-to-the-bitmap:fingerprinting-vector" title="There is a potential fingerprinting vector here."><img alt="(This is a fingerprinting vector.)" height="64" src="https://html.spec.whatwg.org/images/fingerprint.png" width="46"/></a>
-  </p>
-
-  
-
-  <dl><dt><dfn id="dom-textmetrics-width-2"><code>width</code></dfn> attribute</dt><dd><p>The width of that <a data-x-internal="inline-box" href="https://drafts.csswg.org/css2/visuren.html#inline-box" id="drawing-text-to-the-bitmap:inline-box-2">inline box</a>, in <a data-x-internal="'px'" href="https://drafts.csswg.org/css-values/#px" id="drawing-text-to-the-bitmap:'px'-4">CSS pixels</a>. (The
-   text's advance width.)</p></dd><dt><dfn id="dom-textmetrics-actualboundingboxleft-2"><code>actualBoundingBoxLeft</code></dfn> attribute</dt><dd>
-
-    <p>The distance parallel to the baseline from the alignment point given by the <code id="drawing-text-to-the-bitmap:dom-context-2d-textalign-2-2"><a href="#dom-context-2d-textalign-2">textAlign</a></code> attribute to the left side of the bounding
-    rectangle of the given text, in <a data-x-internal="'px'" href="https://drafts.csswg.org/css-values/#px" id="drawing-text-to-the-bitmap:'px'-5">CSS pixels</a>; positive numbers
-    indicating a distance going left from the given alignment point.
-
-    </p><p class="note">The sum of this value and the next (<code id="drawing-text-to-the-bitmap:dom-textmetrics-actualboundingboxright-2"><a href="#dom-textmetrics-actualboundingboxright-2">actualBoundingBoxRight</a></code>) can be wider than
-    the width of the <a data-x-internal="inline-box" href="https://drafts.csswg.org/css2/visuren.html#inline-box" id="drawing-text-to-the-bitmap:inline-box-3">inline box</a> (<code id="drawing-text-to-the-bitmap:dom-textmetrics-width-2"><a href="#dom-textmetrics-width-2">width</a></code>), in
-    particular with slanted fonts where characters overhang their advance width.</p>
-
-   </dd><dt><dfn id="dom-textmetrics-actualboundingboxright-2"><code>actualBoundingBoxRight</code></dfn> attribute</dt><dd>
-
-    <p>The distance parallel to the baseline from the alignment point given by the <code id="drawing-text-to-the-bitmap:dom-context-2d-textalign-2-3"><a href="#dom-context-2d-textalign-2">textAlign</a></code> attribute to the right side of the bounding
-    rectangle of the given text, in <a data-x-internal="'px'" href="https://drafts.csswg.org/css-values/#px" id="drawing-text-to-the-bitmap:'px'-6">CSS pixels</a>; positive numbers
-    indicating a distance going right from the given alignment point.</p>
-
-   </dd><dt><dfn id="dom-textmetrics-fontboundingboxascent-2"><code>fontBoundingBoxAscent</code></dfn> attribute</dt><dd>
-
-    <p>The distance from the horizontal line indicated by the <code id="drawing-text-to-the-bitmap:dom-context-2d-textbaseline-2-2"><a href="#dom-context-2d-textbaseline-2">textBaseline</a></code> attribute to the top of the highest
-    bounding rectangle of all the fonts used to render the text, in <a data-x-internal="'px'" href="https://drafts.csswg.org/css-values/#px" id="drawing-text-to-the-bitmap:'px'-7">CSS
-    pixels</a>; positive numbers indicating a distance going up from the given baseline.</p>
-
-    <p class="note">This value and the next are useful when rendering a background that have to have
-    a consistent height even if the exact text being rendered changes. The <code id="drawing-text-to-the-bitmap:dom-textmetrics-actualboundingboxascent-2"><a href="#dom-textmetrics-actualboundingboxascent-2">actualBoundingBoxAscent</a></code> attribute (and
-    its corresponding attribute for the descent) are useful when drawing a bounding box around
-    specific text.</p>
-
-   </dd><dt><dfn id="dom-textmetrics-fontboundingboxdescent-2"><code>fontBoundingBoxDescent</code></dfn> attribute</dt><dd><p>The distance from the horizontal line indicated by the <code id="drawing-text-to-the-bitmap:dom-context-2d-textbaseline-2-3"><a href="#dom-context-2d-textbaseline-2">textBaseline</a></code> attribute to the bottom of the lowest
-   bounding rectangle of all the fonts used to render the text, in <a data-x-internal="'px'" href="https://drafts.csswg.org/css-values/#px" id="drawing-text-to-the-bitmap:'px'-8">CSS
-   pixels</a>; positive numbers indicating a distance going down from the given
-   baseline.</p></dd><dt><dfn id="dom-textmetrics-actualboundingboxascent-2"><code>actualBoundingBoxAscent</code></dfn> attribute</dt><dd>
-
-    <p>The distance from the horizontal line indicated by the <code id="drawing-text-to-the-bitmap:dom-context-2d-textbaseline-2-4"><a href="#dom-context-2d-textbaseline-2">textBaseline</a></code> attribute to the top of the bounding
-    rectangle of the given text, in <a data-x-internal="'px'" href="https://drafts.csswg.org/css-values/#px" id="drawing-text-to-the-bitmap:'px'-9">CSS pixels</a>; positive numbers
-    indicating a distance going up from the given baseline.
-
-    </p><p class="note">This number can vary greatly based on the input text, even if the first font
-    specified covers all the characters in the input. For example, the <code id="drawing-text-to-the-bitmap:dom-textmetrics-actualboundingboxascent-2-2"><a href="#dom-textmetrics-actualboundingboxascent-2">actualBoundingBoxAscent</a></code> of a lowercase
-    &quot;o&quot; from an alphabetic baseline would be less than that of an uppercase &quot;F&quot;. The value can
-    easily be negative; for example, the distance from the top of the em box (<code id="drawing-text-to-the-bitmap:dom-context-2d-textbaseline-2-5"><a href="#dom-context-2d-textbaseline-2">textBaseline</a></code> value &quot;<code id="drawing-text-to-the-bitmap:dom-context-2d-textbaseline-top"><a href="#dom-context-2d-textbaseline-top">top</a></code>&quot;) to the top of the bounding rectangle when
-    the given text is just a single comma &quot;<code>,</code>&quot; would likely (unless the font is
-    quite unusual) be negative.</p>
-
-   </dd><dt><dfn id="dom-textmetrics-actualboundingboxdescent-2"><code>actualBoundingBoxDescent</code></dfn> attribute</dt><dd><p>The distance from the horizontal line indicated by the <code id="drawing-text-to-the-bitmap:dom-context-2d-textbaseline-2-6"><a href="#dom-context-2d-textbaseline-2">textBaseline</a></code> attribute to the bottom of the bounding
-   rectangle of the given text, in <a data-x-internal="'px'" href="https://drafts.csswg.org/css-values/#px" id="drawing-text-to-the-bitmap:'px'-10">CSS pixels</a>; positive numbers
-   indicating a distance going down from the given baseline.</p></dd><dt><dfn id="dom-textmetrics-emheightascent-2"><code>emHeightAscent</code></dfn> attribute</dt><dd><p>The distance from the horizontal line indicated by the <code id="drawing-text-to-the-bitmap:dom-context-2d-textbaseline-2-7"><a href="#dom-context-2d-textbaseline-2">textBaseline</a></code> attribute to the highest top of the em
-   squares in the <a data-x-internal="line-box" href="https://drafts.csswg.org/css2/visuren.html#line-box" id="drawing-text-to-the-bitmap:line-box">line box</a>, in <a data-x-internal="'px'" href="https://drafts.csswg.org/css-values/#px" id="drawing-text-to-the-bitmap:'px'-11">CSS pixels</a>; positive numbers
-   indicating that the given baseline is below the top of that em square (so this value will usually
-   be positive). Zero if the given baseline is the top of that em square; half the font size if the
-   given baseline is the middle of that em square.</p></dd><dt><dfn id="dom-textmetrics-emheightdescent-2"><code>emHeightDescent</code></dfn> attribute</dt><dd><p>The distance from the horizontal line indicated by the <code id="drawing-text-to-the-bitmap:dom-context-2d-textbaseline-2-8"><a href="#dom-context-2d-textbaseline-2">textBaseline</a></code> attribute to the lowest bottom of the em
-   squares in the <a data-x-internal="line-box" href="https://drafts.csswg.org/css2/visuren.html#line-box" id="drawing-text-to-the-bitmap:line-box-2">line box</a>, in <a data-x-internal="'px'" href="https://drafts.csswg.org/css-values/#px" id="drawing-text-to-the-bitmap:'px'-12">CSS pixels</a>; positive numbers
-   indicating that the given baseline is below the bottom of that em square (so this value will
-   usually be negative). (Zero if the given baseline is the bottom of that em square.)</p></dd><dt><dfn id="dom-textmetrics-hangingbaseline-2"><code>hangingBaseline</code></dfn> attribute</dt><dd><p>The distance from the horizontal line indicated by the <code id="drawing-text-to-the-bitmap:dom-context-2d-textbaseline-2-9"><a href="#dom-context-2d-textbaseline-2">textBaseline</a></code> attribute to the hanging baseline of the
-   <a data-x-internal="line-box" href="https://drafts.csswg.org/css2/visuren.html#line-box" id="drawing-text-to-the-bitmap:line-box-3">line box</a>, in <a data-x-internal="'px'" href="https://drafts.csswg.org/css-values/#px" id="drawing-text-to-the-bitmap:'px'-13">CSS pixels</a>; positive numbers indicating that
-   the given baseline is below the hanging baseline. (Zero if the given baseline is the hanging
-   baseline.)</p></dd><dt><dfn id="dom-textmetrics-alphabeticbaseline-2"><code>alphabeticBaseline</code></dfn> attribute</dt><dd><p>The distance from the horizontal line indicated by the <code id="drawing-text-to-the-bitmap:dom-context-2d-textbaseline-2-10"><a href="#dom-context-2d-textbaseline-2">textBaseline</a></code> attribute to the alphabetic baseline of
-   the <a data-x-internal="line-box" href="https://drafts.csswg.org/css2/visuren.html#line-box" id="drawing-text-to-the-bitmap:line-box-4">line box</a>, in <a data-x-internal="'px'" href="https://drafts.csswg.org/css-values/#px" id="drawing-text-to-the-bitmap:'px'-14">CSS pixels</a>; positive numbers indicating
-   that the given baseline is below the alphabetic baseline. (Zero if the given baseline is the
-   alphabetic baseline.)</p></dd><dt><dfn id="dom-textmetrics-ideographicbaseline-2"><code>ideographicBaseline</code></dfn> attribute</dt><dd><p>The distance from the horizontal line indicated by the <code id="drawing-text-to-the-bitmap:dom-context-2d-textbaseline-2-11"><a href="#dom-context-2d-textbaseline-2">textBaseline</a></code> attribute to the ideographic baseline of
-   the <a data-x-internal="line-box" href="https://drafts.csswg.org/css2/visuren.html#line-box" id="drawing-text-to-the-bitmap:line-box-5">line box</a>, in <a data-x-internal="'px'" href="https://drafts.csswg.org/css-values/#px" id="drawing-text-to-the-bitmap:'px'-15">CSS pixels</a>; positive numbers indicating
-   that the given baseline is below the ideographic baseline. (Zero if the given baseline is the
-   ideographic baseline.)</p></dd></dl>
-
-  <p class="note">Glyphs rendered using <code id="drawing-text-to-the-bitmap:dom-context-2d-filltext-2-2"><a href="#dom-context-2d-filltext-2">fillText()</a></code> and
-  <code id="drawing-text-to-the-bitmap:dom-context-2d-stroketext-2-2"><a href="#dom-context-2d-stroketext-2">strokeText()</a></code> can spill out of the box given by the
-  font size (the em square size) and the width returned by <code id="drawing-text-to-the-bitmap:dom-context-2d-measuretext-2"><a href="#dom-context-2d-measuretext-2">measureText()</a></code> (the text width). Authors are encouraged
-  to use the bounding box values described above if this is an issue.</p>
-
-  <p class="note">A future version of the 2D context API might provide a way to render fragments of
-  documents, rendered using CSS, straight to the canvas. This would be provided in preference to a
-  dedicated way of doing multiline layout.</p>
-
-
-
-  <h6 id="drawing-paths-to-the-canvas"><span class="secno">4.12.5.1.12</span> Drawing paths to the canvas<a class="self-link" href="#drawing-paths-to-the-canvas"/></h6>
-
-  <p>Objects that implement the <code id="drawing-paths-to-the-canvas:canvasdrawpath"><a href="#canvasdrawpath">CanvasDrawPath</a></code> interface have a <dfn id="current-default-path">current default
-  path</dfn>. There is only one <a href="#current-default-path" id="drawing-paths-to-the-canvas:current-default-path">current default path</a>, it is not part of the
-  <a href="#drawing-state" id="drawing-paths-to-the-canvas:drawing-state">drawing state</a>. The <a href="#current-default-path" id="drawing-paths-to-the-canvas:current-default-path-2">current default path</a> is a <a href="#concept-path" id="drawing-paths-to-the-canvas:concept-path">path</a>, as described above.</p>
-
-  <dl class="domintro"><dt><var>context</var> . <code id="dom-context-2d-beginpath"><a href="#dom-context-2d-beginpath-2">beginPath</a></code>()</dt><dd>
-
-    <p>Resets the <a href="#current-default-path" id="drawing-paths-to-the-canvas:current-default-path-3">current default path</a>.</p>
-
-   </dd><dt><var>context</var> . <code id="dom-context-2d-fill"><a href="#dom-context-2d-fill-2">fill</a></code>( [ <var>fillRule</var> ] )</dt><dt><var>context</var> . <code id="drawing-paths-to-the-canvas:dom-context-2d-fill-2"><a href="#dom-context-2d-fill-2">fill</a></code>(<var>path</var> [, <var>fillRule</var> ] )</dt><dd>
-
-    <p>Fills the subpaths of the <a href="#current-default-path" id="drawing-paths-to-the-canvas:current-default-path-4">current default path</a> or the given path with the
-    current fill style, obeying the given fill rule.</p>
-
-   </dd><dt><var>context</var> . <code id="dom-context-2d-stroke"><a href="#dom-context-2d-stroke-2">stroke</a></code>()</dt><dt><var>context</var> . <code id="drawing-paths-to-the-canvas:dom-context-2d-stroke-2"><a href="#dom-context-2d-stroke-2">stroke</a></code>(<var>path</var>)</dt><dd>
-
-    <p>Strokes the subpaths of the <a href="#current-default-path" id="drawing-paths-to-the-canvas:current-default-path-5">current default path</a> or the given path with the
-    current stroke style.</p>
-
-   </dd><dt><var>context</var> . <code id="dom-context-2d-clip"><a href="#dom-context-2d-clip-2">clip</a></code>( [ <var>fillRule</var> ] )</dt><dt><var>context</var> . <code id="drawing-paths-to-the-canvas:dom-context-2d-clip-2"><a href="#dom-context-2d-clip-2">clip</a></code>(<var>path</var> [, <var>fillRule</var> ] )</dt><dd>
-
-    <p>Further constrains the clipping region to the <a href="#current-default-path" id="drawing-paths-to-the-canvas:current-default-path-6">current default path</a> or the given
-    path, using the given fill rule to determine what points are in the path.</p>
-
-   </dd><dt><var>context</var> . <code id="dom-context-2d-resetclip"><a href="#dom-context-2d-resetclip-2">resetClip</a></code>()</dt><dd>
-
-    <p>Unconstrains the clipping region.</p>
-
-   </dd><dt><var>context</var> . <code id="dom-context-2d-ispointinpath"><a href="#dom-context-2d-ispointinpath-2">isPointInPath</a></code>(<var>x</var>, <var>y</var> [, <var>fillRule</var> ] )</dt><dt><var>context</var> . <code id="drawing-paths-to-the-canvas:dom-context-2d-ispointinpath-2"><a href="#dom-context-2d-ispointinpath-2">isPointInPath</a></code>(<var>path</var>, <var>x</var>, <var>y</var> [, <var>fillRule</var> ] )</dt><dd>
-
-    <p>Returns true if the given point is in the <a href="#current-default-path" id="drawing-paths-to-the-canvas:current-default-path-7">current default path</a> or the given
-    path, using the given fill rule to determine what points are in the path.</p>
-
-   </dd><dt><var>context</var> . <code id="dom-context-2d-ispointinstroke"><a href="#dom-context-2d-ispointinstroke-2">isPointInStroke</a></code>(<var>x</var>, <var>y</var>)</dt><dt><var>context</var> . <code id="drawing-paths-to-the-canvas:dom-context-2d-ispointinstroke-2"><a href="#dom-context-2d-ispointinstroke-2">isPointInStroke</a></code>(<var>path</var>, <var>x</var>, <var>y</var>)</dt><dd>
-
-    <p>Returns true if the given point would be in the region covered by the stroke of the
-    <a href="#current-default-path" id="drawing-paths-to-the-canvas:current-default-path-8">current default path</a> or the given path, given the current stroke style.</p>
-
-   </dd></dl><div class="status"><input onclick="toggleStatus(this)" type="button" value="⋰"/><p class="bugs"><strong>Spec bugs:</strong> <a href="https://www.w3.org/Bugs/Public/show_bug.cgi?id=28217" title="&lt;canvas&gt;: not clear if two polygon paths with a common edge should have no line visible">28217</a></p></div>
-
-  
-
-  <p>The <dfn id="dom-context-2d-beginpath-2"><code>beginPath()</code></dfn> method, when invoked,
-  must empty the list of subpaths in the context's <a href="#current-default-path" id="drawing-paths-to-the-canvas:current-default-path-9">current default path</a> so that the it
-  once again has zero subpaths.</p>
-
-  <p>Where the following method definitions use the term <i>intended path</i>, it means the
-  <code id="drawing-paths-to-the-canvas:path2d"><a href="#path2d">Path2D</a></code> argument, if one was provided, or the <a href="#current-default-path" id="drawing-paths-to-the-canvas:current-default-path-10">current default path</a>
-  otherwise.</p>
-
-  <p>When the intended path is a <code id="drawing-paths-to-the-canvas:path2d-2"><a href="#path2d">Path2D</a></code> object, the coordinates and lines of its
-  subpaths must be transformed according to the <a href="#transformations" id="drawing-paths-to-the-canvas:transformations">
-  current transformation matrix</a> on the object implementing the
-  <code id="drawing-paths-to-the-canvas:canvastransform"><a href="#canvastransform">CanvasTransform</a></code> interface when used by these methods (without affecting the
-  <code id="drawing-paths-to-the-canvas:path2d-3"><a href="#path2d">Path2D</a></code> object itself). When the intended path is the <a href="#current-default-path" id="drawing-paths-to-the-canvas:current-default-path-11">current default
-  path</a>, it is not affected by the transform. (This is because transformations already affect
-  the <a href="#current-default-path" id="drawing-paths-to-the-canvas:current-default-path-12">current default path</a> when it is constructed, so applying it when it is painted as
-  well would result in a double transformation.)</p>
-
-  <p>The <dfn id="dom-context-2d-fill-2"><code>fill()</code></dfn> method, when invoked, must fill
-  all the subpaths of the intended path, using <code id="drawing-paths-to-the-canvas:dom-context-2d-fillstyle-2"><a href="#dom-context-2d-fillstyle-2">fillStyle</a></code>, and using the <a href="#fill-rule" id="drawing-paths-to-the-canvas:fill-rule">fill rule</a> indicated
-  by the <var>fillRule</var> argument. Open subpaths must be implicitly closed when being filled
-  (without affecting the actual subpaths).</p>
-
-  <p>The <dfn id="dom-context-2d-stroke-2"><code>stroke()</code></dfn> method, when invoked, must
-  <a href="#trace-a-path" id="drawing-paths-to-the-canvas:trace-a-path">trace</a> the intended path, using this
-  <code id="drawing-paths-to-the-canvas:canvaspathdrawingstyles"><a href="#canvaspathdrawingstyles">CanvasPathDrawingStyles</a></code> object for the line styles, and then fill the resulting path
-  using the <code id="drawing-paths-to-the-canvas:dom-context-2d-strokestyle-2"><a href="#dom-context-2d-strokestyle-2">strokeStyle</a></code> attribute, using the <a href="#dom-context-2d-fillrule-nonzero" id="drawing-paths-to-the-canvas:dom-context-2d-fillrule-nonzero">non-zero winding rule</a>.</p>
-
-  <p class="note">As a result of how the algorithm to <a href="#trace-a-path" id="drawing-paths-to-the-canvas:trace-a-path-2">trace a path</a> is defined,
-  overlapping parts of the paths in one stroke operation are treated as if their union was what was
-  painted.</p>
-
-  <p class="note">The stroke <em>style</em> is affected by the transformation during painting, even
-  if the intended path is the <a href="#current-default-path" id="drawing-paths-to-the-canvas:current-default-path-13">current default path</a>.</p>
-
-  <p>Paths, when filled or stroked, must be painted without affecting the <a href="#current-default-path" id="drawing-paths-to-the-canvas:current-default-path-14">current default
-  path</a> or any <code id="drawing-paths-to-the-canvas:path2d-4"><a href="#path2d">Path2D</a></code> objects, and must be subject to <a href="#shadows" id="drawing-paths-to-the-canvas:shadows">shadow effects</a>, <a href="#dom-context-2d-globalalpha-2" id="drawing-paths-to-the-canvas:dom-context-2d-globalalpha-2">global
-  alpha</a>, the <a href="#clipping-region" id="drawing-paths-to-the-canvas:clipping-region">clipping region</a>, and <a href="#dom-context-2d-globalcompositeoperation-2" id="drawing-paths-to-the-canvas:dom-context-2d-globalcompositeoperation-2">global composition operators</a>. (The effect
-  of transformations is described above and varies based on which path is being used.)</p>
-
-  <hr/>
-
-  <p>The <dfn id="dom-context-2d-clip-2"><code>clip()</code></dfn> method, when invoked, must
-  create a new <dfn id="clipping-region">clipping region</dfn> by calculating the intersection of the current clipping
-  region and the area described by the intended path, using the <a href="#fill-rule" id="drawing-paths-to-the-canvas:fill-rule-2">fill rule</a> indicated by
-  the <var>fillRule</var> argument. Open subpaths must be implicitly closed when computing the
-  clipping region, without affecting the actual subpaths. The new clipping region replaces the
-  current clipping region.</p>
-
-  <p>When the context is initialized, the clipping region must be set to the largest infinite
-  surface (i.e. by default, no clipping occurs).</p>
-
-  
-
-  <p>The <dfn id="dom-context-2d-resetclip-2"><code>resetClip()</code></dfn> method, when invoked,
-  must create a new <a href="#clipping-region" id="drawing-paths-to-the-canvas:clipping-region-2">clipping region</a> that is the largest infinite surface. The new
-  clipping region replaces the current clipping region.</p>
-
-  <hr/>
-
-  <p>The <dfn id="dom-context-2d-ispointinpath-2"><code>isPointInPath()</code></dfn> method, when
-  invoked, must return true if the point given by the <var>x</var> and <var>y</var> coordinates
-  passed to the method, when treated as coordinates in the canvas coordinate space unaffected by the
-  current transformation, is inside the intended path as determined by the <a href="#fill-rule" id="drawing-paths-to-the-canvas:fill-rule-3">fill rule</a>
-  indicated by the <var>fillRule</var> argument; and must return false otherwise. Open subpaths must
-  be implicitly closed when computing the area inside the path, without affecting the actual
-  subpaths. Points on the path itself must be considered to be inside the path. If either of the
-  arguments are infinite or NaN, then the method must return false.</p>
-
-  <hr/>
-
-  <p>The <dfn id="dom-context-2d-ispointinstroke-2"><code>isPointInStroke()</code></dfn> method,
-  when invoked, must return true if the point given by the <var>x</var> and <var>y</var> coordinates
-  passed to the method, when treated as coordinates in the canvas coordinate space unaffected by the
-  current transformation, is inside the path that results from <a href="#trace-a-path" id="drawing-paths-to-the-canvas:trace-a-path-3">tracing</a> the intended path, using the <a href="#dom-context-2d-fillrule-nonzero" id="drawing-paths-to-the-canvas:dom-context-2d-fillrule-nonzero-2">non-zero winding rule</a>, and using the
-  <code id="drawing-paths-to-the-canvas:canvaspathdrawingstyles-2"><a href="#canvaspathdrawingstyles">CanvasPathDrawingStyles</a></code> interface for the line styles; and must return false
-  otherwise. Points on the resulting path must be considered to be inside the path. If either of the
-  arguments are infinite or NaN, then the method must return false.</p>
-
-  <hr/>
-
-  
-
-  <div class="example" id="drawCustomFocusRingExample">
-
-   <p>This <code id="drawing-paths-to-the-canvas:the-canvas-element"><a href="#the-canvas-element">canvas</a></code> element has a couple of checkboxes. The path-related commands are
-   highlighted:</p>
-
-   <pre>&lt;canvas height=400 width=750&gt;
- &lt;label&gt;&lt;input type=checkbox id=showA&gt; Show As&lt;/label&gt;
- &lt;label&gt;&lt;input type=checkbox id=showB&gt; Show Bs&lt;/label&gt;
- &lt;!-- ... --&gt;
-&lt;/canvas&gt;
-&lt;script&gt;
- function drawCheckbox(context, element, x, y, paint) {
-   context.save();
-   context.font = '10px sans-serif';
-   context.textAlign = 'left';
-   context.textBaseline = 'middle';
-   var metrics = context.measureText(element.labels[0].textContent);
-   if (paint) {
-<strong>     context.beginPath();
-     context.strokeStyle = 'black';
-     context.rect(x-5, y-5, 10, 10);
-     context.stroke();
-</strong>     if (element.checked) {
-<strong>       context.fillStyle = 'black';
-       context.fill();
-</strong>     }
-     context.fillText(element.labels[0].textContent, x+5, y);
-   }
-<strong>   context.beginPath();
-   context.rect(x-7, y-7, 12 + metrics.width+2, 14);
-</strong>
-   context.drawFocusIfNeeded(element);
-   context.restore();
- }
- function drawBase() { /* ... */ }
- function drawAs() { /* ... */ }
- function drawBs() { /* ... */ }
- function redraw() {
-   var canvas = document.getElementsByTagName('canvas')[0];
-   var context = canvas.getContext('2d');
-   context.clearRect(0, 0, canvas.width, canvas.height);
-   drawCheckbox(context, document.getElementById('showA'), 20, 40, true);
-   drawCheckbox(context, document.getElementById('showB'), 20, 60, true);
-   drawBase();
-   if (document.getElementById('showA').checked)
-     drawAs();
-   if (document.getElementById('showB').checked)
-     drawBs();
- }
- function processClick(event) {
-   var canvas = document.getElementsByTagName('canvas')[0];
-   var context = canvas.getContext('2d');
-   var x = event.clientX;
-   var y = event.clientY;
-   var node = event.target;
-   while (node) {
-     x -= node.offsetLeft - node.scrollLeft;
-     y -= node.offsetTop - node.scrollTop;
-     node = node.offsetParent;
-   }
-   drawCheckbox(context, document.getElementById('showA'), 20, 40, false);
-   if (<strong>context.isPointInPath(x, y)</strong>)
-     document.getElementById('showA').checked = !(document.getElementById('showA').checked);
-   drawCheckbox(context, document.getElementById('showB'), 20, 60, false);
-   if (<strong>context.isPointInPath(x, y)</strong>)
-     document.getElementById('showB').checked = !(document.getElementById('showB').checked);
-   redraw();
- }
- document.getElementsByTagName('canvas')[0].addEventListener('focus', redraw, true);
- document.getElementsByTagName('canvas')[0].addEventListener('blur', redraw, true);
- document.getElementsByTagName('canvas')[0].addEventListener('change', redraw, true);
- document.getElementsByTagName('canvas')[0].addEventListener('click', processClick, false);
- redraw();
-&lt;/script&gt;</pre>
-
-
-  </div>
-
-  <h6 id="drawing-focus-rings-and-scrolling-paths-into-view"><span class="secno">4.12.5.1.13</span> Drawing focus rings and scrolling paths into view<a class="self-link" href="#drawing-focus-rings-and-scrolling-paths-into-view"/></h6>
-
-  <dl class="domintro"><dt><var>context</var> . <code id="dom-context-2d-drawfocusifneeded"><a href="#dom-context-2d-drawfocusifneeded-2">drawFocusIfNeeded</a></code>(<var>element</var>)</dt><dt><var>context</var> . <code id="drawing-focus-rings-and-scrolling-paths-into-view:dom-context-2d-drawfocusifneeded-2"><a href="#dom-context-2d-drawfocusifneeded-2">drawFocusIfNeeded</a></code>(<var>path</var>, <var>element</var>)</dt><dd>
-
-    <p>If the given element is <a href="https://html.spec.whatwg.org/multipage/interaction.html#focused" id="drawing-focus-rings-and-scrolling-paths-into-view:focused">focused</a>, draws a focus ring around the <a href="#current-default-path" id="drawing-focus-rings-and-scrolling-paths-into-view:current-default-path">current
-    default path</a> or the given path, following the platform conventions for focus rings.</p>
-
-   </dd><dt><var>context</var> . <code id="dom-context-2d-scrollpathintoview"><a href="#dom-context-2d-scrollpathintoview-2">scrollPathIntoView</a></code>()</dt><dt><var>context</var> . <code id="drawing-focus-rings-and-scrolling-paths-into-view:dom-context-2d-scrollpathintoview-2"><a href="#dom-context-2d-scrollpathintoview-2">scrollPathIntoView</a></code>(<var>path</var>)</dt><dd>
-
-    <p>Scrolls the <a href="#current-default-path" id="drawing-focus-rings-and-scrolling-paths-into-view:current-default-path-2">current default path</a> or the given path into view. This is especially
-    useful on devices with small screens, where the whole canvas might not be visible at once.</p>
-
-   </dd></dl>
-
-  
-
-  Objects that implement the <code id="drawing-focus-rings-and-scrolling-paths-into-view:canvasuserinterface"><a href="#canvasuserinterface">CanvasUserInterface</a></code> interface provide the following
-  methods to control drawing focus rings and scrolling paths into view.
-
-  <hr/>
-
-  <p id="dom-context-2d-drawosfocusring">The <dfn id="dom-context-2d-drawfocusifneeded-2"><code>drawFocusIfNeeded(<var>element</var>)</code></dfn>
-  method, when invoked, must run these steps:</p>
-
-  <ol><li><p>If <var>element</var> is not <a href="https://html.spec.whatwg.org/multipage/interaction.html#focused" id="drawing-focus-rings-and-scrolling-paths-into-view:focused-2">focused</a> or is not a descendant of the element with
-   whose context the method is associated, then abort these steps.</p></li><li>
-
-    <p>Draw a focus ring of the appropriate style along the intended path, following platform
-    conventions.</p>
-
-    <p class="note">Some platforms only draw focus rings around elements that have been focused from
-    the keyboard, and not those focused from the mouse. Other platforms simply don't draw focus
-    rings around some elements at all unless relevant accessibility features are enabled. This API
-    is intended to follow these conventions. User agents that implement distinctions based on the
-    manner in which the element was focused are encouraged to classify focus driven by the <code id="drawing-focus-rings-and-scrolling-paths-into-view:dom-focus-2"><a href="https://html.spec.whatwg.org/multipage/interaction.html#dom-focus-2">focus()</a></code> method based on the kind of user interaction event from which
-    the call was triggered (if any).</p>
-
-    <p>The focus ring should not be subject to the <a href="#shadows" id="drawing-focus-rings-and-scrolling-paths-into-view:shadows">shadow effects</a>, the
-    <a href="#dom-context-2d-globalalpha-2" id="drawing-focus-rings-and-scrolling-paths-into-view:dom-context-2d-globalalpha-2">global alpha</a>, the <a href="#dom-context-2d-globalcompositeoperation-2" id="drawing-focus-rings-and-scrolling-paths-into-view:dom-context-2d-globalcompositeoperation-2">global composition operators</a>, or any of
-    the members in the <code id="drawing-focus-rings-and-scrolling-paths-into-view:canvasfillstrokestyles"><a href="#canvasfillstrokestyles">CanvasFillStrokeStyles</a></code>, <code id="drawing-focus-rings-and-scrolling-paths-into-view:canvaspathdrawingstyles"><a href="#canvaspathdrawingstyles">CanvasPathDrawingStyles</a></code>,
-    <code id="drawing-focus-rings-and-scrolling-paths-into-view:canvastextdrawingstyles"><a href="#canvastextdrawingstyles">CanvasTextDrawingStyles</a></code> interfaces, but <em>should</em> be subject to the
-    <a href="#clipping-region" id="drawing-focus-rings-and-scrolling-paths-into-view:clipping-region">clipping region</a>. (The effect of transformations is described above and varies based
-    on which path is being used.)</p>
-
-   </li><li><p><a href="#inform">Inform the user</a> that the focus is at the location given by the
-   intended path. User agents may wait until the next time the <a href="https://html.spec.whatwg.org/multipage/webappapis.html#event-loop" id="drawing-focus-rings-and-scrolling-paths-into-view:event-loop">event loop</a> reaches its
-   <a href="https://html.spec.whatwg.org/multipage/webappapis.html#update-the-rendering" id="drawing-focus-rings-and-scrolling-paths-into-view:update-the-rendering">update the rendering</a> step to optionally inform the user.</p></li></ol>
-
-  <p>User agents should not implicitly close open subpaths in the intended path when drawing the
-  focus ring.</p>
-
-  <p class="note">This might be a moot point, however. For example, if the focus ring is drawn as an
-  axis-aligned bounding rectangle around the points in the intended path, then whether the subpaths
-  are closed or not has no effect. This specification intentionally does not specify precisely how
-  focus rings are to be drawn: user agents are expected to honor their platform's native
-  conventions.</p>
-
-  <hr/>
-
-  <p>The <dfn id="dom-context-2d-scrollpathintoview-2"><code>scrollPathIntoView()</code></dfn>
-  method, when invoked, must run these steps:</p>
-
-  <ol><li><p>Let <var>the specified rectangle</var> be the rectangle of the bounding box of
-   the intended path.</p></li><li><p>Let <var>notional child</var> be a hypothetical element that is a rendered child
-   of the <code id="drawing-focus-rings-and-scrolling-paths-into-view:the-canvas-element"><a href="#the-canvas-element">canvas</a></code> element whose dimensions are those of <var>the specified
-   rectangle</var>.</p></li><li><p><a data-x-internal="scroll-an-element-into-view" href="https://drafts.csswg.org/cssom-view/#scroll-an-element-into-view" id="drawing-focus-rings-and-scrolling-paths-into-view:scroll-an-element-into-view">Scroll <var>notional child</var> into
-   view</a> with the <var>align to top flag</var> set.</p>
-
-   </li><li><p>Optionally, <a href="#inform">inform the user</a> that the caret or selection (or both)
-   cover <var>the specified rectangle</var> of the canvas. The user agent may wait until the next
-   time the <a href="https://html.spec.whatwg.org/multipage/webappapis.html#event-loop" id="drawing-focus-rings-and-scrolling-paths-into-view:event-loop-2">event loop</a> reaches its <a href="https://html.spec.whatwg.org/multipage/webappapis.html#update-the-rendering" id="drawing-focus-rings-and-scrolling-paths-into-view:update-the-rendering-2">update the rendering</a> step to
-   optionally inform the user.</p></li></ol>
-
-  <p id="inform">&quot;Inform the user&quot;, as used in this section, does not imply any persistent state
-  change. It could mean, for instance, calling a system accessibility API to notify assistive
-  technologies such as magnification tools so that the user's magnifier moves to the given area of
-  the canvas. However, it does not associate the path with the element, or provide a region for
-  tactile feedback, etc.</p>
-
-  
-
-  <h6 id="drawing-images"><span class="secno">4.12.5.1.14</span> Drawing images<a class="self-link" href="#drawing-images"/></h6>
-
-  <p>Objects that implement the <code id="drawing-images:canvasdrawimage"><a href="#canvasdrawimage">CanvasDrawImage</a></code> interface have the <dfn id="dom-context-2d-drawimage"><code>drawImage</code></dfn> method to draw images.</p>
-
-  
-
-  <p>This method can be invoked with three different sets of arguments:</p>
-
-  <ul class="brief"><li><code>drawImage(<var>image</var>, <var>dx</var>, <var>dy</var>)</code>
-   </li><li><code>drawImage(<var>image</var>, <var>dx</var>, <var>dy</var>, <var>dw</var>, <var>dh</var>)</code>
-   </li><li><code>drawImage(<var>image</var>, <var>sx</var>, <var>sy</var>, <var>sw</var>, <var>sh</var>, <var>dx</var>, <var>dy</var>, <var>dw</var>, <var>dh</var>)</code>
-  </li></ul>
-
-  
-
-  <dl class="domintro"><dt><var>context</var> . <code id="dom-context-2d-drawimage-2"><a href="#dom-context-2d-drawimage">drawImage</a></code>(<var>image</var>, <var>dx</var>, <var>dy</var>)</dt><dt><var>context</var> . <code id="drawing-images:dom-context-2d-drawimage"><a href="#dom-context-2d-drawimage">drawImage</a></code>(<var>image</var>, <var>dx</var>, <var>dy</var>, <var>dw</var>, <var>dh</var>)</dt><dt><var>context</var> . <code id="drawing-images:dom-context-2d-drawimage-2"><a href="#dom-context-2d-drawimage">drawImage</a></code>(<var>image</var>, <var>sx</var>, <var>sy</var>, <var>sw</var>, <var>sh</var>, <var>dx</var>, <var>dy</var>, <var>dw</var>, <var>dh</var>)</dt><dd>
-
-    <p>Draws the given image onto the canvas. The arguments are
-    interpreted as follows:</p>
-
-    <p><img alt="The sx and sy parameters give the x and y coordinates of the source rectangle; the sw and sh arguments give the width and height of the source rectangle; the dx and dy give the x and y coordinates of the destination rectangle; and the dw and dh arguments give the width and height of the destination rectangle." height="356" src="https://html.spec.whatwg.org/images/drawImage.png" width="356"/></p>
-
-    <p>If the image isn't yet fully decoded, then nothing is drawn. If the image is a canvas with no
-    data, throws an <a data-x-internal="invalidstateerror" href="https://heycam.github.io/webidl/#invalidstateerror" id="drawing-images:invalidstateerror">&quot;<code>InvalidStateError</code>&quot;</a> <code id="drawing-images:domexception"><a data-x-internal="domexception" href="https://heycam.github.io/webidl/#dfn-DOMException">DOMException</a></code>.</p>
-
-   </dd></dl>
-
-  
-
-  <p>When the <code id="drawing-images:dom-context-2d-drawimage-3"><a href="#dom-context-2d-drawimage">drawImage()</a></code> method is invoked, the user
-  agent must run these steps:</p>
-
-  <ol><li><p>If any of the arguments are infinite or NaN, then abort these steps.</p></li><li><p><a href="#check-the-usability-of-the-image-argument" id="drawing-images:check-the-usability-of-the-image-argument">Check the usability of the <var>image</var> argument</a>. If this
-   returns <i>aborted</i>, then an exception has been thrown and the method doesn't return anything;
-   abort these steps. If it returns <i>bad</i>, then abort these steps without drawing anything.
-   Otherwise it returns <i>good</i>; continue with these steps.</p></li><li>
-
-    <p>Establish the source and destination rectangles as follows:</p>
-
-    <p>If not specified, the <var>dw</var> and <var>dh</var> arguments must default to the values of
-    <var>sw</var> and <var>sh</var>, interpreted such that one <a data-x-internal="'px'" href="https://drafts.csswg.org/css-values/#px" id="drawing-images:'px'">CSS pixel</a>
-    in the image is treated as one unit in the <a href="#output-bitmap" id="drawing-images:output-bitmap">output bitmap</a>'s coordinate space. If the
-    <var>sx</var>, <var>sy</var>, <var>sw</var>, and <var>sh</var> arguments are omitted, then they
-    must default to 0, 0, the image's <a href="https://html.spec.whatwg.org/multipage/infrastructure.html#intrinsic-width" id="drawing-images:intrinsic-width">intrinsic width</a> in image pixels, and the image's
-    <a href="https://html.spec.whatwg.org/multipage/infrastructure.html#intrinsic-height" id="drawing-images:intrinsic-height">intrinsic height</a> in image pixels, respectively. If the image has no <a data-x-internal="intrinsic-dimensions" href="https://drafts.csswg.org/css2/conform.html#intrinsic" id="drawing-images:intrinsic-dimensions">intrinsic
-    dimensions</a>, then the <i>concrete object size</i> must be used instead, as determined
-    using the CSS &quot;<a href="https://drafts.csswg.org/css-images/#default-sizing">Concrete Object
-    Size Resolution</a>&quot; algorithm, with the <i>specified size</i> having neither a definite width
-    nor height, nor any additional constraints, the object's intrinsic properties being those of the
-    <var>image</var> argument, and the <a data-x-internal="default-object-size" href="https://drafts.csswg.org/css-images/#default-object-size" id="drawing-images:default-object-size">default object size</a> being the size of the
-    <a href="#output-bitmap" id="drawing-images:output-bitmap-2">output bitmap</a>. <a href="https://html.spec.whatwg.org/multipage/references.html#refsCSSIMAGES">[CSSIMAGES]</a></p>
-
-    <p>The source rectangle is the rectangle whose corners are the four points (<var>sx</var>, <var>sy</var>), (<var>sx</var>+<var>sw</var>, <var>sy</var>), (<var>sx</var>+<var>sw</var>, <var>sy</var>+<var>sh</var>),
-    (<var>sx</var>, <var>sy</var>+<var>sh</var>).</p>
-
-    <p>The destination rectangle is the rectangle whose corners are the four points (<var>dx</var>, <var>dy</var>), (<var>dx</var>+<var>dw</var>, <var>dy</var>), (<var>dx</var>+<var>dw</var>, <var>dy</var>+<var>dh</var>),
-    (<var>dx</var>, <var>dy</var>+<var>dh</var>).</p>
-
-    <p>When the source rectangle is outside the source image, the source rectangle must be clipped
-    to the source image and the destination rectangle must be clipped in the same proportion.</p>
-
-    <p class="note">When the destination rectangle is outside the destination image (the
-    <a href="#output-bitmap" id="drawing-images:output-bitmap-3">output bitmap</a>), the pixels that land outside the <a href="#output-bitmap" id="drawing-images:output-bitmap-4">output bitmap</a> are
-    discarded, as if the destination was an infinite canvas whose rendering was clipped to the
-    dimensions of the <a href="#output-bitmap" id="drawing-images:output-bitmap-5">output bitmap</a>.</p>
-
-   </li><li><p>If one of the <var>sw</var> or <var>sh</var> arguments is zero, then abort
-   these steps. Nothing is painted.</p></li><li>
-
-    <p>Paint the region of the <var>image</var> argument specified by the source rectangle
-    on the region of the rendering context's <a href="#output-bitmap" id="drawing-images:output-bitmap-6">output bitmap</a> specified by the
-    destination rectangle, after applying the <a href="#transformations" id="drawing-images:transformations">current
-    transformation matrix</a> to the destination rectangle.</p>
-
-    <p>The image data must be processed in the original direction, even if the dimensions given are
-    negative. </p>
-
-    <p>When scaling up, if the <code id="drawing-images:dom-context-2d-imagesmoothingenabled-2"><a href="#dom-context-2d-imagesmoothingenabled-2">imageSmoothingEnabled</a></code> attribute is set to
-    true, the user agent should attempt to apply a smoothing algorithm to the image data when it is
-    scaled. User agents which support multiple filtering algorithms may use the value of the <code id="drawing-images:dom-context-2d-imagesmoothingquality-2"><a href="#dom-context-2d-imagesmoothingquality-2">imageSmoothingQuality</a></code> attribute to guide
-    the choice of filtering algorithm when the <code id="drawing-images:dom-context-2d-imagesmoothingenabled-2-2"><a href="#dom-context-2d-imagesmoothingenabled-2">imageSmoothingEnabled</a></code> attribute is set to
-    true. Otherwise, the image must be rendered using nearest-neighbor interpolation.</p>
-
-    <p class="note">This specification does not define the precise algorithm to use when scaling an
-    image down, or when scaling an image up when the <code id="drawing-images:dom-context-2d-imagesmoothingenabled-2-3"><a href="#dom-context-2d-imagesmoothingenabled-2">imageSmoothingEnabled</a></code> attribute is set to
-    true.</p>
-
-    <p class="note">When a <code id="drawing-images:the-canvas-element"><a href="#the-canvas-element">canvas</a></code> element is drawn onto itself, the <a href="#drawing-model" id="drawing-images:drawing-model">drawing
-    model</a> requires the source to be copied before the image is drawn, so it is possible to
-    copy parts of a <code id="drawing-images:the-canvas-element-2"><a href="#the-canvas-element">canvas</a></code> element onto overlapping parts of itself.</p>
-
-    <p>If the original image data is a bitmap image, then the value painted at a point in the
-    destination rectangle is computed by filtering the original image data. The user agent may use
-    any filtering algorithm (for example bilinear interpolation or nearest-neighbor). When the
-    filtering algorithm requires a pixel value from outside the original image data, it must instead
-    use the value from the nearest edge pixel. (That is, the filter uses 'clamp-to-edge' behavior.)
-    When the filtering algorithm requires a pixel value from outside the source rectangle but inside
-    the original image data, then the value from the original image data must be used.</p>
-    
-    
-
-    <p class="note">Thus, scaling an image in parts or in whole will have the same effect. This does
-    mean that when sprites coming from a single sprite sheet are to be scaled, adjacent images in
-    the sprite sheet can interfere. This can be avoided by ensuring each sprite in the sheet is
-    surrounded by a border of transparent black, or by copying sprites to be scaled into temporary
-    <code id="drawing-images:the-canvas-element-3"><a href="#the-canvas-element">canvas</a></code> elements and drawing the scaled sprites from there.</p>
-
-    <p>Images are painted without affecting the current path, and are subject to <a href="#shadows" id="drawing-images:shadows">shadow effects</a>, <a href="#dom-context-2d-globalalpha-2" id="drawing-images:dom-context-2d-globalalpha-2">global
-    alpha</a>, the <a href="#clipping-region" id="drawing-images:clipping-region">clipping region</a>, and <a href="#dom-context-2d-globalcompositeoperation-2" id="drawing-images:dom-context-2d-globalcompositeoperation-2">global composition operators</a>.</p>
-
-   </li><li><p>If <a href="#the-image-argument-is-not-origin-clean" id="drawing-images:the-image-argument-is-not-origin-clean">the <var>image argument</var> is not origin-clean</a>, then set the
-   <code id="drawing-images:canvasrenderingcontext2d"><a href="#canvasrenderingcontext2d">CanvasRenderingContext2D</a></code>'s <a href="#concept-canvas-origin-clean" id="drawing-images:concept-canvas-origin-clean">origin-clean</a> flag to false.</p></li></ol>
-
-  
-
-
-  <h6 id="pixel-manipulation"><span class="secno">4.12.5.1.15</span> <dfn>Pixel manipulation</dfn><a class="self-link" href="#pixel-manipulation"/></h6>
-
-  <dl class="domintro"><dt><var>imagedata</var> = new <code id="pixel-manipulation:dom-imagedata"><a href="#dom-imagedata">ImageData</a></code>(<var>sw</var>, <var>sh</var>)</dt><dt><var>imagedata</var> = <var>context</var> . <code id="dom-context-2d-createimagedata"><a href="#dom-context-2d-createimagedata-2">createImageData</a></code>(<var>sw</var>, <var>sh</var>)</dt><dd>
-
-    <p>Returns an <code id="pixel-manipulation:imagedata"><a href="#imagedata">ImageData</a></code> object with the given dimensions. All the pixels in the
-    returned object are transparent black.</p>
-
-    <p>Throws an <a data-x-internal="indexsizeerror" href="https://heycam.github.io/webidl/#indexsizeerror" id="pixel-manipulation:indexsizeerror">&quot;<code>IndexSizeError</code>&quot;</a> <code id="pixel-manipulation:domexception"><a data-x-internal="domexception" href="https://heycam.github.io/webidl/#dfn-DOMException">DOMException</a></code> if either of
-    the width or height arguments are zero.</p>
-
-   </dd><dt><var>imagedata</var> = <var>context</var> . <code id="pixel-manipulation:dom-context-2d-createimagedata-2"><a href="#dom-context-2d-createimagedata-2">createImageData</a></code>(<var>imagedata</var>)</dt><dd>
-
-    <p>Returns an <code id="pixel-manipulation:imagedata-2"><a href="#imagedata">ImageData</a></code> object with the same dimensions as the argument. All the
-    pixels in the returned object are transparent black.</p>
-
-   </dd><dt><var>imagedata</var> = new <code id="pixel-manipulation:dom-imagedata-2"><a href="#dom-imagedata">ImageData</a></code>(<var>data</var>, <var>sw</var> [, <var>sh</var> ] )</dt><dd>
-
-    <p>Returns an <code id="pixel-manipulation:imagedata-3"><a href="#imagedata">ImageData</a></code> object using the data provided in the <code id="pixel-manipulation:idl-uint8clampedarray"><a data-x-internal="idl-uint8clampedarray" href="https://heycam.github.io/webidl/#idl-Uint8ClampedArray">Uint8ClampedArray</a></code> argument, interpreted using the given
-    dimensions.</p>
-
-    <p>As each pixel in the data is represented by four numbers, the length of the data needs to be
-    a multiple of four times the given width. If the height is provided as well, then the length
-    needs to be exactly the width times the height times 4.</p>
-
-    <p>Throws an <a data-x-internal="indexsizeerror" href="https://heycam.github.io/webidl/#indexsizeerror" id="pixel-manipulation:indexsizeerror-2">&quot;<code>IndexSizeError</code>&quot;</a> <code id="pixel-manipulation:domexception-2"><a data-x-internal="domexception" href="https://heycam.github.io/webidl/#dfn-DOMException">DOMException</a></code> if the given
-    data and dimensions can't be interpreted consistently, or if either dimension is zero.</p>
-
-   </dd><dt><var>imagedata</var> = <var>context</var> . <code id="dom-context-2d-getimagedata"><a href="#dom-context-2d-getimagedata-2">getImageData</a></code>(<var>sx</var>, <var>sy</var>, <var>sw</var>, <var>sh</var>)</dt><dd>
-
-    <p>Returns an <code id="pixel-manipulation:imagedata-4"><a href="#imagedata">ImageData</a></code> object containing the image data for the given rectangle of
-    the bitmap.</p>
-
-    <p>Throws an <a data-x-internal="indexsizeerror" href="https://heycam.github.io/webidl/#indexsizeerror" id="pixel-manipulation:indexsizeerror-3">&quot;<code>IndexSizeError</code>&quot;</a> <code id="pixel-manipulation:domexception-3"><a data-x-internal="domexception" href="https://heycam.github.io/webidl/#dfn-DOMException">DOMException</a></code> if the either
-    of the width or height arguments are zero.</p>
-
-   </dd><dt><var>imagedata</var> . <code id="dom-imagedata-width"><a href="#dom-imagedata-width-2">width</a></code></dt><dt><var>imagedata</var> . <code id="dom-imagedata-height"><a href="#dom-imagedata-height-2">height</a></code></dt><dd>
-
-    <p>Returns the actual dimensions of the data in the <code id="pixel-manipulation:imagedata-5"><a href="#imagedata">ImageData</a></code> object, in
-    pixels.</p>
-
-   </dd><dt><var>imagedata</var> . <code id="dom-imagedata-data"><a href="#dom-imagedata-data-2">data</a></code></dt><dd>
-
-    <p>Returns the one-dimensional array containing the data in RGBA order, as integers in the range
-    0 to 255.</p>
-
-   </dd><dt><var>context</var> . <code id="dom-context-2d-putimagedata"><a href="#dom-context-2d-putimagedata-2">putImageData</a></code>(<var>imagedata</var>, <var>dx</var>, <var>dy</var> [, <var>dirtyX</var>, <var>dirtyY</var>, <var>dirtyWidth</var>, <var>dirtyHeight</var> ] )</dt><dd>
-
-    <p>Paints the data from the given <code id="pixel-manipulation:imagedata-6"><a href="#imagedata">ImageData</a></code> object onto the bitmap. If a dirty
-    rectangle is provided, only the pixels from that rectangle are painted.</p>
-
-    <p>The <code id="pixel-manipulation:dom-context-2d-globalalpha-2"><a href="#dom-context-2d-globalalpha-2">globalAlpha</a></code> and <code id="pixel-manipulation:dom-context-2d-globalcompositeoperation-2"><a href="#dom-context-2d-globalcompositeoperation-2">globalCompositeOperation</a></code> attributes, as
-    well as the shadow attributes, are ignored for the purposes of this method call; pixels in the
-    canvas are replaced wholesale, with no composition, alpha blending, no shadows, etc.</p>
-
-    <p>Throws an <a data-x-internal="invalidstateerror" href="https://heycam.github.io/webidl/#invalidstateerror" id="pixel-manipulation:invalidstateerror">&quot;<code>InvalidStateError</code>&quot;</a> <code id="pixel-manipulation:domexception-4"><a data-x-internal="domexception" href="https://heycam.github.io/webidl/#dfn-DOMException">DOMException</a></code> if the
-    <var>imagedata</var> object's data's <a href="https://html.spec.whatwg.org/multipage/structured-data.html#detached" id="pixel-manipulation:detached">[[Detached]]</a> internal slot value is true.</p>
-
-   </dd></dl>
-
-  
-
-  <p>Objects that implement the <code id="pixel-manipulation:canvasimagedata"><a href="#canvasimagedata">CanvasImageData</a></code> interface provide the following methods
-  for reading and writing pixel data to the bitmap.</p>
-
-  <p>The <dfn id="dom-imagedata"><code>ImageData()</code></dfn> constructors and the
-  <dfn id="dom-context-2d-createimagedata-2"><code>createImageData()</code></dfn> methods are
-  used to instantiate new <code id="pixel-manipulation:imagedata-7"><a href="#imagedata">ImageData</a></code> objects.</p>
-
-  <p>When the <code id="pixel-manipulation:dom-imagedata-3"><a href="#dom-imagedata">ImageData()</a></code> constructor is invoked with two
-  numeric arguments <var>sw</var> and <var>sh</var>, it must <a href="#create-an-imagedata-object" id="pixel-manipulation:create-an-imagedata-object">create an <code>ImageData</code>
-  object</a> with parameter <var>pixelsPerRow</var> set to <var>sw</var>, and <var>rows</var> set
-  to <var>sh</var>. The image data of the newly created <code id="pixel-manipulation:imagedata-8"><a href="#imagedata">ImageData</a></code> object must be
-  initialized to transparent black. If both <var>sw</var> and <var>sh</var> are non-zero, then
-  return the new <code id="pixel-manipulation:imagedata-9"><a href="#imagedata">ImageData</a></code> object. If one or both of <var>sw</var> and <var>sh</var>
-  are zero, then the constructor must throw an <a data-x-internal="indexsizeerror" href="https://heycam.github.io/webidl/#indexsizeerror" id="pixel-manipulation:indexsizeerror-4">&quot;<code>IndexSizeError</code>&quot;</a>
-  <code id="pixel-manipulation:domexception-5"><a data-x-internal="domexception" href="https://heycam.github.io/webidl/#dfn-DOMException">DOMException</a></code> instead.</p>
-
-  <p>When the <code id="pixel-manipulation:dom-imagedata-4"><a href="#dom-imagedata">ImageData()</a></code> constructor is invoked with its first
-  argument being an <code id="pixel-manipulation:idl-uint8clampedarray-2"><a data-x-internal="idl-uint8clampedarray" href="https://heycam.github.io/webidl/#idl-Uint8ClampedArray">Uint8ClampedArray</a></code> <var>source</var>
-  and its second and optional third arguments being numeric arguments <var>sw</var> and
-  <var>sh</var>, it must run these steps:</p>
-
-  <ol><li><p>Let <var>length</var> be the number of bytes in <var>source</var>.</p></li><li><p>If <var>length</var> is not a non-zero integral multiple of four, then throw an
-   <a data-x-internal="invalidstateerror" href="https://heycam.github.io/webidl/#invalidstateerror" id="pixel-manipulation:invalidstateerror-2">&quot;<code>InvalidStateError</code>&quot;</a> <code id="pixel-manipulation:domexception-6"><a data-x-internal="domexception" href="https://heycam.github.io/webidl/#dfn-DOMException">DOMException</a></code> and abort these
-   steps.</p></li><li><p>Let <var>length</var> be <var>length</var> divided by four.</p>
-
-   </li><li>
-
-    <p>If <var>length</var> is not an integral multiple of <var>sw</var>, then throw an
-    <a data-x-internal="indexsizeerror" href="https://heycam.github.io/webidl/#indexsizeerror" id="pixel-manipulation:indexsizeerror-5">&quot;<code>IndexSizeError</code>&quot;</a> <code id="pixel-manipulation:domexception-7"><a data-x-internal="domexception" href="https://heycam.github.io/webidl/#dfn-DOMException">DOMException</a></code> and abort these steps.</p>
-
-    <p class="note">At this step, the length is guaranteed to be greater than zero (otherwise the
-    second step above would have aborted the steps), so if <var>sw</var> is zero, this
-    step will throw the exception and abort these steps.</p>
-
-   </li><li><p>Let <var>height</var> be <var>length</var> divided by <var>sw</var>.</p></li><li><p>If the <var>sh</var> argument was not omitted, and its value is not equal to
-   <var>height</var>, then throw an <a data-x-internal="indexsizeerror" href="https://heycam.github.io/webidl/#indexsizeerror" id="pixel-manipulation:indexsizeerror-6">&quot;<code>IndexSizeError</code>&quot;</a>
-   <code id="pixel-manipulation:domexception-8"><a data-x-internal="domexception" href="https://heycam.github.io/webidl/#dfn-DOMException">DOMException</a></code> and abort these steps.</p></li><li>
-
-    <p><a href="#create-an-imagedata-object" id="pixel-manipulation:create-an-imagedata-object-2">Create an <code>ImageData</code> object</a>, with parameter <var>pixelsPerRow</var>
-    set to <var>sw</var>, <var>rows</var> set to <var>sh</var>, and using <var>source</var>.
-    Return the newly created <code id="pixel-manipulation:imagedata-10"><a href="#imagedata">ImageData</a></code> object.</p>
-
-    <p class="note">The resulting object's data is not a <em>copy</em> of <var>source</var>, it's
-    the actual <code id="pixel-manipulation:idl-uint8clampedarray-3"><a data-x-internal="idl-uint8clampedarray" href="https://heycam.github.io/webidl/#idl-Uint8ClampedArray">Uint8ClampedArray</a></code> object passed as the
-    first argument to the constructor.</p>
-
-   </li></ol>
-
-  <p>When the <code id="pixel-manipulation:dom-context-2d-createimagedata-2-2"><a href="#dom-context-2d-createimagedata-2">createImageData()</a></code> method is
-  invoked with two numeric arguments <var>sw</var> and <var>sh</var>, it must <a href="#create-an-imagedata-object" id="pixel-manipulation:create-an-imagedata-object-3">create an
-  <code>ImageData</code> object</a>, with parameter <var>pixelsPerRow</var> set to the
-  absolute magnitude of <var>sw</var>, and parameter <var>rows</var> set to the absolute magnitude
-  of <var>sh</var>. Initialize the image data of the new <code id="pixel-manipulation:imagedata-11"><a href="#imagedata">ImageData</a></code> object to
-  transparent black. If both <var>sw</var> and <var>sh</var> are non-zero, then return
-  the new <code id="pixel-manipulation:imagedata-12"><a href="#imagedata">ImageData</a></code> object. If one or both of <var>sw</var> and <var>sh</var> are
-  zero, then throw an <a data-x-internal="indexsizeerror" href="https://heycam.github.io/webidl/#indexsizeerror" id="pixel-manipulation:indexsizeerror-7">&quot;<code>IndexSizeError</code>&quot;</a> <code id="pixel-manipulation:domexception-9"><a data-x-internal="domexception" href="https://heycam.github.io/webidl/#dfn-DOMException">DOMException</a></code>
-  instead.</p>
-
-  <p>When the <code id="pixel-manipulation:dom-context-2d-createimagedata-2-3"><a href="#dom-context-2d-createimagedata-2">createImageData()</a></code> method is
-  invoked with a single <var>imagedata</var> argument, it must <a href="#create-an-imagedata-object" id="pixel-manipulation:create-an-imagedata-object-4">create an
-  <code>ImageData</code> object</a>, with parameter <var>pixelsPerRow</var> set to the value of
-  the <code id="pixel-manipulation:dom-imagedata-width-2"><a href="#dom-imagedata-width-2">width</a></code> attribute of the <code id="pixel-manipulation:imagedata-13"><a href="#imagedata">ImageData</a></code>
-  object passed as the argument, and the <var>rows</var> parameter set to the value of the
-  <code id="pixel-manipulation:dom-imagedata-height-2"><a href="#dom-imagedata-height-2">height</a></code> attribute.
-  Initialize the image data of the new <code id="pixel-manipulation:imagedata-14"><a href="#imagedata">ImageData</a></code> object to transparent black. Return
-  the newly created <code id="pixel-manipulation:imagedata-15"><a href="#imagedata">ImageData</a></code> object.</p>
-
-  <p>The <dfn id="dom-context-2d-getimagedata-2"><code>getImageData(<var>sx</var>,
-  <var>sy</var>, <var>sw</var>, <var>sh</var>)</code></dfn> method, when invoked, must,
-  if either the <var>sw</var> or <var>sh</var> arguments are zero, throw an
-  <a data-x-internal="indexsizeerror" href="https://heycam.github.io/webidl/#indexsizeerror" id="pixel-manipulation:indexsizeerror-8">&quot;<code>IndexSizeError</code>&quot;</a> <code id="pixel-manipulation:domexception-10"><a data-x-internal="domexception" href="https://heycam.github.io/webidl/#dfn-DOMException">DOMException</a></code>; otherwise,
-  
-  if the <code id="pixel-manipulation:canvasrenderingcontext2d"><a href="#canvasrenderingcontext2d">CanvasRenderingContext2D</a></code>'s <a href="#concept-canvas-origin-clean" id="pixel-manipulation:concept-canvas-origin-clean">origin-clean</a> flag is set to false, it must throw a
-  <a data-x-internal="securityerror" href="https://heycam.github.io/webidl/#securityerror" id="pixel-manipulation:securityerror">&quot;<code>SecurityError</code>&quot;</a> <code id="pixel-manipulation:domexception-11"><a data-x-internal="domexception" href="https://heycam.github.io/webidl/#dfn-DOMException">DOMException</a></code>;
-  
-  otherwise, it must <a href="#create-an-imagedata-object" id="pixel-manipulation:create-an-imagedata-object-5">create an <code>ImageData</code> object</a>, with parameter
-  <var>pixelsPerRow</var> set to <var>sw</var>, and parameter <var>rows</var> set to <var>sh</var>.
-  Set the pixel values of the image data of the newly created <code id="pixel-manipulation:imagedata-16"><a href="#imagedata">ImageData</a></code> object to
-  represent the <a href="#output-bitmap" id="pixel-manipulation:output-bitmap">output bitmap</a> for the area of that bitmap denoted by the rectangle
-  whose corners are the four points (<var>sx</var>, <var>sy</var>), (<span><var>sx</var>+<var>sw</var></span>, <var>sy</var>), (<span><var>sx</var>+<var>sw</var></span>, <span><var>sy</var>+<var>sh</var></span>), (<var>sx</var>,
-  <var>sy</var>+<var>sh</var>), in the bitmap's coordinate space units.
-  Pixels outside the <a href="#output-bitmap" id="pixel-manipulation:output-bitmap-2">output bitmap</a> must be set to transparent black. Pixel values
-  must not be premultiplied by alpha.</p>
-
-  <p>When the user agent is required to <dfn id="create-an-imagedata-object">create an <code>ImageData</code> object</dfn>, given a
-  positive integer number of rows <var>rows</var>, a positive integer number of pixels per row
-  <var>pixelsPerRow</var>, and an optional <code id="pixel-manipulation:idl-uint8clampedarray-4"><a data-x-internal="idl-uint8clampedarray" href="https://heycam.github.io/webidl/#idl-Uint8ClampedArray">Uint8ClampedArray</a></code> <var>source</var>, it must run these
-  steps:</p>
-
-  <ol><li><p>Let <var>imageData</var> be a new uninitialized <code id="pixel-manipulation:imagedata-17"><a href="#imagedata">ImageData</a></code> object.</p></li><li><p>If <var>source</var> is specified, then assign the <dfn id="dom-imagedata-data-2"><code>data</code></dfn> attribute of <var>imageData</var> to
-   <var>source</var>.</p></li><li>
-    <p>If <var>source</var> is not specified, then initialize the <code id="pixel-manipulation:dom-imagedata-data-2"><a href="#dom-imagedata-data-2">data</a></code> attribute of <var>imageData</var> to a new <code id="pixel-manipulation:idl-uint8clampedarray-5"><a data-x-internal="idl-uint8clampedarray" href="https://heycam.github.io/webidl/#idl-Uint8ClampedArray">Uint8ClampedArray</a></code> object. The <code id="pixel-manipulation:idl-uint8clampedarray-6"><a data-x-internal="idl-uint8clampedarray" href="https://heycam.github.io/webidl/#idl-Uint8ClampedArray">Uint8ClampedArray</a></code> object must use a new <a href="#canvas-pixel-arraybuffer" id="pixel-manipulation:canvas-pixel-arraybuffer">Canvas
-    Pixel <code>ArrayBuffer</code></a> for its storage, and must have a
-    zero start offset and a length equal to the length of its storage, in bytes. The <a href="#canvas-pixel-arraybuffer" id="pixel-manipulation:canvas-pixel-arraybuffer-2">Canvas
-    Pixel <code>ArrayBuffer</code></a> must have the correct size to
-    store <var>rows</var> × <var>pixelsPerRow</var> pixels.</p>
-
-    <p>If the <a href="#canvas-pixel-arraybuffer" id="pixel-manipulation:canvas-pixel-arraybuffer-3">Canvas Pixel <code>ArrayBuffer</code></a> cannot be
-    allocated, then rethrow the <code id="pixel-manipulation:js-rangeerror"><a data-x-internal="js-rangeerror" href="https://tc39.github.io/ecma262/#sec-native-error-types-used-in-this-standard-rangeerror">RangeError</a></code> thrown by JavaScript,
-    and abort these steps.</p>
-   </li><li><p>Initialize the <dfn id="dom-imagedata-width-2"><code>width</code></dfn> attribute of
-   <var>imageData</var> to <var>pixelsPerRow</var>.</p></li><li><p>Initialize the <dfn id="dom-imagedata-height-2"><code>height</code></dfn> attribute of
-   <var>imageData</var> to <var>rows</var>.</p></li><li><p>Return <var>imageData</var>.</p></li></ol>
-
-  <p><code id="pixel-manipulation:imagedata-18"><a href="#imagedata">ImageData</a></code> objects are <a href="https://html.spec.whatwg.org/multipage/structured-data.html#serializable-objects" id="pixel-manipulation:serializable-objects">serializable objects</a>. Their <a href="https://html.spec.whatwg.org/multipage/structured-data.html#serialization-steps" id="pixel-manipulation:serialization-steps">serialization
-  steps</a>, given <var>value</var> and <var>serialized</var>, are:</p>
-
-  <ol><li><p>Set <var>serialized</var>.[[Data]] to the <a href="https://html.spec.whatwg.org/multipage/structured-data.html#sub-serialization" id="pixel-manipulation:sub-serialization">sub-serialization</a> of the value of
-   <var>value</var>'s <code id="pixel-manipulation:dom-imagedata-data-2-2"><a href="#dom-imagedata-data-2">data</a></code> attribute.</p></li><li><p>Set <var>serialized</var>.[[Width]] to the value of <var>value</var>'s <code id="pixel-manipulation:dom-imagedata-width-2-2"><a href="#dom-imagedata-width-2">width</a></code> attribute.</p></li><li><p>Set <var>serialized</var>.[[Height]] to the value of <var>value</var>'s <code id="pixel-manipulation:dom-imagedata-height-2-2"><a href="#dom-imagedata-height-2">height</a></code> attribute.</p></li></ol>
-
-  <p>Their <a href="https://html.spec.whatwg.org/multipage/structured-data.html#deserialization-steps" id="pixel-manipulation:deserialization-steps">deserialization steps</a>, given <var>serialized</var> and <var>value</var>,
-  are:</p>
-
-  <ol><li><p>Initialize <var>value</var>'s <code id="pixel-manipulation:dom-imagedata-data-2-3"><a href="#dom-imagedata-data-2">data</a></code> attribute
-   to the <a href="https://html.spec.whatwg.org/multipage/structured-data.html#sub-deserialization" id="pixel-manipulation:sub-deserialization">sub-deserialization</a> of <var>serialized</var>.[[Data]].</p></li><li><p>Initialize <var>value</var>'s <code id="pixel-manipulation:dom-imagedata-width-2-3"><a href="#dom-imagedata-width-2">width</a></code> attribute
-   to <var>serialized</var>.[[Width]].</p></li><li><p>Initialize <var>value</var>'s <code id="pixel-manipulation:dom-imagedata-height-2-3"><a href="#dom-imagedata-height-2">height</a></code> attribute
-   to <var>serialized</var>.[[Height]].</p></li></ol>
-
-  <p>A <dfn id="canvas-pixel-arraybuffer">Canvas Pixel <code>ArrayBuffer</code></dfn> is an <code id="pixel-manipulation:idl-arraybuffer"><a data-x-internal="idl-arraybuffer" href="https://heycam.github.io/webidl/#idl-ArrayBuffer">ArrayBuffer</a></code> whose data is represented in left-to-right order, row
-  by row top to bottom, starting with the top left, with each pixel's red, green, blue, and alpha
-  components being given in that order for each pixel. Each component of each pixel represented in
-  this array must be in the range 0..255, representing the 8 bit value for that component. The
-  components must be assigned consecutive indices starting with 0 for the top left pixel's red
-  component.</p>
-
-  <p>The <dfn id="dom-context-2d-putimagedata-2"><code>putImageData()</code></dfn> method writes
-  data from <code id="pixel-manipulation:imagedata-19"><a href="#imagedata">ImageData</a></code> structures back to the rendering context's <a href="#output-bitmap" id="pixel-manipulation:output-bitmap-3">output
-  bitmap</a>. Its arguments are: <var>imagedata</var>, <var>dx</var>, <var>dy</var>,
-  <var>dirtyX</var>, <var>dirtyY</var>, <var>dirtyWidth</var>, and <var>dirtyHeight</var>.</p>
-
-  <p>When the last four arguments to this method are omitted, they must be assumed to have the
-  values 0, 0, the <code id="pixel-manipulation:dom-imagedata-width-2-4"><a href="#dom-imagedata-width-2">width</a></code> member of the <var>imagedata</var> structure, and the <code id="pixel-manipulation:dom-imagedata-height-2-4"><a href="#dom-imagedata-height-2">height</a></code>
-  member of the <var>imagedata</var> structure, respectively.</p>
-
-  <p>The method, when invoked, must act as follows:</p>
-
-  <ol><li>
-
-    <p>If <var>imagedata</var>'s <code id="pixel-manipulation:dom-imagedata-data-2-4"><a href="#dom-imagedata-data-2">data</a></code> attribute value's
-    <a href="https://html.spec.whatwg.org/multipage/structured-data.html#detached" id="pixel-manipulation:detached-2">[[Detached]]</a> internal slot value is true, then throw an
-    <a data-x-internal="invalidstateerror" href="https://heycam.github.io/webidl/#invalidstateerror" id="pixel-manipulation:invalidstateerror-3">&quot;<code>InvalidStateError</code>&quot;</a> <code id="pixel-manipulation:domexception-12"><a data-x-internal="domexception" href="https://heycam.github.io/webidl/#dfn-DOMException">DOMException</a></code> and abort these
-    steps.</p>
-
-   </li><li>
-
-    <p>If <var>dirtyWidth</var> is negative, then let <var>dirtyX</var> be <span><var>dirtyX</var>+<var>dirtyWidth</var></span>, and let <var>dirtyWidth</var> be equal
-    to the absolute magnitude of <var>dirtyWidth</var>.</p>
-
-    <p>If <var>dirtyHeight</var> is negative, then let <var>dirtyY</var> be <span><var>dirtyY</var>+<var>dirtyHeight</var></span>, and let <var>dirtyHeight</var> be
-    equal to the absolute magnitude of <var>dirtyHeight</var>.</p>
-
-   </li><li>
-
-    <p>If <var>dirtyX</var> is negative, then let <var>dirtyWidth</var> be <span><var>dirtyWidth</var>+<var>dirtyX</var></span>, and let <var>dirtyX</var> be zero.</p>
-
-    <p>If <var>dirtyY</var> is negative, then let <var>dirtyHeight</var> be <span><var>dirtyHeight</var>+<var>dirtyY</var></span>, and let <var>dirtyY</var> be zero.</p>
-
-   </li><li>
-
-    <p>If <var>dirtyX</var>+<var>dirtyWidth</var> is greater than the <code id="pixel-manipulation:dom-imagedata-width-2-5"><a href="#dom-imagedata-width-2">width</a></code> attribute of the <var>imagedata</var> argument, then
-    let <var>dirtyWidth</var> be the value of that <code id="pixel-manipulation:dom-imagedata-width-2-6"><a href="#dom-imagedata-width-2">width</a></code>
-    attribute, minus the value of <var>dirtyX</var>.</p>
-
-    <p>If <var>dirtyY</var>+<var>dirtyHeight</var> is greater than the <code id="pixel-manipulation:dom-imagedata-height-2-5"><a href="#dom-imagedata-height-2">height</a></code> attribute of the <var>imagedata</var> argument, then
-    let <var>dirtyHeight</var> be the value of that <code id="pixel-manipulation:dom-imagedata-height-2-6"><a href="#dom-imagedata-height-2">height</a></code> attribute, minus the value of <var>dirtyY</var>.</p>
-
-   </li><li>
-
-    <p>If, after those changes, either <var>dirtyWidth</var> or <var>dirtyHeight</var> are negative
-    or zero, then abort these steps without affecting any bitmaps.</p>
-
-   </li><li><p>For all integer values of <var>x</var> and <var>y</var> where <span><var>dirtyX</var> ≤ <var>x</var> &lt; <span><var>dirtyX</var>+<var>dirtyWidth</var></span></span> and <span><var>dirtyY</var> ≤ <var>y</var> &lt; <span><var>dirtyY</var>+<var>dirtyHeight</var></span></span>, copy the
-   four channels of the pixel with coordinate (<var>x</var>, <var>y</var>) in
-   the <var>imagedata</var> data structure's <a href="#canvas-pixel-arraybuffer" id="pixel-manipulation:canvas-pixel-arraybuffer-4">Canvas Pixel
-   <code>ArrayBuffer</code></a> to the pixel with coordinate (<span><var>dx</var>+<var>x</var></span>, <var>dy</var>+<var>y</var>)
-   in the rendering context's <a href="#output-bitmap" id="pixel-manipulation:output-bitmap-4">output bitmap</a>.</p></li></ol>
-
-  <p class="note">Due to the lossy nature of converting to and from premultiplied alpha color
-  values, pixels that have just been set using <code id="pixel-manipulation:dom-context-2d-putimagedata-2"><a href="#dom-context-2d-putimagedata-2">putImageData()</a></code> might be returned to an equivalent
-  <code id="pixel-manipulation:dom-context-2d-getimagedata-2"><a href="#dom-context-2d-getimagedata-2">getImageData()</a></code> as different values.</p>
-
-  <p>The current path, <a href="#transformations" id="pixel-manipulation:transformations">transformation matrix</a>,
-  <a href="#shadows" id="pixel-manipulation:shadows">shadow attributes</a>, <a href="#dom-context-2d-globalalpha-2" id="pixel-manipulation:dom-context-2d-globalalpha-2-2">global
-  alpha</a>, the <a href="#clipping-region" id="pixel-manipulation:clipping-region">clipping region</a>, and <a href="#dom-context-2d-globalcompositeoperation-2" id="pixel-manipulation:dom-context-2d-globalcompositeoperation-2-2">global composition operator</a> must not
-  affect the methods described in this section.</p>
-
-  
-
-  <div class="example">
-
-   <p>In the following example, the script generates an <code id="pixel-manipulation:imagedata-20"><a href="#imagedata">ImageData</a></code> object so that it can
-   draw onto it.</p>
-
-   <pre>// canvas is a reference to a &lt;canvas&gt; element
-var context = canvas.getContext('2d');
-
-// create a blank slate
-var data = context.createImageData(canvas.width, canvas.height);
-
-// create some plasma
-FillPlasma(data, 'green'); // green plasma
-
-// add a cloud to the plasma
-AddCloud(data, data.width/2, data.height/2); // put a cloud in the middle
-
-// paint the plasma+cloud on the canvas
-context.putImageData(data, 0, 0);
-
-// support methods
-function FillPlasma(data, color) { ... }
-function AddCloud(data, x, y) { ... }</pre>
-
-  </div>
-
-  <div class="example">
-
-   <p>Here is an example of using <code id="pixel-manipulation:dom-context-2d-getimagedata-2-2"><a href="#dom-context-2d-getimagedata-2">getImageData()</a></code> and <code id="pixel-manipulation:dom-context-2d-putimagedata-2-2"><a href="#dom-context-2d-putimagedata-2">putImageData()</a></code> to implement an edge detection
-   filter.</p>
-
-   <pre>&lt;!DOCTYPE HTML&gt;
-&lt;html lang=&quot;en&quot;&gt;
- &lt;head&gt;
-  &lt;title&gt;Edge detection demo&lt;/title&gt;
-  &lt;script&gt;
-   var image = new Image();
-   function init() {
-     image.onload = demo;
-     image.src = &quot;image.jpeg&quot;;
-   }
-   function demo() {
-     var canvas = document.getElementsByTagName('canvas')[0];
-     var context = canvas.getContext('2d');
-
-     // draw the image onto the canvas
-     context.drawImage(image, 0, 0);
-
-     // get the image data to manipulate
-     var input = context.getImageData(0, 0, canvas.width, canvas.height);
-
-     // get an empty slate to put the data into
-     var output = context.createImageData(canvas.width, canvas.height);
-
-     // alias some variables for convenience
-     // In this case input.width and input.height
-     // match canvas.width and canvas.height
-     // but we'll use the former to keep the code generic.
-     var w = input.width, h = input.height;
-     var inputData = input.data;
-     var outputData = output.data;
-
-     // edge detection
-     for (var y = 1; y &lt; h-1; y += 1) {
-       for (var x = 1; x &lt; w-1; x += 1) {
-         for (var c = 0; c &lt; 3; c += 1) {
-           var i = (y*w + x)*4 + c;
-           outputData[i] = 127 + -inputData[i - w*4 - 4] -   inputData[i - w*4] - inputData[i - w*4 + 4] +
-                                 -inputData[i - 4]       + 8*inputData[i]       - inputData[i + 4] +
-                                 -inputData[i + w*4 - 4] -   inputData[i + w*4] - inputData[i + w*4 + 4];
-         }
-         outputData[(y*w + x)*4 + 3] = 255; // alpha
-       }
-     }
-
-     // put the image data back after manipulation
-     context.putImageData(output, 0, 0);
-   }
-  &lt;/script&gt;
- &lt;/head&gt;
- &lt;body onload=&quot;init()&quot;&gt;
-  &lt;canvas&gt;&lt;/canvas&gt;
- &lt;/body&gt;
-&lt;/html&gt;</pre>
-
-  </div>
-
-
-
-
-  <h6 id="compositing"><span class="secno">4.12.5.1.16</span> Compositing<a class="self-link" href="#compositing"/></h6>
-
-  <dl class="domintro"><dt><var>context</var> . <code id="dom-context-2d-globalalpha"><a href="#dom-context-2d-globalalpha-2">globalAlpha</a></code> [ = <var>value</var> ]</dt><dd>
-
-    <p>Returns the current alpha value applied to rendering operations.</p>
-
-    <p>Can be set, to change the alpha value. Values outside of the range 0.0 .. 1.0 are
-    ignored.</p>
-
-   </dd><dt><var>context</var> . <code id="dom-context-2d-globalcompositeoperation"><a href="#dom-context-2d-globalcompositeoperation-2">globalCompositeOperation</a></code> [ = <var>value</var> ]</dt><dd>
-
-    <p>Returns the current composition operation, from the values defined in the Compositing and
-    Blending specification. <a href="https://html.spec.whatwg.org/multipage/references.html#refsCOMPOSITE">[COMPOSITE]</a>.</p>
-
-    <p>Can be set, to change the composition operation. Unknown values are ignored.</p>
-
-   </dd></dl><div class="status"><input onclick="toggleStatus(this)" type="button" value="⋰"/><p class="bugs"><strong>Spec bugs:</strong> <a href="https://www.w3.org/Bugs/Public/show_bug.cgi?id=27313" title="It seems like this should be defined in terms of an IDL enum. If not, please clarify the relationshi [...]">27313</a></p></div>
-
-  
-
-  <p>All drawing operations on an object which implements the <code id="compositing:canvascompositing"><a href="#canvascompositing">CanvasCompositing</a></code>
-  interface are affected by the global compositing attributes, <code id="compositing:dom-context-2d-globalalpha-2"><a href="#dom-context-2d-globalalpha-2">globalAlpha</a></code> and <code id="compositing:dom-context-2d-globalcompositeoperation-2"><a href="#dom-context-2d-globalcompositeoperation-2">globalCompositeOperation</a></code>.</p>
-
-  
-
-  <p>The <dfn id="dom-context-2d-globalalpha-2"><code>globalAlpha</code></dfn> attribute gives an
-  alpha value that is applied to shapes and images before they are composited onto the <a href="#output-bitmap" id="compositing:output-bitmap">output
-  bitmap</a>. The value must be in the range from 0.0 (fully transparent) to 1.0 (no additional
-  transparency). If an attempt is made to set the attribute to a value outside this range, including
-  Infinity and Not-a-Number (NaN) values, then the attribute must retain its previous value. When
-  the context is created, the <code id="compositing:dom-context-2d-globalalpha-2-2"><a href="#dom-context-2d-globalalpha-2">globalAlpha</a></code> attribute
-  must initially have the value 1.0.</p>
-
-  <p>The <dfn id="dom-context-2d-globalcompositeoperation-2"><code>globalCompositeOperation</code></dfn> attribute
-  sets the <dfn id="current-composition-operator">current composition operator</dfn>, which controls how shapes and images are drawn onto the
-  <a href="#output-bitmap" id="compositing:output-bitmap-2">output bitmap</a>, once they have had <code id="compositing:dom-context-2d-globalalpha-2-3"><a href="#dom-context-2d-globalalpha-2">globalAlpha</a></code> and the current transformation matrix
-  applied. The possible values are those defined in the Compositing and Blending specification, and
-  include the values <dfn id="gcop-source-over"><code>source-over</code></dfn>
-  and <dfn id="gcop-copy"><code>copy</code></dfn>.
-  <a href="https://html.spec.whatwg.org/multipage/references.html#refsCOMPOSITE">[COMPOSITE]</a></p>
-
-  <p>These values are all case-sensitive — they must be used exactly as defined. User agents
-  must not recognize values that are not a <a href="https://html.spec.whatwg.org/multipage/infrastructure.html#case-sensitive" id="compositing:case-sensitive">case-sensitive</a> match for one of the values
-  given in the Compositing and Blending specification. <a href="https://html.spec.whatwg.org/multipage/references.html#refsCOMPOSITE">[COMPOSITE]</a></p>
-
-  <p>On setting, if the user agent does not recognize the specified value, it must be ignored,
-  leaving the value of <code id="compositing:dom-context-2d-globalcompositeoperation-2-2"><a href="#dom-context-2d-globalcompositeoperation-2">globalCompositeOperation</a></code> unaffected.
-  Otherwise, the attribute must be set to the given new value.</p>
-
-  <p>When the context is created, the <code id="compositing:dom-context-2d-globalcompositeoperation-2-3"><a href="#dom-context-2d-globalcompositeoperation-2">globalCompositeOperation</a></code> attribute must
-  initially have the value <code id="compositing:gcop-source-over"><a href="#gcop-source-over">source-over</a></code>.</p>
-
-  
-
-
-
-  <h6 id="image-smoothing"><span class="secno">4.12.5.1.17</span> Image smoothing<a class="self-link" href="#image-smoothing"/></h6>
-
-  <dl class="domintro"><dt><var>context</var> . <code id="dom-context-2d-imagesmoothingenabled"><a href="#dom-context-2d-imagesmoothingenabled-2">imageSmoothingEnabled</a></code> [ = <var>value</var> ]</dt><dd>
-
-    <p>Returns whether pattern fills and the <code id="image-smoothing:dom-context-2d-drawimage"><a href="#dom-context-2d-drawimage">drawImage()</a></code> method will attempt to smooth images if
-    their pixels don't line up exactly with the display, when scaling images up.</p>
-
-    <p>Can be set, to change whether images are smoothed (true) or not (false).</p>
-
-   </dd><dt><var>context</var> . <code id="dom-context-2d-imagesmoothingquality"><a href="#dom-context-2d-imagesmoothingquality-2">imageSmoothingQuality</a></code> [ = <var>value</var> ]</dt><dd>
-
-    <p>Returns the current image-smoothing-quality preference.</p>
-
-    <p>Can be set, to change the preferred quality of image smoothing. The possible values are
-    &quot;<code id="image-smoothing:dom-context-2d-imagesmoothingquality-low"><a href="#dom-context-2d-imagesmoothingquality-low">low</a></code>&quot;, &quot;<code id="image-smoothing:dom-context-2d-imagesmoothingquality-medium"><a href="#dom-context-2d-imagesmoothingquality-medium">medium</a></code>&quot; and &quot;<code id="image-smoothing:dom-context-2d-imagesmoothingquality-high"><a href="#dom-context-2d-imagesmoothingquality-high">high</a></code>&quot;. Unknown values are ignored.</p>
-
-   </dd></dl>
-
-  
-
-  <p>Objects that implement the <code id="image-smoothing:canvasimagesmoothing"><a href="#canvasimagesmoothing">CanvasImageSmoothing</a></code> interface have attributes that
-  control how image smoothing is performed.</p>
-
-  <p>The <dfn id="dom-context-2d-imagesmoothingenabled-2"><code>imageSmoothingEnabled</code></dfn>
-  attribute, on getting, must return the last value it was set to. On setting, it must be set to the
-  new value. When the object implementing the <code id="image-smoothing:canvasimagesmoothing-2"><a href="#canvasimagesmoothing">CanvasImageSmoothing</a></code> interface is
-  created, the attribute must be set to true.</p>
-
-  <p>The <dfn id="dom-context-2d-imagesmoothingquality-2"><code>imageSmoothingQuality</code></dfn>
-  attribute, on getting, must return the last value it was set to. On setting, it must be set to the
-  new value. When the object implementing the <code id="image-smoothing:canvasimagesmoothing-3"><a href="#canvasimagesmoothing">CanvasImageSmoothing</a></code> interface is
-  created, the attribute must be set to &quot;<code id="image-smoothing:dom-context-2d-imagesmoothingquality-low-2"><a href="#dom-context-2d-imagesmoothingquality-low">low</a></code>&quot;.</p>
-
-  
-
-
-  <h6 id="shadows"><span class="secno">4.12.5.1.18</span> <dfn>Shadows</dfn><a class="self-link" href="#shadows"/></h6>
-
-  <p>All drawing operations on an object which implements the <code id="shadows:canvasshadowstyles"><a href="#canvasshadowstyles">CanvasShadowStyles</a></code>
-  interface are affected by the four global shadow attributes.</p>
-
-  <dl class="domintro"><dt><var>context</var> . <code id="dom-context-2d-shadowcolor"><a href="#dom-context-2d-shadowcolor-2">shadowColor</a></code> [ = <var>value</var> ]</dt><dd>
-
-    <p>Returns the current shadow color.</p>
-
-    <p>Can be set, to change the shadow color. Values that cannot be parsed as CSS colors are ignored.</p>
-
-   </dd><dt><var>context</var> . <code id="dom-context-2d-shadowoffsetx"><a href="#dom-context-2d-shadowoffsetx-2">shadowOffsetX</a></code> [ = <var>value</var> ]</dt><dt><var>context</var> . <code id="dom-context-2d-shadowoffsety"><a href="#dom-context-2d-shadowoffsety-2">shadowOffsetY</a></code> [ = <var>value</var> ]</dt><dd>
-
-    <p>Returns the current shadow offset.</p>
-
-    <p>Can be set, to change the shadow offset. Values that are not finite numbers are ignored.</p>
-
-   </dd><dt><var>context</var> . <code id="dom-context-2d-shadowblur"><a href="#dom-context-2d-shadowblur-2">shadowBlur</a></code> [ = <var>value</var> ]</dt><dd>
-
-    <p>Returns the current level of blur applied to shadows.</p>
-
-    <p>Can be set, to change the blur level. Values that are not finite numbers greater than or
-    equal to zero are ignored.</p>
-
-   </dd></dl>
-
-  
-
-  <p>The <dfn id="dom-context-2d-shadowcolor-2"><code>shadowColor</code></dfn> attribute sets the
-  color of the shadow.</p>
-
-  <p>When the context is created, the <code id="shadows:dom-context-2d-shadowcolor-2"><a href="#dom-context-2d-shadowcolor-2">shadowColor</a></code>
-  attribute initially must be fully-transparent black.</p>
-
-  <p>On getting, the <a href="#serialisation-of-a-color" id="shadows:serialisation-of-a-color">serialization of the color</a>
-  must be returned.</p>
-
-  <p>On setting, the new value must be <a href="https://html.spec.whatwg.org/multipage/infrastructure.html#parsed-as-a-css-color-value" id="shadows:parsed-as-a-css-color-value">parsed as a CSS &lt;color&gt; value</a> and the
-  color assigned. If the value cannot be <a href="https://html.spec.whatwg.org/multipage/infrastructure.html#parsed-as-a-css-color-value" id="shadows:parsed-as-a-css-color-value-2">parsed as a CSS &lt;color&gt; value</a> then it
-  must be ignored, and the attribute must retain its previous value. <a href="https://html.spec.whatwg.org/multipage/references.html#refsCSSCOLOR">[CSSCOLOR]</a></p>
-
-  <p>The <dfn id="dom-context-2d-shadowoffsetx-2"><code>shadowOffsetX</code></dfn> and <dfn id="dom-context-2d-shadowoffsety-2"><code>shadowOffsetY</code></dfn> attributes specify the distance
-  that the shadow will be offset in the positive horizontal and positive vertical distance
-  respectively. Their values are in coordinate space units. They are not affected by the current
-  transformation matrix.</p>
-
-  <p>When the context is created, the shadow offset attributes must initially have the value
-  0.</p>
-
-  <p>On getting, they must return their current value. On setting, the attribute being set must be
-  set to the new value, except if the value is infinite or NaN, in which case the new value must be
-  ignored.</p>
-
-  <p>The <dfn id="dom-context-2d-shadowblur-2"><code>shadowBlur</code></dfn> attribute specifies
-  the level of the blurring effect. (The units do not map to coordinate space units, and are not
-  affected by the current transformation matrix.)</p>
-
-  <p>When the context is created, the <code id="shadows:dom-context-2d-shadowblur-2"><a href="#dom-context-2d-shadowblur-2">shadowBlur</a></code>
-  attribute must initially have the value 0.</p>
-
-  <p>On getting, the attribute must return its current value. On setting the attribute must be set
-  to the new value, except if the value is negative, infinite or NaN, in which case the new value
-  must be ignored.</p>
-
-  <p><dfn id="when-shadows-are-drawn">Shadows are only drawn if</dfn> the opacity component of
-  the alpha component of the color of <code id="shadows:dom-context-2d-shadowcolor-2-2"><a href="#dom-context-2d-shadowcolor-2">shadowColor</a></code> is
-  non-zero and either the <code id="shadows:dom-context-2d-shadowblur-2-2"><a href="#dom-context-2d-shadowblur-2">shadowBlur</a></code> is non-zero, or
-  the <code id="shadows:dom-context-2d-shadowoffsetx-2"><a href="#dom-context-2d-shadowoffsetx-2">shadowOffsetX</a></code> is non-zero, or the <code id="shadows:dom-context-2d-shadowoffsety-2"><a href="#dom-context-2d-shadowoffsety-2">shadowOffsetY</a></code> is non-zero.</p>
-
-  <p><a href="#when-shadows-are-drawn" id="shadows:when-shadows-are-drawn">When shadows are drawn</a>, they must be rendered as follows:</p>
-
-  <ol><li><p>Let <var>A</var> be an infinite transparent black bitmap on which the source
-   image for which a shadow is being created has been rendered.</p></li><li><p>Let <var>B</var> be an infinite transparent black bitmap, with a coordinate
-   space and an origin identical to <var>A</var>.</p></li><li><p>Copy the alpha channel of <var>A</var> to <var>B</var>, offset by <code id="shadows:dom-context-2d-shadowoffsetx-2-2"><a href="#dom-context-2d-shadowoffsetx-2">shadowOffsetX</a></code> in the positive <var>x</var>
-   direction, and <code id="shadows:dom-context-2d-shadowoffsety-2-2"><a href="#dom-context-2d-shadowoffsety-2">shadowOffsetY</a></code> in the positive
-   <var>y</var> direction.</p></li><li>
-
-    <p>If <code id="shadows:dom-context-2d-shadowblur-2-3"><a href="#dom-context-2d-shadowblur-2">shadowBlur</a></code> is greater than 0:</p>
-
-    <ol><li> <p>Let <var>σ</var> be half the value of <code id="shadows:dom-context-2d-shadowblur-2-4"><a href="#dom-context-2d-shadowblur-2">shadowBlur</a></code>.</p></li><li> <p>Perform a 2D Gaussian Blur on <var>B</var>, using <var>σ</var>
-     as the standard deviation.</p>  </li></ol>
-
-    <p>User agents may limit values of <var>σ</var> to an implementation-specific
-    maximum value to avoid exceeding hardware limitations during the Gaussian blur operation.</p>
-
-   </li><li><p>Set the red, green, and blue components of every pixel in <var>B</var> to the
-   red, green, and blue components (respectively) of the color of <code id="shadows:dom-context-2d-shadowcolor-2-3"><a href="#dom-context-2d-shadowcolor-2">shadowColor</a></code>.</p></li><li><p>Multiply the alpha component of every pixel in <var>B</var> by the alpha
-   component of the color of <code id="shadows:dom-context-2d-shadowcolor-2-4"><a href="#dom-context-2d-shadowcolor-2">shadowColor</a></code>.</p></li><li><p>The shadow is in the bitmap <var>B</var>, and is rendered as part of the
-   <a href="#drawing-model" id="shadows:drawing-model">drawing model</a> described below.</p></li></ol>
-
-  
-
-  <p>If the current composition operation is <code id="shadows:gcop-copy"><a href="#gcop-copy">copy</a></code>, then shadows
-  effectively won't render (since the shape will overwrite the shadow).</p>
-
-  <h6 id="filters"><span class="secno">4.12.5.1.19</span> Filters<a class="self-link" href="#filters"/></h6>
-
-  <p>All drawing operations on an object which implements the <code id="filters:canvasfilters"><a href="#canvasfilters">CanvasFilters</a></code>
-  interface are affected by the global <dfn id="dom-context-2d-filter"><code>filter</code></dfn>
-  attribute.</p>
-
-  <dl class="domintro"><dt><var>context</var> . <code id="dom-context-2d-filter-2"><a href="#dom-context-2d-filter">filter</a></code> [ = <var>value</var> ]</dt><dd>
-
-    <p>Returns the current filter.</p>
-
-    <p>Can be set, to change the filter. Values that cannot be parsed as a
-    <a data-x-internal="filter-function-list" href="https://drafts.fxtf.org/filters/#typedef-filter-function-list" id="filters:filter-function-list">&lt;filter-function-list&gt;</a> value are ignored.</p>
-
-   </dd></dl>
-
-  
-
-  <p>The <code id="filters:dom-context-2d-filter"><a href="#dom-context-2d-filter">filter</a></code> attribute, on getting, must
-  return the last value it was successfully set to. The value must not be re-serialized. On setting,
-  if the new value is 'none' (not the empty string, null, or undefined), filters must be disabled
-  for the context. Otherwise, the value must be parsed as a
-  <a data-x-internal="filter-function-list" href="https://drafts.fxtf.org/filters/#typedef-filter-function-list" id="filters:filter-function-list-2">&lt;filter-function-list&gt;</a> value. If the value cannot be parsed as a
-  <a data-x-internal="filter-function-list" href="https://drafts.fxtf.org/filters/#typedef-filter-function-list" id="filters:filter-function-list-3">&lt;filter-function-list&gt;</a> value, where using property-independent style sheet
-  syntax like 'inherit' or 'initial' is considered an invalid value, then it must be ignored, and
-  the attribute must retain its previous value. When creating the object implementing the
-  <code id="filters:canvasfilters-2"><a href="#canvasfilters">CanvasFilters</a></code> interface, the attribute must be set to 'none'.</p>
-
-  <p>A <a data-x-internal="filter-function-list" href="https://drafts.fxtf.org/filters/#typedef-filter-function-list" id="filters:filter-function-list-4">&lt;filter-function-list&gt;</a> value consists of a sequence of one or more
-  filter functions or references to SVG filters. The input to the filter is used as the input
-  to the first item in the list. Subsequent items take the output of the previous item as
-  their input. <a href="https://html.spec.whatwg.org/multipage/references.html#refsFILTERS">[FILTERS]</a></p>
-
-  <p>Coordinates used in the value of the <code id="filters:dom-context-2d-filter-2"><a href="#dom-context-2d-filter">filter</a></code> attribute are interpreted such that one pixel is
-  equivalent to one SVG user space unit and to one canvas coordinate space unit. Filter coordinates
-  are not affected by the <a href="#transformations" id="filters:transformations">current transformation
-  matrix</a>. The current transformation matrix affects only the input to the filter. Filters
-  are applied in the <a href="#output-bitmap" id="filters:output-bitmap">output bitmap</a>'s coordinate space.</p>
-
-  <p>When the value of the <code id="filters:dom-context-2d-filter-3"><a href="#dom-context-2d-filter">filter</a></code> attribute defines
-  lengths using percentages or using <a data-x-internal="'em'" href="https://drafts.csswg.org/css-values/#em" id="filters:'em'">'em'</a> or <a data-x-internal="'ex'" href="https://drafts.csswg.org/css-values/#ex" id="filters:'ex'">'ex'</a> units, these must be
-  interpreted relative to the <a data-x-internal="computed-value" href="https://drafts.csswg.org/css-cascade/#computed-value" id="filters:computed-value">computed value</a> of the <a data-x-internal="'font-size'" href="https://drafts.csswg.org/css-fonts/#font-size-prop" id="filters:'font-size'">'font-size'</a> property
-  of the <a href="#font-style-source-object" id="filters:font-style-source-object">font style source object</a> at the time that the attribute is set, if it is an
-  element. If the <a data-x-internal="computed-value" href="https://drafts.csswg.org/css-cascade/#computed-value" id="filters:computed-value-2">computed values</a> are undefined for a
-  particular case (e.g. because the <a href="#font-style-source-object" id="filters:font-style-source-object-2">font style source object</a> is not an element or is
-  not <a href="https://html.spec.whatwg.org/multipage/rendering.html#being-rendered" id="filters:being-rendered">being rendered</a>), then the relative keywords must be interpreted relative to the
-  default value of the <code id="filters:dom-context-2d-font-2"><a href="#dom-context-2d-font-2">font</a></code> attribute. The 'larger' and
-  'smaller' keywords are not supported.</p>
-
-  <p>If the value of the <code id="filters:dom-context-2d-filter-4"><a href="#dom-context-2d-filter">filter</a></code> attribute refers to an
-  SVG filter in the same document, and this SVG filter changes, then the changed filter is used for
-  the next draw operation.</p>
-
-  <p>If the value of the <code id="filters:dom-context-2d-filter-5"><a href="#dom-context-2d-filter">filter</a></code> attribute refers to an
-  SVG filter in an external resource document and that document is not loaded when a drawing
-  operation is invoked, then the drawing operation must proceed with no filtering.</p>
-
-  
-
-  <h6 id="working-with-externally-defined-svg-filters"><span class="secno">4.12.5.1.20</span> Working with externally-defined SVG filters<a class="self-link" href="#working-with-externally-defined-svg-filters"/></h6>
-
-  <p><i>This section is non-normative.</i></p>
-
-  <p>Since drawing is performed using filter value 'none' until an externally-defined
-  filter has finished loading, authors might wish to determine whether such a filter
-  has finished loading before proceeding with a drawing operation. One way to accomplish
-  this is to load the externally-defined filter elsewhere within the same page in some
-  element that sends a <code>load</code> event (for example, an <a data-x-internal="svg-use" href="https://www.w3.org/TR/SVG11/struct.html#UseElement" id="working-with-externally-defined-svg-filters:svg-use">SVG
-  <code>use</code></a> element), and wait for the <code>load</code> event to be
-  dispatched.</p>
-
-  
-
-  <h6 id="drawing-model"><span class="secno">4.12.5.1.21</span> <dfn>Drawing model</dfn><a class="self-link" href="#drawing-model"/></h6>
-
-  <p>When a shape or image is painted, user agents must follow these steps, in the order given (or
-  act as if they do):</p>
-
-  <ol><li><p>Render the shape or image onto an infinite transparent black bitmap, creating image <var>A</var>, as described in the previous sections. For shapes, the current fill, stroke,
-   and line styles must be honored, and the stroke must itself also be subjected to the current
-   transformation matrix.</p></li><li><p>When the filter attribute is set to a value other than 'none' and all the
-   externally-defined filters it references, if any, are in documents that are currently loaded,
-   then use image <var>A</var> as the input to the <code id="drawing-model:dom-context-2d-filter"><a href="#dom-context-2d-filter">filter</a></code>, creating image <var>B</var>. Otherwise, let
-   <var>B</var> be an alias for <var>A</var>.</p></li><li><p><a href="#when-shadows-are-drawn" id="drawing-model:when-shadows-are-drawn">When shadows are drawn</a>, render the shadow from image <var>B</var>,
-   using the current shadow styles, creating image <var>C</var>.</p></li><li><p><a href="#when-shadows-are-drawn" id="drawing-model:when-shadows-are-drawn-2">When shadows are drawn</a>, multiply the alpha component of every pixel in <var>C</var> by <code id="drawing-model:dom-context-2d-globalalpha-2"><a href="#dom-context-2d-globalalpha-2">globalAlpha</a></code>.</p></li><li><p><a href="#when-shadows-are-drawn" id="drawing-model:when-shadows-are-drawn-3">When shadows are drawn</a>, composite <var>C</var> within the
-   <a href="#clipping-region" id="drawing-model:clipping-region">clipping region</a> over the current <a href="#output-bitmap" id="drawing-model:output-bitmap">output bitmap</a> using the <a href="#current-composition-operator" id="drawing-model:current-composition-operator">current
-   composition operator</a>.</p></li><li><p>Multiply the alpha component of every pixel in <var>B</var> by <code id="drawing-model:dom-context-2d-globalalpha-2-2"><a href="#dom-context-2d-globalalpha-2">globalAlpha</a></code>.</p></li><li><p>Composite <var>B</var> within the <a href="#clipping-region" id="drawing-model:clipping-region-2">clipping region</a> over the current
-   <a href="#output-bitmap" id="drawing-model:output-bitmap-2">output bitmap</a> using the <a href="#current-composition-operator" id="drawing-model:current-composition-operator-2">current composition operator</a>.</p></li></ol>
-
-  <p>When compositing onto the <a href="#output-bitmap" id="drawing-model:output-bitmap-3">output bitmap</a>, pixels that would fall outside of the
-  <a href="#output-bitmap" id="drawing-model:output-bitmap-4">output bitmap</a> must be discarded.</p>
-
-  
-
-
-
-
-  <h6 id="best-practices"><span class="secno">4.12.5.1.22</span> Best practices<a class="self-link" href="#best-practices"/></h6>
-
-  <p>When a canvas is interactive, authors should include focusable elements in the element's
-  fallback content corresponding to each focusable part of the canvas, as in the <a href="#drawCustomFocusRingExample">example above</a>.</p>
-
-  <p>When rendering focus rings, to ensure that focus rings have the appearance of native focus
-  rings, authors should use the <code id="best-practices:dom-context-2d-drawfocusifneeded-2"><a href="#dom-context-2d-drawfocusifneeded-2">drawFocusIfNeeded()</a></code> method, passing it the
-  element for which a ring is being drawn. This method only draws the focus ring if the element is
-  <a href="https://html.spec.whatwg.org/multipage/interaction.html#focused" id="best-practices:focused">focused</a>, so that it can simply be called whenever drawing the element, without
-  checking whether the element is focused or not first.</p>
-
-  <p>In addition to drawing focus rings, authors should use the <code id="best-practices:dom-context-2d-scrollpathintoview-2"><a href="#dom-context-2d-scrollpathintoview-2">scrollPathIntoView()</a></code> method when an element in
-  the canvas is focused, to make sure it is visible on the screen (if applicable).</p>
-
-  <p id="no-text-editing-in-canvas-please">Authors should avoid implementing text editing controls
-  using the <code id="best-practices:the-canvas-element"><a href="#the-canvas-element">canvas</a></code> element. Doing so has a large number of disadvantages:</p>
-
-  <ul><li>Mouse placement of the caret has to be reimplemented.</li><li>Keyboard movement of the caret has to be reimplemented (possibly across lines, for multiline
-   text input).</li><li>Scrolling of the text control has to be implemented (horizontally for long lines, vertically
-   for multiline input).</li><li>Native features such as copy-and-paste have to be reimplemented.</li><li>Native features such as spell-checking have to be reimplemented.</li><li>Native features such as drag-and-drop have to be reimplemented.</li><li>Native features such as page-wide text search have to be reimplemented.</li><li>Native features specific to the user, for example custom text services, have to be
-   reimplemented. This is close to impossible since each user might have different services
-   installed, and there is an unbounded set of possible such services.</li><li>Bidirectional text editing has to be reimplemented.</li><li>For multiline text editing, line wrapping has to be implemented for all relevant
-   languages.</li><li>Text selection has to be reimplemented.</li><li>Dragging of bidirectional text selections has to be reimplemented.</li><li>Platform-native keyboard shortcuts have to be reimplemented.</li><li>Platform-native input method editors (IMEs) have to be reimplemented.</li><li>Undo and redo functionality has to be reimplemented.</li><li>Accessibility features such as magnification following the caret or selection have to be
-   reimplemented.</li></ul>
-
-  <p>This is a huge amount of work, and authors are most strongly encouraged to avoid doing any of
-  it by instead using the <code id="best-practices:the-input-element"><a href="https://html.spec.whatwg.org/multipage/input.html#the-input-element">input</a></code> element, the <code id="best-practices:the-textarea-element"><a href="https://html.spec.whatwg.org/multipage/form-elements.html#the-textarea-element">textarea</a></code> element, or the
-  <code id="best-practices:attr-contenteditable"><a href="https://html.spec.whatwg.org/multipage/interaction.html#attr-contenteditable">contenteditable</a></code> attribute.</p>
-
-
-  <h6 id="examples"><span class="secno">4.12.5.1.23</span> Examples<a class="self-link" href="#examples"/></h6>
-
-  <p><i>This section is non-normative.</i></p>
-
-  <div class="example">
-
-  <p>Here is an example of a script that uses canvas to draw <a href="data:text/html;charset=utf-8;base64,PCFET0NUWVBFIEhUTUw%2BDQo8aHRtbCBsYW5nPSJlbiI%2BDQogPGhlYWQ%2BDQogIDx0aXRsZT5QcmV0dHkgR2xvd2luZyBMaW5lczwvdGl0bGU%2BDQogPC9oZWFkPg0KIDxib2R5Pg0KPGNhbnZhcyB3aWR0aD0iODAwIiBoZWlnaHQ9IjQ1MCI%2BPC9jYW52YXM%2BDQo8c2NyaXB0Pg0KDQogdmFyIGNvbnRleHQgPSBkb2N1bWVudC5nZXRFbGVtZW50c0J5VGFnTmFtZSgnY2FudmFzJylbMF0uZ2V0Q29udGV4dCgnMmQnKTsNCg0KIHZhciBsYXN0WCA9IGNvbnRleHQuY2FudmFzLndpZHRoICogTWF0aC5yYW5kb20oKTsNCiB2YXIgbGFzdFkgPSBjb250ZXh0LmNhbnZhcy5oZWlnaHQgKiBNYXRoLnJhbmRvbSgpOw0KIHZhciBodWUgPSAwOw0KIGZ1bmN0aW9uIGxpbmUoKSB7DQogICBjb250ZXh0LnNhdmUoKTsNCiAgIGNvbnRleHQudHJhbnNsYXRlKGNvbnRleHQuY2FudmFzLndpZHRoLzIsIGNvbnRleHQuY2FudmFzLmhlaWdodC8yKTsNCiAgIGNvbnRleHQuc2NhbGUoMC45LCAwLjkpOw0KICAgY29udGV4dC50cmFuc2xhdGUoLWNvbnRleHQuY2FudmFzLndpZHRoLzIsIC1jb250ZXh0LmNhbnZhcy5oZWlnaHQvMik7DQogICBjb250ZXh0LmJlZ2luUGF0aCgpOw0KICAgY29udGV4dC5saW5lV2lkdGggPSA1ICsgTWF0aC5yYW5kb20oKSAqIDEwOw0KICAgY29udGV4dC5tb3ZlVG8obGFzdFgsIGxhc3RZKTsNCiAgIGxhc3RYID0gY29udGV4dC5jYW52YXMud2lkdGggKiBNYXRoLnJhbmRvbSgpOw0KICAgbGFzdFkgPSBjb250ZXh0LmNhbnZhcy5oZWlnaHQgKiBNYXRoLnJhbmRvbSgpOw0KICAgY29udGV4dC5iZXppZXJDdXJ2ZVRvKGNvbnRleHQuY2FudmFzLndpZHRoICogTWF0aC5yYW5kb20oKSwNCiAgICAgICAgICAgICAgICAgICAgICAgICBjb250ZXh0LmNhbnZhcy5oZWlnaHQgKiBNYXRoLnJhbmRvbSgpLA0KICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRleHQuY2FudmFzLndpZHRoICogTWF0aC5yYW5kb20oKSwNCiAgICAgICAgICAgICAgICAgICAgICAgICBjb250ZXh0LmNhbnZhcy5oZWlnaHQgKiBNYXRoLnJhbmRvbSgpLA0KICAgICAgICAgICAgICAgICAgICAgICAgIGxhc3RYLCBsYXN0WSk7DQoNCiAgIGh1ZSA9IGh1ZSArIDEwICogTWF0aC5yYW5kb20oKTsNCiAgIGNvbnRleHQuc3Ryb2tlU3R5bGUgPSAnaHNsKCcgKyBodWUgKyAnLCA1MCUsIDUwJSknOw0KICAgY29udGV4dC5zaGFkb3dDb2xvciA9ICd3aGl0ZSc7DQogICBjb250ZXh0LnNoYWRvd0JsdXIgPSAxMDsNCiAgIGNvbnRleHQuc3Ryb2tlKCk7DQogICBjb250ZXh0LnJlc3RvcmUoKTsNCiB9DQogc2V0SW50ZXJ2YWwobGluZSwgNTApOw0KDQogZnVuY3Rpb24gYmxhbmsoKSB7DQogICBjb250ZXh0LmZpbGxTdHlsZSA9ICdyZ2JhKDAsMCwwLDAuMSknOw0KICAgY29udGV4dC5maWxsUmVjdCgwLCAwLCBjb250ZXh0LmNhbnZhcy53aWR0aCwgY29udGV4dC5jYW52YXMuaGVpZ2h0KTsNCiB9DQogc2V0SW50ZXJ2YWwoYmxhbmssIDQwKTsNCg0KPC9zY3JpcHQ%2BDQogPC9ib2R5Pg0KPC9odG1sPg0K">pretty glowing lines</a>.</p>
-
-  <pre>&lt;canvas width=&quot;800&quot; height=&quot;450&quot;&gt;&lt;/canvas&gt;
-&lt;script&gt;
-
- var context = document.getElementsByTagName('canvas')[0].getContext('2d');
-
- var lastX = context.canvas.width * Math.random();
- var lastY = context.canvas.height * Math.random();
- var hue = 0;
- function line() {
-   context.save();
-   context.translate(context.canvas.width/2, context.canvas.height/2);
-   context.scale(0.9, 0.9);
-   context.translate(-context.canvas.width/2, -context.canvas.height/2);
-   context.beginPath();
-   context.lineWidth = 5 + Math.random() * 10;
-   context.moveTo(lastX, lastY);
-   lastX = context.canvas.width * Math.random();
-   lastY = context.canvas.height * Math.random();
-   context.bezierCurveTo(context.canvas.width * Math.random(),
-                         context.canvas.height * Math.random(),
-                         context.canvas.width * Math.random(),
-                         context.canvas.height * Math.random(),
-                         lastX, lastY);
-
-   hue = hue + 10 * Math.random();
-   context.strokeStyle = 'hsl(' + hue + ', 50%, 50%)';
-   context.shadowColor = 'white';
-   context.shadowBlur = 10;
-   context.stroke();
-   context.restore();
- }
- setInterval(line, 50);
-
- function blank() {
-   context.fillStyle = 'rgba(0,0,0,0.1)';
-   context.fillRect(0, 0, context.canvas.width, context.canvas.height);
- }
- setInterval(blank, 40);
-
-&lt;/script&gt;</pre>
-
-  </div>
-
-  <div class="example">
-
-   <p>The 2D rendering context for <code id="examples:the-canvas-element"><a href="#the-canvas-element">canvas</a></code> is often used for sprite-based games. The
-   following example demonstrates this:</p>
-
-   <iframe height="216" src="https://html.spec.whatwg.org/demos/canvas/blue-robot/index-idle.html" width="396"/>
-
-   <p>Here is the source for this example:</p>
-
-   <pre>&lt;!DOCTYPE HTML&gt;
-&lt;meta charset=&quot;utf-8&quot;&gt;
-&lt;title&gt;Blue Robot Demo&lt;/title&gt;
-&lt;style&gt;
-  html { overflow: hidden; min-height: 200px; min-width: 380px; }
-  body { height: 200px; position: relative; margin: 8px; }
-  .buttons { position: absolute; bottom: 0px; left: 0px; margin: 4px; }
-&lt;/style&gt;
-&lt;canvas width=&quot;380&quot; height=&quot;200&quot;&gt;&lt;/canvas&gt;
-&lt;script&gt;
- var Landscape = function (context, width, height) {
-   this.offset = 0;
-   this.width = width;
-   this.advance = function (dx) {
-     this.offset += dx;
-   };
-   this.horizon = height * 0.7;
-   // This creates the sky gradient (from a darker blue to white at the bottom)
-   this.sky = context.createLinearGradient(0, 0, 0, this.horizon);
-   this.sky.addColorStop(0.0, 'rgb(55,121,179)');
-   this.sky.addColorStop(0.7, 'rgb(121,194,245)');
-   this.sky.addColorStop(1.0, 'rgb(164,200,214)');
-   // this creates the grass gradient (from a darker green to a lighter green)
-   this.earth = context.createLinearGradient(0, this.horizon, 0, height);
-   this.earth.addColorStop(0.0, 'rgb(81,140,20)');
-   this.earth.addColorStop(1.0, 'rgb(123,177,57)');
-   this.paintBackground = function (context, width, height) {
-     // first, paint the sky and grass rectangles
-     context.fillStyle = this.sky;
-     context.fillRect(0, 0, width, this.horizon);
-     context.fillStyle = this.earth;
-     context.fillRect(0, this.horizon, width, height-this.horizon);
-     // then, draw the cloudy banner
-     // we make it cloudy by having the draw text off the top of the
-     // canvas, and just having the blurred shadow shown on the canvas
-     context.save();
-     context.translate(width-((this.offset+(this.width*3.2)) % (this.width*4.0))+0, 0);
-     context.shadowColor = 'white';
-     context.shadowOffsetY = 30+this.horizon/3; // offset down on canvas
-     context.shadowBlur = '5';
-     context.fillStyle = 'white';
-     context.textAlign = 'left';
-     context.textBaseline = 'top';
-     context.font = '20px sans-serif';
-     context.fillText('WHATWG ROCKS', 10, -30); // text up above canvas
-     context.restore();
-     // then, draw the background tree
-     context.save();
-     context.translate(width-((this.offset+(this.width*0.2)) % (this.width*1.5))+30, 0);
-     context.beginPath();
-     context.fillStyle = 'rgb(143,89,2)';
-     context.lineStyle = 'rgb(10,10,10)';
-     context.lineWidth = 2;
-     context.rect(0, this.horizon+5, 10, -50); // trunk
-     context.fill();
-     context.stroke();
-     context.beginPath();
-     context.fillStyle = 'rgb(78,154,6)';
-     context.arc(5, this.horizon-60, 30, 0, Math.PI*2); // leaves
-     context.fill();
-     context.stroke();
-     context.restore();
-   };
-   this.paintForeground = function (context, width, height) {
-     // draw the box that goes in front
-     context.save();
-     context.translate(width-((this.offset+(this.width*0.7)) % (this.width*1.1))+0, 0);
-     context.beginPath();
-     context.rect(0, this.horizon - 5, 25, 25);
-     context.fillStyle = 'rgb(220,154,94)';
-     context.lineStyle = 'rgb(10,10,10)';
-     context.lineWidth = 2;
-     context.fill();
-     context.stroke();
-     context.restore();
-   };
- };
-&lt;/script&gt;
-&lt;script&gt;
- var BlueRobot = function () {
-   this.sprites = new Image();
-   this.sprites.src = 'blue-robot.png'; // this sprite sheet has 8 cells
-   this.targetMode = 'idle';
-   this.walk = function () {
-     this.targetMode = 'walk';
-   };
-   this.stop = function () {
-     this.targetMode = 'idle';
-   };
-   this.frameIndex = {
-     'idle': [0], // first cell is the idle frame
-     'walk': [1,2,3,4,5,6], // the walking animation is cells 1-6
-     'stop': [7], // last cell is the stopping animation
-   };
-   this.mode = 'idle';
-   this.frame = 0; // index into frameIndex
-   this.tick = function () {
-     // this advances the frame and the robot
-     // the return value is how many pixels the robot has moved
-     this.frame += 1;
-     if (this.frame &gt;= this.frameIndex[this.mode].length) {
-       // we've reached the end of this animation cycle
-       this.frame = 0;
-       if (this.mode != this.targetMode) {
-         // switch to next cycle
-         if (this.mode == 'walk') {
-           // we need to stop walking before we decide what to do next
-           this.mode = 'stop';
-         } else if (this.mode == 'stop') {
-           if (this.targetMode == 'walk')
-             this.mode = 'walk';
-           else
-             this.mode = 'idle';
-         } else if (this.mode == 'idle') {
-           if (this.targetMode == 'walk')
-             this.mode = 'walk';
-         }
-       }
-     }
-     if (this.mode == 'walk')
-       return 8;
-     return 0;
-   },
-   this.paint = function (context, x, y) {
-     if (!this.sprites.complete) return;
-     // draw the right frame out of the sprite sheet onto the canvas
-     // we assume each frame is as high as the sprite sheet
-     // the x,y coordinates give the position of the bottom center of the sprite
-     context.drawImage(this.sprites,
-                       this.frameIndex[this.mode][this.frame] * this.sprites.height, 0, this.sprites.height, this.sprites.height,
-                       x-this.sprites.height/2, y-this.sprites.height, this.sprites.height, this.sprites.height);
-   };
- };
-&lt;/script&gt;
-&lt;script&gt;
- var canvas = document.getElementsByTagName('canvas')[0];
- var context = canvas.getContext('2d');
- var landscape = new Landscape(context, canvas.width, canvas.height);
- var blueRobot = new BlueRobot();
- // paint when the browser wants us to, using requestAnimationFrame()
- function paint() {
-   context.clearRect(0, 0, canvas.width, canvas.height);
-   landscape.paintBackground(context, canvas.width, canvas.height);
-   blueRobot.paint(context, canvas.width/2, landscape.horizon*1.1);
-   landscape.paintForeground(context, canvas.width, canvas.height);
-   requestAnimationFrame(paint);
- }
- paint();
- // but tick every 150ms, so that we don't slow down when we don't paint
- setInterval(function () {
-   var dx = blueRobot.tick();
-   landscape.advance(dx);
- }, 100);
-&lt;/script&gt;
-&lt;p class=&quot;buttons&quot;&gt;
- &lt;input type=button value=&quot;Walk&quot; onclick=&quot;blueRobot.walk()&quot;&gt;
- &lt;input type=button value=&quot;Stop&quot; onclick=&quot;blueRobot.stop()&quot;&gt;
-&lt;footer&gt;
- &lt;small&gt; Blue Robot Player Sprite by &lt;a href=&quot;https://johncolburn.deviantart.com/&quot;&gt;JohnColburn&lt;/a&gt;.
- Licensed under the terms of the Creative Commons Attribution Share-Alike 3.0 Unported license.&lt;/small&gt;
- &lt;small&gt; This work is itself licensed under a &lt;a rel=&quot;license&quot; href=&quot;https://creativecommons.org/licenses/by-sa/3.0/&quot;&gt;Creative
- Commons Attribution-ShareAlike 3.0 Unported License&lt;/a&gt;.&lt;/small&gt;
-&lt;/footer&gt;
-</pre>
-
-  </div>
-
-
-
-
-  <h5 id="the-imagebitmap-rendering-context"><span class="secno">4.12.5.2</span> The <code id="the-imagebitmap-rendering-context:imagebitmap"><a href="https://html.spec.whatwg.org/multipage/imagebitmap-and-animations.html#imagebitmap">ImageBitmap</a></code> rendering context<a class="self-link" href="#the-imagebitmap-rendering-context"/></h5>
-
-  <h6 id="introduction-6"><span class="secno">4.12.5.2.1</span> Introduction<a class="self-link" href="#introduction-6"/></h6>
-
-  <p><code id="introduction-6:imagebitmaprenderingcontext"><a href="#imagebitmaprenderingcontext">ImageBitmapRenderingContext</a></code> is a performance-oriented interface that provides a
-  low overhead method for displaying the contents of <code id="introduction-6:imagebitmap"><a href="https://html.spec.whatwg.org/multipage/imagebitmap-and-animations.html#imagebitmap">ImageBitmap</a></code> objects. It uses
-  transfer semantics to reduce overall memory consumption. It also streamlines performance by
-  avoiding intermediate compositing, unlike the <code id="introduction-6:dom-context-2d-drawimage"><a href="#dom-context-2d-drawimage">drawImage()</a></code> method of
-  <code id="introduction-6:canvasrenderingcontext2d"><a href="#canvasrenderingcontext2d">CanvasRenderingContext2D</a></code>.</p>
-
-  <p>Using an <code id="introduction-6:the-img-element"><a href="https://html.spec.whatwg.org/multipage/embedded-content.html#the-img-element">img</a></code> element as an intermediate for getting an image resource into a
-  canvas, for example, would result in two copies of the decoded image existing in memory at the
-  same time: the <code id="introduction-6:the-img-element-2"><a href="https://html.spec.whatwg.org/multipage/embedded-content.html#the-img-element">img</a></code> element's copy, and the one in the canvas's backing store. This
-  memory cost can be prohibitive when dealing with extremely large images. This can be avoided by
-  using <code id="introduction-6:imagebitmaprenderingcontext-2"><a href="#imagebitmaprenderingcontext">ImageBitmapRenderingContext</a></code>.</p>
-
-  <div class="example">
-   <p>Using <code id="introduction-6:imagebitmaprenderingcontext-3"><a href="#imagebitmaprenderingcontext">ImageBitmapRenderingContext</a></code>, here is how to transcode an image to the JPEG
-   format in a memory- and CPU-efficient way:</p>
-
-   <pre>createImageBitmap(inputImageBlob).then(image =&gt; {
-  const canvas = document.createElement('canvas');
-  const context = canvas.getContext('bitmaprenderer');
-  context.transferFromImageBitmap(image);
-
-  canvas.toBlob(outputJPEGBlob =&gt; {
-    // Do something with outputJPEGBlob.
-  }, 'image/jpeg');
-});</pre>
-  </div>
-
-  <h6 id="the-imagebitmaprenderingcontext-interface"><span class="secno">4.12.5.2.2</span> The <code id="the-imagebitmaprenderingcontext-interface:imagebitmaprenderingcontext"><a href="#imagebitmaprenderingcontext">ImageBitmapRenderingContext</a></code> interface<a class="self-link" href="#the-imagebitmaprenderingcontext-interface"/></h6>
-
-  <pre class="idl">[Exposed=Window]
-interface <dfn id="imagebitmaprenderingcontext">ImageBitmapRenderingContext</dfn> {
-  readonly attribute <a href="#htmlcanvaselement" id="the-imagebitmaprenderingcontext-interface:htmlcanvaselement">HTMLCanvasElement</a> <a href="#dom-imagebitmaprenderingcontext-canvas-2" id="the-imagebitmaprenderingcontext-interface:dom-imagebitmaprenderingcontext-canvas-2">canvas</a>;
-  void <a href="#dom-imagebitmaprenderingcontext-transferfromimagebitmap-2" id="the-imagebitmaprenderingcontext-interface:dom-imagebitmaprenderingcontext-transferfromimagebitmap-2">transferFromImageBitmap</a>(ImageBitmap? bitmap);
-};
-
-dictionary <dfn id="imagebitmaprenderingcontextsettings">ImageBitmapRenderingContextSettings</dfn> {
-  boolean <a href="#dom-imagebitmaprenderingcontextsettings-alpha" id="the-imagebitmaprenderingcontext-interface:dom-imagebitmaprenderingcontextsettings-alpha">alpha</a> = true;
-};</pre>
-
-  <dl class="domintro"><dt><var>context</var> = <var>canvas</var> . <code id="the-imagebitmaprenderingcontext-interface:dom-canvas-getcontext-2"><a href="#dom-canvas-getcontext-2">getContext</a></code>('bitmaprenderer' [, { [ <code id="the-imagebitmaprenderingcontext-interface:dom-imagebitmaprenderingcontextsettings-alpha-2"><a href="#dom-imagebitmaprenderingcontextsettings-alpha">alpha</a></code>: false ] } ] )</dt><dd>
-
-    <p>Returns an <code id="the-imagebitmaprenderingcontext-interface:imagebitmaprenderingcontext-2"><a href="#imagebitmaprenderingcontext">ImageBitmapRenderingContext</a></code> object that is permanently bound to a
-    particular <code id="the-imagebitmaprenderingcontext-interface:the-canvas-element"><a href="#the-canvas-element">canvas</a></code> element.</p>
-
-    <p>If the <code id="the-imagebitmaprenderingcontext-interface:dom-imagebitmaprenderingcontextsettings-alpha-3"><a href="#dom-imagebitmaprenderingcontextsettings-alpha">alpha</a></code> setting is
-    provided and set to false, then the canvas is forced to always be opaque.</p>
-
-   </dd><dt><var>context</var> . <code id="dom-imagebitmaprenderingcontext-canvas"><a href="#dom-imagebitmaprenderingcontext-canvas-2">canvas</a></code></dt><dd>
-
-    <p>Returns the <code id="the-imagebitmaprenderingcontext-interface:the-canvas-element-2"><a href="#the-canvas-element">canvas</a></code> element that the context is bound to.</p>
-
-   </dd><dt><var>context</var> . <code id="dom-imagebitmaprenderingcontext-transferfromimagebitmap"><a href="#dom-imagebitmaprenderingcontext-transferfromimagebitmap-2">transferFromImageBitmap</a></code>(imageBitmap)</dt><dd>
-
-    <p>Transfers the underlying <a href="https://html.spec.whatwg.org/multipage/imagebitmap-and-animations.html#concept-imagebitmap-bitmap-data" id="the-imagebitmaprenderingcontext-interface:concept-imagebitmap-bitmap-data">bitmap data</a>
-    from <var>imageBitmap</var> to <var>context</var>, and the bitmap becomes the contents of the
-    <code id="the-imagebitmaprenderingcontext-interface:the-canvas-element-3"><a href="#the-canvas-element">canvas</a></code> element to which <var>context</var> is bound.</p>
-
-   </dd><dt><var>context</var> . <code id="the-imagebitmaprenderingcontext-interface:dom-imagebitmaprenderingcontext-transferfromimagebitmap-2-2"><a href="#dom-imagebitmaprenderingcontext-transferfromimagebitmap-2">transferFromImageBitmap</a></code>(
-   null)</dt><dd>
-
-    <p>Replaces contents of the <code id="the-imagebitmaprenderingcontext-interface:the-canvas-element-4"><a href="#the-canvas-element">canvas</a></code> element to which <var>context</var>
-    is bound with a transparent black bitmap whose size corresponds to the <code id="the-imagebitmaprenderingcontext-interface:attr-canvas-width"><a href="#attr-canvas-width">width</a></code> and <code id="the-imagebitmaprenderingcontext-interface:attr-canvas-height"><a href="#attr-canvas-height">height</a></code>
-    content attributes of the <code id="the-imagebitmaprenderingcontext-interface:the-canvas-element-5"><a href="#the-canvas-element">canvas</a></code> element.</p>
-
-   </dd></dl>
-
-  
-
-  <p>The <dfn id="dom-imagebitmaprenderingcontext-canvas-2"><code>canvas</code></dfn> attribute
-  must return the value it was initialized to when the object was created.</p>
-
-  <p>An <code id="the-imagebitmaprenderingcontext-interface:imagebitmaprenderingcontext-3"><a href="#imagebitmaprenderingcontext">ImageBitmapRenderingContext</a></code> object has an <dfn id="concept-imagebitmaprenderingcontext-output-bitmap">output bitmap</dfn>, which is a
-  reference to <a href="https://html.spec.whatwg.org/multipage/imagebitmap-and-animations.html#concept-imagebitmap-bitmap-data" id="the-imagebitmaprenderingcontext-interface:concept-imagebitmap-bitmap-data-2">bitmap data</a>.</p>
-
-  <p>An <code id="the-imagebitmaprenderingcontext-interface:imagebitmaprenderingcontext-4"><a href="#imagebitmaprenderingcontext">ImageBitmapRenderingContext</a></code> object has a <dfn id="concept-imagebitmaprenderingcontext-bitmap-mode">bitmap mode</dfn>, which can be set to
-  <dfn id="concept-imagebitmaprenderingcontext-valid">valid</dfn> or <dfn id="concept-imagebitmaprenderingcontext-blank">blank</dfn>. A value of <a href="#concept-imagebitmaprenderingcontext-valid" id="the-imagebitmaprenderingcontext-interface:concept-imagebitmaprenderingcontext-valid">valid</a> indicates that the context's
-  <a href="#concept-imagebitmaprenderingcontext-output-bitmap" id="the-imagebitmaprenderingcontext-interface:concept-imagebitmaprenderingcontext-output-bitmap">output bitmap</a> refers to
-  <a href="https://html.spec.whatwg.org/multipage/imagebitmap-and-animations.html#concept-imagebitmap-bitmap-data" id="the-imagebitmaprenderingcontext-interface:concept-imagebitmap-bitmap-data-3">bitmap data</a> that was acquired via <code id="the-imagebitmaprenderingcontext-interface:dom-imagebitmaprenderingcontext-transferfromimagebitmap-2-3"><a href="#dom-imagebitmaprenderingcontext-transferfromimagebitmap-2">transferFromImageBitmap()</a></code>.
-  A value <a href="#concept-imagebitmaprenderingcontext-blank" id="the-imagebitmaprenderingcontext-interface:concept-imagebitmaprenderingcontext-blank">blank</a> indicates that the
-  context's <a href="#concept-imagebitmaprenderingcontext-output-bitmap" id="the-imagebitmaprenderingcontext-interface:concept-imagebitmaprenderingcontext-output-bitmap-2">output
-  bitmap</a> is a default transparent bitmap.</p>
-
-  <p>An <code id="the-imagebitmaprenderingcontext-interface:imagebitmaprenderingcontext-5"><a href="#imagebitmaprenderingcontext">ImageBitmapRenderingContext</a></code> object also has an <dfn id="concept-imagebitmaprenderingcontext-alpha">alpha</dfn> flag, which can be set to true or
-  false. When an <code id="the-imagebitmaprenderingcontext-interface:imagebitmaprenderingcontext-6"><a href="#imagebitmaprenderingcontext">ImageBitmapRenderingContext</a></code> object has its <a href="#concept-imagebitmaprenderingcontext-alpha" id="the-imagebitmaprenderingcontext-interface:concept-imagebitmaprenderingcontext-alpha">alpha</a> flag set to false, the contents
-  of the <code id="the-imagebitmaprenderingcontext-interface:the-canvas-element-6"><a href="#the-canvas-element">canvas</a></code> element to which the context is bound are obtained by
-  compositing the context's <a href="#concept-imagebitmaprenderingcontext-output-bitmap" id="the-imagebitmaprenderingcontext-interface:concept-imagebitmaprenderingcontext-output-bitmap-3">output bitmap</a> onto an opaque
-  black bitmap of the same size using the source-over composite operation. If the <a href="#concept-imagebitmaprenderingcontext-alpha" id="the-imagebitmaprenderingcontext-interface:concept-imagebitmaprenderingcontext-alpha-2">alpha</a> flag is set to true, then the
-  <a href="#concept-imagebitmaprenderingcontext-output-bitmap" id="the-imagebitmaprenderingcontext-interface:concept-imagebitmaprenderingcontext-output-bitmap-4">output bitmap</a> is used
-  as the contents of the <code id="the-imagebitmaprenderingcontext-interface:the-canvas-element-7"><a href="#the-canvas-element">canvas</a></code> element to which the context is bound. <a href="https://html.spec.whatwg.org/multipage/references.html#refsCOMPOSITE">[COMPOSITE]</a></p>
-
-  <p class="note">The step of compositing over an opaque black bitmap ought to be elided whenever
-  equivalent results can be obtained more efficiently by other means.</p>
-
-  <hr/>
-
-  <p>When a user agent is required to <dfn id="set-an-imagebitmaprenderingcontext's-output-bitmap">set an <code>ImageBitmapRenderingContext</code>'s output
-  bitmap</dfn>, with a <var>context</var> argument that is an
-  <code id="the-imagebitmaprenderingcontext-interface:imagebitmaprenderingcontext-7"><a href="#imagebitmaprenderingcontext">ImageBitmapRenderingContext</a></code> object and an optional argument <var>bitmap</var> that
-  refers to <a href="https://html.spec.whatwg.org/multipage/imagebitmap-and-animations.html#concept-imagebitmap-bitmap-data" id="the-imagebitmaprenderingcontext-interface:concept-imagebitmap-bitmap-data-4">bitmap data</a>, it must run these
-  steps:</p>
-
-  <ol><li><p>If a <var>bitmap</var> argument was not provided, then:</p>
-
-    <ol><li><p>Set <var>context</var>'s <a href="#concept-imagebitmaprenderingcontext-bitmap-mode" id="the-imagebitmaprenderingcontext-interface:concept-imagebitmaprenderingcontext-bitmap-mode">bitmap mode</a> to <a href="#concept-imagebitmaprenderingcontext-blank" id="the-imagebitmaprenderingcontext-interface:concept-imagebitmaprenderingcontext-blank-2">blank</a>.</p></li><li><p>Let <var>canvas</var> be the <code id="the-imagebitmaprenderingcontext-interface:the-canvas-element-8"><a href="#the-canvas-element">canvas</a></code> element to which <var>context</var>
-     is bound.</p></li><li><p>Set <var>context</var>'s <a href="#concept-imagebitmaprenderingcontext-output-bitmap" id="the-imagebitmaprenderingcontext-interface:concept-imagebitmaprenderingcontext-output-bitmap-5">output bitmap</a> to be fully
-     transparent black with an <a href="https://html.spec.whatwg.org/multipage/infrastructure.html#intrinsic-width" id="the-imagebitmaprenderingcontext-interface:intrinsic-width">intrinsic width</a> equal to the numeric value of
-     <var>canvas</var>'s <code id="the-imagebitmaprenderingcontext-interface:attr-canvas-width-2"><a href="#attr-canvas-width">width</a></code> attribute and an
-     <a href="https://html.spec.whatwg.org/multipage/infrastructure.html#intrinsic-height" id="the-imagebitmaprenderingcontext-interface:intrinsic-height">intrinsic height</a> equal to the numeric value of <var>canvas</var>'s <code id="the-imagebitmaprenderingcontext-interface:attr-canvas-height-2"><a href="#attr-canvas-height">height</a></code> attribute, those values being interpreted in <a data-x-internal="'px'" href="https://drafts.csswg.org/css-values/#px" id="the-imagebitmaprenderingcontext-interface:'px'">CSS pixels</a>.</p></li><li><p>Set the <a href="#concept-imagebitmaprenderingcontext-output-bitmap" id="the-imagebitmaprenderingcontext-interface:concept-imagebitmaprenderingcontext-output-bitmap-6">output bitmap</a>'s <a href="#concept-canvas-origin-clean" id="the-imagebitmaprenderingcontext-interface:concept-canvas-origin-clean">origin-clean</a> flag to true.</p></li></ol>
-
-   </li><li><p>If a <var>bitmap</var> argument was provided, then:</p>
-
-    <ol><li><p>Set <var>context</var>'s <a href="#concept-imagebitmaprenderingcontext-bitmap-mode" id="the-imagebitmaprenderingcontext-interface:concept-imagebitmaprenderingcontext-bitmap-mode-2">bitmap mode</a> to <a href="#concept-imagebitmaprenderingcontext-valid" id="the-imagebitmaprenderingcontext-interface:concept-imagebitmaprenderingcontext-valid-2">valid</a>.</p></li><li>
-      <p>Set <var>context</var>'s <a href="#concept-imagebitmaprenderingcontext-output-bitmap" id="the-imagebitmaprenderingcontext-interface:concept-imagebitmaprenderingcontext-output-bitmap-7">output bitmap</a> to refer
-      to the same underlying bitmap data as <var>bitmap</var>, without making a copy.</p>
-
-      <p class="note">The <a href="#concept-canvas-origin-clean" id="the-imagebitmaprenderingcontext-interface:concept-canvas-origin-clean-2">origin-clean</a> flag of
-      <var>bitmap</var> is included in the bitmap data to be referenced by <var>context</var>'s
-      <a href="#concept-imagebitmaprenderingcontext-output-bitmap" id="the-imagebitmaprenderingcontext-interface:concept-imagebitmaprenderingcontext-output-bitmap-8">output bitmap</a>.</p>
-     </li></ol>
-
-   </li></ol>
-
-  <hr/>
-
-  <p>The <dfn id="imagebitmaprenderingcontext-creation-algorithm"><code>ImageBitmapRenderingContext</code> creation algorithm</dfn>, which is passed a
-  <var>target</var> (a <code id="the-imagebitmaprenderingcontext-interface:the-canvas-element-9"><a href="#the-canvas-element">canvas</a></code> element) and optionally some arguments, consists of
-  running the following steps:</p>
-
-  <ol><li><p>If the algorithm was passed some arguments, then let <var>arg</var> be the first such
-   argument. Otherwise, let <var>arg</var> be undefined.</p></li><li><p>Let <var>settings</var> be the result of <a href="#coerce-context-arguments-for-imagebitmaprenderingcontext" id="the-imagebitmaprenderingcontext-interface:coerce-context-arguments-for-imagebitmaprenderingcontext">coercing the <var>arg</var> context arguments for
-   <code>ImageBitmapRenderingContext</code></a>.</p></li><li><p>Create a new <code id="the-imagebitmaprenderingcontext-interface:imagebitmaprenderingcontext-8"><a href="#imagebitmaprenderingcontext">ImageBitmapRenderingContext</a></code> object.</p></li><li><p>Initialize its <code id="the-imagebitmaprenderingcontext-interface:dom-context-2d-canvas-2"><a href="#dom-context-2d-canvas-2">canvas</a></code> attribute to point to
-   <var>target</var>.</p></li><li><p>Let the new <code id="the-imagebitmaprenderingcontext-interface:imagebitmaprenderingcontext-9"><a href="#imagebitmaprenderingcontext">ImageBitmapRenderingContext</a></code> object's <a href="#concept-imagebitmaprenderingcontext-output-bitmap" id="the-imagebitmaprenderingcontext-interface:concept-imagebitmaprenderingcontext-output-bitmap-9">output bitmap</a> and
-   <var>target</var>'s bitmap be a shared reference to the same bitmap.</p></li><li><p>Run the steps to <a href="#set-an-imagebitmaprenderingcontext's-output-bitmap" id="the-imagebitmaprenderingcontext-interface:set-an-imagebitmaprenderingcontext's-output-bitmap">set an <code>ImageBitmapRenderingContext</code>'s output
-   bitmap</a>, using the new <code id="the-imagebitmaprenderingcontext-interface:imagebitmaprenderingcontext-10"><a href="#imagebitmaprenderingcontext">ImageBitmapRenderingContext</a></code> object as the
-   <var>context</var> argument, and with no <var>bitmap</var> argument.</p></li><li><p>Initialize <var>context</var>'s <a href="#concept-imagebitmaprenderingcontext-alpha" id="the-imagebitmaprenderingcontext-interface:concept-imagebitmaprenderingcontext-alpha-3">alpha</a> flag to true.
-
-   </p></li><li>
-
-    <p>Process each of the members of <var>settings</var> as follows:</p>
-
-    <dl><dt><dfn id="dom-imagebitmaprenderingcontextsettings-alpha"><code>alpha</code></dfn></dt><dd>If false, then set <var>context</var>'s <a href="#concept-imagebitmaprenderingcontext-alpha" id="the-imagebitmaprenderingcontext-interface:concept-imagebitmaprenderingcontext-alpha-4">alpha</a> flag to false.</dd></dl>
-
-   </li><li><p>Return the new <code id="the-imagebitmaprenderingcontext-interface:imagebitmaprenderingcontext-11"><a href="#imagebitmaprenderingcontext">ImageBitmapRenderingContext</a></code> object.</p></li></ol>
-
-  <hr/>
-
-  <p>When a user agent is required to <dfn id="coerce-context-arguments-for-imagebitmaprenderingcontext">coerce context arguments for
-  <code>ImageBitmapRenderingContext</code></dfn>, it must run these steps:</p>
-
-  <ol><li><p>Let <var>input</var> be the argument to coerce.</p></li><li><p>Let <var>jsval</var> be the result of <a data-x-internal="concept-idl-convert" href="https://heycam.github.io/webidl/#es-type-mapping" id="the-imagebitmaprenderingcontext-interface:concept-idl-convert">converting</a> <var>input</var> to a JavaScript value. (This can
-   throw an exception.)</p></li><li><p>Let <var>dict</var> be the result of <a data-x-internal="concept-idl-convert" href="https://heycam.github.io/webidl/#es-type-mapping" id="the-imagebitmaprenderingcontext-interface:concept-idl-convert-2">converting</a>
-   <var>jsval</var> to the dictionary type <code id="the-imagebitmaprenderingcontext-interface:imagebitmaprenderingcontextsettings"><a href="#imagebitmaprenderingcontextsettings">ImageBitmapRenderingContextSettings</a></code>. (This
-   can throw an exception.)</p></li><li><p>Return <var>dict</var>.</p></li></ol>
-
-  <hr/>
-
-  <p>The <dfn id="dom-imagebitmaprenderingcontext-transferfromimagebitmap-2"><code>transferFromImageBitmap(<var>imageBitmap</var>)</code></dfn>
-  method, when invoked, must run these steps:</p>
-
-  <ol><li><p>Let <var>bitmapContext</var> be the <code id="the-imagebitmaprenderingcontext-interface:imagebitmaprenderingcontext-12"><a href="#imagebitmaprenderingcontext">ImageBitmapRenderingContext</a></code> object on
-   which the <code id="the-imagebitmaprenderingcontext-interface:dom-imagebitmaprenderingcontext-transferfromimagebitmap-2-4"><a href="#dom-imagebitmaprenderingcontext-transferfromimagebitmap-2">transferFromImageBitmap()</a></code>
-   method was called.</p></li><li><p>If <var>imageBitmap</var> is null, then run the steps to <a href="#set-an-imagebitmaprenderingcontext's-output-bitmap" id="the-imagebitmaprenderingcontext-interface:set-an-imagebitmaprenderingcontext's-output-bitmap-2">set an
-   ImageBitmapRenderingContext's output bitmap</a>, with <var>bitmapContext</var> as the
-   <var>context</var> argument and no <var>bitmap</var> argument, then abort these steps.</p></li><li><p>If the value of <var>imageBitmap</var>'s <a href="https://html.spec.whatwg.org/multipage/structured-data.html#detached" id="the-imagebitmaprenderingcontext-interface:detached">[[Detached]]</a> internal slot is set to
-   true, then throw an <a data-x-internal="invalidstateerror" href="https://heycam.github.io/webidl/#invalidstateerror" id="the-imagebitmaprenderingcontext-interface:invalidstateerror">&quot;<code>InvalidStateError</code>&quot;</a> <code id="the-imagebitmaprenderingcontext-interface:domexception"><a data-x-internal="domexception" href="https://heycam.github.io/webidl/#dfn-DOMException">DOMException</a></code> and
-   abort these steps.</p></li><li><p>Run the steps to <a href="#set-an-imagebitmaprenderingcontext's-output-bitmap" id="the-imagebitmaprenderingcontext-interface:set-an-imagebitmaprenderingcontext's-output-bitmap-3">set an <code>ImageBitmapRenderingContext</code>'s output
-   bitmap</a>, with the <var>context</var> argument equal to <var>bitmapContext</var>, and the
-   <var>bitmap</var> argument referring to <var>imageBitmap</var>'s underlying <a href="https://html.spec.whatwg.org/multipage/imagebitmap-and-animations.html#concept-imagebitmap-bitmap-data" id="the-imagebitmaprenderingcontext-interface:concept-imagebitmap-bitmap-data-5">bitmap data</a>.
-
-   </p></li><li><p>Set the value of <var>imageBitmap</var>'s <a href="https://html.spec.whatwg.org/multipage/structured-data.html#detached" id="the-imagebitmaprenderingcontext-interface:detached-2">[[Detached]]</a> internal slot to
-   true.</p></li><li><p>Unset <var>imageBitmap's</var> <a href="https://html.spec.whatwg.org/multipage/imagebitmap-and-animations.html#concept-imagebitmap-bitmap-data" id="the-imagebitmaprenderingcontext-interface:concept-imagebitmap-bitmap-data-6">bitmap
-   data</a>.</p></li></ol>
-
-  
-
-
-
-
-  <h5 id="the-offscreencanvas-interface"><span class="secno">4.12.5.3</span> The <code id="the-offscreencanvas-interface:offscreencanvas"><a href="#offscreencanvas">OffscreenCanvas</a></code> interface<a class="self-link" href="#the-offscreencanvas-interface"/></h5><div class="status"><input onclick="toggleStatus(this)" type="button" value="⋰"/><p class="support"><strong>Support:</strong> offscreencanvas<span class="and_chr no"><span>Chrome for Android</span> <span>None</span></span><span class="chrome no"><span>Chrome</span> <span>None</span></span><span class="and_uc no"><span>UC Browser for Android</span> <span>None</span></span><span class="ios_saf no"><span>iOS Safari</span> <span>None</span></span><span class="firefox no"><span>Firefox</span> <span>None</span></span><span class="ie no"><span>IE</span> <span>None</span></span><span class="samsung no"><span>Samsung Internet</span> <span>None</span></span><span class="op_mini no"><span>Opera Mini</span> <span>None</span></span><span class="safari no"><span>Safari</span> <span>None</span></span><span class="android no"><span>Android Browser</span> <span>None</span></span><span class="opera no"><span>Opera</span> <span>None</span></span><span class="edge no"><span>Edge</span> <span>None</span></span></p><p class="caniuse">Source: <a href="https://caniuse.com/#feat=offscreencanvas">caniuse.com</a></p></div>
-
-  <pre class="idl">typedef (<a href="#offscreencanvasrenderingcontext2d" id="the-offscreencanvas-interface:offscreencanvasrenderingcontext2d">OffscreenCanvasRenderingContext2D</a> or
-        <a data-x-internal="webglrenderingcontext" href="https://www.khronos.org/registry/webgl/specs/latest/1.0/#WebGLRenderingContext" id="the-offscreencanvas-interface:webglrenderingcontext">WebGLRenderingContext</a>) <dfn id="offscreenrenderingcontext">OffscreenRenderingContext</dfn>;
-
-dictionary <dfn id="imageencodeoptions">ImageEncodeOptions</dfn> {
-  DOMString <a href="#image-encode-options-type" id="the-offscreencanvas-interface:image-encode-options-type">type</a> = &quot;image/png&quot;;
-  unrestricted double <a href="#image-encode-options-quality" id="the-offscreencanvas-interface:image-encode-options-quality">quality</a> = 1.0;
-};
-
-enum <dfn id="offscreenrenderingcontexttype">OffscreenRenderingContextType</dfn> { &quot;<a href="#offscreen-context-type-2d" id="the-offscreencanvas-interface:offscreen-context-type-2d">2d</a>&quot;, &quot;<a href="#offscreen-context-type-webgl" id="the-offscreencanvas-interface:offscreen-context-type-webgl">webgl</a>&quot; };
-
-[<a href="#dom-offscreencanvas-2" id="the-offscreencanvas-interface:dom-offscreencanvas-2">Constructor</a>([EnforceRange] unsigned long long width, [EnforceRange] unsigned long long height), Exposed=(Window,Worker), <a href="https://html.spec.whatwg.org/multipage/structured-data.html#transferable" id="the-offscreencanvas-interface:transferable">Transferable</a>]
-interface <dfn id="offscreencanvas">OffscreenCanvas</dfn> : <a data-x-internal="eventtarget" href="https://dom.spec.whatwg.org/#interface-eventtarget" id="the-offscreencanvas-interface:eventtarget">EventTarget</a> {
-  attribute unsigned long long <a href="#dom-offscreencanvas-width-2" id="the-offscreencanvas-interface:dom-offscreencanvas-width-2">width</a>;
-  attribute unsigned long long <a href="#dom-offscreencanvas-height-2" id="the-offscreencanvas-interface:dom-offscreencanvas-height-2">height</a>;
-
-  <a href="#offscreenrenderingcontext" id="the-offscreencanvas-interface:offscreenrenderingcontext">OffscreenRenderingContext</a>? <a href="#dom-offscreencanvas-getcontext-2" id="the-offscreencanvas-interface:dom-offscreencanvas-getcontext-2">getContext</a>(<a href="#offscreenrenderingcontexttype" id="the-offscreencanvas-interface:offscreenrenderingcontexttype">OffscreenRenderingContextType</a> contextType, any... arguments);
-  <a href="https://html.spec.whatwg.org/multipage/imagebitmap-and-animations.html#imagebitmap" id="the-offscreencanvas-interface:imagebitmap">ImageBitmap</a> <a href="#dom-offscreencanvas-transfertoimagebitmap-2" id="the-offscreencanvas-interface:dom-offscreencanvas-transfertoimagebitmap-2">transferToImageBitmap</a>();
-  Promise&lt;<a data-x-internal="blob" href="https://w3c.github.io/FileAPI/#blob" id="the-offscreencanvas-interface:blob">Blob</a>&gt; <a href="#dom-offscreencanvas-converttoblob-2" id="the-offscreencanvas-interface:dom-offscreencanvas-converttoblob-2">convertToBlob</a>(optional <a href="#imageencodeoptions" id="the-offscreencanvas-interface:imageencodeoptions">ImageEncodeOptions</a> options);
-};
-</pre>
-
-  <p><code id="the-offscreencanvas-interface:offscreencanvas-2"><a href="#offscreencanvas">OffscreenCanvas</a></code> objects are used to create rendering contexts, much like an
-  <code id="the-offscreencanvas-interface:htmlcanvaselement"><a href="#htmlcanvaselement">HTMLCanvasElement</a></code>, but with no connection to the DOM. This makes it possible to
-  use canvas rendering contexts in <a href="https://html.spec.whatwg.org/multipage/workers.html#workers">workers</a>.</p>
-
-  <p>An <code id="the-offscreencanvas-interface:offscreencanvas-3"><a href="#offscreencanvas">OffscreenCanvas</a></code> object may hold a weak reference to a <dfn id="offscreencanvas-placeholder">placeholder <code>canvas</code> element</dfn>, which is
-  typically in the DOM, whose embedded content is provided by the <code id="the-offscreencanvas-interface:offscreencanvas-4"><a href="#offscreencanvas">OffscreenCanvas</a></code>
-  object. The bitmap of the <code id="the-offscreencanvas-interface:offscreencanvas-5"><a href="#offscreencanvas">OffscreenCanvas</a></code> object is pushed to the <a href="#offscreencanvas-placeholder" id="the-offscreencanvas-interface:offscreencanvas-placeholder">placeholder <code>canvas</code> element</a> by
-  calling the <dfn id="offscreencontext-commit"><code>commit()</code></dfn> method of the
-  <code id="the-offscreencanvas-interface:offscreencanvas-6"><a href="#offscreencanvas">OffscreenCanvas</a></code> object's rendering context. All rendering context types that
-  can be created by an <code id="the-offscreencanvas-interface:offscreencanvas-7"><a href="#offscreencanvas">OffscreenCanvas</a></code> object must implement a <code id="the-offscreencanvas-interface:offscreencontext-commit"><a href="#offscreencontext-commit">commit()</a></code> method. The exact behavior of the commit
-  method (e.g. whether it copies or transfers bitmaps) may vary, as defined by the rendering
-  contexts' respective specifications. Only the <a href="#offscreencanvasrenderingcontext2d" id="the-offscreencanvas-interface:offscreencanvasrenderingcontext2d-2">2D context for offscreen canvases</a> is defined
-  in this specification.</p>
-
-  <dl class="domintro"><dt><var>offscreenCanvas</var> = new <code id="dom-offscreencanvas"><a href="#dom-offscreencanvas-2">OffscreenCanvas</a></code>(<var>width</var>,
-   <var>height</var>)</dt><dt>
-
-   </dt><dd>
-
-    <p>Returns a new <code id="the-offscreencanvas-interface:offscreencanvas-8"><a href="#offscreencanvas">OffscreenCanvas</a></code> object that is not linked to a <a href="#offscreencanvas-placeholder" id="the-offscreencanvas-interface:offscreencanvas-placeholder-2">placeholder <code>canvas</code> element</a>, and
-    whose bitmap's size is determined by the <var>width</var> and <var>height</var> arguments.</p>
-
-   </dd><dt><var>context</var> = <var>offscreenCanvas</var> . <code id="dom-offscreencanvas-getcontext"><a href="#dom-offscreencanvas-getcontext-2">getContext</a></code>(<var>contextType</var> [, ... ] )</dt><dd>
-
-    <p>Returns an object that exposes an API for drawing on the <code id="the-offscreencanvas-interface:offscreencanvas-9"><a href="#offscreencanvas">OffscreenCanvas</a></code>
-    object. The first argument specifies the desired API, either &quot;<code id="the-offscreencanvas-interface:offscreen-context-type-2d-2"><a href="#offscreen-context-type-2d">2d</a></code>&quot;, or &quot;<code id="the-offscreencanvas-interface:offscreen-context-type-webgl-2"><a href="#offscreen-context-type-webgl">webgl</a></code>&quot;. Subsequent arguments are handled by that
-    API.</p>
-
-    <p>This specification defines the &quot;<code id="the-offscreencanvas-interface:canvas-context-2d"><a href="#canvas-context-2d">2d</a></code>&quot; context below,
-    which is similar but distinct from the &quot;<code id="the-offscreencanvas-interface:offscreen-context-type-2d-3"><a href="#offscreen-context-type-2d">2d</a></code>&quot;
-    context that is created from a <code id="the-offscreencanvas-interface:the-canvas-element"><a href="#the-canvas-element">canvas</a></code> element. There is also a specification that
-    defines a &quot;<code id="the-offscreencanvas-interface:offscreen-context-type-webgl-3"><a href="#offscreen-context-type-webgl">webgl</a></code>&quot; context.
-    <a href="https://html.spec.whatwg.org/multipage/references.html#refsWEBGL">[WEBGL]</a></p>
-
-    <p>Returns null if the canvas has already been initialized with another context type (e.g.
-    trying to get a &quot;<code id="the-offscreencanvas-interface:offscreen-context-type-2d-4"><a href="#offscreen-context-type-2d">2d</a></code>&quot; context after getting a
-    &quot;<code id="the-offscreencanvas-interface:offscreen-context-type-webgl-4"><a href="#offscreen-context-type-webgl">webgl</a></code>&quot; context).</p>
-
-   </dd></dl>
-
-  
-
-  <p>An <code id="the-offscreencanvas-interface:offscreencanvas-10"><a href="#offscreencanvas">OffscreenCanvas</a></code> object has an internal <dfn id="offscreencanvas-bitmap">bitmap</dfn> that is initialized when the object
-  is created. The width and height of the <a href="#offscreencanvas-bitmap" id="the-offscreencanvas-interface:offscreencanvas-bitmap">bitmap</a> are
-  equal to the values of the <code id="the-offscreencanvas-interface:dom-offscreencanvas-width-2-2"><a href="#dom-offscreencanvas-width-2">width</a></code> and <code id="the-offscreencanvas-interface:dom-offscreencanvas-height-2-2"><a href="#dom-offscreencanvas-height-2">height</a></code> attributes of the <code id="the-offscreencanvas-interface:offscreencanvas-11"><a href="#offscreencanvas">OffscreenCanvas</a></code>
-  object. Initially, all the bitmap's pixels are transparent black.</p>
-
-  <p>An <code id="the-offscreencanvas-interface:offscreencanvas-12"><a href="#offscreencanvas">OffscreenCanvas</a></code> object can have a rendering context bound to it. Initially,
-  it does not have a bound rendering context. To keep track of whether it has a rendering context
-  or not, and what kind of rendering context it is, an <code id="the-offscreencanvas-interface:offscreencanvas-13"><a href="#offscreencanvas">OffscreenCanvas</a></code> object also
-  has a <dfn id="offscreencanvas-context-mode">context mode</dfn>, which is initially <dfn id="offscreencanvas-context-none">none</dfn> but can be changed to either <dfn id="offscreencanvas-context-2d">2d</dfn>, <dfn id="offscreencanvas-context-webgl">webgl</dfn> or <dfn id="offscreencanvas-context-detached">detached</dfn> by algorithms defined in this
-  specification.</p>
-
-  <p>The constructor <dfn id="dom-offscreencanvas-2"><code>OffscreenCanvas(<var>width</var>,
-  <var>height</var>)</code></dfn>, when invoked, must create a new <code id="the-offscreencanvas-interface:offscreencanvas-14"><a href="#offscreencanvas">OffscreenCanvas</a></code>
-  object with its <a href="#offscreencanvas-bitmap" id="the-offscreencanvas-interface:offscreencanvas-bitmap-2">bitmap</a> initialized to a rectangular
-  array of transparent black pixels of the dimensions specified by <var>width</var> and
-  <var>height</var>; and its <code id="the-offscreencanvas-interface:dom-offscreencanvas-width-2-3"><a href="#dom-offscreencanvas-width-2">width</a></code> and <code id="the-offscreencanvas-interface:dom-offscreencanvas-height-2-3"><a href="#dom-offscreencanvas-height-2">height</a></code> attributes initialized to <var>width</var> and
-  <var>height</var> respectively.</p>
-
-  <hr/>
-
-  <p><code id="the-offscreencanvas-interface:offscreencanvas-15"><a href="#offscreencanvas">OffscreenCanvas</a></code> objects are <a href="https://html.spec.whatwg.org/multipage/structured-data.html#transferable-objects" id="the-offscreencanvas-interface:transferable-objects">transferable</a>. Their <a href="https://html.spec.whatwg.org/multipage/structured-data.html#transfer-steps" id="the-offscreencanvas-interface:transfer-steps">transfer steps</a>, given <var>value</var> and
-  <var>dataHolder</var>, are as follows:</p>
-
-  <ol><li><p>If <var>value</var>'s <a href="#offscreencanvas-context-mode" id="the-offscreencanvas-interface:offscreencanvas-context-mode">context mode</a> is
-   not equal to <a href="#offscreencanvas-context-none" id="the-offscreencanvas-interface:offscreencanvas-context-none">none</a>, then throw an
-   <a data-x-internal="invalidstateerror" href="https://heycam.github.io/webidl/#invalidstateerror" id="the-offscreencanvas-interface:invalidstateerror">&quot;<code>InvalidStateError</code>&quot;</a> <code id="the-offscreencanvas-interface:domexception"><a data-x-internal="domexception" href="https://heycam.github.io/webidl/#dfn-DOMException">DOMException</a></code>.</p></li><li><p>Set <var>value</var>'s <a href="#offscreencanvas-context-mode" id="the-offscreencanvas-interface:offscreencanvas-context-mode-2">context mode</a> to
-   <a href="#offscreencanvas-context-detached" id="the-offscreencanvas-interface:offscreencanvas-context-detached">detached</a>.</p></li><li><p>Let <var>width</var> and <var>height</var> be the dimensions of <var>value</var>'s <a href="#offscreencanvas-bitmap" id="the-offscreencanvas-interface:offscreencanvas-bitmap-3">bitmap</a>.</p></li><li><p>Unset <var>value</var>'s <a href="#offscreencanvas-bitmap" id="the-offscreencanvas-interface:offscreencanvas-bitmap-4">bitmap</a>.</p></li><li><p>Set <var>dataHolder</var>.[[With]] to <var>width</var>, and
-   <var>dataHolder</var>.[[Height]] to <var>height</var>.</p></li><li><p>Set <var>dataHolder</var>.[[PlaceholderCanvas]] to be a weak reference to
-   <var>value</var>'s <a href="#offscreencanvas-placeholder" id="the-offscreencanvas-interface:offscreencanvas-placeholder-3">placeholder <code>canvas</code>
-   element</a>, if <var>value</var> has one, or null if it does not.</p></li></ol>
-
-  <p>Their <a href="https://html.spec.whatwg.org/multipage/structured-data.html#transfer-receiving-steps" id="the-offscreencanvas-interface:transfer-receiving-steps">transfer-receiving steps</a>, given <var>dataHolder</var> and <var>value</var>,
-  are:</p>
-
-  <ol><li><p>Initialize <var>value</var>'s <a href="#offscreencanvas-bitmap" id="the-offscreencanvas-interface:offscreencanvas-bitmap-5">bitmap</a> to a
-   rectangular array of transparent black pixels with width given by <var>dataHolder</var>.[[Width]]
-   and height given by <var>dataHolder</var>.[[Height]].</p></li><li><p>If <var>dataHolder</var>.[[PlaceholderCanvas]] is not null, set <var>value</var>'s <a href="#offscreencanvas-placeholder" id="the-offscreencanvas-interface:offscreencanvas-placeholder-4">placeholder <code>canvas</code> element</a> to
-   <var>dataHolder</var>.[[PlaceholderCanvas]] (while maintaining the weak reference
-   semantics).</p></li></ol>
-
-  <hr/>
-
-  <p>The <dfn id="dom-offscreencanvas-getcontext-2"><code>getContext(<var>contextId</var>,
-  <var>arguments...</var>)</code></dfn> method of an <code id="the-offscreencanvas-interface:offscreencanvas-16"><a href="#offscreencanvas">OffscreenCanvas</a></code> object, when
-  invoked, must run the steps in the cell of the following table whose column header describes the
-  <code id="the-offscreencanvas-interface:offscreencanvas-17"><a href="#offscreencanvas">OffscreenCanvas</a></code> object's <a href="#offscreencanvas-context-mode" id="the-offscreencanvas-interface:offscreencanvas-context-mode-3">context
-  mode</a> and whose row header describes the method's first argument.</p>
-
-  <table><thead><tr><td>
-     </td><th><a href="#offscreencanvas-context-none" id="the-offscreencanvas-interface:offscreencanvas-context-none-2">none</a>
-     </th><th><a href="#offscreencanvas-context-2d" id="the-offscreencanvas-interface:offscreencanvas-context-2d">2d</a>
-     </th><th><a href="#offscreencanvas-context-webgl" id="the-offscreencanvas-interface:offscreencanvas-context-webgl">webgl</a>
-     </th><th><a href="#offscreencanvas-context-detached" id="the-offscreencanvas-interface:offscreencanvas-context-detached-2">detached</a>
-   </th></tr></thead><tbody><tr><th>&quot;<dfn id="offscreen-context-type-2d"><code>2d</code></dfn>&quot;
-     </th><td>
-      Follow the steps to <a href="#offscreen-2d-context-creation-algorithm" id="the-offscreencanvas-interface:offscreen-2d-context-creation-algorithm">create an
-      offscreen 2D context</a> defined in the section below, passing it the
-      <code id="the-offscreencanvas-interface:offscreencanvas-18"><a href="#offscreencanvas">OffscreenCanvas</a></code> object and the method's <var>arguments...</var>, to obtain
-      an <code id="the-offscreencanvas-interface:offscreencanvasrenderingcontext2d-3"><a href="#offscreencanvasrenderingcontext2d">OffscreenCanvasRenderingContext2D</a></code> object; if this does not throw an
-      exception, then set the <code id="the-offscreencanvas-interface:offscreencanvas-19"><a href="#offscreencanvas">OffscreenCanvas</a></code> object's <a href="#offscreencanvas-context-mode" id="the-offscreencanvas-interface:offscreencanvas-context-mode-4">context mode</a> to <a href="#offscreencanvas-context-2d" id="the-offscreencanvas-interface:offscreencanvas-context-2d-2">2d</a>, and return the new
-      <code id="the-offscreencanvas-interface:offscreencanvasrenderingcontext2d-4"><a href="#offscreencanvasrenderingcontext2d">OffscreenCanvasRenderingContext2D</a></code> object.
-     </td><td>
-      Return the same object as was returned the last time the method was invoked with this same
-      first argument.
-     </td><td>
-      Return null.
-     </td><td>
-      Throw an <a data-x-internal="invalidstateerror" href="https://heycam.github.io/webidl/#invalidstateerror" id="the-offscreencanvas-interface:invalidstateerror-2">&quot;<code>InvalidStateError</code>&quot;</a> <code id="the-offscreencanvas-interface:domexception-2"><a data-x-internal="domexception" href="https://heycam.github.io/webidl/#dfn-DOMException">DOMException</a></code>.
-
-    </td></tr><tr><th>&quot;<dfn id="offscreen-context-type-webgl"><code>webgl</code></dfn>&quot;
-     </th><td>
-      Follow the instructions given in the WebGL specification's <i>Context Creation</i> section to
-      obtain either a <code id="the-offscreencanvas-interface:webglrenderingcontext-2"><a data-x-internal="webglrenderingcontext" href="https://www.khronos.org/registry/webgl/specs/latest/1.0/#WebGLRenderingContext">WebGLRenderingContext</a></code> or null; if the returned value is null,
-      then return null and abort these steps, otherwise, set the <code id="the-offscreencanvas-interface:offscreencanvas-20"><a href="#offscreencanvas">OffscreenCanvas</a></code>
-      object's <a href="#offscreencanvas-context-mode" id="the-offscreencanvas-interface:offscreencanvas-context-mode-5">context mode</a> to <a href="#offscreencanvas-context-webgl" id="the-offscreencanvas-interface:offscreencanvas-context-webgl-2">webgl</a>, and return the
-      <code id="the-offscreencanvas-interface:webglrenderingcontext-3"><a data-x-internal="webglrenderingcontext" href="https://www.khronos.org/registry/webgl/specs/latest/1.0/#WebGLRenderingContext">WebGLRenderingContext</a></code> object. <a href="https://html.spec.whatwg.org/multipage/references.html#refsWEBGL">[WEBGL]</a>
-     </td><td>
-      Return null.
-     </td><td>
-      Return the same value as was returned the last time the method was invoked with this same
-      first argument.
-     </td><td>
-      Throw an <a data-x-internal="invalidstateerror" href="https://heycam.github.io/webidl/#invalidstateerror" id="the-offscreencanvas-interface:invalidstateerror-3">&quot;<code>InvalidStateError</code>&quot;</a> <code id="the-offscreencanvas-interface:domexception-3"><a data-x-internal="domexception" href="https://heycam.github.io/webidl/#dfn-DOMException">DOMException</a></code>.
-
-  </td></tr></tbody></table>
-
-  <hr/>
-
-  
-
-  <dl class="domintro"><dt><var>offscreenCanvas</var> . <code id="dom-offscreencanvas-width"><a href="#dom-offscreencanvas-width-2">width</a></code> [
-   = <var>value</var> ]</dt><dt><var>offscreenCanvas</var> . <code id="dom-offscreencanvas-height"><a href="#dom-offscreencanvas-height-2">height</a></code> [
-   = <var>value</var> ]</dt><dd>
-    <p>These attributes return the dimensions of the <code id="the-offscreencanvas-interface:offscreencanvas-21"><a href="#offscreencanvas">OffscreenCanvas</a></code> object's <a href="#offscreencanvas-bitmap" id="the-offscreencanvas-interface:offscreencanvas-bitmap-6">bitmap</a>.</p>
-
-    <p>They can be set, to replace the <a href="#offscreencanvas-bitmap" id="the-offscreencanvas-interface:offscreencanvas-bitmap-7">bitmap</a> with a
-    new, transparent black bitmap of the specified dimensions (effectively resizing it).</p>
-   </dd></dl>
-
-  
-
-  <p>If either the <dfn id="dom-offscreencanvas-width-2"><code>width</code></dfn> or <dfn id="dom-offscreencanvas-height-2"><code>height</code></dfn> attributes of an
-  <code id="the-offscreencanvas-interface:offscreencanvas-22"><a href="#offscreencanvas">OffscreenCanvas</a></code> object are set (to a new value or to the same value as before) and
-  the <code id="the-offscreencanvas-interface:offscreencanvas-23"><a href="#offscreencanvas">OffscreenCanvas</a></code> object's <a href="#offscreencanvas-context-mode" id="the-offscreencanvas-interface:offscreencanvas-context-mode-6">context
-  mode</a> is <a href="#offscreencanvas-context-2d" id="the-offscreencanvas-interface:offscreencanvas-context-2d-3">2d</a>, then replace the
-  <code id="the-offscreencanvas-interface:offscreencanvas-24"><a href="#offscreencanvas">OffscreenCanvas</a></code> object's <a href="#offscreencanvas-bitmap" id="the-offscreencanvas-interface:offscreencanvas-bitmap-8">bitmap</a> with a
-  new transparent black bitmap and <a href="#reset-the-rendering-context-to-its-default-state" id="the-offscreencanvas-interface:reset-the-rendering-context-to-its-default-state">reset the rendering context to its default state</a>.
-  The new bitmap's dimensions are equal to the new values of the <code id="the-offscreencanvas-interface:dom-offscreencanvas-width-2-4"><a href="#dom-offscreencanvas-width-2">width</a></code> and <code id="the-offscreencanvas-interface:dom-offscreencanvas-height-2-4"><a href="#dom-offscreencanvas-height-2">height</a></code> attributes.</p>
-
-  <p>The resizing behavior for &quot;<code id="the-offscreencanvas-interface:offscreen-context-type-webgl-5"><a href="#offscreen-context-type-webgl">webgl</a></code>&quot;
-  contexts is defined in the WebGL specification. <a href="https://html.spec.whatwg.org/multipage/references.html#refsWEBGL">[WEBGL]</a></p>
-
-  
-
-  <p class="note">If an <code id="the-offscreencanvas-interface:offscreencanvas-25"><a href="#offscreencanvas">OffscreenCanvas</a></code> object whose dimensions were changed has
-  a <a href="#offscreencanvas-placeholder" id="the-offscreencanvas-interface:offscreencanvas-placeholder-5">placeholder <code>canvas</code> element</a>, then
-  the <a href="#offscreencanvas-placeholder" id="the-offscreencanvas-interface:offscreencanvas-placeholder-6">placeholder <code>canvas</code> element</a>'s
-  <a data-x-internal="intrinsic-dimensions" href="https://drafts.csswg.org/css2/conform.html#intrinsic" id="the-offscreencanvas-interface:intrinsic-dimensions">intrinsic size</a> will only be updated via the <code id="the-offscreencanvas-interface:offscreencontext-commit-2"><a href="#offscreencontext-commit">commit()</a></code> method of the <code id="the-offscreencanvas-interface:offscreencanvas-26"><a href="#offscreencanvas">OffscreenCanvas</a></code>
-  object's rendering context.</p>
-
-  <dl class="domintro"><dt><var>promise</var> = <var>offscreenCanvas</var> . <code id="dom-offscreencanvas-converttoblob"><a href="#dom-offscreencanvas-converttoblob-2">convertToBlob</a></code>( [<var>options</var>] )</dt><dd>
-    <p>Returns a promise that will fulfill with a new <code id="the-offscreencanvas-interface:blob-2"><a data-x-internal="blob" href="https://w3c.github.io/FileAPI/#blob">Blob</a></code> object representing a file
-    containing the image in the <code id="the-offscreencanvas-interface:offscreencanvas-27"><a href="#offscreencanvas">OffscreenCanvas</a></code> object.</p>
-
-    <p>The argument, if provided, is a dictionary that controls the encoding options of the image
-    file to be created. The <code id="the-offscreencanvas-interface:image-encode-options-type-2"><a href="#image-encode-options-type">type</a></code>
-    field specifies the file format and has a default value of &quot;<code id="the-offscreencanvas-interface:image/png"><a href="https://html.spec.whatwg.org/multipage/indices.html#image/png">image/png</a></code>&quot;; that type
-    is also used if the requested type isn't supported. If the image format supports variable
-    quality (such as &quot;<code id="the-offscreencanvas-interface:image/jpeg"><a href="https://html.spec.whatwg.org/multipage/indices.html#image/jpeg">image/jpeg</a></code>&quot;), then the <code id="the-offscreencanvas-interface:image-encode-options-quality-2"><a href="#image-encode-options-quality">quality</a></code> field is a number in the range 0.0
-    to 1.0 inclusive indicating the desired quality level for the resulting image.</p>
-   </dd><dt><var>canvas</var> . <code id="dom-offscreencanvas-transfertoimagebitmap"><a href="#dom-offscreencanvas-transfertoimagebitmap-2">transferToImageBitmap</a></code>()</dt><dd>
-    <p>Returns a newly created <code id="the-offscreencanvas-interface:imagebitmap-2"><a href="https://html.spec.whatwg.org/multipage/imagebitmap-and-animations.html#imagebitmap">ImageBitmap</a></code> object with the image in the
-    <code id="the-offscreencanvas-interface:offscreencanvas-28"><a href="#offscreencanvas">OffscreenCanvas</a></code> object. The image in the <code id="the-offscreencanvas-interface:offscreencanvas-29"><a href="#offscreencanvas">OffscreenCanvas</a></code> object is
-    replaced with a new blank image.</p>
-   </dd></dl>
-
-  
-
-  <p>The <dfn id="dom-offscreencanvas-converttoblob-2"><code>convertToBlob(<var>options</var>)</code></dfn> method,
-  when invoked, must run the following steps:</p>
-
-  <ol><li><p>If the value of this <code id="the-offscreencanvas-interface:offscreencanvas-30"><a href="#offscreencanvas">OffscreenCanvas</a></code> object's <a href="https://html.spec.whatwg.org/multipage/structured-data.html#detached" id="the-offscreencanvas-interface:detached">[[Detached]]</a>
-   internal slot is set to true, then return a promise rejected with an
-   <a data-x-internal="invalidstateerror" href="https://heycam.github.io/webidl/#invalidstateerror" id="the-offscreencanvas-interface:invalidstateerror-4">&quot;<code>InvalidStateError</code>&quot;</a> <code id="the-offscreencanvas-interface:domexception-4"><a data-x-internal="domexception" href="https://heycam.github.io/webidl/#dfn-DOMException">DOMException</a></code> and abort these
-   steps.</p></li><li><p>If this <code id="the-offscreencanvas-interface:offscreencanvas-31"><a href="#offscreencanvas">OffscreenCanvas</a></code> object's <a href="#offscreencanvas-context-mode" id="the-offscreencanvas-interface:offscreencanvas-context-mode-7">context mode</a> is <a href="#offscreencanvas-context-2d" id="the-offscreencanvas-interface:offscreencanvas-context-2d-4">2d</a> and the rendering context's <a href="#offscreencontext2d-bitmap" id="the-offscreencanvas-interface:offscreencontext2d-bitmap">bitmap</a>'s <a href="#offscreencontext2d-origin-clean" id="the-offscreencanvas-interface:offscreencontext2d-origin-clean">origin-clean</a> flag is set to false, then return a
-   promise rejected with a <a data-x-internal="securityerror" href="https://heycam.github.io/webidl/#securityerror" id="the-offscreencanvas-interface:securityerror">&quot;<code>SecurityError</code>&quot;</a> <code id="the-offscreencanvas-interface:domexception-5"><a data-x-internal="domexception" href="https://heycam.github.io/webidl/#dfn-DOMException">DOMException</a></code> and
-   abort these steps.</p>
-
-   </li><li><p>If this <code id="the-offscreencanvas-interface:offscreencanvas-32"><a href="#offscreencanvas">OffscreenCanvas</a></code> object's <a href="#offscreencanvas-bitmap" id="the-offscreencanvas-interface:offscreencanvas-bitmap-9">bitmap</a> has no pixels (i.e. either its
-   horizontal dimension or its vertical dimension is zero) then return a promise rejected with an
-   <a data-x-internal="indexsizeerror" href="https://heycam.github.io/webidl/#indexsizeerror" id="the-offscreencanvas-interface:indexsizeerror">&quot;<code>IndexSizeError</code>&quot;</a> <code id="the-offscreencanvas-interface:domexception-6"><a data-x-internal="domexception" href="https://heycam.github.io/webidl/#dfn-DOMException">DOMException</a></code> and abort these
-   steps.</p></li><li><p>Let <var>result</var> be a new promise object.</p></li><li><p>Return <var>result</var>, and <a href="https://html.spec.whatwg.org/multipage/webappapis.html#queue-a-task" id="the-offscreencanvas-interface:queue-a-task">queue a task</a> to run the remaining steps
-   <a href="https://html.spec.whatwg.org/multipage/infrastructure.html#in-parallel" id="the-offscreencanvas-interface:in-parallel">in parallel</a>.</p></li><li><p>Let <var>blob</var> be a <code id="the-offscreencanvas-interface:blob-3"><a data-x-internal="blob" href="https://w3c.github.io/FileAPI/#blob">Blob</a></code> object, created in the <a href="https://html.spec.whatwg.org/multipage/webappapis.html#concept-relevant-realm" id="the-offscreencanvas-interface:concept-relevant-realm">relevant Realm</a> of this <code id="the-offscreencanvas-interface:offscreencanvas-33"><a href="#offscreencanvas">OffscreenCanvas</a></code>
-   object, representing <a href="#a-serialisation-of-the-bitmap-as-a-file" id="the-offscreencanvas-interface:a-serialisation-of-the-bitmap-as-a-file">a serialization of
-   this <code>OffscreenCanvas</code> object's <span>bitmap</span> as
-   a file</a>, passing the values of the <dfn id="image-encode-options-type"><code>type</code></dfn> and <dfn id="image-encode-options-quality"><code>quality</code></dfn> fields of <var>options</var>, if
-   <var>options</var> was specified. <a href="https://html.spec.whatwg.org/multipage/references.html#refsFILEAPI">[FILEAPI]</a></p></li><li><p>If <var>blob</var> is null, then reject <var>result</var> with an
-   <a data-x-internal="encodingerror" href="https://heycam.github.io/webidl/#encodingerror" id="the-offscreencanvas-interface:encodingerror">&quot;<code>EncodingError</code>&quot;</a> <code id="the-offscreencanvas-interface:domexception-7"><a data-x-internal="domexception" href="https://heycam.github.io/webidl/#dfn-DOMException">DOMException</a></code>.</p></li><li><p>Otherwise, resolve <var>result</var> with <var>blob</var>.</p></li></ol>
-
-  <p>The <dfn id="dom-offscreencanvas-transfertoimagebitmap-2"><code>transferToImageBitmap()</code></dfn> method,
-  when invoked, must run the following steps:</p>
-  <ol><li><p>If the value of this <code id="the-offscreencanvas-interface:offscreencanvas-34"><a href="#offscreencanvas">OffscreenCanvas</a></code> object's <a href="https://html.spec.whatwg.org/multipage/structured-data.html#detached" id="the-offscreencanvas-interface:detached-2">[[Detached]]</a>
-   internal slot is set to true, then throw an <a data-x-internal="invalidstateerror" href="https://heycam.github.io/webidl/#invalidstateerror" id="the-offscreencanvas-interface:invalidstateerror-5">&quot;<code>InvalidStateError</code>&quot;</a>
-   <code id="the-offscreencanvas-interface:domexception-8"><a data-x-internal="domexception" href="https://heycam.github.io/webidl/#dfn-DOMException">DOMException</a></code> and abort these steps.</p></li><li><p>If this <code id="the-offscreencanvas-interface:offscreencanvas-35"><a href="#offscreencanvas">OffscreenCanvas</a></code> object's <a href="#offscreencanvas-context-mode" id="the-offscreencanvas-interface:offscreencanvas-context-mode-8">context mode</a> is set to <a href="#offscreencanvas-context-none" id="the-offscreencanvas-interface:offscreencanvas-context-none-3">none</a>, then throw an
-   <a data-x-internal="invalidstateerror" href="https://heycam.github.io/webidl/#invalidstateerror" id="the-offscreencanvas-interface:invalidstateerror-6">&quot;<code>InvalidStateError</code>&quot;</a> <code id="the-offscreencanvas-interface:domexception-9"><a data-x-internal="domexception" href="https://heycam.github.io/webidl/#dfn-DOMException">DOMException</a></code> and abort these
-   steps.</p></li><li><p>Let <var>image</var> be a newly created <code id="the-offscreencanvas-interface:imagebitmap-3"><a href="https://html.spec.whatwg.org/multipage/imagebitmap-and-animations.html#imagebitmap">ImageBitmap</a></code> object that references
-   the same underlying bitmap data as this <code id="the-offscreencanvas-interface:offscreencanvas-36"><a href="#offscreencanvas">OffscreenCanvas</a></code> object's <a href="#offscreencanvas-bitmap" id="the-offscreencanvas-interface:offscreencanvas-bitmap-10">bitmap</a>.</p></li><li><p>Set this <code id="the-offscreencanvas-interface:offscreencanvas-37"><a href="#offscreencanvas">OffscreenCanvas</a></code> object's <a href="#offscreencanvas-bitmap" id="the-offscreencanvas-interface:offscreencanvas-bitmap-11">bitmap</a> to reference a newly created bitmap of the
-   same dimensions as the previous bitmap, and with its pixels initialized to transparent black,
-   or opaque black if the rendering context's <a href="#offscreencontext2d-alpha" id="the-offscreencanvas-interface:offscreencontext2d-alpha">alpha</a> flag is set to false.</p></li><li><p>Return <var>image</var>.</p></li></ol>
-  
-
-  <h6 id="the-offscreen-2d-rendering-context"><span class="secno">4.12.5.3.1</span> The offscreen 2D rendering context<a class="self-link" href="#the-offscreen-2d-rendering-context"/></h6>
-
-  <pre class="idl">[Exposed=(Window,Worker)]
-interface <a href="#offscreencanvasrenderingcontext2d" id="the-offscreen-2d-rendering-context:offscreencanvasrenderingcontext2d">OffscreenCanvasRenderingContext2D</a> {
-  void <a href="#offscreencontext2d-commit-2" id="the-offscreen-2d-rendering-context:offscreencontext2d-commit-2">commit</a>();
-  readonly attribute <a href="#offscreencanvas" id="the-offscreen-2d-rendering-context:offscreencanvas">OffscreenCanvas</a> <a href="#offscreencontext2d-canvas-2" id="the-offscreen-2d-rendering-context:offscreencontext2d-canvas-2">canvas</a>;
-};
-
-<a href="#offscreencanvasrenderingcontext2d" id="the-offscreen-2d-rendering-context:offscreencanvasrenderingcontext2d-2">OffscreenCanvasRenderingContext2D</a> implements <a href="#canvasstate" id="the-offscreen-2d-rendering-context:canvasstate">CanvasState</a>;
-<a href="#offscreencanvasrenderingcontext2d" id="the-offscreen-2d-rendering-context:offscreencanvasrenderingcontext2d-3">OffscreenCanvasRenderingContext2D</a> implements <a href="#canvastransform" id="the-offscreen-2d-rendering-context:canvastransform">CanvasTransform</a>;
-<a href="#offscreencanvasrenderingcontext2d" id="the-offscreen-2d-rendering-context:offscreencanvasrenderingcontext2d-4">OffscreenCanvasRenderingContext2D</a> implements <a href="#canvascompositing" id="the-offscreen-2d-rendering-context:canvascompositing">CanvasCompositing</a>;
-<a href="#offscreencanvasrenderingcontext2d" id="the-offscreen-2d-rendering-context:offscreencanvasrenderingcontext2d-5">OffscreenCanvasRenderingContext2D</a> implements <a href="#canvasimagesmoothing" id="the-offscreen-2d-rendering-context:canvasimagesmoothing">CanvasImageSmoothing</a>;
-<a href="#offscreencanvasrenderingcontext2d" id="the-offscreen-2d-rendering-context:offscreencanvasrenderingcontext2d-6">OffscreenCanvasRenderingContext2D</a> implements <a href="#canvasfillstrokestyles" id="the-offscreen-2d-rendering-context:canvasfillstrokestyles">CanvasFillStrokeStyles</a>;
-<a href="#offscreencanvasrenderingcontext2d" id="the-offscreen-2d-rendering-context:offscreencanvasrenderingcontext2d-7">OffscreenCanvasRenderingContext2D</a> implements <a href="#canvasshadowstyles" id="the-offscreen-2d-rendering-context:canvasshadowstyles">CanvasShadowStyles</a>;
-<a href="#offscreencanvasrenderingcontext2d" id="the-offscreen-2d-rendering-context:offscreencanvasrenderingcontext2d-8">OffscreenCanvasRenderingContext2D</a> implements <a href="#canvasfilters" id="the-offscreen-2d-rendering-context:canvasfilters">CanvasFilters</a>;
-<a href="#offscreencanvasrenderingcontext2d" id="the-offscreen-2d-rendering-context:offscreencanvasrenderingcontext2d-9">OffscreenCanvasRenderingContext2D</a> implements <a href="#canvasrect" id="the-offscreen-2d-rendering-context:canvasrect">CanvasRect</a>;
-<a href="#offscreencanvasrenderingcontext2d" id="the-offscreen-2d-rendering-context:offscreencanvasrenderingcontext2d-10">OffscreenCanvasRenderingContext2D</a> implements <a href="#canvasdrawpath" id="the-offscreen-2d-rendering-context:canvasdrawpath">CanvasDrawPath</a>;
-<a href="#offscreencanvasrenderingcontext2d" id="the-offscreen-2d-rendering-context:offscreencanvasrenderingcontext2d-11">OffscreenCanvasRenderingContext2D</a> implements <a href="#canvasdrawimage" id="the-offscreen-2d-rendering-context:canvasdrawimage">CanvasDrawImage</a>;
-<a href="#offscreencanvasrenderingcontext2d" id="the-offscreen-2d-rendering-context:offscreencanvasrenderingcontext2d-12">OffscreenCanvasRenderingContext2D</a> implements <a href="#canvasimagedata" id="the-offscreen-2d-rendering-context:canvasimagedata">CanvasImageData</a>;
-<a href="#offscreencanvasrenderingcontext2d" id="the-offscreen-2d-rendering-context:offscreencanvasrenderingcontext2d-13">OffscreenCanvasRenderingContext2D</a> implements <a href="#canvaspathdrawingstyles" id="the-offscreen-2d-rendering-context:canvaspathdrawingstyles">CanvasPathDrawingStyles</a>;
-<a href="#offscreencanvasrenderingcontext2d" id="the-offscreen-2d-rendering-context:offscreencanvasrenderingcontext2d-14">OffscreenCanvasRenderingContext2D</a> implements <a href="#canvaspath" id="the-offscreen-2d-rendering-context:canvaspath">CanvasPath</a>;
-</pre>
-
-  <p>The <dfn id="offscreencanvasrenderingcontext2d"><code>OffscreenCanvasRenderingContext2D</code></dfn> is a rendering context
-  interface for drawing to the <a href="#offscreencanvas-bitmap" id="the-offscreen-2d-rendering-context:offscreencanvas-bitmap">bitmap</a> of an
-  <code id="the-offscreen-2d-rendering-context:offscreencanvas-2"><a href="#offscreencanvas">OffscreenCanvas</a></code> object. It is similar to <code id="the-offscreen-2d-rendering-context:canvasrenderingcontext2d"><a href="#canvasrenderingcontext2d">CanvasRenderingContext2D</a></code>,
-  with the following differences:</p>
-  <ul><li><p><a href="#canvastext" id="the-offscreen-2d-rendering-context:canvastext">text rendering</a> is not supported;</p></li><li><p>there is no support for <a href="#canvasuserinterface" id="the-offscreen-2d-rendering-context:canvasuserinterface">user interface</a>
-   features;</p></li><li><p>its <code id="the-offscreen-2d-rendering-context:offscreencontext2d-canvas-2-2"><a href="#offscreencontext2d-canvas-2">canvas</a></code> attribute refers to an
-   <code id="the-offscreen-2d-rendering-context:offscreencanvas-3"><a href="#offscreencanvas">OffscreenCanvas</a></code> object rather than a <code id="the-offscreen-2d-rendering-context:the-canvas-element"><a href="#the-canvas-element">canvas</a></code> element;</p></li><li><p>it has a <code id="the-offscreen-2d-rendering-context:offscreencontext2d-commit-2-2"><a href="#offscreencontext2d-commit-2">commit()</a></code> method for pushing the
-   rendered image to the context's <code id="the-offscreen-2d-rendering-context:offscreencanvas-4"><a href="#offscreencanvas">OffscreenCanvas</a></code> object's <a href="#offscreencanvas-placeholder" id="the-offscreen-2d-rendering-context:offscreencanvas-placeholder">placeholder <code>canvas</code> element</a>.</p></li></ul>
-
-  <p>An <code id="the-offscreen-2d-rendering-context:offscreencanvasrenderingcontext2d-15"><a href="#offscreencanvasrenderingcontext2d">OffscreenCanvasRenderingContext2D</a></code> object has a <dfn id="offscreencontext2d-bitmap">bitmap</dfn> that is initialized when the object is
-  created.</p>
-
-  <p>The <a href="#offscreencontext2d-bitmap" id="the-offscreen-2d-rendering-context:offscreencontext2d-bitmap">bitmap</a> has an <dfn id="offscreencontext2d-origin-clean">origin-clean</dfn> flag, which can be set to true or
-  false. Initially, when one of these bitmaps is created, its <a href="#offscreencontext2d-origin-clean" id="the-offscreen-2d-rendering-context:offscreencontext2d-origin-clean">origin-clean</a> flag must be set to true.</p>
-
-  <p>An <code id="the-offscreen-2d-rendering-context:offscreencanvasrenderingcontext2d-16"><a href="#offscreencanvasrenderingcontext2d">OffscreenCanvasRenderingContext2D</a></code> object also has an <dfn id="offscreencontext2d-alpha">alpha</dfn> flag, which can be set to true or false. Initially,
-  when the context is created, its alpha flag must be set to true. When an
-  <code id="the-offscreen-2d-rendering-context:offscreencanvasrenderingcontext2d-17"><a href="#offscreencanvasrenderingcontext2d">OffscreenCanvasRenderingContext2D</a></code> object has its <a href="#offscreencontext2d-alpha" id="the-offscreen-2d-rendering-context:offscreencontext2d-alpha">alpha</a> flag set to false, then its alpha channel must be
-  fixed to 1.0 (fully opaque) for all pixels, and attempts to change the alpha component of any pixel
-  must be silently ignored.</p>
-
-  <p>An <code id="the-offscreen-2d-rendering-context:offscreencanvasrenderingcontext2d-18"><a href="#offscreencanvasrenderingcontext2d">OffscreenCanvasRenderingContext2D</a></code> object has an <dfn id="associated-offscreencanvas-object">associated
-  <code>OffscreenCanvas</code> object</dfn>, which is the <code id="the-offscreen-2d-rendering-context:offscreencanvas-5"><a href="#offscreencanvas">OffscreenCanvas</a></code> object
-  from which the <code id="the-offscreen-2d-rendering-context:offscreencanvasrenderingcontext2d-19"><a href="#offscreencanvasrenderingcontext2d">OffscreenCanvasRenderingContext2D</a></code> object was created.
-
-  </p><dl class="domintro"><dt><var>offscreenCanvasRenderingContext2D</var> . <code id="offscreencontext2d-commit"><a href="#offscreencontext2d-commit-2">commit</a></code>()</dt><dd>
-    <p>Copies the rendering context's <a href="#offscreencontext2d-bitmap" id="the-offscreen-2d-rendering-context:offscreencontext2d-bitmap-2">bitmap</a> to
-    the bitmap of the <a href="#offscreencanvas-placeholder" id="the-offscreen-2d-rendering-context:offscreencanvas-placeholder-2">placeholder <code>canvas</code>
-    element</a> of the <a href="#associated-offscreencanvas-object" id="the-offscreen-2d-rendering-context:associated-offscreencanvas-object">associated <code>OffscreenCanvas</code> object</a>. The copy
-    operation is asynchronous.</p>
-   </dd><dt><var>offscreenCanvas</var> = <var>offscreenCanvasRenderingContext2D</var> . <code id="offscreencontext2d-canvas"><a href="#offscreencontext2d-canvas-2">canvas</a></code></dt><dd>
-    <p>Returns the <a href="#associated-offscreencanvas-object" id="the-offscreen-2d-rendering-context:associated-offscreencanvas-object-2">associated <code>OffscreenCanvas</code> object</a>.</p>
-   </dd></dl>
-
-  
-
-  <p>The <dfn id="offscreen-2d-context-creation-algorithm">offscreen 2D context creation algorithm</dfn>, which is passed a
-  <var>target</var> (an <code id="the-offscreen-2d-rendering-context:offscreencanvas-6"><a href="#offscreencanvas">OffscreenCanvas</a></code> object) and optionally some arguments,
-  consists of running the following steps:</p>
-
-  <ol><li><p>If the algorithm was passed some arguments, let <var>arg</var> be the first such
-   argument. Otherwise, let <var>arg</var> be undefined.</p></li><li><p>Let <var>settings</var> be the result of <a href="#coerce-context-arguments-for-2d" id="the-offscreen-2d-rendering-context:coerce-context-arguments-for-2d">coercing the <var>arg</var> context arguments
-   for 2D</a>.</p></li><li><p>Let <var>context</var> be a new <code id="the-offscreen-2d-rendering-context:offscreencanvasrenderingcontext2d-20"><a href="#offscreencanvasrenderingcontext2d">OffscreenCanvasRenderingContext2D</a></code>
-   object.</p></li><li><p>Set <var>context</var>'s <a href="#associated-offscreencanvas-object" id="the-offscreen-2d-rendering-context:associated-offscreencanvas-object-3">associated <code>OffscreenCanvas</code> object</a> to
-   <var>target</var>.</p></li><li><p>Process each of the members of <var>settings</var> as follows:</p>
-    <dl><dt><code id="the-offscreen-2d-rendering-context:dom-canvasrenderingcontext2dsettings-alpha"><a href="#dom-canvasrenderingcontext2dsettings-alpha">alpha</a></code></dt><dd>If false, set <var>context</var>'s <a href="#offscreencontext2d-alpha" id="the-offscreen-2d-rendering-context:offscreencontext2d-alpha-2">alpha</a>
-     flag to false.</dd></dl>
-   </li><li><p>Set <var>context</var>'s <a href="#offscreencontext2d-bitmap" id="the-offscreen-2d-rendering-context:offscreencontext2d-bitmap-3">bitmap</a> to a newly
-   created bitmap with the dimensions specified by the <code id="the-offscreen-2d-rendering-context:dom-offscreencanvas-width-2"><a href="#dom-offscreencanvas-width-2">width</a></code> and <code id="the-offscreen-2d-rendering-context:dom-offscreencanvas-height-2"><a href="#dom-offscreencanvas-height-2">height</a></code> attributes of <var>target</var>, and set
-   <var>target</var>'s bitmap to the same bitmap (so that they are shared).</p></li><li><p>If <var>context</var>'s <a href="#offscreencontext2d-alpha" id="the-offscreen-2d-rendering-context:offscreencontext2d-alpha-3">alpha</a> flag is set
-   to true, initialize all the pixels of <var>context</var>'s <a href="#offscreencontext2d-bitmap" id="the-offscreen-2d-rendering-context:offscreencontext2d-bitmap-4">bitmap</a> to transparent black. Otherwise, initialize
-   the pixels to opaque black.</p></li><li><p>Return <var>context</var>.</p></li></ol>
-
-  <p>The <dfn id="offscreencontext2d-commit-2"><code>commit()</code></dfn> method, when invoked,
-  must run the following steps:</p>
-
-  <ol><li><p>If this <code id="the-offscreen-2d-rendering-context:offscreencanvasrenderingcontext2d-21"><a href="#offscreencanvasrenderingcontext2d">OffscreenCanvasRenderingContext2D</a></code>'s <a href="#associated-offscreencanvas-object" id="the-offscreen-2d-rendering-context:associated-offscreencanvas-object-4">associated
-    <code>OffscreenCanvas</code> object</a> does not have a <a href="#offscreencanvas-placeholder" id="the-offscreen-2d-rendering-context:offscreencanvas-placeholder-3">placeholder <code>canvas</code> element</a>, abort
-    these steps.</p></li><li><p>Let <var>image</var> be a copy of this <code id="the-offscreen-2d-rendering-context:offscreencanvasrenderingcontext2d-22"><a href="#offscreencanvasrenderingcontext2d">OffscreenCanvasRenderingContext2D</a></code>'s
-    <a href="#offscreencontext2d-bitmap" id="the-offscreen-2d-rendering-context:offscreencontext2d-bitmap-5">bitmap</a>, including the value of its <a href="#offscreencontext2d-origin-clean" id="the-offscreen-2d-rendering-context:offscreencontext2d-origin-clean-2">origin-clean</a> flag.</p></li><li>
-     <p><a href="https://html.spec.whatwg.org/multipage/webappapis.html#queue-a-task" id="the-offscreen-2d-rendering-context:queue-a-task">Queue a task</a> in the <a href="#offscreencanvas-placeholder" id="the-offscreen-2d-rendering-context:offscreencanvas-placeholder-4">placeholder <code>canvas</code> element</a>'s
-     <a href="https://html.spec.whatwg.org/multipage/webappapis.html#relevant-settings-object" id="the-offscreen-2d-rendering-context:relevant-settings-object">relevant settings object</a>'s <a href="https://html.spec.whatwg.org/multipage/webappapis.html#responsible-event-loop" id="the-offscreen-2d-rendering-context:responsible-event-loop">responsible event loop</a> (which will be a
-     <a href="https://html.spec.whatwg.org/multipage/browsers.html#browsing-context" id="the-offscreen-2d-rendering-context:browsing-context">browsing context</a> <a href="https://html.spec.whatwg.org/multipage/webappapis.html#event-loop" id="the-offscreen-2d-rendering-context:event-loop">event loop</a>) to set the <a href="#offscreencanvas-placeholder" id="the-offscreen-2d-rendering-context:offscreencanvas-placeholder-5">placeholder <code>canvas</code> element</a>'s
-     <a href="#output-bitmap" id="the-offscreen-2d-rendering-context:output-bitmap">output bitmap</a> to be a reference to <var>image</var>.</p>
-
-     <p class="note">If <var>image</var> has different dimensions than the bitmap previously
-     referenced as the <a href="#offscreencanvas-placeholder" id="the-offscreen-2d-rendering-context:offscreencanvas-placeholder-6">placeholder <code>canvas</code>
-     element</a>'s <a href="#output-bitmap" id="the-offscreen-2d-rendering-context:output-bitmap-2">output bitmap</a>, then this task will result in a change in
-     the <a href="#offscreencanvas-placeholder" id="the-offscreen-2d-rendering-context:offscreencanvas-placeholder-7">placeholder <code>canvas</code>
-     element</a>'s <a data-x-internal="intrinsic-dimensions" href="https://drafts.csswg.org/css2/conform.html#intrinsic" id="the-offscreen-2d-rendering-context:intrinsic-dimensions">intrinsic size</a>, which can affect
-     document layout.</p>
-    </li></ol>
-
-  <p class="note">Implementations are encouraged to short-circuit the graphics update steps of
-  the <a href="https://html.spec.whatwg.org/multipage/browsers.html#browsing-context" id="the-offscreen-2d-rendering-context:browsing-context-2">browsing context</a> <a href="https://html.spec.whatwg.org/multipage/webappapis.html#event-loop" id="the-offscreen-2d-rendering-context:event-loop-2">event loop</a> for the purposes of updating the
-  contents of a <a href="#offscreencanvas-placeholder" id="the-offscreen-2d-rendering-context:offscreencanvas-placeholder-8">placeholder <code>canvas</code>
-  element</a> to the display. This could mean, for example, that the <code id="the-offscreen-2d-rendering-context:offscreencontext2d-commit-2-3"><a href="#offscreencontext2d-commit-2">commit()</a></code> method can copy the bitmap contents directly
-  to a graphics buffer that is mapped to the physical display location of the <a href="#offscreencanvas-placeholder" id="the-offscreen-2d-rendering-context:offscreencanvas-placeholder-9">placeholder <code>canvas</code> element</a>. This or
-  similar short-circuiting approaches can significantly reduce display latency, especially in cases
-  where the <code id="the-offscreen-2d-rendering-context:offscreencontext2d-commit-2-4"><a href="#offscreencontext2d-commit-2">commit()</a></code> method is invoked from a worker
-  and the <a href="https://html.spec.whatwg.org/multipage/webappapis.html#event-loop" id="the-offscreen-2d-rendering-context:event-loop-3">event loop</a> of the <a href="#offscreencanvas-placeholder" id="the-offscreen-2d-rendering-context:offscreencanvas-placeholder-10">placeholder <code>canvas</code> element</a>'s
-  <a href="https://html.spec.whatwg.org/multipage/browsers.html#browsing-context" id="the-offscreen-2d-rendering-context:browsing-context-3">browsing context</a> is busy. However, such shortcuts can not have any
-  script-observable side-effects. This means that the committed bitmap still needs to be sent to
-  the <a href="#offscreencanvas-placeholder" id="the-offscreen-2d-rendering-context:offscreencanvas-placeholder-11">placeholder <code>canvas</code> element</a>, in
-  case the element is used as a <code id="the-offscreen-2d-rendering-context:canvasimagesource"><a href="#canvasimagesource">CanvasImageSource</a></code>, as an
-  <code id="the-offscreen-2d-rendering-context:imagebitmapsource"><a href="https://html.spec.whatwg.org/multipage/imagebitmap-and-animations.html#imagebitmapsource">ImageBitmapSource</a></code>, or in case <code id="the-offscreen-2d-rendering-context:dom-canvas-todataurl-2"><a href="#dom-canvas-todataurl-2">toDataURL()</a></code>
-  or <code id="the-offscreen-2d-rendering-context:dom-canvas-toblob-2"><a href="#dom-canvas-toblob-2">toBlob()</a></code> are called on it.</p>
-
-  <p>The <dfn id="offscreencontext2d-canvas-2"><code>canvas</code></dfn> attribute, on getting,
-  must return this <code id="the-offscreen-2d-rendering-context:offscreencanvasrenderingcontext2d-23"><a href="#offscreencanvasrenderingcontext2d">OffscreenCanvasRenderingContext2D</a></code>'s <a href="#associated-offscreencanvas-object" id="the-offscreen-2d-rendering-context:associated-offscreencanvas-object-5">associated
-  <code>OffscreenCanvas</code> object</a>.
-
-  </p>
-
-  
-
-  <h5 id="colour-spaces-and-colour-correction"><span class="secno">4.12.5.4</span> Color spaces and color correction<a class="self-link" href="#colour-spaces-and-colour-correction"/></h5>
-
-  <p>The <code id="colour-spaces-and-colour-correction:the-canvas-element"><a href="#the-canvas-element">canvas</a></code> APIs must perform color correction at only two points: when rendering
-  images with their own gamma correction and color space information onto a bitmap, to convert the
-  image to the color space used by the bitmaps (e.g. using the 2D Context's <code id="colour-spaces-and-colour-correction:dom-context-2d-drawimage"><a href="#dom-context-2d-drawimage">drawImage()</a></code> method with an
-  <code id="colour-spaces-and-colour-correction:htmlorsvgimageelement"><a href="#htmlorsvgimageelement">HTMLOrSVGImageElement</a></code> object), and when rendering the actual canvas bitmap to the
-  output device.</p>
-
-  <p class="note">Thus, in the 2D context, colors used to draw shapes onto the canvas will exactly
-  match colors obtained through the <code id="colour-spaces-and-colour-correction:dom-context-2d-getimagedata-2"><a href="#dom-context-2d-getimagedata-2">getImageData()</a></code> method.</p>
-
-  <p>The <code id="colour-spaces-and-colour-correction:dom-canvas-todataurl-2"><a href="#dom-canvas-todataurl-2">toDataURL()</a></code> method, when invoked, must not
-  include color space information in the resources they return. Where the output format allows it,
-  the color of pixels in resources created by <code id="colour-spaces-and-colour-correction:dom-canvas-todataurl-2-2"><a href="#dom-canvas-todataurl-2">toDataURL()</a></code>
-  must match those returned by the <code id="colour-spaces-and-colour-correction:dom-context-2d-getimagedata-2-2"><a href="#dom-context-2d-getimagedata-2">getImageData()</a></code>
-  method.</p>
-
-  <p>In user agents that support CSS, the color space used by a <code id="colour-spaces-and-colour-correction:the-canvas-element-2"><a href="#the-canvas-element">canvas</a></code> element must
-  match the color space used for processing any colors for that element in CSS.</p>
-
-  <p>The gamma correction and color space information of images must be handled in such a way that
-  an image rendered directly using an <code id="colour-spaces-and-colour-correction:the-img-element"><a href="https://html.spec.whatwg.org/multipage/embedded-content.html#the-img-element">img</a></code> element would use the same colors as one
-  painted on a <code id="colour-spaces-and-colour-correction:the-canvas-element-3"><a href="#the-canvas-element">canvas</a></code> element that is then itself rendered. Furthermore, the rendering
-  of images that have no color correction information (such as those returned by the <code id="colour-spaces-and-colour-correction:dom-canvas-todataurl-2-3"><a href="#dom-canvas-todataurl-2">toDataURL()</a></code> method) must be rendered with no color
-  correction.</p>
-
-  <p class="note">Thus, in the 2D context, calling the <code id="colour-spaces-and-colour-correction:dom-context-2d-drawimage-2"><a href="#dom-context-2d-drawimage">drawImage()</a></code> method to render the output of the <code id="colour-spaces-and-colour-correction:dom-canvas-todataurl-2-4"><a href="#dom-canvas-todataurl-2">toDataURL()</a></code> method to the canvas, given the appropriate
-  dimensions, has no visible effect.</p>
-
-  
-
-
-
-  <h5 id="serialising-bitmaps-to-a-file"><span class="secno">4.12.5.5</span> Serializing bitmaps to a file<a class="self-link" href="#serialising-bitmaps-to-a-file"/></h5>
-
-  
-
-  <p>When a user agent is to create <dfn id="a-serialisation-of-the-bitmap-as-a-file">a
-  serialization of the bitmap as a file</dfn>, given an optional <var>type</var> and
-  <var>quality</var>, it must create an image file in the format given by <var>type</var>, or if
-  <var>type</var> was not supplied, in the PNG format. If an error occurs during the creation of
-  the image file (e.g. an internal encoder error), then the result of the serialization is null.
-  <a href="https://html.spec.whatwg.org/multipage/references.html#refsPNG">[PNG]</a></p>
-
-  <p>The image file's pixel data must be the bitmap's pixel data scaled to one image pixel per
-  coordinate space unit, and if the file format used supports encoding resolution metadata, the
-  resolution must be given as 96dpi (one image pixel per <a data-x-internal="'px'" href="https://drafts.csswg.org/css-values/#px" id="serialising-bitmaps-to-a-file:'px'">CSS pixel</a>).</p>
-
-  <p>If <var>type</var> is supplied, then it must be interpreted as a <a data-x-internal="mime-type" href="https://mimesniff.spec.whatwg.org/#mime-type" id="serialising-bitmaps-to-a-file:mime-type">MIME
-  type</a> giving the format to use. If the type has any parameters, then it must be treated as
-  not supported.</p>
-
-  <p class="example">For example, the value &quot;<code id="serialising-bitmaps-to-a-file:image/png"><a href="https://html.spec.whatwg.org/multipage/indices.html#image/png">image/png</a></code>&quot; would mean to generate a PNG
-  image, the value &quot;<code id="serialising-bitmaps-to-a-file:image/jpeg"><a href="https://html.spec.whatwg.org/multipage/indices.html#image/jpeg">image/jpeg</a></code>&quot; would mean to generate a JPEG image, and the value
-  &quot;<code id="serialising-bitmaps-to-a-file:image/svg+xml"><a href="https://html.spec.whatwg.org/multipage/indices.html#image/svg+xml">image/svg+xml</a></code>&quot; would mean to generate an SVG image (which would require that the
-  user agent track how the bitmap was generated, an unlikely, though potentially awesome,
-  feature).</p>
-
-  <p>User agents must support PNG (&quot;<code id="serialising-bitmaps-to-a-file:image/png-2"><a href="https://html.spec.whatwg.org/multipage/indices.html#image/png">image/png</a></code>&quot;). User agents may support other types.
-  If the user agent does not support the requested type, then it must create the file using the PNG
-  format. <a href="https://html.spec.whatwg.org/multipage/references.html#refsPNG">[PNG]</a></p>
-
-  <p>User agents must <a data-x-internal="converted-to-ascii-lowercase" href="https://infra.spec.whatwg.org/#ascii-lowercase" id="serialising-bitmaps-to-a-file:converted-to-ascii-lowercase">convert the provided type to ASCII
-  lowercase</a> before establishing if they support that type.</p>
-
-  <p>For image types that do not support an alpha channel, the serialized image must be the bitmap
-  image composited onto a solid black background using the source-over operator.</p>
-
-  <p>If <var>type</var> is an image format that supports variable quality (such as
-  &quot;<code id="serialising-bitmaps-to-a-file:image/jpeg-2"><a href="https://html.spec.whatwg.org/multipage/indices.html#image/jpeg">image/jpeg</a></code>&quot;) and <var>quality</var> is given, then, if <a data-x-internal="js-type" href="https://tc39.github.io/ecma262/#sec-ecmascript-data-types-and-values" id="serialising-bitmaps-to-a-file:js-type">Type</a>(<var>quality</var>) is Number, and <var>quality</var> is in the range
-  0.0 to 1.0 inclusive, the user agent must treat <var>quality</var> as the desired quality level.
-  If <a data-x-internal="js-type" href="https://tc39.github.io/ecma262/#sec-ecmascript-data-types-and-values" id="serialising-bitmaps-to-a-file:js-type-2">Type</a>(<var>quality</var>) is not Number, or if <var>quality</var>
-  is outside that range, the user agent must use its default quality value, as if the
-  <var>quality</var> argument had not been given.</p>
-
-  <p class="note">The use of type-testing here, instead of simply declaring <var>quality</var> as
-  a Web IDL <code>double</code>, is a historical artifact.</p>
-
-  
-
-
-  
-
-  <h5 id="security-with-canvas-elements"><span class="secno">4.12.5.6</span> Security with <code id="security-with-canvas-elements:the-canvas-element"><a href="#the-canvas-element">canvas</a></code> elements<a class="self-link" href="#security-with-canvas-elements"/></h5>
-
-  <p><i>This section is non-normative.</i></p>
-
-  <p><strong>Information leakage</strong> can occur if scripts from one <a href="https://html.spec.whatwg.org/multipage/origin.html#concept-origin" id="security-with-canvas-elements:concept-origin">origin</a> can
-  access information (e.g. read pixels) from images from another origin (one that isn't the <a href="https://html.spec.whatwg.org/multipage/origin.html#same-origin" id="security-with-canvas-elements:same-origin">same</a>).</p>
-
-  <p>To mitigate this, bitmaps used with <code id="security-with-canvas-elements:the-canvas-element-2"><a href="#the-canvas-element">canvas</a></code> elements and <code id="security-with-canvas-elements:imagebitmap"><a href="https://html.spec.whatwg.org/multipage/imagebitmap-and-animations.html#imagebitmap">ImageBitmap</a></code>
-  objects are defined to have a flag indicating whether they are <a href="#concept-canvas-origin-clean" id="security-with-canvas-elements:concept-canvas-origin-clean">origin-clean</a>. All bitmaps start with their <a href="#concept-canvas-origin-clean" id="security-with-canvas-elements:concept-canvas-origin-clean-2">origin-clean</a> set to true. The flag is set to false
-  when cross-origin images are used.</p>
-
-  <p>The <code id="security-with-canvas-elements:dom-canvas-todataurl-2"><a href="#dom-canvas-todataurl-2">toDataURL()</a></code>, <code id="security-with-canvas-elements:dom-canvas-toblob-2"><a href="#dom-canvas-toblob-2">toBlob()</a></code>, and <code id="security-with-canvas-elements:dom-context-2d-getimagedata-2"><a href="#dom-context-2d-getimagedata-2">getImageData()</a></code> methods check the flag and will
-  throw a <a data-x-internal="securityerror" href="https://heycam.github.io/webidl/#securityerror" id="security-with-canvas-elements:securityerror">&quot;<code>SecurityError</code>&quot;</a> <code id="security-with-canvas-elements:domexception"><a data-x-internal="domexception" href="https://heycam.github.io/webidl/#dfn-DOMException">DOMException</a></code> rather than leak
-  cross-origin data.</p>
-
-  <p>The value of the <a href="#concept-canvas-origin-clean" id="security-with-canvas-elements:concept-canvas-origin-clean-3">origin-clean</a> flag is
-  propagated from a source <code id="security-with-canvas-elements:the-canvas-element-3"><a href="#the-canvas-element">canvas</a></code> element's bitmap to a new <code id="security-with-canvas-elements:imagebitmap-2"><a href="https://html.spec.whatwg.org/multipage/imagebitmap-and-animations.html#imagebitmap">ImageBitmap</a></code>
-  object by <code id="security-with-canvas-elements:dom-createimagebitmap-2"><a href="https://html.spec.whatwg.org/multipage/imagebitmap-and-animations.html#dom-createimagebitmap-2">createImageBitmap()</a></code>. Conversely, a
-  destination <code id="security-with-canvas-elements:the-canvas-element-4"><a href="#the-canvas-element">canvas</a></code> element's bitmap will have its <a href="#concept-canvas-origin-clean" id="security-with-canvas-elements:concept-canvas-origin-clean-4">origin-clean</a> flags set to false by <code id="security-with-canvas-elements:dom-context-2d-drawimage"><a href="#dom-context-2d-drawimage">drawImage</a></code> if the source image is an
-  <code id="security-with-canvas-elements:imagebitmap-3"><a href="https://html.spec.whatwg.org/multipage/imagebitmap-and-animations.html#imagebitmap">ImageBitmap</a></code> object whose bitmap has its <a href="#concept-canvas-origin-clean" id="security-with-canvas-elements:concept-canvas-origin-clean-5">origin-clean</a> flag set to false.</p>
-
-  <p>The flag can be reset in certain situations; for example, when changing the value of the
-  <code id="security-with-canvas-elements:attr-canvas-width"><a href="#attr-canvas-width">width</a></code> or the <code id="security-with-canvas-elements:attr-canvas-height"><a href="#attr-canvas-height">height</a></code> content attribute of the <code id="security-with-canvas-elements:the-canvas-element-5"><a href="#the-canvas-element">canvas</a></code> element
-  to which a <code id="security-with-canvas-elements:canvasrenderingcontext2d"><a href="#canvasrenderingcontext2d">CanvasRenderingContext2D</a></code> is bound, the bitmap is
-  cleared and its <a href="#concept-canvas-origin-clean" id="security-with-canvas-elements:concept-canvas-origin-clean-6">origin-clean</a> flag is reset.</p>
-
-  <p>When using an <code id="security-with-canvas-elements:imagebitmaprenderingcontext"><a href="#imagebitmaprenderingcontext">ImageBitmapRenderingContext</a></code>, the value of the <a href="#concept-canvas-origin-clean" id="security-with-canvas-elements:concept-canvas-origin-clean-7">origin-clean</a> flag is propagated from
-  <code id="security-with-canvas-elements:imagebitmap-4"><a href="https://html.spec.whatwg.org/multipage/imagebitmap-and-animations.html#imagebitmap">ImageBitmap</a></code> objects when they are transferred to the <code id="security-with-canvas-elements:the-canvas-element-6"><a href="#the-canvas-element">canvas</a></code>
-  via <a href="#dom-imagebitmaprenderingcontext-transferfromimagebitmap-2" id="security-with-canvas-elements:dom-imagebitmaprenderingcontext-transferfromimagebitmap-2">transferFromImageBitmap()</a>.</p>
-
-  
-
-  </body></html>
diff --git a/third_party/blink/web_tests/external/wpt/html/canvas/tools/gentestutils.py b/third_party/blink/web_tests/external/wpt/html/canvas/tools/gentestutils.py
index d677f4d3..b6861db5 100644
--- a/third_party/blink/web_tests/external/wpt/html/canvas/tools/gentestutils.py
+++ b/third_party/blink/web_tests/external/wpt/html/canvas/tools/gentestutils.py
@@ -407,62 +407,3 @@
                 f.write(templates['w3cworker'] % template_params)
 
     print()
-
-
-    def getNodeText(node):
-        t, offsets = '', []
-
-        # Skip over any previous annotations we added
-        if node.nodeType == node.ELEMENT_NODE and 'testrefs' in node.getAttribute('class').split(' '):
-            return t, offsets
-
-        if node.nodeType == node.TEXT_NODE:
-            val = node.nodeValue
-            val = val.replace(unichr(0xa0), ' ') # replace &nbsp;s
-            t += val
-            offsets += [ (node, len(node.nodeValue)) ]
-        for n in node.childNodes:
-            child_t, child_offsets = getNodeText(n)
-            t += child_t
-            offsets += child_offsets
-        return t, offsets
-
-    def htmlSerializer(element):
-        element.normalize()
-        rv = []
-        specialtext = ['style', 'script', 'xmp', 'iframe', 'noembed', 'noframes', 'noscript']
-        empty = ['area', 'base', 'basefont', 'bgsound', 'br', 'col', 'embed', 'frame',
-                 'hr', 'img', 'input', 'link', 'meta', 'param', 'spacer', 'wbr']
-
-        def serializeElement(element):
-            if element.nodeType == Node.DOCUMENT_TYPE_NODE:
-                rv.append("<!DOCTYPE %s>" % element.name)
-            elif element.nodeType == Node.DOCUMENT_NODE:
-                for child in element.childNodes:
-                    serializeElement(child)
-            elif element.nodeType == Node.COMMENT_NODE:
-                rv.append("<!--%s-->" % element.nodeValue)
-            elif element.nodeType == Node.TEXT_NODE:
-                unescaped = False
-                n = element.parentNode
-                while n is not None:
-                    if n.nodeName in specialtext:
-                        unescaped = True
-                        break
-                    n = n.parentNode
-                if unescaped:
-                    rv.append(element.nodeValue)
-                else:
-                    rv.append(escapeHTML(element.nodeValue))
-            else:
-                rv.append("<%s" % element.nodeName)
-                if element.hasAttributes():
-                    for name, value in element.attributes.items():
-                        rv.append(' %s="%s"' % (name, escapeHTML(value)))
-                rv.append(">")
-                if element.nodeName not in empty:
-                    for child in element.childNodes:
-                        serializeElement(child)
-                    rv.append("</%s>" % element.nodeName)
-        serializeElement(element)
-        return '<!DOCTYPE html>\n' + ''.join(rv)
diff --git a/third_party/blink/web_tests/external/wpt/html/canvas/tools/spec.yaml b/third_party/blink/web_tests/external/wpt/html/canvas/tools/spec.yaml
index d4b1840a..34f013f 100644
--- a/third_party/blink/web_tests/external/wpt/html/canvas/tools/spec.yaml
+++ b/third_party/blink/web_tests/external/wpt/html/canvas/tools/spec.yaml
@@ -5,93 +5,92 @@
 
 assertions:
   - id: canvas.type
-    text: "interface HTMLCanvasElement<^> : HTMLElement {"
+    text: "interface HTMLCanvasElement : HTMLElement {"
   - id: size.width
-    text: "interface HTMLCanvasElement<...>attribute unsigned long width;<^>"
+    text: "interface HTMLCanvasElement<...>attribute unsigned long width;"
   - id: size.height
-    text: "interface HTMLCanvasElement<...>attribute unsigned long height;<^>"
+    text: "interface HTMLCanvasElement<...>attribute unsigned long height;"
   - id: canvas.getContext
-    text: "interface HTMLCanvasElement<...>object\\? getContext(in DOMString contextId, in any... args);<^>"
+    text: "interface HTMLCanvasElement<...>object\\? getContext(in DOMString contextId, in any... args);"
   - id: fallback
-    text: "The contents of the canvas element, if any, are the element's fallback content<^>."
+    text: "The contents of the canvas element, if any, are the element's fallback content."
   - id: size.nonnegativeinteger
-    text: "The rules for parsing non-negative integers *must* be used to obtain their numeric values<^>."
+    text: "The rules for parsing non-negative integers *must* be used to obtain their numeric values."
   - id: size.missing
-    text: "If an attribute is missing<^>, <...> then the default value *must* be used instead."
+    text: "If an attribute is missing, <...> then the default value *must* be used instead."
   - id: size.error
-    text: "if parsing its value returns an error<^>, then the default value *must* be used instead."
+    text: "if parsing its value returns an error, then the default value *must* be used instead."
   - id: size.default
-    text: "The width attribute defaults to 300, and the height attribute defaults to 150<^>."
+    text: "The width attribute defaults to 300, and the height attribute defaults to 150."
   - id: size.css
-    text: "the element can be sized arbitrarily by a style sheet. During rendering, the image is scaled to fit this layout size<^>."
+    text: "the element can be sized arbitrarily by a style sheet. During rendering, the image is scaled to fit this layout size."
   - id: initial.reset
-    text: "When the canvas element is created, and subsequently whenever the width and height attributes are set (whether to a new value or to the previous value), the bitmap and any associated contexts *must* be cleared back to their initial state <...><^>."
+    text: "When the canvas element is created, and subsequently whenever the width and height attributes are set (whether to a new value or to the previous value), the bitmap and any associated contexts *must* be cleared back to their initial state <...>."
   - id: initial.colour
-    text: "When the canvas is initialized, its bitmap *must* be cleared to transparent black<^>."
+    text: "When the canvas is initialized, its bitmap *must* be cleared to transparent black."
   - id: size.reflect
-    text: "The width and height IDL attributes *must* reflect the respective content attributes of the same name<^>,"
+    text: "The width and height IDL attributes *must* reflect the respective content attributes of the same name,"
 
   - id: context.unrecognised
-    text: "If contextId is not the name of a context supported by the user agent, return null and abort these steps<^>."
+    text: "If contextId is not the name of a context supported by the user agent, return null and abort these steps."
   - id: context.unique
-    text: "If the getContext() method has already been invoked on this element for the same contextId, return the same object as was returned that time, and abort these steps<^>."
+    text: "If the getContext() method has already been invoked on this element for the same contextId, return the same object as was returned that time, and abort these steps."
   - id: context.2d
-    text: "When the getContext() method of a canvas element is to return a new object for the contextId 2d, the user agent *must* return a new CanvasRenderingContext2D object<^>."
+    text: "When the getContext() method of a canvas element is to return a new object for the contextId 2d, the user agent *must* return a new CanvasRenderingContext2D object."
   - id: context.2d.extraargs
-    text: "When the getContext() method of a canvas element is to return a new object for the contextId 2d, the user agent *must* return a new CanvasRenderingContext2D object. Any additional arguments are ignored<^>."
+    text: "When the getContext() method of a canvas element is to return a new object for the contextId 2d, the user agent *must* return a new CanvasRenderingContext2D object. Any additional arguments are ignored."
 
   - id: toDataURL.noarguments
-    text: "When a user agent is to create a serialization of the image as a file, <...> if there are no arguments, in the PNG format<^>."
+    text: "When a user agent is to create a serialization of the image as a file, <...> if there are no arguments, in the PNG format."
   - id: toDataURL.zerosize
-    text: "If the canvas has no pixels (i.e. either its horizontal dimension or its vertical dimension is zero) then return the string \"data:,\"<^> and abort these steps."
+    text: "If the canvas has no pixels (i.e. either its horizontal dimension or its vertical dimension is zero) then return the string \"data:,\" and abort these steps."
   - id: toDataURL.witharguments
-    text: "If arguments is not empty, the first value must be interpreted as a MIME type giving the format to use<^>."
+    text: "If arguments is not empty, the first value must be interpreted as a MIME type giving the format to use."
   - id: toDataURL.noalpha
-    text: "For image types that do not support an alpha channel, the serialized image *must* be the canvas image composited onto a solid black background using the source-over operator<^>."
+    text: "For image types that do not support an alpha channel, the serialized image *must* be the canvas image composited onto a solid black background using the source-over operator."
   - id: toDataURL.png
-    text: "User agents *must* support PNG (\"image/png\")<^>."
+    text: "User agents *must* support PNG (\"image/png\")."
   - id: toDataURL.unrecognised
-    text: "If the user agent does not support the requested type, it *must* create the file using the PNG format<^>."
+    text: "If the user agent does not support the requested type, it *must* create the file using the PNG format."
   - id: toDataURL.lowercase
-    text: "User agents *must* convert the provided type to ASCII lowercase before establishing if they support that type<^>."
+    text: "User agents *must* convert the provided type to ASCII lowercase before establishing if they support that type."
   - id: toDataURL.jpeg
-    previously: [ 0, "image/png", false ]
-    text: "image/jpeg<^>"
+    text: "image/jpeg"
   - id: toDataURL.jpeg.quality
-    text: "The second argument, if it is a number in the range 0.0 to 1.0 inclusive, *must* be treated as the desired quality level<^>."
+    text: "The second argument, if it is a number in the range 0.0 to 1.0 inclusive, *must* be treated as the desired quality level."
   - id: toDataURL.jpeg.nan
-    text: "If it is not a number<^> <...>, the user agent *must* use its default value, as if the argument had been omitted."
+    text: "If it is not a number <...>, the user agent *must* use its default value, as if the argument had been omitted."
   - id: toDataURL.jpeg.range
-    text: "If it is <...> outside that range<^>, the user agent *must* use its default value, as if the argument had been omitted."
+    text: "If it is <...> outside that range, the user agent *must* use its default value, as if the argument had been omitted."
   - id: toDataURL.arguments
-    text: "Other arguments *must* be ignored and must not cause the user agent to raise an exception<^>."
+    text: "Other arguments *must* be ignored and must not cause the user agent to raise an exception."
 
   - id: 2d.coordinatespace
-    text: "flat Cartesian surface whose origin (0,0) is at the top left corner, with the coordinate space having x values increasing when going right, and y values increasing when going down<^>."
+    text: "flat Cartesian surface whose origin (0,0) is at the top left corner, with the coordinate space having x values increasing when going right, and y values increasing when going down."
   - id: context.2d.type
-    text: "interface CanvasRenderingContext2D<^> {"
+    text: "interface CanvasRenderingContext2D {"
   - id: 2d.canvasGradient.type
-    text: "interface CanvasGradient<^> {"
+    text: "interface CanvasGradient {"
   - id: 2d.imageData.type
-    text: "interface ImageData<^> {"
+    text: "interface ImageData {"
   - id: 2d.canvas.attribute
-    text: "readonly<^> attribute HTMLCanvasElement canvas;"
+    text: "readonly attribute HTMLCanvasElement canvas;"
   - id: 2d.canvas
-    text: "The canvas attribute *must* return the canvas element that the context paints on<^>."
+    text: "The canvas attribute *must* return the canvas element that the context paints on."
   - id: 2d.nonfinite
-    text: "Except where otherwise specified, for the 2D context interface, any method call with a numeric argument whose value is infinite or a NaN value *must* be ignored<^>."
+    text: "Except where otherwise specified, for the 2D context interface, any method call with a numeric argument whose value is infinite or a NaN value *must* be ignored."
 
   - id: 2d.currentColor.onset
-    text: "Whenever the CSS value currentColor is used as a color in this API, the \"computed value of the 'color' property\" for the purposes of determining the computed value of the currentColor keyword is the computed value of the 'color' property on the element in question at the time that the color is specified<^>"
+    text: "Whenever the CSS value currentColor is used as a color in this API, the \"computed value of the 'color' property\" for the purposes of determining the computed value of the currentColor keyword is the computed value of the 'color' property on the element in question at the time that the color is specified"
   - id: 2d.currentColor.outofdoc
-    text: "If the computed value of the 'color' property is undefined for a particular case (e.g. because the element is not in a Document), then the \"computed value of the 'color' property\" for the purposes of determining the computed value of the currentColor keyword is fully opaque black<^>."
+    text: "If the computed value of the 'color' property is undefined for a particular case (e.g. because the element is not in a Document), then the \"computed value of the 'color' property\" for the purposes of determining the computed value of the currentColor keyword is fully opaque black."
   - id: 2d.currentColor.gradient
-    text: "In the case of addColorStop() on CanvasGradient, the \"computed value of the 'color' property\" for the purposes of determining the computed value of the currentColor keyword is always fully opaque black<^> (there is no associated element)."
+    text: "In the case of addColorStop() on CanvasGradient, the \"computed value of the 'color' property\" for the purposes of determining the computed value of the currentColor keyword is always fully opaque black (there is no associated element)."
 
   - id: 2d.state.transformation
-    text: "The current transformation matrix<^>."
+    text: "The current transformation matrix."
   - id: 2d.state.clip
-    text: "The current clipping region<^>."
+    text: "The current clipping region."
   - meta: |
       for s in [
         'strokeStyle', 'fillStyle', 'globalAlpha',
@@ -102,623 +101,611 @@
       ]:
         assertions.append( {
           'id': '2d.state.%s' % s,
-          'text': 'The current values of the following attributes:<...>%s<^>' % s
+          'text': 'The current values of the following attributes:<...>%s' % s
         } )
   - id: 2d.state.path
-    text: "The current path<^> <...> are not part of the drawing state."
+    text: "The current path <...> are not part of the drawing state."
   - id: 2d.state.bitmap
-    text: "The <...> current bitmap<^> are not part of the drawing state."
+    text: "The <...> current bitmap are not part of the drawing state."
 
   - id: 2d.state.save
-    text: "The save() method *must* push a copy of the current drawing state onto the drawing state stack<^>."
+    text: "The save() method *must* push a copy of the current drawing state onto the drawing state stack."
   - id: 2d.state.restore
-    text: "The restore() method *must* pop the top entry in the drawing state stack, and reset the drawing state it describes<^>."
+    text: "The restore() method *must* pop the top entry in the drawing state stack, and reset the drawing state it describes."
   - id: 2d.state.restore.underflow
-    text: "If there is no saved state, the method *must* do nothing<^>."
+    text: "If there is no saved state, the method *must* do nothing."
 
   - id: 2d.transformation.initial
-    text: "When the context is created, the transformation matrix *must* initially be the identity transform<^>."
+    text: "When the context is created, the transformation matrix *must* initially be the identity transform."
   - id: 2d.transformation.order
-    text: "The transformations *must* be performed in reverse order<^>."
+    text: "The transformations *must* be performed in reverse order."
   - id: 2d.transformation.scale
-    text: "The scale(x, y) method *must* add the scaling transformation described by the arguments to the transformation matrix<^>."
+    text: "The scale(x, y) method *must* add the scaling transformation described by the arguments to the transformation matrix."
   - id: 2d.transformation.scale.multiple
-    text: "The factors are multiples<^>."
+    text: "The factors are multiples."
   - id: 2d.transformation.rotate
-    text: "The rotate(angle) method *must* add the rotation transformation described by the argument to the transformation matrix<^>."
+    text: "The rotate(angle) method *must* add the rotation transformation described by the argument to the transformation matrix."
   - id: 2d.transformation.rotate.direction
-    text: "The angle argument represents a clockwise rotation angle<^>"
+    text: "The angle argument represents a clockwise rotation angle"
   - id: 2d.transformation.rotate.radians
-    text: "The angle argument <...> expressed in radians<^>."
+    text: "The angle argument <...> expressed in radians."
   - id: 2d.transformation.translate
-    text: "The translate(x, y) method *must* add the translation transformation described by the arguments to the transformation matrix<^>."
+    text: "The translate(x, y) method *must* add the translation transformation described by the arguments to the transformation matrix."
   - id: 2d.transformation.transform
-    text: "The transform(a, b, c, d, e, f) method *must* replace the current transformation matrix with the result of multiplying the current transformation matrix with the matrix described by<^>:"
+    text: "The transform(a, b, c, d, e, f) method *must* replace the current transformation matrix with the result of multiplying the current transformation matrix with the matrix described by:"
   - id: 2d.transformation.transform.multiply
-    text: "The transform(a, b, c, d, e, f) method *must* replace the current transformation matrix with the result of multiplying<^> the current transformation matrix with the matrix described by:"
+    text: "The transform(a, b, c, d, e, f) method *must* replace the current transformation matrix with the result of multiplying the current transformation matrix with the matrix described by:"
   - id: 2d.transformation.setTransform
-    text: "The setTransform(a, b, c, d, e, f) method *must* <...> invoke the transform(a, b, c, d, e, f) method with the same arguments<^>"
+    text: "The setTransform(a, b, c, d, e, f) method *must* <...> invoke the transform(a, b, c, d, e, f) method with the same arguments"
   - id: 2d.transformation.setTransform.identity
-    text: "The setTransform(a, b, c, d, e, f) method *must* reset the current transform to the identity matrix<^>, "
+    text: "The setTransform(a, b, c, d, e, f) method *must* reset the current transform to the identity matrix, "
 
 
   - id: 2d.composite.operation
-    text: "All drawing operations are affected by the global compositing attributes, globalAlpha and globalCompositeOperation<^>."
+    text: "All drawing operations are affected by the global compositing attributes, globalAlpha and globalCompositeOperation."
 
   - id: 2d.composite.globalAlpha.shape
-    text: "The globalAlpha attribute gives an alpha value that is applied to shapes<^> and images before they are composited onto the canvas."
+    text: "The globalAlpha attribute gives an alpha value that is applied to shapes and images before they are composited onto the canvas."
   - id: 2d.composite.globalAlpha.image
-    text: "The globalAlpha attribute gives an alpha value that is applied to shapes and images<^> before they are composited onto the canvas."
+    text: "The globalAlpha attribute gives an alpha value that is applied to shapes and images before they are composited onto the canvas."
   - id: 2d.composite.globalAlpha.range
-    text: "The value must be in the range from 0.0 (fully transparent) to 1.0 (no additional transparency). If an attempt is made to set the attribute to a value outside this range, including Infinity and Not-a-Number (NaN) values, the attribute *must* retain its previous value<^>."
+    text: "The value must be in the range from 0.0 (fully transparent) to 1.0 (no additional transparency). If an attempt is made to set the attribute to a value outside this range, including Infinity and Not-a-Number (NaN) values, the attribute *must* retain its previous value."
   - id: 2d.composite.globalAlpha.default
-    text: "When the context is created, the globalAlpha attribute *must* initially have the value 1.0<^>."
+    text: "When the context is created, the globalAlpha attribute *must* initially have the value 1.0."
 
   - id: 2d.composite.operation.shape
-    text: "The globalCompositeOperation attribute sets how shapes<^> and images are drawn onto the existing bitmap,"
+    text: "The globalCompositeOperation attribute sets how shapes and images are drawn onto the existing bitmap,"
   - id: 2d.composite.operation.image
-    text: "The globalCompositeOperation attribute sets how shapes and images<^> are drawn onto the existing bitmap,"
+    text: "The globalCompositeOperation attribute sets how shapes and images are drawn onto the existing bitmap,"
 
   - id: 2d.composite.source-atop
-    text: "source-atop<^><eol>"
+    text: "source-atop"
   - id: 2d.composite.source-in
-    text: "source-in<^><eol>"
+    text: "source-in"
   - id: 2d.composite.source-out
-    text: "source-out<^><eol>"
+    text: "source-out"
   - id: 2d.composite.source-over
-    text: "source-over (default)<^><eol>"
+    text: "source-over (default)"
   - id: 2d.composite.destination-atop
-    text: "destination-atop<^><eol>"
+    text: "destination-atop"
   - id: 2d.composite.destination-in
-    text: "destination-in<^><eol>"
+    text: "destination-in"
   - id: 2d.composite.destination-out
-    text: "destination-out<^><eol>"
+    text: "destination-out"
   - id: 2d.composite.destination-over
-    text: "destination-over<^><eol>"
+    text: "destination-over"
   - id: 2d.composite.lighter
-    text: "lighter<^><eol>"
+    text: "lighter"
   - id: 2d.composite.copy
-    text: "copy<^><eol>"
+    text: "copy"
   - id: 2d.composite.xor
-    text: "xor<^><eol>"
+    text: "xor"
   - id: 2d.composite.clear
-    text: "clear<^><eol>"
+    text: "clear"
 
   - id: 2d.composite.operation.casesensitive
-    text: "These values are all case-sensitive<^> <...> they *must* be used exactly as shown."
+    text: "These values are all case-sensitive <...> they *must* be used exactly as shown."
   - id: 2d.composite.operation.exact
-    text: "User agents *must* not recognize values that are not a case-sensitive match for one of the values given above<^>."
+    text: "User agents *must* not recognize values that are not a case-sensitive match for one of the values given above."
   - id: 2d.composite.operation.porterduff
-    text: "The operators in the above list *must* be treated as described by the Porter-Duff operator given at the start of their description (e.g. A over B)<^>."
+    text: "The operators in the above list *must* be treated as described by the Porter-Duff operator given at the start of their description (e.g. A over B)."
   - id: 2d.composite.operation.unrecognised
-    text: "On setting, if the user agent does not recognize the specified value, it *must* be ignored, leaving the value of globalCompositeOperation unaffected<^>."
+    text: "On setting, if the user agent does not recognize the specified value, it *must* be ignored, leaving the value of globalCompositeOperation unaffected."
   - id: 2d.composite.operation.default
-    text: "When the context is created, the globalCompositeOperation attribute *must* initially have the value source-over<^>."
+    text: "When the context is created, the globalCompositeOperation attribute *must* initially have the value source-over."
 
 
   - id: 2d.colours.parse
-    text: "On setting, strings *must* be parsed as CSS <color> values and the color assigned<^>,"
+    text: "On setting, strings *must* be parsed as CSS <color> values and the color assigned,"
   - id: 2d.gradient.assign
-    text: "On setting, <...> CanvasGradient<^> and CanvasPattern objects *must* be assigned themselves."
+    text: "On setting, <...> CanvasGradient and CanvasPattern objects *must* be assigned themselves."
   - id: 2d.pattern.assign
-    text: "On setting, <...> CanvasGradient and CanvasPattern<^> objects *must* be assigned themselves."
+    text: "On setting, <...> CanvasGradient and CanvasPattern objects *must* be assigned themselves."
   - id: 2d.colours.invalidstring
-    text: "If the value is a string but cannot be parsed as a CSS <color> value<^>, <...> then it *must* be ignored, and the attribute must retain its previous value."
+    text: "If the value is a string but cannot be parsed as a CSS <color> value, <...> then it *must* be ignored, and the attribute must retain its previous value."
   - id: 2d.colours.invalidtype
-    text: "If the value is <...> neither a string, a CanvasGradient, nor a CanvasPattern<^>, then it *must* be ignored, and the attribute must retain its previous value."
+    text: "If the value is <...> neither a string, a CanvasGradient, nor a CanvasPattern, then it *must* be ignored, and the attribute must retain its previous value."
   - id: 2d.colours.getcolour
-    text: "On getting, if the value is a color, then the serialization of the color *must* be returned<^>."
+    text: "On getting, if the value is a color, then the serialization of the color *must* be returned."
   - id: 2d.gradient.object
-    text: "if it is not a color but a CanvasGradient<^> or CanvasPattern, then the respective object *must* be returned."
+    text: "if it is not a color but a CanvasGradient or CanvasPattern, then the respective object *must* be returned."
   - id: 2d.pattern.object
-    text: "if it is not a color but a CanvasGradient or CanvasPattern<^>, then the respective object *must* be returned."
+    text: "if it is not a color but a CanvasGradient or CanvasPattern, then the respective object *must* be returned."
   - id: 2d.serializecolour.solid
-    text: "if it has alpha equal to 1.0, then the string is a lowercase six-digit hex value<^>"
+    text: "if it has alpha equal to 1.0, then the string is a lowercase six-digit hex value"
   - id: 2d.serializecolour.transparent
-    text: "Otherwise, the color value has alpha less than 1.0, and the string is the color value in the CSS rgba() functional-notation format<^>:"
+    text: "Otherwise, the color value has alpha less than 1.0, and the string is the color value in the CSS rgba() functional-notation format:"
   - id: 2d.colours.default
-    text: "When the context is created, the strokeStyle and fillStyle attributes *must* initially have the string value #000000<^>."
+    text: "When the context is created, the strokeStyle and fillStyle attributes *must* initially have the string value #000000."
 
   - id: 2d.gradient.interpolate.linear
-    text: "Between each such stop, the colors and the alpha component *must* be linearly interpolated<^> over the RGBA space without premultiplying the alpha value to find the color to use at that offset."
+    text: "Between each such stop, the colors and the alpha component *must* be linearly interpolated over the RGBA space without premultiplying the alpha value to find the color to use at that offset."
   - id: 2d.gradient.interpolate.alpha
-    text: "Between each such stop, the colors and the alpha component *must* be linearly interpolated over the RGBA space without premultiplying the alpha value<^> to find the color to use at that offset."
+    text: "Between each such stop, the colors and the alpha component *must* be linearly interpolated over the RGBA space without premultiplying the alpha value to find the color to use at that offset."
   - id: 2d.gradient.outside.first
-    text: "Before the first stop, the color *must* be the color of the first stop<^>."
+    text: "Before the first stop, the color *must* be the color of the first stop."
   - id: 2d.gradient.outside.last
-    text: "After the last stop, the color *must* be the color of the last stop<^>."
+    text: "After the last stop, the color *must* be the color of the last stop."
   - id: 2d.gradient.empty
-    text: "When there are no stops, the gradient is transparent black<^>."
+    text: "When there are no stops, the gradient is transparent black."
 
 
   - id: 2d.gradient.invalidoffset
-    text: "If the offset is less than 0, greater than 1, infinite, or NaN, then an INDEX_SIZE_ERR exception *must* be raised<^>."
+    text: "If the offset is less than 0, greater than 1, infinite, or NaN, then an INDEX_SIZE_ERR exception *must* be raised."
   - id: 2d.gradient.invalidcolour
-    text: "If the color cannot be parsed as a CSS <color> value, then a SYNTAX_ERR exception *must* be raised<^>."
+    text: "If the color cannot be parsed as a CSS <color> value, then a SYNTAX_ERR exception *must* be raised."
   - id: 2d.gradient.update
-    text: "Otherwise, the gradient *must* have a new stop placed, at offset offset relative to the whole gradient, and with the color obtained by parsing color as a CSS <color> value<^>."
+    text: "Otherwise, the gradient *must* have a new stop placed, at offset offset relative to the whole gradient, and with the color obtained by parsing color as a CSS <color> value."
   - id: 2d.gradient.interpolate.overlap
-    text: "If multiple stops are added at the same offset on a gradient, they *must* be placed in the order added, with the first one closest to the start of the gradient, <...><^>."
+    text: "If multiple stops are added at the same offset on a gradient, they *must* be placed in the order added, with the first one closest to the start of the gradient, <...>."
 
   - id: 2d.gradient.linear.nonfinite
-    text: "If any of the arguments to createLinearGradient() are infinite or NaN, the method *must* raise a NOT_SUPPORTED_ERR exception<^>."
+    text: "If any of the arguments to createLinearGradient() are infinite or NaN, the method *must* raise a NOT_SUPPORTED_ERR exception."
   - id: 2d.gradient.linear.return
-    text: "Otherwise, the method *must* return a linear CanvasGradient initialized with the specified line<^>."
+    text: "Otherwise, the method *must* return a linear CanvasGradient initialized with the specified line."
   - id: 2d.gradient.linear.rendering
-    text: "Linear gradients *must* be rendered such that all points on a line perpendicular to the line that crosses the start and end points have the color at the point where those two lines cross (with the colors coming from the interpolation and extrapolation described above)<^>."
+    text: "Linear gradients *must* be rendered such that all points on a line perpendicular to the line that crosses the start and end points have the color at the point where those two lines cross (with the colors coming from the interpolation and extrapolation described above)."
   - id: 2d.gradient.linear.transform
-    text: "The points in the linear gradient *must* be transformed as described by the current transformation matrix when rendering<^>."
+    text: "The points in the linear gradient *must* be transformed as described by the current transformation matrix when rendering."
   - id: 2d.gradient.linear.zerosize
-    text: "If x0 = x1 and y0 = y1, then the linear gradient *must* paint nothing<^>."
+    text: "If x0 = x1 and y0 = y1, then the linear gradient *must* paint nothing."
 
   - id: 2d.gradient.radial.nonfinite
-    text: "If any of the arguments are infinite or NaN, a NOT_SUPPORTED_ERR exception *must* be raised<^>."
+    text: "If any of the arguments are infinite or NaN, a NOT_SUPPORTED_ERR exception *must* be raised."
   - id: 2d.gradient.radial.negative
-    text: "If either of r0 or r1 are negative, an INDEX_SIZE_ERR exception *must* be raised<^>."
+    text: "If either of r0 or r1 are negative, an INDEX_SIZE_ERR exception *must* be raised."
   - id: 2d.gradient.radial.return
-    text: "Otherwise, the method *must* return a radial CanvasGradient initialized with the two specified circles<^>."
+    text: "Otherwise, the method *must* return a radial CanvasGradient initialized with the two specified circles."
   - id: 2d.gradient.radial.rendering
-    text: "Radial gradients *must* be rendered by following these steps<^>:"
+    text: "Radial gradients *must* be rendered by following these steps:"
   - id: 2d.gradient.radial.equal
-    text: "If x0 = x1 and y0 = y1 and r0 = r1, then the radial gradient *must* paint nothing<^>."
+    text: "If x0 = x1 and y0 = y1 and r0 = r1, then the radial gradient *must* paint nothing."
   - id: 2d.gradient.extent
-    text: "Gradients *must* be painted only where the relevant stroking or filling effects requires that they be drawn<^>."
+    text: "Gradients *must* be painted only where the relevant stroking or filling effects requires that they be drawn."
   - id: 2d.gradient.radial.transform
-    text: "The points in the radial gradient *must* be transformed as described by the current transformation matrix when rendering<^>."
+    text: "The points in the radial gradient *must* be transformed as described by the current transformation matrix when rendering."
 
 
   - id: 2d.pattern.modify
-    text: "Modifying this image after calling the createPattern() method *must* not affect the pattern<^>."
+    text: "Modifying this image after calling the createPattern() method *must* not affect the pattern."
   - id: 2d.pattern.transform
     text: "The setTransform(transform) method, when invoked, must run these steps:"
   - id: 2d.pattern.missing
-    text: "If the empty string is specified, repeat *must* be assumed<^>."
+    text: "If the empty string is specified, repeat *must* be assumed."
   - id: 2d.pattern.unrecognised
-    text: "If an unrecognized value is given, then the user agent *must* raise a SYNTAX_ERR exception<^>."
+    text: "If an unrecognized value is given, then the user agent *must* raise a SYNTAX_ERR exception."
   - id: 2d.pattern.exact
-    text: "User agents *must* recognize the four values described above exactly (e.g. they must not do case folding)<^>."
+    text: "User agents *must* recognize the four values described above exactly (e.g. they must not do case folding)."
   - id: 2d.pattern.return
-    text: "the method *must* return a CanvasPattern object suitably initialized<^>."
+    text: "the method *must* return a CanvasPattern object suitably initialized."
   - id: 2d.pattern.IDL
-    text: "CanvasPattern createPattern(in HTMLImageElement image, in DOMString repetition);<...>CanvasPattern createPattern(in HTMLCanvasElement image, in DOMString repetition);<...>CanvasPattern createPattern(in HTMLVideoElement image, in DOMString repetition);<^>"
+    text: "CanvasPattern createPattern(in HTMLImageElement image, in DOMString repetition);<...>CanvasPattern createPattern(in HTMLCanvasElement image, in DOMString repetition);<...>CanvasPattern createPattern(in HTMLVideoElement image, in DOMString repetition);"
   - id: 2d.pattern.incomplete.image
-    text: "If the image argument is an HTMLImageElement object that is not fully decodable<^><...> then the implementation *must* return null."
+    text: "If the image argument is an HTMLImageElement object that is not fully decodable<...> then the implementation *must* return null."
   - id: 2d.pattern.incomplete.video
-    previously: [ 6, "createPattern" ]
-    text: "If the image argument is <...> an HTMLVideoElement object whose readyState attribute is either HAVE_NOTHING or HAVE_METADATA<^>, then the implementation *must* return null."
+    text: "If the image argument is <...> an HTMLVideoElement object whose readyState attribute is either HAVE_NOTHING or HAVE_METADATA, then the implementation *must* return null."
   - id: 2d.pattern.zerocanvas
-    previously: [ 10, "createPattern" ]
-    text: "If the image argument is an HTMLCanvasElement object with either a horizontal dimension or a vertical dimension equal to zero, then the implementation *must* raise an INVALID_STATE_ERR exception<^>."
+    text: "If the image argument is an HTMLCanvasElement object with either a horizontal dimension or a vertical dimension equal to zero, then the implementation *must* raise an INVALID_STATE_ERR exception."
   - id: 2d.pattern.painting
-    text: "Patterns *must* be painted so that the top left of the first image is anchored at the origin of the coordinate space, and images are then repeated horizontally to the left and right (if the repeat-x string was specified) or vertically up and down (if the repeat-y string was specified) or in all four directions all over the canvas (if the repeat string was specified)<^>."
+    text: "Patterns *must* be painted so that the top left of the first image is anchored at the origin of the coordinate space, and images are then repeated horizontally to the left and right (if the repeat-x string was specified) or vertically up and down (if the repeat-y string was specified) or in all four directions all over the canvas (if the repeat string was specified)."
   - id: 2d.pattern.unscaled
-    text: "The images are not scaled by this process; one CSS pixel of the image *must* be painted on one coordinate space unit<^>."
+    text: "The images are not scaled by this process; one CSS pixel of the image *must* be painted on one coordinate space unit."
   - id: 2d.pattern.extent
-    text: "patterns *must* actually be painted only where the stroking or filling effect requires that they be drawn<^>, and are affected by the current transformation matrix."
+    text: "patterns *must* actually be painted only where the stroking or filling effect requires that they be drawn, and are affected by the current transformation matrix."
   - id: 2d.pattern.animated.image
-    text: "When the createPattern() method is passed an animated image as its image argument, the user agent must use the poster frame of the animation, or, if there is no poster frame, the first frame of the animation<^>."
+    text: "When the createPattern() method is passed an animated image as its image argument, the user agent must use the poster frame of the animation, or, if there is no poster frame, the first frame of the animation."
   - id: 2d.pattern.animated.video
-    previously: [ 4, "createPattern" ]
-    text: "When the image argument is an HTMLVideoElement, then the frame at the current playback position *must* be used as the source image<^>,"
+    text: "When the image argument is an HTMLVideoElement, then the frame at the current playback position *must* be used as the source image,"
   - id: 2d.pattern.video.size
-    previously: [ 4, "createPattern" ]
-    text: "When the image argument is an HTMLVideoElement, <...> the source image's dimensions *must* be the intrinsic width and intrinsic height of the media resource (i.e. after any aspect-ratio correction has been applied)<^>."
+    text: "When the image argument is an HTMLVideoElement, <...> the source image's dimensions *must* be the intrinsic width and intrinsic height of the media resource (i.e. after any aspect-ratio correction has been applied)."
 
 
   - id: 2d.lineWidth
-    text: "The lineWidth attribute gives the width of lines, in coordinate space units<^>."
+    text: "The lineWidth attribute gives the width of lines, in coordinate space units."
   - id: 2d.lineWidth.get
-    text: "The lineWidth attribute <...>. On getting, it *must* return the current value<^>."
+    text: "The lineWidth attribute <...>. On getting, it *must* return the current value."
   - id: 2d.lineWidth.invalid
-    text: "The lineWidth attribute <...>. On setting, zero, negative, infinite, and NaN values *must* be ignored, leaving the value unchanged<^>;"
+    text: "The lineWidth attribute <...>. On setting, zero, negative, infinite, and NaN values *must* be ignored, leaving the value unchanged;"
   - id: 2d.lineWidth.set
-    text: "The lineWidth attribute <...>. On setting, <...> other values *must* change the current value to the new value<^>."
+    text: "The lineWidth attribute <...>. On setting, <...> other values *must* change the current value to the new value."
   - id: 2d.lineWidth.default
-    text: "the lineWidth attribute *must* initially have the value 1.0<^>."
+    text: "the lineWidth attribute *must* initially have the value 1.0."
   - id: 2d.lineCap.end
-    text: "The lineCap attribute defines the type of endings that UAs will place on the end of lines<^>."
+    text: "The lineCap attribute defines the type of endings that UAs will place on the end of lines."
   - id: 2d.lineCap.butt
-    text: "The butt value means that the end of each line has a flat edge perpendicular to the direction of the line (and that no additional line cap is added)<^>."
+    text: "The butt value means that the end of each line has a flat edge perpendicular to the direction of the line (and that no additional line cap is added)."
   - id: 2d.lineCap.round
-    text: "The round value means that a semi-circle with the diameter equal to the width of the line *must* then be added on to the end of the line<^>."
+    text: "The round value means that a semi-circle with the diameter equal to the width of the line *must* then be added on to the end of the line."
   - id: 2d.lineCap.square
-    text: "The square value means that a rectangle with the length of the line width and the width of half the line width, placed flat against the edge perpendicular to the direction of the line, *must* be added at the end of each line<^>."
+    text: "The square value means that a rectangle with the length of the line width and the width of half the line width, placed flat against the edge perpendicular to the direction of the line, *must* be added at the end of each line."
   - id: 2d.lineCap.get
-    previously: [ 2, "The lineCap attribute" ]
-    text: "On getting, it *must* return the current value<^>."
+    text: "On getting, it *must* return the current value."
   - id: 2d.lineCap.set
-    text: "On setting, if the new value is one of the literal strings butt, round, and square, then the current value *must* be changed to the new value<^>;"
+    text: "On setting, if the new value is one of the literal strings butt, round, and square, then the current value *must* be changed to the new value;"
   - id: 2d.lineCap.invalid
-    text: "On setting, if the new value is one of the literal strings butt, round, and square, then <...>; other values *must* ignored, leaving the value unchanged<^>."
+    text: "On setting, if the new value is one of the literal strings butt, round, and square, then <...>; other values *must* ignored, leaving the value unchanged."
   - id: 2d.lineCap.default
-    text: "When the context is created, the lineCap attribute *must* initially have the value butt<^>."
+    text: "When the context is created, the lineCap attribute *must* initially have the value butt."
   - id: 2d.lineJoin.get
-    previously: [ 2, "lineJoin" ]
-    text: "On getting, it *must* return the current value<^>."
+    text: "On getting, it *must* return the current value."
   - id: 2d.lineJoin.set
-    text: "On setting, if the new value is one of the literal strings bevel, round, and miter, then the current value *must* be changed to the new value<^>;"
+    text: "On setting, if the new value is one of the literal strings bevel, round, and miter, then the current value *must* be changed to the new value;"
   - id: 2d.lineJoin.invalid
-    text: "On setting, if the new value is one of the literal strings bevel, round, and miter, then <...>; other values *must* be ignored, leaving the value unchanged<^>."
+    text: "On setting, if the new value is one of the literal strings bevel, round, and miter, then <...>; other values *must* be ignored, leaving the value unchanged."
   - id: 2d.lineJoin.default
-    text: "When the context is created, the lineJoin attribute *must* initially have the value miter<^>."
+    text: "When the context is created, the lineJoin attribute *must* initially have the value miter."
   - id: 2d.lineJoin.joins
-    text: "A join exists at any point in a subpath shared by two consecutive lines<^>."
+    text: "A join exists at any point in a subpath shared by two consecutive lines."
   - id: 2d.lineJoin.joinclosed
-    text: "When a subpath is closed, then a join also exists at its first point (equivalent to its last point) connecting the first and last lines in the subpath<^>."
+    text: "When a subpath is closed, then a join also exists at its first point (equivalent to its last point) connecting the first and last lines in the subpath."
   - id: 2d.lineJoin.common
-    text: "A filled triangle connecting these two opposite corners with a straight line, with the third point of the triangle being the join point, *must* be rendered at all joins<^>."
+    text: "A filled triangle connecting these two opposite corners with a straight line, with the third point of the triangle being the join point, *must* be rendered at all joins."
   - id: 2d.lineJoin.round
-    text: "The round value means that a filled arc connecting the two aforementioned corners of the join, abutting (and not overlapping) the aforementioned triangle, with the diameter equal to the line width and the origin at the point of the join, *must* be rendered at joins<^>."
+    text: "The round value means that a filled arc connecting the two aforementioned corners of the join, abutting (and not overlapping) the aforementioned triangle, with the diameter equal to the line width and the origin at the point of the join, *must* be rendered at joins."
   - id: 2d.lineJoin.bevel
-    text: "The bevel value means that this is all that is rendered at joins<^>."
+    text: "The bevel value means that this is all that is rendered at joins."
   - id: 2d.lineJoin.miter
-    text: "The miter value means that a second filled triangle *must* (if it can given the miter length) be rendered at the join, with one line being the line between the two aforementioned corners, abutting the first triangle, and the other two being continuations of the outside edges of the two joining lines, as long as required to intersect without going over the miter length<^>."
+    text: "The miter value means that a second filled triangle *must* (if it can given the miter length) be rendered at the join, with one line being the line between the two aforementioned corners, abutting the first triangle, and the other two being continuations of the outside edges of the two joining lines, as long as required to intersect without going over the miter length."
   - id: 2d.lineJoin.miterLimit
-    text: "If the miter length would cause the miter limit ratio to be exceeded, this second triangle *must* not be rendered<^>."
+    text: "If the miter length would cause the miter limit ratio to be exceeded, this second triangle *must* not be rendered."
   - id: 2d.miterLimit.get
-    text: "The miter limit <...>. On getting, it *must* return the current value<^>."
+    text: "The miter limit <...>. On getting, it *must* return the current value."
   - id: 2d.miterLimit.invalid
-    text: "The miter limit <...>. On setting, zero, negative, infinite, and NaN values *must* be ignored, leaving the value unchanged<^>;"
+    text: "The miter limit <...>. On setting, zero, negative, infinite, and NaN values *must* be ignored, leaving the value unchanged;"
   - id: 2d.miterLimit.set
-    text: "The miter limit <...>. On setting, <...>; other values *must* change the current value to the new value<^>."
+    text: "The miter limit <...>. On setting, <...>; other values *must* change the current value to the new value."
   - id: 2d.miterLimit.default
-    text: "When the context is created, the miterLimit attribute *must* initially have the value 10.0<^>."
+    text: "When the context is created, the miterLimit attribute *must* initially have the value 10.0."
 
 
   - id: 2d.shadow.color.initial
-    text: "When the context is created, the shadowColor attribute initially *must* be fully-transparent black<^>."
+    text: "When the context is created, the shadowColor attribute initially *must* be fully-transparent black."
   - id: 2d.shadow.color.get
-    text: "On getting, the serialization of the color *must* be returned<^>."
+    text: "On getting, the serialization of the color *must* be returned."
   - id: 2d.shadow.color.set
-    text: "On setting, the new value *must* be parsed as a CSS <color> value and the color assigned<^>."
+    text: "On setting, the new value *must* be parsed as a CSS <color> value and the color assigned."
   - id: 2d.shadow.color.invalid
-    text: "If the value cannot be parsed as a CSS <color> value then it *must* be ignored, and the attribute must retain its previous value<^>."
+    text: "If the value cannot be parsed as a CSS <color> value then it *must* be ignored, and the attribute must retain its previous value."
   - id: 2d.shadow.offset.initial
-    text: "When the context is created, the shadow offset attributes *must* initially have the value 0<^>."
+    text: "When the context is created, the shadow offset attributes *must* initially have the value 0."
   - id: 2d.shadow.offset.get
-    text: "On getting, they *must* return their current value<^>."
+    text: "On getting, they *must* return their current value."
   - id: 2d.shadow.offset.set
-    text: "On setting, the attribute being set *must* be set to the new value<^>,"
+    text: "On setting, the attribute being set *must* be set to the new value,"
   - id: 2d.shadow.offset.invalid
-    text: "On setting, <...> if the value is infinite or NaN, in which case the new value *must* be ignored<^>."
+    text: "On setting, <...> if the value is infinite or NaN, in which case the new value *must* be ignored."
   - id: 2d.shadow.blur.initial
-    text: "When the context is created, the shadowBlur attribute *must* initially have the value 0<^>."
+    text: "When the context is created, the shadowBlur attribute *must* initially have the value 0."
   - id: 2d.shadow.blur.get
-    text: "On getting, the attribute *must* return its current value<^>."
+    text: "On getting, the attribute *must* return its current value."
   - id: 2d.shadow.blur.set
-    text: "On setting the attribute *must* be set to the new value<^>,"
+    text: "On setting the attribute *must* be set to the new value,"
   - id: 2d.shadow.blur.invalid
-    text: "On setting <...> if the value is negative, infinite or NaN, in which case the new value *must* be ignored<^>."
+    text: "On setting <...> if the value is negative, infinite or NaN, in which case the new value *must* be ignored."
   - id: 2d.shadow.enable
-    text: "Shadows are only drawn if the opacity component of the alpha component of the color of shadowColor is non-zero and either the shadowBlur is non-zero, or the shadowOffsetX is non-zero, or the shadowOffsetY is non-zero<^>."
+    text: "Shadows are only drawn if the opacity component of the alpha component of the color of shadowColor is non-zero and either the shadowBlur is non-zero, or the shadowOffsetX is non-zero, or the shadowOffsetY is non-zero."
   - id: 2d.shadow.render
-    text: "When shadows are drawn, they *must* be rendered as follows<^>:"
+    text: "When shadows are drawn, they *must* be rendered as follows:"
 
   - id: 2d.rect.transform
-    text: "The current transformation matrix *must* be applied to the following four coordinates<^>,"
+    text: "The current transformation matrix *must* be applied to the following four coordinates,"
   - id: 2d.rect.closed
-    text: "the following four coordinates, which form the path that *must* then be closed to get the specified rectangle<^>:"
+    text: "the following four coordinates, which form the path that *must* then be closed to get the specified rectangle:"
   - id: 2d.clearRect
-    text: "The clearRect(x, y, w, h) method *must* clear the pixels in the specified rectangle that also intersect the current clipping region to a fully transparent black, erasing any previous image<^>."
+    text: "The clearRect(x, y, w, h) method *must* clear the pixels in the specified rectangle that also intersect the current clipping region to a fully transparent black, erasing any previous image."
   - id: 2d.fillRect
-    text: "The fillRect(x, y, w, h) method *must* paint the specified rectangular area using the fillStyle<^>."
+    text: "The fillRect(x, y, w, h) method *must* paint the specified rectangular area using the fillStyle."
   - id: 2d.strokeRect
-    text: "The strokeRect(x, y, w, h) method *must* stroke the specified rectangle's path using the strokeStyle, lineWidth, lineJoin, and (if appropriate) miterLimit attributes<^>."
+    text: "The strokeRect(x, y, w, h) method *must* stroke the specified rectangle's path using the strokeStyle, lineWidth, lineJoin, and (if appropriate) miterLimit attributes."
 
 
   - id: 2d.path.initial
-    text: "Initially, the context's path *must* have zero subpaths<^>."
+    text: "Initially, the context's path *must* have zero subpaths."
   - id: 2d.path.transformation
-    text: "The points and lines added to the path by these methods *must* be transformed according to the current transformation matrix as they are added<^>."
+    text: "The points and lines added to the path by these methods *must* be transformed according to the current transformation matrix as they are added."
   - id: 2d.path.beginPath
-    text: "The beginPath() method *must* empty the list of subpaths so that the context once again has zero subpaths<^>."
+    text: "The beginPath() method *must* empty the list of subpaths so that the context once again has zero subpaths."
   - id: 2d.path.moveTo
-    text: "The moveTo(x, y) method *must* create a new subpath with the specified point as its first (and only) point<^>."
+    text: "The moveTo(x, y) method *must* create a new subpath with the specified point as its first (and only) point."
   - id: 2d.path.ensure
-    text: "When the user agent is to ensure there is a subpath for a coordinate (x, y), the user agent must check to see if the context has any subpaths, and if it does not, then the user agent *must* create a new subpath with the point (x, y) as its first (and only) point, as if the moveTo() method had been called<^>."
+    text: "When the user agent is to ensure there is a subpath for a coordinate (x, y), the user agent must check to see if the context has any subpaths, and if it does not, then the user agent *must* create a new subpath with the point (x, y) as its first (and only) point, as if the moveTo() method had been called."
   - id: 2d.path.closePath.empty
-    text: "The closePath() method *must* do nothing if the context has no subpaths<^>."
+    text: "The closePath() method *must* do nothing if the context has no subpaths."
   - id: 2d.path.closePath.nonempty
-    text: "The closePath() method <...> *must* mark the last subpath as closed, create a new subpath whose first point is the same as the previous subpath's first point, and finally add this new subpath to the path<^>."
+    text: "The closePath() method <...> *must* mark the last subpath as closed, create a new subpath whose first point is the same as the previous subpath's first point, and finally add this new subpath to the path."
   - id: 2d.path.lineTo.empty
-    text: "The lineTo(x, y) method *must* ensure there is a subpath for (x, y) if the context has no subpaths<^>."
+    text: "The lineTo(x, y) method *must* ensure there is a subpath for (x, y) if the context has no subpaths."
   - id: 2d.path.lineTo.nonempty
-    text: "The lineTo(x, y) method <...> *must* connect the last point in the subpath to the given point (x, y) using a straight line, and must then add the given point (x, y) to the subpath<^>."
+    text: "The lineTo(x, y) method <...> *must* connect the last point in the subpath to the given point (x, y) using a straight line, and must then add the given point (x, y) to the subpath."
   - id: 2d.path.quadratic.empty
-    text: "The quadraticCurveTo(cpx, cpy, x, y) method *must* ensure there is a subpath for (cpx, cpy)<^>,"
+    text: "The quadraticCurveTo(cpx, cpy, x, y) method *must* ensure there is a subpath for (cpx, cpy),"
   - id: 2d.path.quadratic.nonempty
-    text: "The quadraticCurveTo(cpx, cpy, x, y) method <...> *must* connect the last point in the subpath to the given point (x, y) using a quadratic B<...>zier curve with control point (cpx, cpy), and must then add the given point (x, y) to the subpath<^>."
+    text: "The quadraticCurveTo(cpx, cpy, x, y) method <...> *must* connect the last point in the subpath to the given point (x, y) using a quadratic B<...>zier curve with control point (cpx, cpy), and must then add the given point (x, y) to the subpath."
   - id: 2d.path.bezier.empty
-    text: "The bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y) method *must* ensure there is a subpath for (cp1x, cp1y)<^>,"
+    text: "The bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y) method *must* ensure there is a subpath for (cp1x, cp1y),"
   - id: 2d.path.bezier.nonempty
-    text: "The bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y) method <...> *must* connect the last point in the subpath to the given point (x, y) using a cubic B<...>zier curve with control points (cp1x, cp1y) and (cp2x, cp2y). Then, it must add the point (x, y) to the subpath<^>."
+    text: "The bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y) method <...> *must* connect the last point in the subpath to the given point (x, y) using a cubic B<...>zier curve with control points (cp1x, cp1y) and (cp2x, cp2y). Then, it must add the point (x, y) to the subpath."
   - id: 2d.path.arcTo.empty
-    text: "The arcTo(x1, y1, x2, y2, radius) method *must* first ensure there is a subpath for (x1, y1)<^>."
+    text: "The arcTo(x1, y1, x2, y2, radius) method *must* first ensure there is a subpath for (x1, y1)."
   - id: 2d.path.arcTo.negative
-    previously: [ 2, "arcTo(" ]
-    text: "Negative values for radius *must* cause the implementation to raise an INDEX_SIZE_ERR exception<^>."
+    text: "Negative values for radius *must* cause the implementation to raise an INDEX_SIZE_ERR exception."
   - id: 2d.path.arcTo.coincide.01
-    text: "If the point (x0, y0) is equal to the point (x1, y1)<^>, or if the point (x1, y1) is equal to the point (x2, y2), or if the radius radius is zero, then the method *must* add the point (x1, y1) to the subpath, and connect that point to the previous point (x0, y0) by a straight line."
+    text: "If the point (x0, y0) is equal to the point (x1, y1), or if the point (x1, y1) is equal to the point (x2, y2), or if the radius radius is zero, then the method *must* add the point (x1, y1) to the subpath, and connect that point to the previous point (x0, y0) by a straight line."
   - id: 2d.path.arcTo.coincide.12
-    text: "If the point (x0, y0) is equal to the point (x1, y1), or if the point (x1, y1) is equal to the point (x2, y2)<^>, or if the radius radius is zero, then the method *must* add the point (x1, y1) to the subpath, and connect that point to the previous point (x0, y0) by a straight line."
+    text: "If the point (x0, y0) is equal to the point (x1, y1), or if the point (x1, y1) is equal to the point (x2, y2), or if the radius radius is zero, then the method *must* add the point (x1, y1) to the subpath, and connect that point to the previous point (x0, y0) by a straight line."
   - id: 2d.path.arcTo.zeroradius
-    text: "If the point (x0, y0) is equal to the point (x1, y1), or if the point (x1, y1) is equal to the point (x2, y2), or if the radius radius is zero<^>, then the method *must* add the point (x1, y1) to the subpath, and connect that point to the previous point (x0, y0) by a straight line."
+    text: "If the point (x0, y0) is equal to the point (x1, y1), or if the point (x1, y1) is equal to the point (x2, y2), or if the radius radius is zero, then the method *must* add the point (x1, y1) to the subpath, and connect that point to the previous point (x0, y0) by a straight line."
   - id: 2d.path.arcTo.collinear
-    text: "if the points (x0, y0), (x1, y1), and (x2, y2) all lie on a single straight line, then the method *must* add the point (x1, y1) to the subpath, and connect that point to the previous point (x0, y0) by a straight line<^>."
+    text: "if the points (x0, y0), (x1, y1), and (x2, y2) all lie on a single straight line, then the method *must* add the point (x1, y1) to the subpath, and connect that point to the previous point (x0, y0) by a straight line."
   - id: 2d.path.arcTo.shape
-    text: "The method *must* connect the point (x0, y0) to the start tangent point by a straight line, adding the start tangent point to the subpath, and then must connect the start tangent point to the end tangent point by The Arc, adding the end tangent point to the subpath<^>."
+    text: "The method *must* connect the point (x0, y0) to the start tangent point by a straight line, adding the start tangent point to the subpath, and then must connect the start tangent point to the end tangent point by The Arc, adding the end tangent point to the subpath."
 
   - id: 2d.path.arc.nonempty
-    text: "If the context has any subpaths, then the method *must* add a straight line from the last point in the subpath to the start point of the arc<^>."
+    text: "If the context has any subpaths, then the method *must* add a straight line from the last point in the subpath to the start point of the arc."
   - id: 2d.path.arc.draw
-    text: "it *must* draw the arc between the start point of the arc and the end point of the arc, and add the start and end points of the arc to the subpath<^>."
+    text: "it *must* draw the arc between the start point of the arc and the end point of the arc, and add the start and end points of the arc to the subpath."
   - id: 2d.path.arc.zero
-    text: "If the two points are the same, or if the radius is zero<^>, then the arc is defined as being of zero length in both directions."
+    text: "If the two points are the same, or if the radius is zero, then the arc is defined as being of zero length in both directions."
   - id: 2d.path.arc.negative
-    previously: [ 2, "anticlockwise" ]
-    text: "Negative values for radius *must* cause the implementation to raise an INDEX_SIZE_ERR exception<^>."
+    text: "Negative values for radius *must* cause the implementation to raise an INDEX_SIZE_ERR exception."
 
   - id: 2d.path.rect.subpath
-    text: "The rect(x, y, w, h) method *must* create a new subpath containing just the four points (x, y), (x+w, y), (x+w, y+h), (x, y+h), with those four points connected by straight lines<^>"
+    text: "The rect(x, y, w, h) method *must* create a new subpath containing just the four points (x, y), (x+w, y), (x+w, y+h), (x, y+h), with those four points connected by straight lines"
   - id: 2d.path.rect.closed
-    text: "The rect(x, y, w, h) method <...> *must* then mark the subpath as closed<^>."
+    text: "The rect(x, y, w, h) method <...> *must* then mark the subpath as closed."
   - id: 2d.path.rect.newsubpath
-    text: "The rect(x, y, w, h) method <...> *must* then create a new subpath with the point (x, y) as the only point in the subpath<^>."
+    text: "The rect(x, y, w, h) method <...> *must* then create a new subpath with the point (x, y) as the only point in the subpath."
 
   - id: 2d.path.fill.basic
-    text: "The fill() method *must* fill all the subpaths of the current path, using fillStyle, and using the non-zero winding number rule<^>."
+    text: "The fill() method *must* fill all the subpaths of the current path, using fillStyle, and using the non-zero winding number rule."
   - id: 2d.path.fill.closed
-    text: "Open subpaths *must* be implicitly closed when being filled (without affecting the actual subpaths)<^>."
+    text: "Open subpaths *must* be implicitly closed when being filled (without affecting the actual subpaths)."
   - id: 2d.path.stroke.basic
-    text: "The stroke() method *must* calculate the strokes of all the subpaths of the current path, using the lineWidth, lineCap, lineJoin, and (if appropriate) miterLimit attributes, and then fill the combined stroke area using the strokeStyle attribute<^>."
+    text: "The stroke() method *must* calculate the strokes of all the subpaths of the current path, using the lineWidth, lineCap, lineJoin, and (if appropriate) miterLimit attributes, and then fill the combined stroke area using the strokeStyle attribute."
   - id: 2d.path.unaffected
-    text: "Paths, when filled or stroked, *must* be painted without affecting the current path<^>"
+    text: "Paths, when filled or stroked, *must* be painted without affecting the current path"
   - id: 2d.path.subjected
-    text: "Paths, when filled or stroked, <...> *must* be subject to shadow effects, global alpha, the clipping region, and global composition operators<^>."
+    text: "Paths, when filled or stroked, <...> *must* be subject to shadow effects, global alpha, the clipping region, and global composition operators."
 
   - id: 2d.path.stroke.prune
-    text: "Zero-length line segments *must* be pruned before stroking a path<^>."
+    text: "Zero-length line segments *must* be pruned before stroking a path."
   - id: 2d.path.stroke.empty
-    text: "Empty subpaths *must* be ignored<^>."
+    text: "Empty subpaths *must* be ignored."
 
   - id: 2d.path.clip.basic
-    text: "The clip() method *must* create a new clipping region by calculating the intersection of the current clipping region and the area described by the current path, using the non-zero winding number rule<^>."
+    text: "The clip() method *must* create a new clipping region by calculating the intersection of the current clipping region and the area described by the current path, using the non-zero winding number rule."
   - id: 2d.path.clip.closed
-    text: "Open subpaths *must* be implicitly closed when computing the clipping region, without affecting the actual subpaths<^>."
+    text: "Open subpaths *must* be implicitly closed when computing the clipping region, without affecting the actual subpaths."
   - id: 2d.path.clip.initial
-    text: "When the context is initialized, the clipping region *must* be set to the rectangle with the top left corner at (0,0) and the width and height of the coordinate space<^>."
+    text: "When the context is initialized, the clipping region *must* be set to the rectangle with the top left corner at (0,0) and the width and height of the coordinate space."
   - id: 2d.path.isPointInPath
-    text: "The isPointInPath(x, y) method *must* return true if the point given by the x and y coordinates passed to the method, when treated as coordinates in the canvas coordinate space unaffected by the current transformation, is inside the current path as determined by the non-zero winding number rule; and must return false otherwise<^>."
+    text: "The isPointInPath(x, y) method *must* return true if the point given by the x and y coordinates passed to the method, when treated as coordinates in the canvas coordinate space unaffected by the current transformation, is inside the current path as determined by the non-zero winding number rule; and must return false otherwise."
   - id: 2d.path.isPointInPath.edge
-    text: "The isPointInPath(x, y) method *must* return true if <...>. Points on the path itself are considered to be inside the path<^>."
+    text: "The isPointInPath(x, y) method *must* return true if <...>. Points on the path itself are considered to be inside the path."
   - id: 2d.path.isPointInPath.nonfinite
-    text: "If either of the arguments is infinite or NaN, then the method *must* return false<^>."
+    text: "If either of the arguments is infinite or NaN, then the method *must* return false."
 
   # TODO: Focus management
 
   - id: 2d.text.font.parse
-    text: "The font IDL attribute, on setting, *must* be parsed the same way as the 'font' property of CSS (but without supporting property-independent style sheet syntax like 'inherit')<^>,"
+    text: "The font IDL attribute, on setting, *must* be parsed the same way as the 'font' property of CSS (but without supporting property-independent style sheet syntax like 'inherit'),"
   - id: 2d.text.font.lineheight
-    text: "The font IDL attribute, on setting, *must* be parsed <...> with the 'line-height' component forced to 'normal'<^>,"
+    text: "The font IDL attribute, on setting, *must* be parsed <...> with the 'line-height' component forced to 'normal',"
   - id: 2d.text.font.fontsize
-    text: "The font IDL attribute, on setting, *must* be parsed <...> with the 'font-size' component converted to CSS pixels<^>,"
+    text: "The font IDL attribute, on setting, *must* be parsed <...> with the 'font-size' component converted to CSS pixels,"
   - id: 2d.text.font.systemfonts
-    text: "The font IDL attribute, on setting, *must* be parsed <...> with system fonts being computed to explicit values<^>."
+    text: "The font IDL attribute, on setting, *must* be parsed <...> with system fonts being computed to explicit values."
   - id: 2d.text.font.invalid
-    text: "If the new value is syntactically incorrect (including using property-independent style sheet syntax like 'inherit' or 'initial'), then it *must* be ignored, without assigning a new font value<^>."
+    text: "If the new value is syntactically incorrect (including using property-independent style sheet syntax like 'inherit' or 'initial'), then it *must* be ignored, without assigning a new font value."
 
   - id: 2d.text.font.fontface
-    text: "Font names must be interpreted in the context of the canvas element's stylesheets; any fonts embedded using @font-face *must* therefore be available once they are loaded<^>."
+    text: "Font names must be interpreted in the context of the canvas element's stylesheets; any fonts embedded using @font-face *must* therefore be available once they are loaded."
   - id: 2d.text.font.notfullyloaded
-    text: "If a font is referenced before it is fully loaded, then it *must* be treated as if it was an unknown font, falling back to another as described by the relevant CSS specifications<^>."
+    text: "If a font is referenced before it is fully loaded, then it *must* be treated as if it was an unknown font, falling back to another as described by the relevant CSS specifications."
   - id: 2d.text.font.get
-    text: "On getting, the font attribute *must* return the serialized form of the current font of the context (with no 'line-height' component)<^>."
+    text: "On getting, the font attribute *must* return the serialized form of the current font of the context (with no 'line-height' component)."
   - id: 2d.text.font.default
-    text: "When the context is created, the font of the context *must* be set to 10px sans-serif<^>."
+    text: "When the context is created, the font of the context *must* be set to 10px sans-serif."
   - id: 2d.text.font.size
-    text: "When the 'font-size' component is set to lengths using percentages, 'em' or 'ex' units, or the 'larger' or 'smaller' keywords, these *must* be interpreted relative to the computed value of the 'font-size' property of the corresponding canvas element at the time that the attribute is set<^>."
+    text: "When the 'font-size' component is set to lengths using percentages, 'em' or 'ex' units, or the 'larger' or 'smaller' keywords, these *must* be interpreted relative to the computed value of the 'font-size' property of the corresponding canvas element at the time that the attribute is set."
   - id: 2d.text.font.weight
-    text: "When the 'font-weight' component is set to the relative values 'bolder' and 'lighter', these *must* be interpreted relative to the computed value of the 'font-weight' property of the corresponding canvas element at the time that the attribute is set<^>."
+    text: "When the 'font-weight' component is set to the relative values 'bolder' and 'lighter', these *must* be interpreted relative to the computed value of the 'font-weight' property of the corresponding canvas element at the time that the attribute is set."
   - id: 2d.text.font.undefined
-    text: "If the computed values are undefined for a particular case (e.g. because the canvas element is not in a Document), then the relative keywords *must* be interpreted relative to the normal-weight 10px sans-serif default<^>."
+    text: "If the computed values are undefined for a particular case (e.g. because the canvas element is not in a Document), then the relative keywords *must* be interpreted relative to the normal-weight 10px sans-serif default."
   - id: 2d.text.align.get
-    text: "The textAlign IDL attribute, on getting, *must* return the current value<^>."
+    text: "The textAlign IDL attribute, on getting, *must* return the current value."
   - id: 2d.text.align.set
-    text: "On setting, if the value is one of start, end, left, right, or center, then the value *must* be changed to the new value<^>."
+    text: "On setting, if the value is one of start, end, left, right, or center, then the value *must* be changed to the new value."
   - id: 2d.text.align.invalid
-    text: "The textAlign IDL attribute, <...> Otherwise, the new value *must* be ignored<^>."
+    text: "The textAlign IDL attribute, <...> Otherwise, the new value *must* be ignored."
   - id: 2d.text.align.default
-    text: "When the context is created, the textAlign attribute *must* initially have the value start<^>."
+    text: "When the context is created, the textAlign attribute *must* initially have the value start."
   - id: 2d.text.baseline.get
-    text: "The textBaseline IDL attribute, on getting, *must* return the current value<^>."
+    text: "The textBaseline IDL attribute, on getting, *must* return the current value."
   - id: 2d.text.baseline.set
-    text: "On setting, if the value is one of top, hanging, middle, alphabetic, ideographic, or bottom, then the value *must* be changed to the new value<^>."
+    text: "On setting, if the value is one of top, hanging, middle, alphabetic, ideographic, or bottom, then the value *must* be changed to the new value."
   - id: 2d.text.baseline.invalid
-    text: "The textBaseline IDL attribute, <...> Otherwise, the new value *must* be ignored<^>."
+    text: "The textBaseline IDL attribute, <...> Otherwise, the new value *must* be ignored."
   - id: 2d.text.baseline.default
-    text: "When the context is created, the textBaseline attribute *must* initially have the value alphabetic<^>."
+    text: "When the context is created, the textBaseline attribute *must* initially have the value alphabetic."
 
   - id: 2d.text.draw
-    text: "The fillText() and strokeText() methods <...> when the methods are called, the user agent *must* run the following steps<^>:"
+    text: "The fillText() and strokeText() methods <...> when the methods are called, the user agent *must* run the following steps:"
   - id: 2d.text.draw.spaces
-    text: "Replace all the space characters in text with U+0020 SPACE characters<^>."
+    text: "Replace all the space characters in text with U+0020 SPACE characters."
   - id: 2d.text.draw.direction
-    text: "the 'direction' property of the inline box set to the directionality of the canvas element<^>,"
+    text: "the 'direction' property of the inline box set to the directionality of the canvas element,"
   - id: 2d.text.draw.maxwidth
-    text: "If the maxWidth argument was specified and the hypothetical width of the inline box in the hypothetical line box is greater than maxWidth CSS pixels, then change font to have a more condensed font (if one is available or if a reasonably readable one can be synthesized by applying a horizontal scale factor to the font) or a smaller font, and return to the previous step<^>."
+    text: "If the maxWidth argument was specified and the hypothetical width of the inline box in the hypothetical line box is greater than maxWidth CSS pixels, then change font to have a more condensed font (if one is available or if a reasonably readable one can be synthesized by applying a horizontal scale factor to the font) or a smaller font, and return to the previous step."
   - id: 2d.text.align.left
-    text: "Let the anchor point's horizontal position be the left edge of the inline box<^>."
+    text: "Let the anchor point's horizontal position be the left edge of the inline box."
   - id: 2d.text.align.right
-    text: "Let the anchor point's horizontal position be the right edge of the inline box<^>."
+    text: "Let the anchor point's horizontal position be the right edge of the inline box."
   - id: 2d.text.align.center
-    text: "Let the anchor point's horizontal position be half way between the left and right edges of the inline box<^>."
+    text: "Let the anchor point's horizontal position be half way between the left and right edges of the inline box."
 
   - id: 2d.text.baseline.top
-    text: "Let the anchor point's vertical position be the top of the em box of the first available font of the inline box<^>."
+    text: "Let the anchor point's vertical position be the top of the em box of the first available font of the inline box."
   - id: 2d.text.baseline.hanging
-    text: "Let the anchor point's vertical position be the hanging baseline of the first available font of the inline box<^>."
+    text: "Let the anchor point's vertical position be the hanging baseline of the first available font of the inline box."
   - id: 2d.text.baseline.middle
-    text: "Let the anchor point's vertical position be half way between the bottom and the top of the em box of the first available font of the inline box<^>."
+    text: "Let the anchor point's vertical position be half way between the bottom and the top of the em box of the first available font of the inline box."
   - id: 2d.text.baseline.alphabetic
-    text: "Let the anchor point's vertical position be the alphabetic baseline of the first available font of the inline box<^>."
+    text: "Let the anchor point's vertical position be the alphabetic baseline of the first available font of the inline box."
   - id: 2d.text.baseline.ideographic
-    text: "Let the anchor point's vertical position be the ideographic baseline of the first available font of the inline box<^>."
+    text: "Let the anchor point's vertical position be the ideographic baseline of the first available font of the inline box."
   - id: 2d.text.baseline.bottom
-    text: "Let the anchor point's vertical position be the bottom of the em box of the first available font of the inline box<^>."
+    text: "Let the anchor point's vertical position be the bottom of the em box of the first available font of the inline box."
 
   - id: 2d.text.draw.fill
-    text: "For fillText() fillStyle must be applied to the glyphs and strokeStyle *must* be ignored<^>."
+    text: "For fillText() fillStyle must be applied to the glyphs and strokeStyle *must* be ignored."
   - id: 2d.text.draw.stroke
-    text: "For strokeText() the reverse holds and strokeStyle must be applied to the glyph outlines and fillStyle *must* be ignored<^>."
+    text: "For strokeText() the reverse holds and strokeStyle must be applied to the glyph outlines and fillStyle *must* be ignored."
   - id: 2d.text.measure.spaces
-    text: "When the method is invoked, the user agent *must* replace all the space characters in text with U+0020 SPACE characters<^>,"
+    text: "When the method is invoked, the user agent *must* replace all the space characters in text with U+0020 SPACE characters,"
   - id: 2d.text.measure
-    text: "When the method is invoked, the user agent <...> *must* form a hypothetical infinitely wide CSS line box containing a single inline box containing the text text, with all the properties at their initial values except the 'white-space' property of the inline element set to 'pre' and the 'font' property of the inline element set to the current font of the context as given by the font attribute, and must then return a new TextMetrics object with its width attribute set to the width of that inline box, in CSS pixels<^>."
+    text: "When the method is invoked, the user agent <...> *must* form a hypothetical infinitely wide CSS line box containing a single inline box containing the text text, with all the properties at their initial values except the 'white-space' property of the inline element set to 'pre' and the 'font' property of the inline element set to the current font of the context as given by the font attribute, and must then return a new TextMetrics object with its width attribute set to the width of that inline box, in CSS pixels."
 
   - id: 2d.drawImage.defaultdest
-    text: "If not specified, the dw and dh arguments *must* default to the values of sw and sh, interpreted such that one CSS pixel in the image is treated as one unit in the canvas coordinate space<^>."
+    text: "If not specified, the dw and dh arguments *must* default to the values of sw and sh, interpreted such that one CSS pixel in the image is treated as one unit in the canvas coordinate space."
   - id: 2d.drawImage.defaultsource
-    text: "If the sx, sy, sw, and sh arguments are omitted, they *must* default to 0, 0, the image's intrinsic width in image pixels, and the image's intrinsic height in image pixels, respectively<^>."
+    text: "If the sx, sy, sw, and sh arguments are omitted, they *must* default to 0, 0, the image's intrinsic width in image pixels, and the image's intrinsic height in image pixels, respectively."
   - id: 2d.drawImage.IDL
-    text: "void drawImage(in HTMLVideoElement image, in double sx, in double sy, in double sw, in double sh, in double dx, in double dy, in double dw, in double dh);<^>"
+    text: "void drawImage(in HTMLVideoElement image, in double sx, in double sy, in double sw, in double sh, in double dx, in double dy, in double dw, in double dh);"
   - id: 2d.drawImage.incomplete.image
-    text: "If the image argument is an HTMLImageElement object that is not fully decodable<^><...> then the implementation *must* return without drawing anything."
+    text: "If the image argument is an HTMLImageElement object that is not fully decodable<...> then the implementation *must* return without drawing anything."
   - id: 2d.drawImage.incomplete.video
-    previously: [ 6, "dw and dh" ]
-    text: "If the image argument is <...> an HTMLVideoElement object whose readyState attribute is either HAVE_NOTHING or HAVE_METADATA<^>, then the implementation *must* return without drawing anything."
+    text: "If the image argument is <...> an HTMLVideoElement object whose readyState attribute is either HAVE_NOTHING or HAVE_METADATA, then the implementation *must* return without drawing anything."
   - id: 2d.drawImage.zerocanvas
-    previously: [ 10, "dw and dh" ]
-    text: "If the image argument is an HTMLCanvasElement or an OffscreenCanvas object with either a horizontal dimension or a vertical dimension equal to zero, then the implementation *must* throw an INVALID_STATE_ERR exception<^>."
+    text: "If the image argument is an HTMLCanvasElement or an OffscreenCanvas object with either a horizontal dimension or a vertical dimension equal to zero, then the implementation *must* throw an INVALID_STATE_ERR exception."
   - id: 2d.drawImage.zerosource
-    text: "If one of the sw or sh arguments is zero<^>, the implementation *must* return without drawing anything."
+    text: "If one of the sw or sh arguments is zero, the implementation *must* return without drawing anything."
   - id: 2d.drawImage.paint
-    text: "When drawImage() is invoked, the region of the image specified by the source rectangle *must* be painted on the region of the canvas specified by the destination rectangle<^>, after applying the current transformation matrix to the points of the destination rectangle."
+    text: "When drawImage() is invoked, the region of the image specified by the source rectangle *must* be painted on the region of the canvas specified by the destination rectangle, after applying the current transformation matrix to the points of the destination rectangle."
   - id: 2d.drawImage.original
-    text: "The original image data of the source image *must* be used, not the image as it is rendered (e.g. width and height attributes on the source element have no effect)<^>."
+    text: "The original image data of the source image *must* be used, not the image as it is rendered (e.g. width and height attributes on the source element have no effect)."
   - id: 2d.drawImage.direction
-    text: "The image data *must* be processed in the original direction, even if the dimensions given are negative<^>."
+    text: "The image data *must* be processed in the original direction, even if the dimensions given are negative."
   - id: 2d.drawImage.self
-    text: "When a canvas is drawn onto itself, the drawing model requires the source to be copied before the image is drawn back onto the canvas, so it is possible to copy parts of a canvas onto overlapping parts of itself<^>."
+    text: "When a canvas is drawn onto itself, the drawing model requires the source to be copied before the image is drawn back onto the canvas, so it is possible to copy parts of a canvas onto overlapping parts of itself."
   - id: 2d.drawImage.animated.image
-    text: "When the drawImage() method is passed an animated image as its image argument, the user agent *must* use the poster frame of the animation, or, if there is no poster frame, the first frame of the animation<^>."
+    text: "When the drawImage() method is passed an animated image as its image argument, the user agent *must* use the poster frame of the animation, or, if there is no poster frame, the first frame of the animation."
   - id: 2d.drawImage.animated.video
-    previously: [ 4, "drawImage" ]
-    text: "When the image argument is an HTMLVideoElement, then the frame at the current playback position *must* be used as the source image<^>,"
+    text: "When the image argument is an HTMLVideoElement, then the frame at the current playback position *must* be used as the source image,"
   - id: 2d.drawImage.video.size
-    previously: [ 4, "drawImage" ]
-    text: "When the image argument is an HTMLVideoElement, <...> the source image's dimensions *must* be the intrinsic width and intrinsic height of the media resource (i.e. after any aspect-ratio correction has been applied)<^>."
+    text: "When the image argument is an HTMLVideoElement, <...> the source image's dimensions *must* be the intrinsic width and intrinsic height of the media resource (i.e. after any aspect-ratio correction has been applied)."
   - id: 2d.drawImage.unaffect
-    text: "Images are painted without affecting the current path<^>"
+    text: "Images are painted without affecting the current path"
   - id: 2d.drawImage.subject
-    text: "Images are painted without affecting the current path, and are subject to shadow effects, global alpha, the clipping region, and global composition operators<^>."
+    text: "Images are painted without affecting the current path, and are subject to shadow effects, global alpha, the clipping region, and global composition operators."
 
 
   - id: 2d.imageData.create2.object
-    text: "When the method is invoked with two arguments sw and sh, it *must* return an ImageData object<^>"
+    text: "When the method is invoked with two arguments sw and sh, it *must* return an ImageData object"
   - id: 2d.imageData.create2.size
-    text: "When the method is invoked with two arguments sw and sh, it *must* return an ImageData object representing a rectangle with a width in CSS pixels equal to the absolute magnitude of sw and a height in CSS pixels equal to the absolute magnitude of sh<^>."
+    text: "When the method is invoked with two arguments sw and sh, it *must* return an ImageData object representing a rectangle with a width in CSS pixels equal to the absolute magnitude of sw and a height in CSS pixels equal to the absolute magnitude of sh."
   - id: 2d.imageData.create1.object
-    text: "When invoked with a single imagedata argument, it *must* return an ImageData object<^>"
+    text: "When invoked with a single imagedata argument, it *must* return an ImageData object"
   - id: 2d.imageData.create1.size
-    text: "When invoked with a single imagedata argument, it *must* return an ImageData object representing a rectangle with the same dimensions as the ImageData object passed as the argument<^>."
+    text: "When invoked with a single imagedata argument, it *must* return an ImageData object representing a rectangle with the same dimensions as the ImageData object passed as the argument."
   - id: 2d.imageData.create.initial
-    text: "The ImageData object returned must be filled with transparent black<^>."
+    text: "The ImageData object returned must be filled with transparent black."
 
   - id: 2d.imageData.get.object
-    text: "The getImageData(sx, sy, sw, sh) method *must* return an ImageData object<^>"
+    text: "The getImageData(sx, sy, sw, sh) method *must* return an ImageData object"
   - id: 2d.imageData.get.basic
-    text: "The getImageData(sx, sy, sw, sh) method *must* return an ImageData object representing the underlying pixel data for the area of the canvas denoted by the rectangle whose corners are the four points (sx, sy), (sx+sw, sy), (sx+sw, sy+sh), (sx, sy+sh), in canvas coordinate space units<^>."
+    text: "The getImageData(sx, sy, sw, sh) method *must* return an ImageData object representing the underlying pixel data for the area of the canvas denoted by the rectangle whose corners are the four points (sx, sy), (sx+sw, sy), (sx+sw, sy+sh), (sx, sy+sh), in canvas coordinate space units."
   - id: 2d.imageData.get.outside
-    text: "Pixels outside the canvas *must* be returned as transparent black<^>."
+    text: "Pixels outside the canvas *must* be returned as transparent black."
   - id: 2d.imageData.get.premul
-    text: "Pixels *must* be returned as non-premultiplied alpha values<^>."
+    text: "Pixels *must* be returned as non-premultiplied alpha values."
 
   - id: 2d.imageData.getcreate.nonfinite
-    text: "If any of the arguments to createImageData() or getImageData() are infinite or NaN<^>, the method *must* instead raise a NOT_SUPPORTED_ERR exception."
+    text: "If any of the arguments to createImageData() or getImageData() are infinite or NaN, the method *must* instead raise a NOT_SUPPORTED_ERR exception."
   - id: 2d.imageData.create.null
-    text: "ImageData createImageData(in ImageData imagedata);<^>"
+    text: "ImageData createImageData(in ImageData imagedata);"
   - id: 2d.imageData.getcreate.zero
-    text: "If either the sw or sh arguments are zero, the method *must* instead raise an INDEX_SIZE_ERR exception<^>."
+    text: "If either the sw or sh arguments are zero, the method *must* instead raise an INDEX_SIZE_ERR exception."
 
   - id: 2d.imageData.initial
-    text: "ImageData objects *must* be initialized so that their width attribute is set to w, the number of physical device pixels per row in the image data, their height attribute is set to h, the number of rows in the image data, and their data attribute is initialized to a CanvasPixelArray object holding the image data<^>."
+    text: "ImageData objects *must* be initialized so that their width attribute is set to w, the number of physical device pixels per row in the image data, their height attribute is set to h, the number of rows in the image data, and their data attribute is initialized to a CanvasPixelArray object holding the image data."
   - id: 2d.imageData.one
-    text: "At least one pixel's worth of image data *must* be returned<^>."
+    text: "At least one pixel's worth of image data *must* be returned."
   - id: 2d.pixelarray.order
-    text: "The data *must* be represented in left-to-right order, row by row top to bottom, starting with the top left, with each pixel's red, green, blue, and alpha components being given in that order for each pixel<^>."
+    text: "The data *must* be represented in left-to-right order, row by row top to bottom, starting with the top left, with each pixel's red, green, blue, and alpha components being given in that order for each pixel."
   - id: 2d.pixelarray.range
-    text: "Each component of each device pixel represented in this array *must* be in the range 0..255, representing the 8 bit value for that component<^>."
+    text: "Each component of each device pixel represented in this array *must* be in the range 0..255, representing the 8 bit value for that component."
   - id: 2d.pixelarray.indexes
-    text: "The components *must* be assigned consecutive indices starting with 0 for the top left pixel's red component<^>."
+    text: "The components *must* be assigned consecutive indices starting with 0 for the top left pixel's red component."
   - id: 2d.pixelarray.length
-    text: "The length attribute of a CanvasPixelArray object *must* return this number<^>."
+    text: "The length attribute of a CanvasPixelArray object *must* return this number."
   - id: 2d.pixelarray.retrieve
-    text: "To determine the value of an indexed property index, the user agent *must* return the value of the indexth component in the array<^>."
+    text: "To determine the value of an indexed property index, the user agent *must* return the value of the indexth component in the array."
   - id: 2d.pixelarray.modify
-    text: "To set the value of an existing indexed property index to value value, the value of the indexth component in the array *must* be set to value<^>."
+    text: "To set the value of an existing indexed property index to value value, the value of the indexth component in the array *must* be set to value."
 
   - id: 2d.imageData.put.nonfinite
-    text: "If any of the arguments to the method are infinite or NaN, the method *must* raise a NOT_SUPPORTED_ERR exception<^>."
+    text: "If any of the arguments to the method are infinite or NaN, the method *must* raise a NOT_SUPPORTED_ERR exception."
   - id: 2d.imageData.put.wrongtype
-    text: "void putImageData(in ImageData imagedata, in double dx, in double dy);<...>void putImageData(in ImageData imagedata, in double dx, in double dy, in double dirtyX, in double dirtyY, in double dirtyWidth, in double dirtyHeight);<^>"
+    text: "void putImageData(in ImageData imagedata, in double dx, in double dy);<...>void putImageData(in ImageData imagedata, in double dx, in double dy, in double dirtyX, in double dirtyY, in double dirtyWidth, in double dirtyHeight);"
   - id: 2d.imageData.put.3arg
-    text: "When the last four arguments are omitted, they *must* be assumed to have the values 0, 0, the width member of the imagedata structure, and the height member of the imagedata structure, respectively<^>."
+    text: "When the last four arguments are omitted, they *must* be assumed to have the values 0, 0, the width member of the imagedata structure, and the height member of the imagedata structure, respectively."
   - id: 2d.imageData.put.normal
-    text: "When invoked with arguments that do not, per the last few paragraphs, cause an exception to be raised, the putImageData() method *must* act as follows<^>:"
+    text: "When invoked with arguments that do not, per the last few paragraphs, cause an exception to be raised, the putImageData() method *must* act as follows:"
 
   - id: 2d.imageData.unchanged
-    text: "the following *must* result in no visible changes to the rendering<^>:"
+    text: "the following *must* result in no visible changes to the rendering:"
   - id: 2d.imageData.createround
-    text: "...*must* return ImageData objects with the same dimensions, for any value of w and h<^>."
+    text: "...*must* return ImageData objects with the same dimensions, for any value of w and h."
   - id: 2d.imageData.unaffected
-    text: "The current path, transformation matrix, shadow attributes, global alpha, the clipping region, and global composition operator *must* not affect the getImageData() and putImageData() methods<^>."
+    text: "The current path, transformation matrix, shadow attributes, global alpha, the clipping region, and global composition operator *must* not affect the getImageData() and putImageData() methods."
 
   - id: 2d.drawingmodel
-    text: "When a shape or image is painted, user agents *must* follow these steps, in the order given (or act as if they do)<^>:"
+    text: "When a shape or image is painted, user agents *must* follow these steps, in the order given (or act as if they do):"
 
   - id: 2d.colorspace.correction
-    text: "The canvas APIs *must* perform color correction at only two points: when rendering images with their own gamma correction and color space information onto the canvas, to convert the image to the color space used by the canvas (e.g. using the 2D Context's drawImage() method with an HTMLImageElement object)<^>,"
+    text: "The canvas APIs *must* perform color correction at only two points: when rendering images with their own gamma correction and color space information onto the canvas, to convert the image to the color space used by the canvas (e.g. using the 2D Context's drawImage() method with an HTMLImageElement object),"
   - id: 2d.colorspace.toDataURL.info
-    text: "The toDataURL() method *must* not include color space information in the resource returned<^>."
+    text: "The toDataURL() method *must* not include color space information in the resource returned."
   - id: 2d.colorspace.toDataURL.equal
-    text: "Where the output format allows it, the color of pixels in resources created by toDataURL() *must* match those returned by the getImageData() method<^>."
+    text: "Where the output format allows it, the color of pixels in resources created by toDataURL() *must* match those returned by the getImageData() method."
   - id: 2d.colorspace.match
-    text: "In user agents that support CSS, the color space used by a canvas element *must* match the color space used for processing any colors for that element in CSS<^>."
+    text: "In user agents that support CSS, the color space used by a canvas element *must* match the color space used for processing any colors for that element in CSS."
   - id: 2d.colorspace.img.equal
-    text: "The gamma correction and color space information of images *must* be handled in such a way that an image rendered directly using an img element would use the same colors as one painted on a canvas element that is then itself rendered<^>."
+    text: "The gamma correction and color space information of images *must* be handled in such a way that an image rendered directly using an img element would use the same colors as one painted on a canvas element that is then itself rendered."
   - id: 2d.colorspace.img.noinfo
-    text: "Furthermore, the rendering of images that have no color correction information (such as those returned by the toDataURL() method) *must* be rendered with no color correction<^>."
+    text: "Furthermore, the rendering of images that have no color correction information (such as those returned by the toDataURL() method) *must* be rendered with no color correction."
 
   - id: 2d.scrollPathIntoView.basic
-    text: "The scrollPathIntoView() method, when invoked, *must* run these steps<^>:"
+    text: "The scrollPathIntoView() method, when invoked, *must* run these steps:"
 
   - id: security.start
-    text: "All canvas elements *must* start with their origin-clean set to true<^>."
+    text: "All canvas elements *must* start with their origin-clean set to true."
   - id: security.drawImage.image
     keyword: must
-    text: "The element's 2D context's drawImage() method is called with an HTMLImageElement or an HTMLVideoElement whose origin is not the same as that of the Document object that owns the canvas element<^>."
+    text: "The element's 2D context's drawImage() method is called with an HTMLImageElement or an HTMLVideoElement whose origin is not the same as that of the Document object that owns the canvas element."
   - id: security.drawImage.canvas
     keyword: must
-    text: "The element's 2D context's drawImage() method is called with an HTMLCanvasElement whose origin-clean flag is false<^>."
+    text: "The element's 2D context's drawImage() method is called with an HTMLCanvasElement whose origin-clean flag is false."
   - id: security.fillStyle.image
     keyword: must
-    text: "The element's 2D context's fillStyle attribute is set to a CanvasPattern object that was created from an HTMLImageElement<^> or an HTMLVideoElement whose origin was not the same as that of the Document object that owns the canvas element when the pattern was created."
+    text: "The element's 2D context's fillStyle attribute is set to a CanvasPattern object that was created from an HTMLImageElement or an HTMLVideoElement whose origin was not the same as that of the Document object that owns the canvas element when the pattern was created."
   - id: security.fillStyle.video
     keyword: must
-    text: "The element's 2D context's fillStyle attribute is set to a CanvasPattern object that was created from an HTMLImageElement or an HTMLVideoElement<^> whose origin was not the same as that of the Document object that owns the canvas element when the pattern was created."
+    text: "The element's 2D context's fillStyle attribute is set to a CanvasPattern object that was created from an HTMLImageElement or an HTMLVideoElement whose origin was not the same as that of the Document object that owns the canvas element when the pattern was created."
   - id: security.fillStyle.canvas
     keyword: must
-    text: "The element's 2D context's fillStyle attribute is set to a CanvasPattern object that was created from an HTMLCanvasElement whose origin-clean flag was false when the pattern was created<^>."
+    text: "The element's 2D context's fillStyle attribute is set to a CanvasPattern object that was created from an HTMLCanvasElement whose origin-clean flag was false when the pattern was created."
   - id: security.strokeStyle.image
     keyword: must
-    text: "The element's 2D context's strokeStyle attribute is set to a CanvasPattern object that was created from an HTMLImageElement<^> or an HTMLVideoElement whose origin was not the same as that of the Document object that owns the canvas element when the pattern was created."
+    text: "The element's 2D context's strokeStyle attribute is set to a CanvasPattern object that was created from an HTMLImageElement or an HTMLVideoElement whose origin was not the same as that of the Document object that owns the canvas element when the pattern was created."
   - id: security.strokeStyle.video
     keyword: must
-    text: "The element's 2D context's strokeStyle attribute is set to a CanvasPattern object that was created from an HTMLImageElement or an HTMLVideoElement<^> whose origin was not the same as that of the Document object that owns the canvas element when the pattern was created."
+    text: "The element's 2D context's strokeStyle attribute is set to a CanvasPattern object that was created from an HTMLImageElement or an HTMLVideoElement whose origin was not the same as that of the Document object that owns the canvas element when the pattern was created."
   - id: security.strokeStyle.canvas
     keyword: must
-    text: "The element's 2D context's strokeStyle attribute is set to a CanvasPattern object that was created from an HTMLCanvasElement whose origin-clean flag was false when the pattern was created<^>."
+    text: "The element's 2D context's strokeStyle attribute is set to a CanvasPattern object that was created from an HTMLCanvasElement whose origin-clean flag was false when the pattern was created."
   - id: security.toDataURL
-    text: "Whenever the toDataURL() method of a canvas element whose origin-clean flag is set to false is called, the method *must* raise a SECURITY_ERR exception<^>."
+    text: "Whenever the toDataURL() method of a canvas element whose origin-clean flag is set to false is called, the method *must* raise a SECURITY_ERR exception."
   - id: security.getImageData
-    text: "Whenever the getImageData() method of the 2D context of a canvas element whose origin-clean flag is set to false is called with otherwise correct arguments, the method *must* raise a SECURITY_ERR exception<^>."
+    text: "Whenever the getImageData() method of the 2D context of a canvas element whose origin-clean flag is set to false is called with otherwise correct arguments, the method *must* raise a SECURITY_ERR exception."
diff --git a/third_party/blink/web_tests/external/wpt/html/canvas/tools/specextract.py b/third_party/blink/web_tests/external/wpt/html/canvas/tools/specextract.py
deleted file mode 100644
index c3b4a07..0000000
--- a/third_party/blink/web_tests/external/wpt/html/canvas/tools/specextract.py
+++ /dev/null
@@ -1,68 +0,0 @@
-import html5lib
-import html5lib.treebuilders.dom
-import re
-
-# Expected use:
-#   curl --compressed https://html.spec.whatwg.org/multipage/canvas.html >current-work
-#   python specextract.py
-#
-# Generates current-work-canvas.xhtml, for use by gentest.py to create the annotated spec document
-
-def extract():
-    parser = html5lib.html5parser.HTMLParser(tree=html5lib.getTreeBuilder("dom"))
-    doc = parser.parse(open('current-work', "r"), transport_encoding='utf-8')
-
-    head = doc.getElementsByTagName('head')[0]
-    for n in head.childNodes:
-        if n.tagName == 'script':
-            head.removeChild(n)
-
-    header = doc.getElementsByTagName('header')[0]
-    #thecanvas = doc.getElementById('the-canvas') # doesn't work (?!)
-    thecanvas = [ n for n in doc.getElementsByTagName('h4') if n.getAttribute('id') == 'the-canvas-element' ][0]
-
-    # Add copyright from https://html.spec.whatwg.org/multipage/acknowledgements.html#acknowledgments
-    copy = doc.createElement('p')
-    copy.setAttribute('class', 'copyright')
-    copy.appendChild(doc.createTextNode(u'Parts of this specification are \xA9 Copyright 2004-2014 Apple Inc., Mozilla Foundation, and Opera Software ASA. You are granted a license to use, reproduce and create derivative works of this document.'))
-    header.appendChild(copy)
-
-    keep = [header, thecanvas]
-    node = thecanvas.nextSibling
-    while node.nodeName != 'nav':
-        keep.append(node)
-        node = node.nextSibling
-    p = thecanvas.parentNode
-    for n in p.childNodes[:]:
-        if n not in keep:
-            p.removeChild(n)
-
-    for n in header.childNodes[3:-4]:
-        header.removeChild(n)
-
-    def make_absolute(url):
-        match = re.match(r'(\w+:|#)', url)
-        if match:
-            return url
-        elif url[0] == '/':
-            return 'https://html.spec.whatwg.org' + url
-        else:
-            return 'https://html.spec.whatwg.org/multipage/' + url
-
-    # Fix relative URLs
-    for e in doc.getElementsByTagName('script'):
-        e.setAttribute('src', make_absolute(e.getAttribute('src')))
-    for e in doc.getElementsByTagName('iframe'):
-        e.setAttribute('src', make_absolute(e.getAttribute('src')))
-    for e in doc.getElementsByTagName('img'):
-        e.setAttribute('src', make_absolute(e.getAttribute('src')))
-    for e in doc.getElementsByTagName('a'):
-        e.setAttribute('href', make_absolute(e.getAttribute('href')))
-
-    # Convert to XHTML, because it's quicker to re-parse than HTML5
-    doc.documentElement.setAttribute('xmlns', 'http://www.w3.org/1999/xhtml')
-    doc.removeChild(doc.firstChild) # remove the DOCTYPE
-
-    open('current-work-canvas.xhtml', 'w').write(doc.toxml(encoding = 'UTF-8'))
-
-extract()
diff --git a/third_party/blink/web_tests/external/wpt/html/semantics/scripting-1/the-script-element/moving-between-documents/resources/moving-between-documents-iframe.py b/third_party/blink/web_tests/external/wpt/html/semantics/scripting-1/the-script-element/moving-between-documents/resources/moving-between-documents-iframe.py
index b7b6dac..dbcfe9b 100644
--- a/third_party/blink/web_tests/external/wpt/html/semantics/scripting-1/the-script-element/moving-between-documents/resources/moving-between-documents-iframe.py
+++ b/third_party/blink/web_tests/external/wpt/html/semantics/scripting-1/the-script-element/moving-between-documents/resources/moving-between-documents-iframe.py
@@ -47,7 +47,6 @@
   response.writer.write(u"%x\r\n" % len(body))
   response.writer.write(body)
   response.writer.write(u"\r\n")
-  response.writer.flush()
 
   body = u""
 
@@ -101,4 +100,3 @@
 
   response.writer.write(u"0\r\n")
   response.writer.write(u"\r\n")
-  response.writer.flush()
diff --git a/third_party/blink/web_tests/external/wpt/merchant-validation/constructortentative..http.html b/third_party/blink/web_tests/external/wpt/merchant-validation/constructor.tentative.http.html
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/merchant-validation/constructortentative..http.html
rename to third_party/blink/web_tests/external/wpt/merchant-validation/constructor.tentative.http.html
diff --git a/third_party/blink/web_tests/external/wpt/resource-timing/SyntheticResponse.py b/third_party/blink/web_tests/external/wpt/resource-timing/SyntheticResponse.py
index 944de61..0cce1df3 100644
--- a/third_party/blink/web_tests/external/wpt/resource-timing/SyntheticResponse.py
+++ b/third_party/blink/web_tests/external/wpt/resource-timing/SyntheticResponse.py
@@ -44,8 +44,6 @@
                 response.writer.end_headers()
             else:
                 statusSent = True
-        elif arg == b"flush":
-            response.writer.flush()
 
 #        else:
 #            error "  INVALID ARGUMENT %s" % arg
diff --git a/third_party/blink/web_tests/external/wpt/service-workers/service-worker/navigation-preload/resources/chunked-encoding-scope.py b/third_party/blink/web_tests/external/wpt/service-workers/service-worker/navigation-preload/resources/chunked-encoding-scope.py
index 912f43d..659c4d8c 100644
--- a/third_party/blink/web_tests/external/wpt/service-workers/service-worker/navigation-preload/resources/chunked-encoding-scope.py
+++ b/third_party/blink/web_tests/external/wpt/service-workers/service-worker/navigation-preload/resources/chunked-encoding-scope.py
@@ -14,7 +14,6 @@
             response.writer.write(u"%s\n%s\n" % (len(str(idx)), idx))
         else:
             response.writer.write(u"%s\r\n%s\r\n" % (len(str(idx)), idx))
-        response.writer.flush()
         time.sleep(0.001)
 
     response.writer.write(u"0\r\n\r\n")
diff --git a/third_party/blink/web_tests/external/wpt/service-workers/service-worker/resources/invalid-chunked-encoding-with-flush.py b/third_party/blink/web_tests/external/wpt/service-workers/service-worker/resources/invalid-chunked-encoding-with-flush.py
index 22a6965..05977c6 100644
--- a/third_party/blink/web_tests/external/wpt/service-workers/service-worker/resources/invalid-chunked-encoding-with-flush.py
+++ b/third_party/blink/web_tests/external/wpt/service-workers/service-worker/resources/invalid-chunked-encoding-with-flush.py
@@ -5,7 +5,5 @@
     response.write_status_headers()
 
     time.sleep(1)
-    response.explicit_flush = True
 
     response.writer.write(b"XX\r\n\r\n")
-    response.writer.flush()
diff --git a/third_party/blink/web_tests/external/wpt/tools/wptrunner/requirements.txt b/third_party/blink/web_tests/external/wpt/tools/wptrunner/requirements.txt
index 7c134b8..77c1ea5 100644
--- a/third_party/blink/web_tests/external/wpt/tools/wptrunner/requirements.txt
+++ b/third_party/blink/web_tests/external/wpt/tools/wptrunner/requirements.txt
@@ -1,6 +1,6 @@
 html5lib==1.1
 mozinfo==1.2.1  # https://bugzilla.mozilla.org/show_bug.cgi?id=1621226
-mozlog==6.1
+mozlog==7.0.1
 mozdebug==0.2
 # Pillow 7 requires Python 3
 pillow==6.2.2; python_version <= '2.7'  # pyup: <7.0
diff --git a/third_party/blink/web_tests/external/wpt/tools/wptrunner/requirements_firefox.txt b/third_party/blink/web_tests/external/wpt/tools/wptrunner/requirements_firefox.txt
index 373466d..622c34dc 100644
--- a/third_party/blink/web_tests/external/wpt/tools/wptrunner/requirements_firefox.txt
+++ b/third_party/blink/web_tests/external/wpt/tools/wptrunner/requirements_firefox.txt
@@ -1,10 +1,10 @@
 marionette_driver==3.1.0
 mozcrash==2.0.0
-mozinstall==2.0.0
+mozinstall==2.0.1
 mozleak==0.2
 moznetwork==1.1.0
 mozprocess==1.2.1
 mozprofile==2.5.0
-mozrunner==8.0.0
+mozrunner==8.0.3
 mozversion==2.3.0
 psutil==5.7.3
diff --git a/third_party/blink/web_tests/external/wpt/tools/wptserve/wptserve/response.py b/third_party/blink/web_tests/external/wpt/tools/wptserve/wptserve/response.py
index 1519ed7..6e5ee11 100644
--- a/third_party/blink/web_tests/external/wpt/tools/wptserve/wptserve/response.py
+++ b/third_party/blink/web_tests/external/wpt/tools/wptserve/wptserve/response.py
@@ -41,11 +41,6 @@
        Boolean, default False, indicating whether the body content should be
        sent when the request method is HEAD.
 
-    .. attribute:: explicit_flush
-
-       Boolean indicating whether output should be flushed automatically or only
-       when requested.
-
     .. attribute:: writer
 
        The ResponseWriter for this response
@@ -73,7 +68,6 @@
 
         self.add_required_headers = True
         self.send_body_for_head_request = False
-        self.explicit_flush = False
         self.close_connection = False
 
         self.logger = get_logger()
@@ -665,11 +659,7 @@
     """Object providing an API to write out a HTTP response.
 
     :param handler: The RequestHandler being used.
-    :param response: The Response associated with this writer.
-
-    After each part of the response is written, the output is
-    flushed unless response.explicit_flush is False, in which case
-    the user must call .flush() explicitly."""
+    :param response: The Response associated with this writer."""
     def __init__(self, handler, response):
         self._wfile = handler.wfile
         self._response = response
@@ -707,52 +697,65 @@
 
         :param name: Name of the header field
         :param value: Value of the header field
+        :return: A boolean indicating whether the write succeeds
         """
         if not self._status_written:
             self.write_status(self.default_status)
         self._headers_seen.add(self.encode(name.lower()))
-        self.write(name)
-        self.write(b": ")
+        if not self.write(name):
+            return False
+        if not self.write(b": "):
+            return False
         if isinstance(value, int):
-            self.write(text_type(value))
-        else:
-            self.write(value)
-        self.write(b"\r\n")
-        if not self._response.explicit_flush:
-            self.flush()
+            if not self.write(text_type(value)):
+                return False
+        elif not self.write(value):
+            return False
+        return self.write(b"\r\n")
 
     def write_default_headers(self):
         for name, f in [("Server", self._handler.version_string),
                         ("Date", self._handler.date_time_string)]:
             if not self._seen_header(name):
-                self.write_header(name, f())
+                if not self.write_header(name, f()):
+                    return False
 
         if (isinstance(self._response.content, (binary_type, text_type)) and
             not self._seen_header("content-length")):
             #Would be nice to avoid double-encoding here
-            self.write_header("Content-Length", len(self.encode(self._response.content)))
+            if not self.write_header("Content-Length", len(self.encode(self._response.content))):
+                return False
+
+        return True
 
     def end_headers(self):
         """Finish writing headers and write the separator.
 
         Unless add_required_headers on the response is False,
         this will also add HTTP-mandated headers that have not yet been supplied
-        to the response headers"""
+        to the response headers.
+        :return: A boolean indicating whether the write succeeds
+        """
 
         if self._response.add_required_headers:
-            self.write_default_headers()
+            if not self.write_default_headers():
+                return False
 
-        self.write("\r\n")
+        if not self.write("\r\n"):
+            return False
         if not self._seen_header("content-length"):
             self._response.close_connection = True
-        if not self._response.explicit_flush:
-            self.flush()
         self._headers_complete = True
 
+        return True
+
     def write_content(self, data):
         """Write the body of the response.
 
-        HTTP-mandated headers will be automatically added with status default to 200 if they have not been explicitly set."""
+        HTTP-mandated headers will be automatically added with status default to 200 if they have
+        not been explicitly set.
+        :return: A boolean indicating whether the write succeeds
+        """
         if not self._status_written:
             self.write_status(self.default_status)
         if not self._headers_complete:
@@ -772,7 +775,9 @@
 
     def write(self, data):
         """Write directly to the response, converting unicode to bytes
-        according to response.encoding. Does not flush."""
+        according to response.encoding.
+        :return: A boolean indicating whether the write succeeds
+        """
         self.content_written = True
         try:
             self._wfile.write(self.encode(data))
@@ -782,8 +787,7 @@
             return False
 
     def write_content_file(self, data):
-        """Write a file-like object directly to the response in chunks.
-        Does not flush."""
+        """Write a file-like object directly to the response in chunks."""
         self.content_written = True
         success = True
         while True:
@@ -807,13 +811,3 @@
             return data.encode(self._response.encoding)
         else:
             raise ValueError("data %r should be text or binary, but is %s" % (data, type(data)))
-
-    def flush(self):
-        """Flush the output. Returns False if the flush failed due to
-        the socket being closed by the remote end."""
-        try:
-            self._wfile.flush()
-            return True
-        except socket.error:
-            # This can happen if the socket got closed by the remote end
-            return False
diff --git a/third_party/blink/web_tests/external/wpt/webrtc/protocol/rtp-payloadtypes-expected.txt b/third_party/blink/web_tests/external/wpt/webrtc/protocol/rtp-payloadtypes-expected.txt
new file mode 100644
index 0000000..4f019b9
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webrtc/protocol/rtp-payloadtypes-expected.txt
@@ -0,0 +1,6 @@
+This is a testharness.js-based test.
+PASS setRemoteDescription with a codec in the range 96-127 works
+FAIL setRemoteDescription with a codec in the range 35-63 works assert_true: expected true got false
+FAIL setRemoteDescription with a codec in the range 64-95 throws an InvalidAccessError assert_unreached: Should have rejected: undefined Reached unreachable code
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/external/wpt/webrtc/protocol/rtp-payloadtypes.html b/third_party/blink/web_tests/external/wpt/webrtc/protocol/rtp-payloadtypes.html
new file mode 100644
index 0000000..6806e75
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webrtc/protocol/rtp-payloadtypes.html
@@ -0,0 +1,58 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>payload type handling (assuming rtcp-mux)</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="../RTCPeerConnection-helper.js"></script>
+<script>
+'use strict';
+// Tests behaviour from https://tools.ietf.org/html/rfc5761#section-4
+
+function createOfferSdp(opusPayloadType) {
+  return `v=0
+o=- 0 3 IN IP4 127.0.0.1
+s=-
+t=0 0
+a=fingerprint:sha-256 A7:24:72:CA:6E:02:55:39:BA:66:DF:6E:CC:4C:D8:B0:1A:BF:1A:56:65:7D:F4:03:AD:7E:77:43:2A:29:EC:93
+a=ice-ufrag:6HHHdzzeIhkE0CKj
+a=ice-pwd:XYDGVpfvklQIEnZ6YnyLsAew
+m=audio 9 RTP/SAVPF ${opusPayloadType}
+c=IN IP4 0.0.0.0
+a=rtcp-mux
+a=sendonly
+a=mid:audio
+a=rtpmap:${opusPayloadType} opus/48000/2
+a=setup:actpass
+`;
+}
+
+promise_test(async t => {
+  for (let payloadType = 96; payloadType <= 127; payloadType++) {
+    const pc = new RTCPeerConnection();
+    await pc.setRemoteDescription({type: 'offer', sdp: createOfferSdp(payloadType)});
+    const answer = await pc.createAnswer();
+    assert_true(answer.sdp.includes(`a=rtpmap:${payloadType} opus/48000/2`));
+    pc.close();
+  }
+}, 'setRemoteDescription with a codec in the range 96-127 works');
+
+// This is written as a separate test since it currently fails in Chrome.
+promise_test(async t => {
+  for (let payloadType = 35; payloadType <= 63; payloadType++) {
+    const pc = new RTCPeerConnection();
+    await pc.setRemoteDescription({type: 'offer', sdp: createOfferSdp(payloadType)});
+    const answer = await pc.createAnswer();
+    assert_true(answer.sdp.includes(`a=rtpmap:${payloadType} opus/48000/2`));
+    pc.close();
+  }
+}, 'setRemoteDescription with a codec in the range 35-63 works');
+
+promise_test(async t => {
+  for (let payloadType = 64; payloadType <= 95; payloadType++) {
+    const pc = new RTCPeerConnection();
+    await promise_rejects_dom(t, 'InvalidAccessError',
+      pc.setRemoteDescription({type: 'offer', sdp: createOfferSdp(64)}));
+    pc.close();
+  }
+}, 'setRemoteDescription with a codec in the range 64-95 throws an InvalidAccessError');
+</script>
diff --git a/third_party/blink/web_tests/external/wpt/webstorage/storage_session_window_noopener-expected.txt b/third_party/blink/web_tests/external/wpt/webstorage/storage_session_window_noopener-expected.txt
deleted file mode 100644
index f7a4f86..0000000
--- a/third_party/blink/web_tests/external/wpt/webstorage/storage_session_window_noopener-expected.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-This is a testharness.js-based test.
-FAIL A new noopener window to make sure there is a not copy of the previous window's sessionStorage assert_equals: storage.getItem('FOO') expected (object) null but got (string) "BAR"
-Harness: the test ran to completion.
-
diff --git a/third_party/blink/web_tests/external/wpt/xhr/resources/echo-method.py b/third_party/blink/web_tests/external/wpt/xhr/resources/echo-method.py
index 7899c184..564c3db1 100644
--- a/third_party/blink/web_tests/external/wpt/xhr/resources/echo-method.py
+++ b/third_party/blink/web_tests/external/wpt/xhr/resources/echo-method.py
@@ -14,4 +14,3 @@
 Content-Length: {}
 
 {}'''.format(len(content), content))
-    response.writer.flush()
diff --git a/third_party/blink/web_tests/external/wpt/xhr/resources/inspect-headers.py b/third_party/blink/web_tests/external/wpt/xhr/resources/inspect-headers.py
index 36ef174..72c1a7f 100644
--- a/third_party/blink/web_tests/external/wpt/xhr/resources/inspect-headers.py
+++ b/third_party/blink/web_tests/external/wpt/xhr/resources/inspect-headers.py
@@ -8,13 +8,14 @@
     # Python 3. <http.client.HTTPMessage> doesn't have 'headers" attribute or equivalent
     # [https://bugs.python.org/issue4773].
     # In Python 2, variable raw_headers.headers returns a completely uninterpreted list of lines
-    # contained in the header. In Python 3, raw_headers.as_string() returns entire formatted
-    # message as a string. Here is to construct an equivalent "headers" variable to support tests
-    # in Python 3.
+    # contained in the header. In Python 3, raw_headers.raw_items() returns the (name, value)
+    # header pairs without modification. Here is to construct an equivalent "headers" variable to
+    # support tests in Python 3.
     if PY3:
-        header_list = [
-            isomorphic_encode(s + u'\r\n') for s in raw_headers.as_string().splitlines() if s
-        ]
+        header_list = []
+        for field in raw_headers.raw_items():
+            header = b"%s: %s\r\n" % (isomorphic_encode(field[0]), isomorphic_encode(field[1]))
+            header_list.append(header)
     else:
         header_list = raw_headers.headers
     for line in header_list:
diff --git a/third_party/blink/web_tests/external/wpt_automation/css/selectors/focus-visible-001-manual-automation.js b/third_party/blink/web_tests/external/wpt_automation/css/selectors/focus-visible-001-manual-automation.js
deleted file mode 100644
index 11137788..0000000
--- a/third_party/blink/web_tests/external/wpt_automation/css/selectors/focus-visible-001-manual-automation.js
+++ /dev/null
@@ -1,5 +0,0 @@
-importAutomationScript('/input-events/inputevent_common_input.js');
-
-function inject_input() {
-  return keyDown("Tab");
-};
diff --git a/third_party/blink/web_tests/fast/dom/Document/CaretRangeFromPoint/atomic-inlines.html b/third_party/blink/web_tests/fast/dom/Document/CaretRangeFromPoint/atomic-inlines.html
new file mode 100644
index 0000000..5eb18ca
--- /dev/null
+++ b/third_party/blink/web_tests/fast/dom/Document/CaretRangeFromPoint/atomic-inlines.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<style>
+  body { margin:0; }
+  .container { margin:30px; line-height:20px; }
+  #inlineblock { display: inline-block; }
+  #inlinetable { display: inline-table; }
+  #inlineflex { display: inline-flex; }
+  #inlinegrid { display: inline-grid; }
+</style>
+<div class="container">
+  <div id="inlineblock"><div>asdfgh</div></div>
+</div>
+<div class="container">
+  <div id="inlinetable"><div>asdfgh</div></div>
+</div>
+<div class="container">
+  <div id="inlineflex"><div>asdfgh</div></div>
+</div>
+<div class="container">
+  <div id="inlinegrid"><div>asdfgh</div></div>
+</div>
+<script src="../../../../resources/testharness.js"></script>
+<script src="../../../../resources/testharnessreport.js"></script>
+<script>
+  function test_outside(y, expected_node) {
+      range = document.caretRangeFromPoint(0, y);
+      assert_equals(range.startContainer, expected_node);
+      assert_equals(range.startOffset, 0);
+      range = document.caretRangeFromPoint(300, y);
+      assert_equals(range.startContainer, expected_node);
+      assert_equals(range.startOffset, 1);
+  }
+  test(()=> { test_outside(40, inlineblock); }, "inline-block");
+  test(()=> { test_outside(90, inlinetable); }, "inline-table");
+  test(()=> { test_outside(140, inlineflex); }, "inline-flex");
+  test(()=> { test_outside(190, inlinegrid); }, "inline-grid");
+</script>
diff --git a/third_party/blink/web_tests/fast/forms/week/week-picker-ax.html b/third_party/blink/web_tests/fast/forms/week/week-picker-ax.html
index b3638edb..3b7bb5c 100644
--- a/third_party/blink/web_tests/fast/forms/week/week-picker-ax.html
+++ b/third_party/blink/web_tests/fast/forms/week/week-picker-ax.html
@@ -27,7 +27,7 @@
           markDirtyCounter++;
         }
 
-        if (focusCounter == 1 && markDirtyCounter == 3) {
+        if (focusCounter == 1 && markDirtyCounter >= 3) {
           resolve();
         }
       });
diff --git a/third_party/blink/web_tests/fast/writing-mode/positionForPoint.html b/third_party/blink/web_tests/fast/writing-mode/positionForPoint.html
index 817878f..9dd3aed 100644
--- a/third_party/blink/web_tests/fast/writing-mode/positionForPoint.html
+++ b/third_party/blink/web_tests/fast/writing-mode/positionForPoint.html
@@ -30,5 +30,5 @@
     }
 
     test(1, 20, 50);
-    test(2, 20, 180);
+    test(2, 40, 180);
 </script>
diff --git a/third_party/blink/web_tests/flag-specific/disable-layout-ng/editing/selection/offset-from-point-expected.txt b/third_party/blink/web_tests/flag-specific/disable-layout-ng/editing/selection/offset-from-point-expected.txt
new file mode 100644
index 0000000..96e60654
--- /dev/null
+++ b/third_party/blink/web_tests/flag-specific/disable-layout-ng/editing/selection/offset-from-point-expected.txt
@@ -0,0 +1,116 @@
+12 345 6789
+
+12 345 6789
+
+12 345 6789
+
+12 345 6789
+
+LTR
+0=-1 (-1)
+1=11 (12)
+2=31 (20)
+3=51 (20)
+4=71 (20)
+5=91 (20)
+6=111 (20)
+7=131 (20)
+8=151 (20)
+9=171 (20)
+10=191 (20)
+11=211 (20)
+LTR (Complex Path)
+0=-1 (-1)
+1=11 (12)
+2=31 (20)
+3=51 (20)
+4=71 (20)
+5=91 (20)
+6=111 (20)
+7=131 (20)
+8=151 (20)
+9=171 (20)
+10=191 (20)
+11=211 (20)
+RTL
+11=-1 (-1)
+8=11 (12)
+9=31 (20)
+10=51 (20)
+7=71 (20)
+6=91 (20)
+4=111 (20)
+5=131 (20)
+3=151 (20)
+2=171 (20)
+1=191 (20)
+0=211 (20)
+RTL (Complex Path)
+11=-1 (-1)
+8=11 (12)
+9=31 (20)
+10=51 (20)
+7=71 (20)
+6=91 (20)
+4=111 (20)
+5=131 (20)
+3=151 (20)
+2=171 (20)
+1=191 (20)
+0=211 (20)
+VERTICAL-LR
+0=-1 (-1)
+1=11 (12)
+2=31 (20)
+3=51 (20)
+4=71 (20)
+5=91 (20)
+6=111 (20)
+7=131 (20)
+8=151 (20)
+9=171 (20)
+10=191 (20)
+11=211 (20)
+0=220 (9)
+VERTICAL-LR (Complex Path)
+0=-1 (-1)
+1=11 (12)
+2=31 (20)
+3=51 (20)
+4=71 (20)
+5=91 (20)
+6=111 (20)
+7=131 (20)
+8=151 (20)
+9=171 (20)
+10=191 (20)
+11=211 (20)
+0=220 (9)
+VERTICAL-RL
+0=-1 (-1)
+1=11 (12)
+2=31 (20)
+3=51 (20)
+4=71 (20)
+5=91 (20)
+6=111 (20)
+7=131 (20)
+8=151 (20)
+9=171 (20)
+10=191 (20)
+11=211 (20)
+1=220 (9)
+VERTICAL-RL (Complex Path)
+0=-1 (-1)
+1=11 (12)
+2=31 (20)
+3=51 (20)
+4=71 (20)
+5=91 (20)
+6=111 (20)
+7=131 (20)
+8=151 (20)
+9=171 (20)
+10=191 (20)
+11=211 (20)
+1=220 (9)
diff --git a/third_party/blink/web_tests/http/tests/devtools/components/geometry-expected.txt b/third_party/blink/web_tests/http/tests/devtools/components/geometry-expected.txt
index e39db245..6903b5e 100644
--- a/third_party/blink/web_tests/http/tests/devtools/components/geometry-expected.txt
+++ b/third_party/blink/web_tests/http/tests/devtools/components/geometry-expected.txt
@@ -37,17 +37,3 @@
 rad: 1.5708
 rad: 3.1416
 
-Running: testEulerAnglesFromRotationMatrix
-Euler angles: 29.9762 60.0238 45.0200
-Euler angles: 60.0238 29.9762 45.0200
-Euler angles: 0 19.8684 69.9875
-
-Running: testEulerAnglesToRotate3DString
-Transform: rotate3d(0,1,0,0deg) rotate3d(-1,0,0,0deg) rotate3d(0,0,1,0deg)
-Transform: rotate3d(0,1,0,1deg) rotate3d(-1,0,0,2deg) rotate3d(0,-0.03489949670250097,0.9993908270190958,3deg)
-Transform: rotate3d(0,1,0,-1deg) rotate3d(-1,0,0,-2deg) rotate3d(0,0.03489949670250097,0.9993908270190958,3deg)
-Transform: rotate3d(0,1,0,-1deg) rotate3d(-1,0,0,2deg) rotate3d(0,-0.03489949670250097,0.9993908270190958,-3deg)
-Transform: rotate3d(0,1,0,0deg) rotate3d(-1,0,0,1deg) rotate3d(0,-0.01745240643728351,0.9998476951563913,2deg)
-Transform: rotate3d(0,1,0,1deg) rotate3d(-1,0,0,0deg) rotate3d(0,0,1,2deg)
-Transform: rotate3d(0,1,0,1deg) rotate3d(-1,0,0,2deg) rotate3d(0,-0.03489949670250097,0.9993908270190958,0deg)
-
diff --git a/third_party/blink/web_tests/http/tests/devtools/components/geometry.js b/third_party/blink/web_tests/http/tests/devtools/components/geometry.js
index 811bc32..5e2e0aa12 100644
--- a/third_party/blink/web_tests/http/tests/devtools/components/geometry.js
+++ b/third_party/blink/web_tests/http/tests/devtools/components/geometry.js
@@ -98,36 +98,6 @@
         TestRunner.addResult(String.sprintf('rad: %.4f', UI.Geometry.degreesToRadians(angles[i])));
 
       next();
-    },
-
-    function testEulerAnglesFromRotationMatrix(next) {
-      var rotationMatrices = [
-        'matrix3d(0.612, 0.353, -0.707, 0, 0.280, 0.739, 0.612, 0, 0.739, -0.573, 0.353, 0, 0, 0, 0, 1)',
-
-        'matrix3d(0.353, 0.612, -0.707, 0, -0.573, 0.739, 0.353, 0, 0.739, 0.280, 0.612, 0, 0, 0, 0, 1)',
-
-        'matrix3d(0.342, 0, -0.939, 0, 0.321, 0.939, 0.116, 0, 0.883, -0.342, 0.321, 0, 0, 0, 0, 1)'
-      ];
-
-      for (var i = 0; i < rotationMatrices.length; ++i) {
-        var angles = UI.Geometry.EulerAngles.fromRotationMatrix(new WebKitCSSMatrix(rotationMatrices[i]));
-        TestRunner.addResult(String.sprintf('Euler angles: %.4f %.4f %.4f', angles.alpha, angles.beta, angles.gamma));
-      }
-      next();
-    },
-
-    function testEulerAnglesToRotate3DString(next) {
-      var angles = [
-        new UI.Geometry.EulerAngles(0, 0, 0), new UI.Geometry.EulerAngles(1, 2, 3),
-        new UI.Geometry.EulerAngles(-1, -2, 3), new UI.Geometry.EulerAngles(-1, 2, -3),
-        new UI.Geometry.EulerAngles(0, 1, 2), new UI.Geometry.EulerAngles(1, 0, 2), new UI.Geometry.EulerAngles(1, 2, 0)
-      ];
-
-      for (var i = 0; i < angles.length; ++i) {
-        var rotate3DString = angles[i].toRotate3DString();
-        TestRunner.addResult(String.sprintf('Transform: %s', rotate3DString));
-      }
-      next();
     }
 
   ]);
diff --git a/third_party/blink/web_tests/media/media-file.js b/third_party/blink/web_tests/media/media-file.js
index 80eef5c..64398bd8 100644
--- a/third_party/blink/web_tests/media/media-file.js
+++ b/third_party/blink/web_tests/media/media-file.js
@@ -39,6 +39,17 @@
     }
 }
 
+function videoPresentationPromise(video) {
+    return new Promise(resolve => video.requestVideoFrameCallback(resolve));
+}
+
+// This function should be called before setting video.src to guarantee that we
+// catch all new frames.
+function allVideosPresentedPromise() {
+    let videos = Array.from(document.getElementsByTagName('video'));
+    return Promise.all(videos.map(video => videoPresentationPromise(video)));
+}
+
 function setSrcById(id, src) {
     var element = document.getElementById(id);
     if (element)
diff --git a/third_party/blink/web_tests/media/video-object-fit-change.html b/third_party/blink/web_tests/media/video-object-fit-change.html
index 0306d91..0d38cd5 100644
--- a/third_party/blink/web_tests/media/video-object-fit-change.html
+++ b/third_party/blink/web_tests/media/video-object-fit-change.html
@@ -18,27 +18,23 @@
 
         function init()
         {
+            var videosPresented = allVideosPresentedPromise();
             setSrcByTagName("video", "content/test.ogv");
 
-            var totalCount = document.getElementsByTagName('video').length;
-            var count = totalCount;
-            document.addEventListener("canplaythrough", function () {
-                if (!--count)
-                    setTimeout(function() { changeStyle(); }, 500);
-            }, true);
+            videosPresented.then(changeStyle);
         }
 
-	function changeStyle()
-	{
-	    video1.style.objectFit = 'contain';
-	    video2.style.objectFit = 'cover';
-	    video3.style.objectFit = 'fill';
-	    video4.style.objectFit = 'scale-down';
+        function changeStyle()
+        {
+            video1.style.objectFit = 'contain';
+            video2.style.objectFit = 'cover';
+            video3.style.objectFit = 'fill';
+            video4.style.objectFit = 'scale-down';
 
             if (window.testRunner) {
                 setTimeout(function() { testRunner.notifyDone(); }, 500);
             }
-	}
+        }
     </script>
 
   </head>
diff --git a/third_party/blink/web_tests/media/video-object-fit.html b/third_party/blink/web_tests/media/video-object-fit.html
index 1b2cd49..40c52102 100644
--- a/third_party/blink/web_tests/media/video-object-fit.html
+++ b/third_party/blink/web_tests/media/video-object-fit.html
@@ -18,16 +18,10 @@
 
         function init()
         {
+            var videosPresented = allVideosPresentedPromise();
             setSrcByTagName("video", "content/test.ogv");
 
-            var totalCount = document.getElementsByTagName('video').length;
-            var count = totalCount;
-            document.addEventListener("canplaythrough", function () {
-                if (!--count) {
-                    if (window.testRunner)
-                        setTimeout(function() { testRunner.notifyDone(); }, totalCount * 150);
-                }
-            }, true);
+            videosPresented.then(() => testRunner.notifyDone());
         }
     </script>
 
diff --git a/third_party/blink/web_tests/platform/linux/virtual/gpu-rasterization-disable-yuv/images/yuv-decode-eligible/webp-no-color-profile-lossy-expected.png b/third_party/blink/web_tests/platform/linux/virtual/gpu-rasterization-disable-yuv/images/yuv-decode-eligible/webp-no-color-profile-lossy-expected.png
deleted file mode 100644
index b419bff..0000000
--- a/third_party/blink/web_tests/platform/linux/virtual/gpu-rasterization-disable-yuv/images/yuv-decode-eligible/webp-no-color-profile-lossy-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac-mac-arm11.0/media/video-aspect-ratio-expected.png b/third_party/blink/web_tests/platform/mac-mac-arm11.0/media/video-aspect-ratio-expected.png
new file mode 100644
index 0000000..4137bec
--- /dev/null
+++ b/third_party/blink/web_tests/platform/mac-mac-arm11.0/media/video-aspect-ratio-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/media/video-aspect-ratio-expected.png b/third_party/blink/web_tests/platform/mac/media/video-aspect-ratio-expected.png
index 4137bec..30b8ba3 100644
--- a/third_party/blink/web_tests/platform/mac/media/video-aspect-ratio-expected.png
+++ b/third_party/blink/web_tests/platform/mac/media/video-aspect-ratio-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/virtual/gpu-rasterization-disable-yuv/images/yuv-decode-eligible/webp-no-color-profile-lossy-expected.png b/third_party/blink/web_tests/platform/mac/virtual/gpu-rasterization-disable-yuv/images/yuv-decode-eligible/webp-no-color-profile-lossy-expected.png
deleted file mode 100644
index b419bff..0000000
--- a/third_party/blink/web_tests/platform/mac/virtual/gpu-rasterization-disable-yuv/images/yuv-decode-eligible/webp-no-color-profile-lossy-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/media/video-aspect-ratio-expected.png b/third_party/blink/web_tests/platform/win/media/video-aspect-ratio-expected.png
index ee3d638..6764937 100644
--- a/third_party/blink/web_tests/platform/win/media/video-aspect-ratio-expected.png
+++ b/third_party/blink/web_tests/platform/win/media/video-aspect-ratio-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/virtual/gpu-rasterization-disable-yuv/images/yuv-decode-eligible/webp-no-color-profile-lossy-expected.png b/third_party/blink/web_tests/platform/win/virtual/gpu-rasterization-disable-yuv/images/yuv-decode-eligible/webp-no-color-profile-lossy-expected.png
deleted file mode 100644
index b419bff..0000000
--- a/third_party/blink/web_tests/platform/win/virtual/gpu-rasterization-disable-yuv/images/yuv-decode-eligible/webp-no-color-profile-lossy-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/gpu-rasterization-disable-yuv/images/yuv-decode-eligible/webp-no-color-profile-lossy-expected.png b/third_party/blink/web_tests/platform/win7/virtual/gpu-rasterization-disable-yuv/images/yuv-decode-eligible/webp-no-color-profile-lossy-expected.png
deleted file mode 100644
index b419bff..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/gpu-rasterization-disable-yuv/images/yuv-decode-eligible/webp-no-color-profile-lossy-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/virtual/gpu-rasterization-disable-yuv/README.md b/third_party/blink/web_tests/virtual/gpu-rasterization-disable-yuv/README.md
index 185c830..970f9ed6 100644
--- a/third_party/blink/web_tests/virtual/gpu-rasterization-disable-yuv/README.md
+++ b/third_party/blink/web_tests/virtual/gpu-rasterization-disable-yuv/README.md
@@ -1,6 +1,7 @@
-# Test suite to run images/yuv-decode-eligible with GPU rasterization
-# and with the DecodeLossyWebPImagesToYUV feature disabled. This is because
-# YUV decoding will eventually become the default for many image decoding
-# cases and receives test coverage through virtual/gpu-rasterization. However
-# there are some cases where images might not go through YUV decoding, so this
-# test suite maintains coverage of those.
+Test suite to run images/yuv-decode-eligible with --enable-gpu-rasterization
+--disable-blink-features=DecodeLossyWebPImagesToYUV and
+--disable-blink-features=DecodeJpeg420ImagesToYUV. 
+
+YUV decoding is the default for many image decoding cases and receives test
+coverage through virtual/gpu-rasterization. This suite maintains coverage for
+images that do not use YUV decoding.
diff --git a/third_party/blink/web_tests/virtual/gpu-rasterization/README.md b/third_party/blink/web_tests/virtual/gpu-rasterization/README.md
index ee29a90..1d4ecd972 100644
--- a/third_party/blink/web_tests/virtual/gpu-rasterization/README.md
+++ b/third_party/blink/web_tests/virtual/gpu-rasterization/README.md
@@ -1,9 +1,10 @@
-# Test suite to run images/ with GPU rasterization and with the flag 
-# --enable-features=DecodeLossyWebPImagesToYUV until it is enabled by
-# default.
-# 
-# This allows YUV decoding and rasterization for images that would support it:
-# currently just lossy WebP images without alpha that have been fully loaded at
-# decode time. Because incremental YUV decoding hasn't been implemented
-# (crbug.com/943519), the tests that go down this path also use JavaScript to
-# ensure all image data has been received before we attempt decoding.
+Test suite to run images/ with --enable-gpu-rasterization.
+
+This suite tests YUV decoding and rasterization for images that have been fully
+loaded at decode time and formats that support it, e.g.
+* lossy WebP images without alpha that  and
+* JPEG YUV images with a 4:2:0 subsampling.
+
+Because incremental YUV decoding hasn't been implemented (crbug.com/943519), the
+WebP tests use JavaScript to ensure all image data has been received before we
+attempt decoding.
diff --git a/third_party/blink/web_tests/wpt_internal/display-lock/css-content-visibility/accessibility/content-visibility-accessibility-008.html b/third_party/blink/web_tests/wpt_internal/display-lock/css-content-visibility/accessibility/content-visibility-accessibility-008.html
index fddb68d..2cd76f4 100644
--- a/third_party/blink/web_tests/wpt_internal/display-lock/css-content-visibility/accessibility/content-visibility-accessibility-008.html
+++ b/third_party/blink/web_tests/wpt_internal/display-lock/css-content-visibility/accessibility/content-visibility-accessibility-008.html
@@ -44,6 +44,7 @@
   requestAnimationFrame(() => requestAnimationFrame(() => {
     // The ax object for #target got replaced since the layout object changed, so use the new ax object.
     axTarget = axElementById("target");
+    axTarget.childrenCount;  // Touch children to cause invalidations. Only necessary in web tests. Normally serializer does this.
     t.step(() => { assert_false(axTarget.isIgnored); });
     // Note that when locked, the ignored text nodes don't show up as children; so we expect 2.
     t.step(() => { assert_equals(axTarget.childrenCount, 2, "When locked, nodes in hidden subtree are visible"); });
diff --git a/third_party/metrics_proto/README.chromium b/third_party/metrics_proto/README.chromium
index 2917dce1..c0a6db5b 100644
--- a/third_party/metrics_proto/README.chromium
+++ b/third_party/metrics_proto/README.chromium
@@ -1,8 +1,8 @@
 Name: Metrics Protos
 Short Name: metrics_proto
 URL: This is the canonical public repository
-Version: 340693871
-Date: 2020/11/04 UTC
+Version: 344139149
+Date: 2020/11/24 UTC
 License: BSD
 Security Critical: Yes
 
diff --git a/third_party/metrics_proto/cast_logs.proto b/third_party/metrics_proto/cast_logs.proto
index a914367..2b423643 100644
--- a/third_party/metrics_proto/cast_logs.proto
+++ b/third_party/metrics_proto/cast_logs.proto
@@ -164,7 +164,7 @@
   repeated CastConnectionInfo cast_connection_info = 2;
 
   // Stores Cast-enabled device specific events with a various context data.
-  // Next tag: 26
+  // Next tag: 27
   message CastEventProto {
     // The name of the action, hashed by same logic used to hash user action
     // event and histogram.
@@ -243,6 +243,20 @@
 
     // Model version of hotword detector.
     optional string hotword_model_id = 25;
+
+    enum LaunchFrom {
+      FROM_UNKNOWN = 0;
+      // Launched by itself, or by the user interacting directly with the
+      // receiver device (e.g. use a TV remote to launch an app on Android TV).
+      FROM_LOCAL = 1;
+      // Launched by a Cast V1 sender using DIAL.
+      FROM_DIAL = 2;
+      // Launched by a Cast V2 sender device.
+      FROM_CAST_V2 = 3;
+      // Launched from the cloud.
+      FROM_CCS = 4;
+    }
+    optional LaunchFrom launch_from = 26;
   }
   repeated CastEventProto cast_event = 3;
 
diff --git a/third_party/metrics_proto/system_profile.proto b/third_party/metrics_proto/system_profile.proto
index fbce0ea..43e8b486 100644
--- a/third_party/metrics_proto/system_profile.proto
+++ b/third_party/metrics_proto/system_profile.proto
@@ -17,7 +17,7 @@
 // Almost all the fields should be populated on every upload. (The only
 // exception is some fields in the stability section that are only uploaded
 // once per browsing session, usually shortly after startup.)
-// Next tag: 35
+// Next tag: 36
 message SystemProfileProto {
   // The time when the client was compiled/linked, in seconds since the epoch.
   optional int64 build_timestamp = 1;
@@ -981,6 +981,22 @@
   // "com.android.chrome".
   optional string app_package_name = 26;
 
+  // The package which installed Chrome, as reported by
+  // PackageManager.getInstallerPackageName().
+  enum InstallerPackage {
+    // This field was not set.
+    INSTALLER_PACKAGE_UNKNOWN = 0;
+    // The installer package name returned by Android was empty.
+    INSTALLER_PACKAGE_NONE = 1;
+    // 'com.android.vending'.
+    INSTALLER_PACKAGE_GOOGLE_PLAY_STORE = 2;
+    // Any other non-empty value.
+    INSTALLER_PACKAGE_OTHER = 3;
+  }
+
+  // The package which installed Chrome, as reported by Android.
+  optional InstallerPackage installer_package = 35;
+
   // Data related to the "Better Together" multi-device features. This is only
   // uploaded on Chrome OS.
   // Next Tag: 5
diff --git a/tools/grit/PRESUBMIT.py b/tools/grit/PRESUBMIT.py
index cf8f3a7..43d3e98f 100644
--- a/tools/grit/PRESUBMIT.py
+++ b/tools/grit/PRESUBMIT.py
@@ -16,7 +16,9 @@
       output_api, [
           input_api.os_path.join('grit', 'test_suite_all.py'),
           input_api.os_path.join(input_api.PresubmitLocalPath(),
-                                 'preprocess_grit_test.py')
+                                 'preprocess_grit_test.py'),
+          input_api.os_path.join(input_api.PresubmitLocalPath(),
+                                 'preprocess_if_expr_test.py')
       ],
       run_on_python3=False)  # See https://crbug.com/1145395.
 
diff --git a/tools/grit/grit/format/html_inline.py b/tools/grit/grit/format/html_inline.py
index da55216ea..cd1fe1f3 100755
--- a/tools/grit/grit/format/html_inline.py
+++ b/tools/grit/grit/format/html_inline.py
@@ -255,6 +255,52 @@
     self.inlined_data = inlined_data
     self.inlined_files = inlined_files
 
+
+def CheckConditionalElements(grd_node, str):
+  def IsConditionSatisfied(src_match):
+    expr1 = src_match.group('expr1') or ''
+    expr2 = src_match.group('expr2') or ''
+    return grd_node is None or grd_node.EvaluateCondition(expr1 + expr2)
+
+  """Helper function to conditionally inline inner elements"""
+  while True:
+    begin_if = _BEGIN_IF_BLOCK.search(str)
+    if begin_if is None:
+      if _END_IF_BLOCK.search(str) is not None:
+        raise Exception('Unmatched </if>')
+      return str
+
+    condition_satisfied = IsConditionSatisfied(begin_if)
+    leading = str[0:begin_if.start()]
+    content_start = begin_if.end()
+
+    # Find matching "if" block end.
+    count = 1
+    pos = begin_if.end()
+    while True:
+      end_if = _END_IF_BLOCK.search(str, pos)
+      if end_if is None:
+        raise Exception('Unmatched <if>')
+
+      next_if = _BEGIN_IF_BLOCK.search(str, pos)
+      if next_if is None or next_if.start() >= end_if.end():
+        count = count - 1
+        if count == 0:
+          break
+        pos = end_if.end()
+      else:
+        count = count + 1
+        pos = next_if.end()
+
+    content = str[content_start:end_if.start()]
+    trailing = str[end_if.end():]
+
+    if condition_satisfied:
+      str = leading + CheckConditionalElements(grd_node, content) + trailing
+    else:
+      str = leading + trailing
+
+
 def DoInline(
     input_filename, grd_node, allow_external_script=False,
     preprocess_only=False, names_only=False, strip_whitespace=False,
@@ -317,50 +363,6 @@
       filename = filename_expansion_function(filename)
     return os.path.normpath(os.path.join(base_path, filename))
 
-  def IsConditionSatisfied(src_match):
-    expr1 = src_match.group('expr1') or ''
-    expr2 = src_match.group('expr2') or ''
-    return grd_node is None or grd_node.EvaluateCondition(expr1 + expr2)
-
-  def CheckConditionalElements(str):
-    """Helper function to conditionally inline inner elements"""
-    while True:
-      begin_if = _BEGIN_IF_BLOCK.search(str)
-      if begin_if is None:
-        if _END_IF_BLOCK.search(str) is not None:
-          raise Exception('Unmatched </if>')
-        return str
-
-      condition_satisfied = IsConditionSatisfied(begin_if)
-      leading = str[0:begin_if.start()]
-      content_start = begin_if.end()
-
-      # Find matching "if" block end.
-      count = 1
-      pos = begin_if.end()
-      while True:
-        end_if = _END_IF_BLOCK.search(str, pos)
-        if end_if is None:
-          raise Exception('Unmatched <if>')
-
-        next_if = _BEGIN_IF_BLOCK.search(str, pos)
-        if next_if is None or next_if.start() >= end_if.end():
-          count = count - 1
-          if count == 0:
-            break
-          pos = end_if.end()
-        else:
-          count = count + 1
-          pos = next_if.end()
-
-      content = str[content_start:end_if.start()]
-      trailing = str[end_if.end():]
-
-      if condition_satisfied:
-        str = leading + CheckConditionalElements(content) + trailing
-      else:
-        str = leading + trailing
-
   def InlineFileContents(src_match,
                          pattern,
                          inlined_files=inlined_files,
@@ -483,7 +485,7 @@
   # this twice. The first pass is so that we don't even bother calling
   # InlineScript, InlineCSSFile and InlineIncludeFiles on text we're eventually
   # going to throw out anyway.
-  flat_text = CheckConditionalElements(flat_text)
+  flat_text = CheckConditionalElements(grd_node, flat_text)
 
   flat_text = _INCLUDE_RE.sub(InlineIncludeFiles, flat_text)
 
@@ -506,7 +508,7 @@
 
   # Check conditional elements, second pass. This catches conditionals in any
   # of the text we just inlined.
-  flat_text = CheckConditionalElements(flat_text)
+  flat_text = CheckConditionalElements(grd_node, flat_text)
 
   # Allow custom modifications before inlining images.
   if rewrite_function:
diff --git a/tools/grit/preprocess_if_expr.gni b/tools/grit/preprocess_if_expr.gni
new file mode 100644
index 0000000..71c1cc1
--- /dev/null
+++ b/tools/grit/preprocess_if_expr.gni
@@ -0,0 +1,49 @@
+# Copyright 2020 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+import("//build/config/python.gni")
+import("//tools/grit/grit_defines.gni")
+
+template("preprocess_if_expr") {
+  # TODO(crbug.com/1112471): Get this to run cleanly under Python 3.
+  python2_action(target_name) {
+    script = "//tools/grit/preprocess_if_expr.py"
+
+    if (defined(invoker.deps)) {
+      deps = invoker.deps
+    }
+
+    inputs = []
+    outputs = []
+    foreach(in_file, invoker.in_files) {
+      inputs += [ invoker.in_folder + "/" + in_file ]
+      outputs += [ invoker.out_folder + "/" + in_file ]
+    }
+
+    args = [
+             "--in-folder",
+             rebase_path(invoker.in_folder, root_build_dir),
+             "--out-folder",
+             rebase_path(invoker.out_folder, root_build_dir),
+             "--in-files",
+           ] + invoker.in_files + grit_defines
+
+    if (defined(invoker.defines)) {
+      foreach(define, invoker.defines) {
+        args += [
+          "-D",
+          define,
+        ]
+      }
+    }
+
+    if (defined(invoker.out_manifest)) {
+      args += [
+        "--out-manifest",
+        rebase_path(invoker.out_manifest, root_build_dir),
+      ]
+      outputs += [ invoker.out_manifest ]
+    }
+  }
+}
diff --git a/tools/grit/preprocess_if_expr.py b/tools/grit/preprocess_if_expr.py
new file mode 100644
index 0000000..b06735fd
--- /dev/null
+++ b/tools/grit/preprocess_if_expr.py
@@ -0,0 +1,111 @@
+# Copyright 2020 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+import argparse
+import errno
+import io
+import json
+import os
+import sys
+
+# For Node, EvaluateExpression
+import grit.node.base
+# For CheckConditionalElements
+import grit.format.html_inline
+
+_CWD = os.getcwd()
+
+
+class PreprocessIfExprNode(grit.node.base.Node):
+  def __init__(self):
+    super(PreprocessIfExprNode, self).__init__()
+
+  def PreprocessIfExpr(self, content):
+    return grit.format.html_inline.CheckConditionalElements(self, content)
+
+  def EvaluateCondition(self, expr):
+    return grit.node.base.Node.EvaluateExpression(expr, self.defines,
+                                                  self.target_platform, {})
+
+  def SetDefines(self, defines):
+    self.defines = defines
+
+  def SetTargetPlatform(self, target_platform):
+    self.target_platform = target_platform
+
+  @staticmethod
+  def Construct(defines, target_platform):
+    node = PreprocessIfExprNode()
+    node.SetDefines(defines)
+    node.SetTargetPlatform(target_platform or sys.platform)
+    return node
+
+
+def ParseDefinesArg(definesArg):
+  defines = {}
+  for define_arg in definesArg:
+    define, = define_arg
+    parts = [part.strip() for part in define.split('=', 1)]
+    name = parts[0]
+    val = True if len(parts) == 1 else parts[1]
+    if (val == "1" or val == "true"):
+      val = True
+    elif (val == "0" or val == "false"):
+      val = False
+    defines[name] = val
+  return defines
+
+
+def main(argv):
+  parser = argparse.ArgumentParser()
+  parser.add_argument('--in-folder', required=True)
+  parser.add_argument('--out-folder', required=True)
+  parser.add_argument('--out-manifest')
+  parser.add_argument('--in-files', required=True, nargs="*")
+  parser.add_argument('-D', '--defines', nargs="*", action='append')
+  parser.add_argument('-E', '--environment')
+  parser.add_argument('-t', '--target')
+  args = parser.parse_args(argv)
+
+  in_folder = os.path.normpath(os.path.join(_CWD, args.in_folder))
+  out_folder = os.path.normpath(os.path.join(_CWD, args.out_folder))
+
+  defines = ParseDefinesArg(args.defines)
+
+  node = PreprocessIfExprNode.Construct(defines, args.target)
+
+  for input_file in args.in_files:
+    content = ""
+    with io.open(os.path.join(in_folder, input_file),
+                 encoding='utf-8',
+                 mode='r') as f:
+      content = f.read()
+
+    preprocessed = node.PreprocessIfExpr(content)
+    out_path = os.path.join(out_folder, input_file)
+    out_dir = os.path.dirname(out_path)
+    assert out_dir.startswith(out_folder), \
+           'Cannot preprocess files to locations not under %s.' % out_dir
+    try:
+      os.makedirs(out_dir)
+    except OSError as e:
+      # Ignore directory exists errors. This can happen if two build rules
+      # for overlapping directories hit the makedirs line at the same time.
+      if e.errno != errno.EEXIST:
+        raise
+    with io.open(out_path, mode='wb') as f:
+      f.write(preprocessed.encode('utf-8'))
+
+  if args.out_manifest:
+    manifest_data = {}
+    manifest_data['base_dir'] = '%s' % args.out_folder
+    manifest_data['files'] = args.in_files
+    manifest_file = open(
+        os.path.normpath(os.path.join(_CWD, args.out_manifest)), 'wb')
+    json.dump(manifest_data, manifest_file)
+  return
+
+
+if __name__ == '__main__':
+  main(sys.argv[1:])
diff --git a/tools/grit/preprocess_if_expr_test.py b/tools/grit/preprocess_if_expr_test.py
new file mode 100644
index 0000000..1738bf46
--- /dev/null
+++ b/tools/grit/preprocess_if_expr_test.py
@@ -0,0 +1,49 @@
+# Copyright 2020 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+import os
+import shutil
+import tempfile
+import unittest
+
+import preprocess_if_expr
+
+_HERE_DIR = os.path.dirname(__file__)
+
+
+class PreprocessIfExprTest(unittest.TestCase):
+  def setUp(self):
+    self._out_folder = None
+
+  def tearDown(self):
+    if self._out_folder:
+      shutil.rmtree(self._out_folder)
+
+  def _read_out_file(self, file_name):
+    assert self._out_folder
+    return open(os.path.join(self._out_folder, file_name), 'r').read()
+
+  def _run_test(self, defines, file_name):
+    assert not self._out_folder
+    self._out_folder = tempfile.mkdtemp(dir=_HERE_DIR)
+    preprocess_if_expr.main([
+        '--in-folder',
+        os.path.join(_HERE_DIR, 'preprocess_tests'),
+        '--out-folder',
+        self._out_folder,
+        '--in-files',
+        file_name,
+    ] + defines)
+
+  def testPreprocess(self):
+    self._run_test(['-D', 'foo', '-D', 'bar'], 'test_with_ifexpr.js')
+    actual = self._read_out_file('test_with_ifexpr.js')
+    self.assertIn('I should be included in HTML', actual)
+    self.assertIn('I should be included in JS', actual)
+    self.assertNotIn('I should be excluded from HTML', actual)
+    self.assertNotIn('I should be excluded from JS', actual)
+
+
+if __name__ == '__main__':
+  unittest.main()
diff --git a/tools/mb/mb_config.pyl b/tools/mb/mb_config.pyl
index 7da0c81..176f353 100644
--- a/tools/mb/mb_config.pyl
+++ b/tools/mb/mb_config.pyl
@@ -3265,7 +3265,7 @@
     },
 
     'vulkan_ndk': {
-      'gn_args': 'android32_ndk_api_level=26 android64_ndk_api_level=26',
+      'gn_args': 'android32_ndk_api_level=29 android64_ndk_api_level=29',
     },
 
     'webview_google': {
diff --git a/tools/mb/mb_config_expectations/chromium.gpu.fyi.json b/tools/mb/mb_config_expectations/chromium.gpu.fyi.json
index 48abe89..86efc752 100644
--- a/tools/mb/mb_config_expectations/chromium.gpu.fyi.json
+++ b/tools/mb/mb_config_expectations/chromium.gpu.fyi.json
@@ -15,8 +15,8 @@
   },
   "Android FYI 32 Vk Release (Pixel 2)": {
     "gn_args": {
-      "android32_ndk_api_level": 26,
-      "android64_ndk_api_level": 26,
+      "android32_ndk_api_level": 29,
+      "android64_ndk_api_level": 29,
       "build_angle_trace_perf_tests": true,
       "dcheck_always_on": true,
       "ffmpeg_branding": "Chrome",
@@ -31,8 +31,8 @@
   },
   "Android FYI 32 dEQP Vk Release (Pixel 2)": {
     "gn_args": {
-      "android32_ndk_api_level": 26,
-      "android64_ndk_api_level": 26,
+      "android32_ndk_api_level": 29,
+      "android64_ndk_api_level": 29,
       "build_angle_deqp_tests": true,
       "dcheck_always_on": true,
       "ffmpeg_branding": "Chrome",
@@ -46,8 +46,8 @@
   },
   "Android FYI 64 Vk Release (Pixel 2)": {
     "gn_args": {
-      "android32_ndk_api_level": 26,
-      "android64_ndk_api_level": 26,
+      "android32_ndk_api_level": 29,
+      "android64_ndk_api_level": 29,
       "build_angle_trace_perf_tests": true,
       "dcheck_always_on": true,
       "ffmpeg_branding": "Chrome",
@@ -63,8 +63,8 @@
   },
   "Android FYI 64 dEQP Vk Release (Pixel 2)": {
     "gn_args": {
-      "android32_ndk_api_level": 26,
-      "android64_ndk_api_level": 26,
+      "android32_ndk_api_level": 29,
+      "android64_ndk_api_level": 29,
       "build_angle_deqp_tests": true,
       "dcheck_always_on": true,
       "ffmpeg_branding": "Chrome",
@@ -323,8 +323,8 @@
   },
   "GPU FYI Perf Android 64 Builder": {
     "gn_args": {
-      "android32_ndk_api_level": 26,
-      "android64_ndk_api_level": 26,
+      "android32_ndk_api_level": 29,
+      "android64_ndk_api_level": 29,
       "build_angle_trace_perf_tests": true,
       "dcheck_always_on": false,
       "ffmpeg_branding": "Chrome",
diff --git a/tools/mb/mb_config_expectations/tryserver.chromium.android.json b/tools/mb/mb_config_expectations/tryserver.chromium.android.json
index a4cca2a..6ba7cfe 100644
--- a/tools/mb/mb_config_expectations/tryserver.chromium.android.json
+++ b/tools/mb/mb_config_expectations/tryserver.chromium.android.json
@@ -796,8 +796,8 @@
   },
   "gpu-fyi-try-android-q-pixel-2-deqp-vk-32": {
     "gn_args": {
-      "android32_ndk_api_level": 26,
-      "android64_ndk_api_level": 26,
+      "android32_ndk_api_level": 29,
+      "android64_ndk_api_level": 29,
       "build_angle_deqp_tests": true,
       "dcheck_always_on": true,
       "ffmpeg_branding": "Chrome",
@@ -811,8 +811,8 @@
   },
   "gpu-fyi-try-android-q-pixel-2-deqp-vk-64": {
     "gn_args": {
-      "android32_ndk_api_level": 26,
-      "android64_ndk_api_level": 26,
+      "android32_ndk_api_level": 29,
+      "android64_ndk_api_level": 29,
       "build_angle_deqp_tests": true,
       "dcheck_always_on": true,
       "ffmpeg_branding": "Chrome",
@@ -827,8 +827,8 @@
   },
   "gpu-fyi-try-android-q-pixel-2-vk-32": {
     "gn_args": {
-      "android32_ndk_api_level": 26,
-      "android64_ndk_api_level": 26,
+      "android32_ndk_api_level": 29,
+      "android64_ndk_api_level": 29,
       "build_angle_trace_perf_tests": true,
       "dcheck_always_on": true,
       "ffmpeg_branding": "Chrome",
@@ -843,8 +843,8 @@
   },
   "gpu-fyi-try-android-q-pixel-2-vk-64": {
     "gn_args": {
-      "android32_ndk_api_level": 26,
-      "android64_ndk_api_level": 26,
+      "android32_ndk_api_level": 29,
+      "android64_ndk_api_level": 29,
       "build_angle_trace_perf_tests": true,
       "dcheck_always_on": true,
       "ffmpeg_branding": "Chrome",
diff --git a/tools/mb/mb_config_expectations/tryserver.chromium.angle.json b/tools/mb/mb_config_expectations/tryserver.chromium.angle.json
index 3b50d9f3..fc2f09d 100644
--- a/tools/mb/mb_config_expectations/tryserver.chromium.angle.json
+++ b/tools/mb/mb_config_expectations/tryserver.chromium.angle.json
@@ -29,8 +29,8 @@
   },
   "android_angle_vk32_deqp_rel_ng": {
     "gn_args": {
-      "android32_ndk_api_level": 26,
-      "android64_ndk_api_level": 26,
+      "android32_ndk_api_level": 29,
+      "android64_ndk_api_level": 29,
       "build_angle_deqp_tests": true,
       "dcheck_always_on": true,
       "ffmpeg_branding": "Chrome",
@@ -44,8 +44,8 @@
   },
   "android_angle_vk32_rel_ng": {
     "gn_args": {
-      "android32_ndk_api_level": 26,
-      "android64_ndk_api_level": 26,
+      "android32_ndk_api_level": 29,
+      "android64_ndk_api_level": 29,
       "build_angle_trace_perf_tests": true,
       "dcheck_always_on": true,
       "ffmpeg_branding": "Chrome",
@@ -60,8 +60,8 @@
   },
   "android_angle_vk64_deqp_rel_ng": {
     "gn_args": {
-      "android32_ndk_api_level": 26,
-      "android64_ndk_api_level": 26,
+      "android32_ndk_api_level": 29,
+      "android64_ndk_api_level": 29,
       "build_angle_deqp_tests": true,
       "dcheck_always_on": true,
       "ffmpeg_branding": "Chrome",
@@ -76,8 +76,8 @@
   },
   "android_angle_vk64_rel_ng": {
     "gn_args": {
-      "android32_ndk_api_level": 26,
-      "android64_ndk_api_level": 26,
+      "android32_ndk_api_level": 29,
+      "android64_ndk_api_level": 29,
       "build_angle_trace_perf_tests": true,
       "dcheck_always_on": true,
       "ffmpeg_branding": "Chrome",
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml
index 139a34d..fdeb877 100644
--- a/tools/metrics/histograms/enums.xml
+++ b/tools/metrics/histograms/enums.xml
@@ -29574,8 +29574,8 @@
   <int value="2968" label="SVGSMILDiscardElementParsed"/>
   <int value="2969" label="SVGSMILDiscardElementTriggered"/>
   <int value="2971" label="V8PointerEvent_GetPredictedEvents_Method"/>
-  <int value="2972" label="ScrollSnapOnViewportBreaks"/>
-  <int value="2973" label="ScrollPaddingOnViewportBreaks"/>
+  <int value="2972" label="OBSOLETE_ScrollSnapOnViewportBreaks"/>
+  <int value="2973" label="OBSOLETE_ScrollPaddingOnViewportBreaks"/>
   <int value="2974" label="DownloadInAdFrame"/>
   <int value="2975" label="DownloadInSandbox"/>
   <int value="2976" label="DownloadWithoutUserGesture"/>
@@ -39781,6 +39781,11 @@
   <int value="1" label="Cache Miss"/>
 </enum>
 
+<enum name="KaleidoscopeDialogClosedBoolean">
+  <int value="0" label="The user did not open a watch action"/>
+  <int value="1" label="The user did open a watch action"/>
+</enum>
+
 <enum name="KaleidoscopeFirstRunProgress">
   <int value="0" label="Completed"/>
   <int value="1" label="Provider Selection"/>
diff --git a/tools/metrics/histograms/histograms_xml/android/histograms.xml b/tools/metrics/histograms/histograms_xml/android/histograms.xml
index fb6839c..36f0fec 100644
--- a/tools/metrics/histograms/histograms_xml/android/histograms.xml
+++ b/tools/metrics/histograms/histograms_xml/android/histograms.xml
@@ -1145,9 +1145,8 @@
 </histogram>
 
 <histogram name="Android.Language.UiIsSystemLanguage" enum="BooleanMatched"
-    expires_after="2020-12-01">
+    expires_after="2021-12-01">
   <owner>perrier@chromium.org</owner>
-  <owner>megjablon@chromium.org</owner>
   <owner>chrome-language@google.com</owner>
   <summary>
     Reports whether the Chrome UI language is the same as the Android system
@@ -1156,9 +1155,8 @@
 </histogram>
 
 <histogram name="Android.Language.WrongLanguageAfterResume" enum="Boolean"
-    expires_after="2020-12-01">
-  <owner>tiborg@chromium.org</owner>
-  <owner>heamy@chromium.org</owner>
+    expires_after="2021-12-01">
+  <owner>perrier@chromium.org</owner>
   <owner>chrome-language@google.com</owner>
   <summary>
     Reports whether Chrome was started in a language other than the system
diff --git a/tools/metrics/histograms/histograms_xml/blink/histograms.xml b/tools/metrics/histograms/histograms_xml/blink/histograms.xml
index 582b45a..0c4e5ee 100644
--- a/tools/metrics/histograms/histograms_xml/blink/histograms.xml
+++ b/tools/metrics/histograms/histograms_xml/blink/histograms.xml
@@ -1479,6 +1479,17 @@
   </summary>
 </histogram>
 
+<histogram name="Blink.MemoryCache.RevalidationPolicy.PerTopFrameSite"
+    enum="RevalidationPolicy" expires_after="2021-04-21">
+  <owner>shivanisha@chromium.org</owner>
+  <owner>privacy-sandbox-dev@chromium.org</owner>
+  <summary>
+    RevalidationPolicy used for requests for each resource type. Logged only if
+    the resource is found in the memory cache and if the same top-frame site had
+    loaded this resource earlier.
+  </summary>
+</histogram>
+
 <histogram name="Blink.MemoryCache.RevalidationPolicy.Preload"
     enum="RevalidationPolicy" expires_after="2021-04-21">
   <owner>hiroshige@chromium.org</owner>
diff --git a/tools/metrics/histograms/histograms_xml/histogram_suffixes_list.xml b/tools/metrics/histograms/histograms_xml/histogram_suffixes_list.xml
index 2031cf2c..f40130f 100644
--- a/tools/metrics/histograms/histograms_xml/histogram_suffixes_list.xml
+++ b/tools/metrics/histograms/histograms_xml/histogram_suffixes_list.xml
@@ -15861,6 +15861,8 @@
   <affected-histogram name="Blink.MemoryCache.RevalidationPolicy"/>
   <affected-histogram name="Blink.MemoryCache.RevalidationPolicy.Dead"/>
   <affected-histogram name="Blink.MemoryCache.RevalidationPolicy.PerDocument"/>
+  <affected-histogram
+      name="Blink.MemoryCache.RevalidationPolicy.PerTopFrameSite"/>
   <affected-histogram name="Blink.MemoryCache.RevalidationPolicy.Preload"/>
   <affected-histogram name="PreloadScanner.Counts"/>
   <affected-histogram name="PreloadScanner.Counts.Miss"/>
diff --git a/tools/metrics/histograms/histograms_xml/media/histograms.xml b/tools/metrics/histograms/histograms_xml/media/histograms.xml
index bdb3d622..81e9c411 100644
--- a/tools/metrics/histograms/histograms_xml/media/histograms.xml
+++ b/tools/metrics/histograms/histograms_xml/media/histograms.xml
@@ -2140,6 +2140,16 @@
   </summary>
 </histogram>
 
+<histogram name="Media.Kaleidoscope.DialogClosed"
+    enum="KaleidoscopeDialogClosedBoolean" expires_after="2021-08-19">
+  <owner>beccahughes@chromium.org</owner>
+  <owner>media-dev@chromium.org</owner>
+  <summary>
+    Recorded each time a user closes a dialog inside Kaleidoscope with whether
+    the user opened a watch action from that dialog.
+  </summary>
+</histogram>
+
 <histogram name="Media.Kaleidoscope.FirstRunProgress"
     enum="KaleidoscopeFirstRunProgress" expires_after="2021-08-19">
   <owner>steimel@chromium.org</owner>
diff --git a/tools/metrics/histograms/histograms_xml/others/histograms.xml b/tools/metrics/histograms/histograms_xml/others/histograms.xml
index d4a85eb..fa3477b2 100644
--- a/tools/metrics/histograms/histograms_xml/others/histograms.xml
+++ b/tools/metrics/histograms/histograms_xml/others/histograms.xml
@@ -7666,8 +7666,8 @@
 </histogram>
 
 <histogram name="LanguageSettings.Actions" enum="LanguageSettingsActionType"
-    expires_after="2020-12-01">
-  <owner>googleo@chromium.org</owner>
+    expires_after="2021-12-01">
+  <owner>perrier@chromium.org</owner>
   <owner>chrome-language@google.com</owner>
   <summary>
     The actions taken on languages settings, recorded every time they happen.
diff --git a/tools/perf/core/bot_platforms.py b/tools/perf/core/bot_platforms.py
index 8166fba..10ce287 100644
--- a/tools/perf/core/bot_platforms.py
+++ b/tools/perf/core/bot_platforms.py
@@ -495,7 +495,7 @@
     'Windows Intel HD 630 towers, Core i7-7700 3.6 GHz, 16GB RAM,'
     ' Intel Kaby Lake HD Graphics 630', _WIN_10_BENCHMARK_CONFIGS,
     26, 'win', executables=_WIN_10_EXECUTABLE_CONFIGS)
-WIN_7 = PerfPlatform('Win 7 Perf', 'N/A', _WIN_7_BENCHMARK_CONFIGS, 3, 'win')
+WIN_7 = PerfPlatform('Win 7 Perf', 'N/A', _WIN_7_BENCHMARK_CONFIGS, 2, 'win')
 WIN_7_GPU = PerfPlatform('Win 7 Nvidia GPU Perf', 'N/A',
                          _WIN_7_GPU_BENCHMARK_CONFIGS, 3, 'win')
 
diff --git a/tools/perf/core/shard_maps/timing_data/win_7_perf_timing.json b/tools/perf/core/shard_maps/timing_data/win_7_perf_timing.json
index e004caf6..990a6d2 100644
--- a/tools/perf/core/shard_maps/timing_data/win_7_perf_timing.json
+++ b/tools/perf/core/shard_maps/timing_data/win_7_perf_timing.json
@@ -1,42 +1,42 @@
 [
     {
-        "duration": "46.0",
+        "duration": "49.0",
         "name": "loading.desktop/AirBnB_warm"
     },
     {
-        "duration": "37.0",
+        "duration": "38.0",
         "name": "loading.desktop/Aljayyash_cold"
     },
     {
-        "duration": "18.0",
+        "duration": "21.0",
         "name": "loading.desktop/AllRecipes_cold"
     },
     {
-        "duration": "25.0",
+        "duration": "24.0",
         "name": "loading.desktop/Baidu_warm"
     },
     {
-        "duration": "32.0",
+        "duration": "34.0",
         "name": "loading.desktop/Naver_cold"
     },
     {
-        "duration": "9.0",
+        "duration": "10.0",
         "name": "loading.desktop/Orange_cold"
     },
     {
-        "duration": "9.0",
+        "duration": "10.0",
         "name": "loading.desktop/Orange_warm"
     },
     {
-        "duration": "57.0",
+        "duration": "60.0",
         "name": "loading.desktop/Taobao_warm"
     },
     {
-        "duration": "48.0",
+        "duration": "51.0",
         "name": "loading.desktop/TheOnion_cold"
     },
     {
-        "duration": "26.0",
+        "duration": "27.0",
         "name": "loading.desktop/ru.wikipedia_warm"
     }
 ]
\ No newline at end of file
diff --git a/tools/perf/core/shard_maps/win_7_perf_map.json b/tools/perf/core/shard_maps/win_7_perf_map.json
index b3b5a7c5..c6d1935 100644
--- a/tools/perf/core/shard_maps/win_7_perf_map.json
+++ b/tools/perf/core/shard_maps/win_7_perf_map.json
@@ -2,7 +2,7 @@
     "0": {
         "benchmarks": {
             "loading.desktop": {
-                "end": 5,
+                "end": 6,
                 "abridged": true
             }
         }
@@ -10,28 +10,18 @@
     "1": {
         "benchmarks": {
             "loading.desktop": {
-                "begin": 5,
-                "end": 7,
-                "abridged": true
-            }
-        }
-    },
-    "2": {
-        "benchmarks": {
-            "loading.desktop": {
-                "begin": 7,
+                "begin": 6,
                 "abridged": true
             }
         }
     },
     "extra_infos": {
         "num_stories": 10,
-        "predicted_min_shard_time": 178.0,
+        "predicted_min_shard_time": 310.0,
         "predicted_min_shard_index": 1,
-        "predicted_max_shard_time": 224.0,
-        "predicted_max_shard_index": 2,
-        "shard #0": 212.0,
-        "shard #1": 178.0,
-        "shard #2": 224.0
+        "predicted_max_shard_time": 338.0,
+        "predicted_max_shard_index": 0,
+        "shard #0": 338.0,
+        "shard #1": 310.0
     }
 }
\ No newline at end of file
diff --git a/tools/resources/generate_resource_allowlist.py b/tools/resources/generate_resource_allowlist.py
index af35bce3..bafa4a0 100755
--- a/tools/resources/generate_resource_allowlist.py
+++ b/tools/resources/generate_resource_allowlist.py
@@ -28,29 +28,26 @@
                            'bin')
 
 
+def ExtractAllowlistFromFile(path, resource_ids):
+  with open(path, 'rb') as f:
+    data = f.read()
+  prefix = b'AllowlistedResource<'
+  start_idx = 0
+  while start_idx != -1:
+    start_idx = data.find(prefix, start_idx)
+    if start_idx != -1:
+      end_idx = data.find(b'>', start_idx)
+      resource_ids.add(int(data[start_idx + len(prefix):end_idx]))
+      start_idx = end_idx
+
+
 def GetResourceAllowlistELF(path):
   # Produce a resource allowlist by searching for debug info referring to
-  # AllowlistedResource. It's sufficient to look for strings in .debug_str
-  # rather than trying to parse all of the debug info.
-  readelf = subprocess.Popen(['readelf', '-p', '.debug_str', path],
-                             stdout=subprocess.PIPE)
+  # AllowlistedResource.
+  # This used to use "readelf -p .debug_str", but it doesn't seem to work with
+  # use_debug_fission=true. Reading the raw file is faster anyways.
   resource_ids = set()
-  for line in readelf.stdout:
-    # Read a line of the form "  [   123]  AllowlistedResource<456>". We're
-    # only interested in the string, not the offset. We're also not interested
-    # in header lines.
-    split = line.split(']', 1)
-    if len(split) < 2:
-      continue
-    s = split[1][2:]
-    if s.startswith('AllowlistedResource<'):
-      try:
-        resource_ids.add(int(s[len('AllowlistedResource<'):-len('>') - 1]))
-      except ValueError:
-        continue
-  exit_code = readelf.wait()
-  if exit_code != 0:
-    raise Exception('readelf exited with exit code %d' % exit_code)
+  ExtractAllowlistFromFile(path, resource_ids)
   return resource_ids
 
 
@@ -111,17 +108,8 @@
   paths = ar.ExpandThinArchives(paths)
 
   resource_ids = set()
-  prefix = b'AllowlistedResource<'
   for p in paths:
-    with open(p, 'rb') as f:
-      data = f.read()
-    start_idx = 0
-    while start_idx != -1:
-      start_idx = data.find(prefix, start_idx)
-      if start_idx != -1:
-        end_idx = data.find(b'>', start_idx)
-        resource_ids.add(int(data[start_idx + len(prefix):end_idx]))
-        start_idx = end_idx
+    ExtractAllowlistFromFile(p, resource_ids)
   return resource_ids
 
 
diff --git a/ui/webui/resources/cr_elements/cr_fingerprint/cr_fingerprint_progress_arc.js b/ui/webui/resources/cr_elements/cr_fingerprint/cr_fingerprint_progress_arc.js
index 347fc7022..5a16538 100644
--- a/ui/webui/resources/cr_elements/cr_fingerprint/cr_fingerprint_progress_arc.js
+++ b/ui/webui/resources/cr_elements/cr_fingerprint/cr_fingerprint_progress_arc.js
@@ -2,8 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-// #import {CrLottieElement} from '../cr_lottie/cr_lottie.m.js';
-
 /** @type {string} */
 /* #export */ const FINGEPRINT_TICK_DARK_URL =
     'chrome://theme/IDR_FINGERPRINT_COMPLETE_TICK_DARK';
diff --git a/ui/webui/resources/cr_elements/cr_toolbar/cr_toolbar_selection_overlay.js b/ui/webui/resources/cr_elements/cr_toolbar/cr_toolbar_selection_overlay.js
index 7a93044..4386d4a 100644
--- a/ui/webui/resources/cr_elements/cr_toolbar/cr_toolbar_selection_overlay.js
+++ b/ui/webui/resources/cr_elements/cr_toolbar/cr_toolbar_selection_overlay.js
@@ -42,6 +42,10 @@
     'updateSelectionLabel_(show, selectionLabel)',
   ],
 
+  hostAttributes: {
+    'role': 'toolbar',
+  },
+
   /** @return {HTMLElement} */
   get deleteButton() {
     return /** @type {HTMLElement} */ (this.$$('#delete'));
@@ -64,6 +68,7 @@
     this.debounce('updateSelectionLabel_', () => {
       this.selectionLabel_ =
           this.show ? this.selectionLabel : this.selectionLabel_;
+      this.setAttribute('aria-label', this.selectionLabel_);
     });
   },
 
diff --git a/weblayer/browser/java/BUILD.gn b/weblayer/browser/java/BUILD.gn
index 262af50..9147086 100644
--- a/weblayer/browser/java/BUILD.gn
+++ b/weblayer/browser/java/BUILD.gn
@@ -227,6 +227,7 @@
     "//components/omnibox/browser:browser_java",
     "//components/page_info/android:java",
     "//components/payments/content/android:java",
+    "//components/payments/content/android:service_java",
     "//components/payments/mojom:mojom_java",
     "//components/permissions/android:java",
     "//components/prefs/android:java",
diff --git a/weblayer/public/java/org/chromium/weblayer/Tab.java b/weblayer/public/java/org/chromium/weblayer/Tab.java
index 8b242c6..ca30011 100644
--- a/weblayer/public/java/org/chromium/weblayer/Tab.java
+++ b/weblayer/public/java/org/chromium/weblayer/Tab.java
@@ -47,6 +47,8 @@
     private static final Map<Integer, Tab> sTabMap = new HashMap<Integer, Tab>();
 
     private ITab mImpl;
+    // Remember the stack of Tab destruction.
+    private Throwable mDestroyStack;
     private final NavigationController mNavigationController;
     private final FindInPageController mFindInPageController;
     private final MediaCaptureController mMediaCaptureController;
@@ -117,7 +119,7 @@
 
     private void throwIfDestroyed() {
         if (mImpl == null) {
-            throw new IllegalStateException("Tab can not be used once destroyed");
+            throw new IllegalStateException("Tab can not be used once destroyed", mDestroyStack);
         }
     }
 
@@ -831,6 +833,7 @@
             if (getTabById(mId) == this) unregisterTab(this);
             mDestroyOnRemove = false;
             mImpl = null;
+            mDestroyStack = new RuntimeException("onRemovedFromBrowser");
         }
     }
 
@@ -903,6 +906,7 @@
                 // Ensure that the app will fail fast if the embedder mistakenly tries to call back
                 // into the implementation via this Tab.
                 mImpl = null;
+                mDestroyStack = new RuntimeException("onTabDestroyed");
             } else {
                 // This Tab should not have been destroyed yet.
                 assert mImpl != null;