lighthouse 9.5.0-dev.20220509 → 9.6.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (259) hide show
  1. package/changelog.md +70 -0
  2. package/dist/report/bundle.esm.js +400 -808
  3. package/dist/report/flow.js +22 -27
  4. package/dist/report/standalone.js +18 -23
  5. package/flow-report/src/summary/category.tsx +1 -1
  6. package/jest.config.js +1 -1
  7. package/lighthouse-cli/.eslintrc.cjs +4 -3
  8. package/lighthouse-cli/bin.js +1 -0
  9. package/lighthouse-cli/cli-flags.js +4 -3
  10. package/lighthouse-cli/commands/commands.js +1 -0
  11. package/lighthouse-cli/commands/list-audits.js +1 -0
  12. package/lighthouse-cli/commands/list-locales.js +1 -0
  13. package/lighthouse-cli/commands/list-trace-categories.js +1 -0
  14. package/lighthouse-cli/index.js +1 -0
  15. package/lighthouse-cli/printer.js +1 -0
  16. package/lighthouse-cli/run.js +24 -9
  17. package/lighthouse-cli/sentry-prompt.js +1 -0
  18. package/lighthouse-cli/test/smokehouse/core-tests.js +1 -0
  19. package/lighthouse-cli/test/smokehouse/frontends/back-compat-util.js +1 -0
  20. package/lighthouse-cli/test/smokehouse/frontends/lib.js +1 -0
  21. package/lighthouse-cli/test/smokehouse/frontends/node.js +1 -0
  22. package/lighthouse-cli/test/smokehouse/frontends/smokehouse-bin.js +1 -0
  23. package/lighthouse-cli/test/smokehouse/lib/child-process-error.js +1 -0
  24. package/lighthouse-cli/test/smokehouse/lib/concurrent-mapper.js +1 -0
  25. package/lighthouse-cli/test/smokehouse/lib/local-console.js +1 -0
  26. package/lighthouse-cli/test/smokehouse/lighthouse-runners/bundle.js +23 -109
  27. package/lighthouse-cli/test/smokehouse/lighthouse-runners/cli.js +3 -2
  28. package/lighthouse-cli/test/smokehouse/lighthouse-runners/devtools.js +19 -28
  29. package/lighthouse-cli/test/smokehouse/report-assert.js +4 -3
  30. package/lighthouse-cli/test/smokehouse/smokehouse.js +1 -1
  31. package/lighthouse-cli/test/smokehouse/version-check-test.js +3 -0
  32. package/lighthouse-cli/test/smokehouse/version-check.js +1 -0
  33. package/lighthouse-core/audits/accessibility/accesskeys.js +1 -1
  34. package/lighthouse-core/audits/accessibility/aria-allowed-attr.js +1 -1
  35. package/lighthouse-core/audits/accessibility/aria-command-name.js +1 -1
  36. package/lighthouse-core/audits/accessibility/aria-hidden-body.js +1 -1
  37. package/lighthouse-core/audits/accessibility/aria-hidden-focus.js +1 -1
  38. package/lighthouse-core/audits/accessibility/aria-input-field-name.js +1 -1
  39. package/lighthouse-core/audits/accessibility/aria-meter-name.js +1 -1
  40. package/lighthouse-core/audits/accessibility/aria-progressbar-name.js +1 -1
  41. package/lighthouse-core/audits/accessibility/aria-required-attr.js +1 -1
  42. package/lighthouse-core/audits/accessibility/aria-required-children.js +1 -1
  43. package/lighthouse-core/audits/accessibility/aria-required-parent.js +1 -1
  44. package/lighthouse-core/audits/accessibility/aria-roles.js +1 -1
  45. package/lighthouse-core/audits/accessibility/aria-toggle-field-name.js +1 -1
  46. package/lighthouse-core/audits/accessibility/aria-tooltip-name.js +1 -1
  47. package/lighthouse-core/audits/accessibility/aria-treeitem-name.js +1 -1
  48. package/lighthouse-core/audits/accessibility/aria-valid-attr-value.js +1 -1
  49. package/lighthouse-core/audits/accessibility/aria-valid-attr.js +1 -1
  50. package/lighthouse-core/audits/accessibility/button-name.js +1 -1
  51. package/lighthouse-core/audits/accessibility/bypass.js +1 -1
  52. package/lighthouse-core/audits/accessibility/color-contrast.js +1 -1
  53. package/lighthouse-core/audits/accessibility/definition-list.js +1 -1
  54. package/lighthouse-core/audits/accessibility/dlitem.js +1 -1
  55. package/lighthouse-core/audits/accessibility/document-title.js +1 -1
  56. package/lighthouse-core/audits/accessibility/duplicate-id-active.js +1 -1
  57. package/lighthouse-core/audits/accessibility/duplicate-id-aria.js +1 -1
  58. package/lighthouse-core/audits/accessibility/form-field-multiple-labels.js +1 -1
  59. package/lighthouse-core/audits/accessibility/frame-title.js +1 -1
  60. package/lighthouse-core/audits/accessibility/heading-order.js +1 -1
  61. package/lighthouse-core/audits/accessibility/html-has-lang.js +1 -1
  62. package/lighthouse-core/audits/accessibility/html-lang-valid.js +1 -1
  63. package/lighthouse-core/audits/accessibility/image-alt.js +1 -1
  64. package/lighthouse-core/audits/accessibility/input-image-alt.js +1 -1
  65. package/lighthouse-core/audits/accessibility/label.js +1 -1
  66. package/lighthouse-core/audits/accessibility/link-name.js +1 -1
  67. package/lighthouse-core/audits/accessibility/list.js +1 -1
  68. package/lighthouse-core/audits/accessibility/listitem.js +5 -5
  69. package/lighthouse-core/audits/accessibility/meta-refresh.js +1 -1
  70. package/lighthouse-core/audits/accessibility/meta-viewport.js +1 -1
  71. package/lighthouse-core/audits/accessibility/object-alt.js +1 -1
  72. package/lighthouse-core/audits/accessibility/tabindex.js +1 -1
  73. package/lighthouse-core/audits/accessibility/td-headers-attr.js +1 -1
  74. package/lighthouse-core/audits/accessibility/th-has-data-cells.js +1 -1
  75. package/lighthouse-core/audits/accessibility/valid-lang.js +1 -1
  76. package/lighthouse-core/audits/accessibility/video-caption.js +1 -1
  77. package/lighthouse-core/audits/byte-efficiency/byte-efficiency-audit.js +1 -2
  78. package/lighthouse-core/audits/byte-efficiency/duplicated-javascript.js +12 -11
  79. package/lighthouse-core/audits/byte-efficiency/efficient-animated-content.js +1 -1
  80. package/lighthouse-core/audits/byte-efficiency/legacy-javascript.js +24 -22
  81. package/lighthouse-core/audits/byte-efficiency/offscreen-images.js +2 -3
  82. package/lighthouse-core/audits/byte-efficiency/render-blocking-resources.js +3 -2
  83. package/lighthouse-core/audits/byte-efficiency/unminified-css.js +5 -3
  84. package/lighthouse-core/audits/byte-efficiency/unminified-javascript.js +11 -10
  85. package/lighthouse-core/audits/byte-efficiency/unused-css-rules.js +1 -0
  86. package/lighthouse-core/audits/byte-efficiency/unused-javascript.js +8 -11
  87. package/lighthouse-core/audits/byte-efficiency/uses-responsive-images.js +1 -1
  88. package/lighthouse-core/audits/byte-efficiency/uses-text-compression.js +1 -1
  89. package/lighthouse-core/audits/deprecations.js +598 -8
  90. package/lighthouse-core/audits/diagnostics.js +3 -4
  91. package/lighthouse-core/audits/dobetterweb/doctype.js +9 -20
  92. package/lighthouse-core/audits/dobetterweb/geolocation-on-start.js +1 -1
  93. package/lighthouse-core/audits/dobetterweb/no-document-write.js +1 -1
  94. package/lighthouse-core/audits/dobetterweb/notification-on-start.js +1 -1
  95. package/lighthouse-core/audits/dobetterweb/uses-http2.js +1 -2
  96. package/lighthouse-core/audits/dobetterweb/uses-passive-event-listeners.js +1 -1
  97. package/lighthouse-core/audits/errors-in-console.js +2 -2
  98. package/lighthouse-core/audits/long-tasks.js +2 -3
  99. package/lighthouse-core/audits/metrics/experimental-interaction-to-next-paint.js +3 -1
  100. package/lighthouse-core/audits/metrics/first-contentful-paint-3g.js +2 -2
  101. package/lighthouse-core/audits/metrics/first-contentful-paint.js +2 -3
  102. package/lighthouse-core/audits/metrics/first-meaningful-paint.js +2 -3
  103. package/lighthouse-core/audits/metrics/interactive.js +2 -3
  104. package/lighthouse-core/audits/metrics/largest-contentful-paint.js +2 -3
  105. package/lighthouse-core/audits/metrics/max-potential-fid.js +2 -3
  106. package/lighthouse-core/audits/metrics/speed-index.js +2 -3
  107. package/lighthouse-core/audits/metrics/total-blocking-time.js +2 -3
  108. package/lighthouse-core/audits/metrics.js +2 -3
  109. package/lighthouse-core/audits/no-unload-listeners.js +15 -7
  110. package/lighthouse-core/audits/predictive-perf.js +1 -2
  111. package/lighthouse-core/audits/preload-lcp-image.js +3 -3
  112. package/lighthouse-core/audits/redirects.js +1 -1
  113. package/lighthouse-core/audits/script-treemap-data.js +45 -45
  114. package/lighthouse-core/audits/seo/http-status-code.js +4 -2
  115. package/lighthouse-core/audits/seo/link-text.js +0 -2
  116. package/lighthouse-core/audits/server-response-time.js +17 -2
  117. package/lighthouse-core/audits/service-worker.js +2 -7
  118. package/lighthouse-core/audits/timing-budget.js +2 -3
  119. package/lighthouse-core/audits/uses-rel-preconnect.js +1 -1
  120. package/lighthouse-core/audits/uses-rel-preload.js +1 -1
  121. package/lighthouse-core/audits/valid-source-maps.js +14 -12
  122. package/lighthouse-core/audits/violation-audit.js +1 -1
  123. package/lighthouse-core/audits/work-during-interaction.js +280 -0
  124. package/lighthouse-core/computed/critical-request-chains.js +9 -5
  125. package/lighthouse-core/computed/js-bundles.js +11 -11
  126. package/lighthouse-core/computed/main-resource.js +2 -3
  127. package/lighthouse-core/computed/metrics/first-contentful-paint-all-frames.js +1 -1
  128. package/lighthouse-core/computed/metrics/first-contentful-paint.js +1 -1
  129. package/lighthouse-core/computed/metrics/first-meaningful-paint.js +1 -1
  130. package/lighthouse-core/computed/metrics/interactive.js +1 -1
  131. package/lighthouse-core/computed/metrics/lantern-first-contentful-paint.js +1 -1
  132. package/lighthouse-core/computed/metrics/lantern-first-meaningful-paint.js +1 -1
  133. package/lighthouse-core/computed/metrics/lantern-interactive.js +1 -1
  134. package/lighthouse-core/computed/metrics/lantern-largest-contentful-paint.js +1 -1
  135. package/lighthouse-core/computed/metrics/lantern-max-potential-fid.js +1 -1
  136. package/lighthouse-core/computed/metrics/lantern-metric.js +5 -3
  137. package/lighthouse-core/computed/metrics/lantern-speed-index.js +1 -1
  138. package/lighthouse-core/computed/metrics/lantern-total-blocking-time.js +1 -1
  139. package/lighthouse-core/computed/metrics/largest-contentful-paint-all-frames.js +1 -1
  140. package/lighthouse-core/computed/metrics/largest-contentful-paint.js +1 -1
  141. package/lighthouse-core/computed/metrics/max-potential-fid.js +1 -1
  142. package/lighthouse-core/computed/metrics/metric.js +0 -1
  143. package/lighthouse-core/computed/metrics/responsiveness.js +12 -9
  144. package/lighthouse-core/computed/metrics/speed-index.js +1 -1
  145. package/lighthouse-core/computed/metrics/timing-summary.js +6 -13
  146. package/lighthouse-core/computed/metrics/total-blocking-time.js +1 -1
  147. package/lighthouse-core/computed/module-duplication.js +5 -6
  148. package/lighthouse-core/computed/page-dependency-graph.js +28 -55
  149. package/lighthouse-core/computed/resource-summary.js +5 -5
  150. package/lighthouse-core/computed/unused-css.js +7 -6
  151. package/lighthouse-core/computed/unused-javascript-summary.js +36 -16
  152. package/lighthouse-core/config/budget.js +2 -2
  153. package/lighthouse-core/config/default-config.js +1 -2
  154. package/lighthouse-core/config/metrics-to-audits.js +5 -0
  155. package/lighthouse-core/fraggle-rock/api.js +1 -1
  156. package/lighthouse-core/fraggle-rock/config/default-config.js +8 -5
  157. package/lighthouse-core/fraggle-rock/gather/base-artifacts.js +3 -6
  158. package/lighthouse-core/fraggle-rock/gather/driver.js +2 -2
  159. package/lighthouse-core/fraggle-rock/gather/navigation-runner.js +26 -51
  160. package/lighthouse-core/fraggle-rock/gather/runner-helpers.js +3 -0
  161. package/lighthouse-core/fraggle-rock/gather/session.js +2 -2
  162. package/lighthouse-core/fraggle-rock/gather/snapshot-runner.js +4 -5
  163. package/lighthouse-core/fraggle-rock/gather/timespan-runner.js +6 -6
  164. package/lighthouse-core/gather/connections/cri.js +0 -1
  165. package/lighthouse-core/gather/driver/execution-context.js +2 -4
  166. package/lighthouse-core/gather/driver/navigation.js +9 -9
  167. package/lighthouse-core/gather/driver/network-monitor.js +3 -16
  168. package/lighthouse-core/gather/driver.js +1 -6
  169. package/lighthouse-core/gather/fetcher.js +210 -34
  170. package/lighthouse-core/gather/gather-runner.js +17 -13
  171. package/lighthouse-core/gather/gatherers/accessibility.js +4 -16
  172. package/lighthouse-core/gather/gatherers/console-messages.js +2 -4
  173. package/lighthouse-core/gather/gatherers/dobetterweb/doctype.js +2 -4
  174. package/lighthouse-core/gather/gatherers/full-page-screenshot.js +2 -3
  175. package/lighthouse-core/gather/gatherers/js-usage.js +87 -12
  176. package/lighthouse-core/gather/gatherers/link-elements.js +14 -12
  177. package/lighthouse-core/gather/gatherers/main-document-content.js +8 -8
  178. package/lighthouse-core/gather/gatherers/script-elements.js +56 -7
  179. package/lighthouse-core/gather/gatherers/seo/robots-txt.js +30 -2
  180. package/lighthouse-core/gather/gatherers/source-maps.js +1 -3
  181. package/lighthouse-core/gather/gatherers/trace-elements.js +21 -2
  182. package/lighthouse-core/gather/gatherers/web-app-manifest.js +2 -2
  183. package/lighthouse-core/index.js +2 -26
  184. package/lighthouse-core/lib/cdt/generated/SourceMap.js +1 -1
  185. package/lighthouse-core/lib/dependency-graph/simulator/network-analyzer.js +29 -8
  186. package/lighthouse-core/lib/navigation-error.js +4 -13
  187. package/lighthouse-core/lib/script-helpers.js +6 -11
  188. package/lighthouse-core/lib/url-shim.js +2 -2
  189. package/lighthouse-core/runner.js +5 -0
  190. package/lighthouse-core/scripts/manual-chrome-launcher.js +1 -0
  191. package/lighthouse-core/util-commonjs.js +24 -28
  192. package/package.json +12 -12
  193. package/readme.md +1 -1
  194. package/report/.eslintrc.cjs +1 -3
  195. package/report/assets/styles.css +10 -12
  196. package/report/assets/templates.html +9 -10
  197. package/report/clients/bundle.js +1 -0
  198. package/report/clients/standalone.js +1 -0
  199. package/report/generator/report-generator.js +21 -46
  200. package/report/renderer/api.js +1 -0
  201. package/report/renderer/category-renderer.js +1 -0
  202. package/report/renderer/components.js +304 -303
  203. package/report/renderer/crc-details-renderer.js +1 -0
  204. package/report/renderer/details-renderer.js +10 -10
  205. package/report/renderer/dom.js +1 -0
  206. package/report/renderer/drop-down-menu.js +1 -0
  207. package/report/renderer/element-screenshot-renderer.js +4 -0
  208. package/report/renderer/features-util.js +1 -0
  209. package/report/renderer/i18n.js +62 -118
  210. package/report/renderer/logger.js +1 -0
  211. package/report/renderer/open-tab.js +3 -1
  212. package/report/renderer/performance-category-renderer.js +1 -0
  213. package/report/renderer/pwa-category-renderer.js +1 -0
  214. package/report/renderer/report-renderer.js +1 -0
  215. package/report/renderer/report-ui-features.js +1 -0
  216. package/report/renderer/snippet-renderer.js +1 -0
  217. package/report/renderer/swap-locale-feature.js +1 -0
  218. package/report/renderer/text-encoding.js +1 -0
  219. package/report/renderer/topbar-features.js +1 -0
  220. package/report/renderer/util.js +24 -27
  221. package/report/test/clients/bundle-test.js +4 -0
  222. package/report/test/generator/file-namer-test.js +1 -0
  223. package/report/test/generator/report-generator-test.js +20 -25
  224. package/report/test/renderer/category-renderer-test.js +3 -0
  225. package/report/test/renderer/components-test.js +3 -0
  226. package/report/test/renderer/crc-details-renderer-test.js +3 -0
  227. package/report/test/renderer/details-renderer-test.js +12 -58
  228. package/report/test/renderer/dom-test.js +3 -0
  229. package/report/test/renderer/element-screenshot-renderer-test.js +6 -3
  230. package/report/test/renderer/i18n-test.js +25 -70
  231. package/report/test/renderer/performance-category-renderer-test.js +4 -11
  232. package/report/test/renderer/pwa-category-renderer-test.js +3 -0
  233. package/report/test/renderer/report-renderer-axe-test.js +3 -0
  234. package/report/test/renderer/report-renderer-test.js +3 -0
  235. package/report/test/renderer/report-ui-features-test.js +3 -0
  236. package/report/test/renderer/snippet-renderer-test.js +3 -0
  237. package/report/test/renderer/text-encoding-test.js +3 -0
  238. package/report/test/renderer/util-test.js +5 -2
  239. package/report/test-assets/faux-psi.js +1 -2
  240. package/shared/localization/locales/en-US.json +260 -53
  241. package/shared/localization/locales/en-XL.json +260 -53
  242. package/shared/test/localization/format-test.js +2 -0
  243. package/shared/test/localization/locales-test.js +2 -0
  244. package/shared/test/localization/swap-locale-test.js +2 -0
  245. package/third-party/chromium-synchronization/inspector-issueAdded-types-test.js +2 -0
  246. package/third-party/chromium-synchronization/installability-errors-test.js +2 -0
  247. package/tsconfig.json +0 -1
  248. package/types/artifacts.d.ts +9 -48
  249. package/types/config.d.ts +0 -2
  250. package/types/externs.d.ts +2 -2
  251. package/types/gatherer.d.ts +2 -1
  252. package/types/global-lh.d.ts +0 -3
  253. package/types/lhr/audit-details.d.ts +3 -1
  254. package/types/lhr/lhr.d.ts +2 -2
  255. package/types/lhr/treemap.d.ts +1 -0
  256. package/lighthouse-core/audits/script-elements-test-audit.js +0 -30
  257. package/lighthouse-core/gather/gatherers/scripts.js +0 -154
  258. package/report/test/.eslintrc.cjs +0 -11
  259. package/shared/test/localization/.eslintrc.cjs +0 -11
@@ -314,26 +314,24 @@ class Util {
314
314
  }
315
315
 
316
316
  const MAX_LENGTH = 64;
317
- if (parsedUrl.protocol !== 'data:') {
318
- // Always elide hexadecimal hash
319
- name = name.replace(/([a-f0-9]{7})[a-f0-9]{13}[a-f0-9]*/g, `$1${ELLIPSIS}`);
320
- // Also elide other hash-like mixed-case strings
321
- name = name.replace(/([a-zA-Z0-9-_]{9})(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])[a-zA-Z0-9-_]{10,}/g,
322
- `$1${ELLIPSIS}`);
323
- // Also elide long number sequences
324
- name = name.replace(/(\d{3})\d{6,}/g, `$1${ELLIPSIS}`);
325
- // Merge any adjacent ellipses
326
- name = name.replace(/\u2026+/g, ELLIPSIS);
327
-
328
- // Elide query params first
329
- if (name.length > MAX_LENGTH && name.includes('?')) {
330
- // Try to leave the first query parameter intact
331
- name = name.replace(/\?([^=]*)(=)?.*/, `?$1$2${ELLIPSIS}`);
332
-
333
- // Remove it all if it's still too long
334
- if (name.length > MAX_LENGTH) {
335
- name = name.replace(/\?.*/, `?${ELLIPSIS}`);
336
- }
317
+ // Always elide hexadecimal hash
318
+ name = name.replace(/([a-f0-9]{7})[a-f0-9]{13}[a-f0-9]*/g, `$1${ELLIPSIS}`);
319
+ // Also elide other hash-like mixed-case strings
320
+ name = name.replace(/([a-zA-Z0-9-_]{9})(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])[a-zA-Z0-9-_]{10,}/g,
321
+ `$1${ELLIPSIS}`);
322
+ // Also elide long number sequences
323
+ name = name.replace(/(\d{3})\d{6,}/g, `$1${ELLIPSIS}`);
324
+ // Merge any adjacent ellipses
325
+ name = name.replace(/\u2026+/g, ELLIPSIS);
326
+
327
+ // Elide query params first
328
+ if (name.length > MAX_LENGTH && name.includes('?')) {
329
+ // Try to leave the first query parameter intact
330
+ name = name.replace(/\?([^=]*)(=)?.*/, `?$1$2${ELLIPSIS}`);
331
+
332
+ // Remove it all if it's still too long
333
+ if (name.length > MAX_LENGTH) {
334
+ name = name.replace(/\?.*/, `?${ELLIPSIS}`);
337
335
  }
338
336
  }
339
337
 
@@ -429,11 +427,10 @@ class Util {
429
427
  break;
430
428
  case 'devtools': {
431
429
  const {cpuSlowdownMultiplier, requestLatencyMs} = throttling;
432
- // eslint-disable-next-line max-len
433
430
  cpuThrottling = `${Util.i18n.formatNumber(cpuSlowdownMultiplier)}x slowdown (DevTools)`;
434
- networkThrottling = `${Util.i18n.formatMilliseconds(requestLatencyMs)} HTTP RTT, ` +
435
- `${Util.i18n.formatKbps(throttling.downloadThroughputKbps)} down, ` +
436
- `${Util.i18n.formatKbps(throttling.uploadThroughputKbps)} up (DevTools)`;
431
+ networkThrottling = `${Util.i18n.formatNumber(requestLatencyMs)}${NBSP}ms HTTP RTT, ` +
432
+ `${Util.i18n.formatNumber(throttling.downloadThroughputKbps)}${NBSP}Kbps down, ` +
433
+ `${Util.i18n.formatNumber(throttling.uploadThroughputKbps)}${NBSP}Kbps up (DevTools)`;
437
434
 
438
435
  const isSlow4G = () => {
439
436
  return requestLatencyMs === 150 * 3.75 &&
@@ -445,10 +442,9 @@ class Util {
445
442
  }
446
443
  case 'simulate': {
447
444
  const {cpuSlowdownMultiplier, rttMs, throughputKbps} = throttling;
448
- // eslint-disable-next-line max-len
449
445
  cpuThrottling = `${Util.i18n.formatNumber(cpuSlowdownMultiplier)}x slowdown (Simulated)`;
450
- networkThrottling = `${Util.i18n.formatMilliseconds(rttMs)} TCP RTT, ` +
451
- `${Util.i18n.formatKbps(throughputKbps)} throughput (Simulated)`;
446
+ networkThrottling = `${Util.i18n.formatNumber(rttMs)}${NBSP}ms TCP RTT, ` +
447
+ `${Util.i18n.formatNumber(throughputKbps)}${NBSP}Kbps throughput (Simulated)`;
452
448
 
453
449
  const isSlow4G = () => {
454
450
  return rttMs === 150 && throughputKbps === 1.6 * 1024;
@@ -704,7 +700,7 @@ Util.UIStrings = UIStrings;
704
700
 
705
701
  /** @typedef {import('./dom.js').DOM} DOM */
706
702
 
707
- /* eslint-disable max-len, quotes, comma-spacing */
703
+ /* eslint-disable max-len */
708
704
 
709
705
 
710
706
  /**
@@ -712,19 +708,19 @@ Util.UIStrings = UIStrings;
712
708
  */
713
709
  function create3pFilterComponent(dom) {
714
710
  const el0 = dom.createFragment();
715
- const el1 = dom.createElement("style");
716
- el1.append("\n .lh-3p-filter {\n color: var(--color-gray-600);\n float: right;\n padding: 6px var(--stackpack-padding-horizontal);\n }\n .lh-3p-filter-label, .lh-3p-filter-input {\n vertical-align: middle;\n user-select: none;\n }\n .lh-3p-filter-input:disabled + .lh-3p-ui-string {\n text-decoration: line-through;\n }\n ");
711
+ const el1 = dom.createElement('style');
712
+ el1.append('\n .lh-3p-filter {\n color: var(--color-gray-600);\n float: right;\n padding: 6px var(--stackpack-padding-horizontal);\n }\n .lh-3p-filter-label, .lh-3p-filter-input {\n vertical-align: middle;\n user-select: none;\n }\n .lh-3p-filter-input:disabled + .lh-3p-ui-string {\n text-decoration: line-through;\n }\n ');
717
713
  el0.append(el1);
718
- const el2 = dom.createElement("div", "lh-3p-filter");
719
- const el3 = dom.createElement("label", "lh-3p-filter-label");
720
- const el4 = dom.createElement("input", "lh-3p-filter-input");
714
+ const el2 = dom.createElement('div', 'lh-3p-filter');
715
+ const el3 = dom.createElement('label', 'lh-3p-filter-label');
716
+ const el4 = dom.createElement('input', 'lh-3p-filter-input');
721
717
  el4.setAttribute('type', 'checkbox');
722
718
  el4.setAttribute('checked', '');
723
- const el5 = dom.createElement("span", "lh-3p-ui-string");
724
- el5.append("Show 3rd party resources");
725
- const el6 = dom.createElement("span", "lh-3p-filter-count");
726
- el3.append(" ",el4," ",el5," (",el6,") ");
727
- el2.append(" ",el3," ");
719
+ const el5 = dom.createElement('span', 'lh-3p-ui-string');
720
+ el5.append('Show 3rd party resources');
721
+ const el6 = dom.createElement('span', 'lh-3p-filter-count');
722
+ el3.append(' ', el4, ' ', el5, ' (', el6, ') ');
723
+ el2.append(' ', el3, ' ');
728
724
  el0.append(el2);
729
725
  return el0;
730
726
  }
@@ -734,22 +730,22 @@ function create3pFilterComponent(dom) {
734
730
  */
735
731
  function createAuditComponent(dom) {
736
732
  const el0 = dom.createFragment();
737
- const el1 = dom.createElement("div", "lh-audit");
738
- const el2 = dom.createElement("details", "lh-expandable-details");
739
- const el3 = dom.createElement("summary");
740
- const el4 = dom.createElement("div", "lh-audit__header lh-expandable-details__summary");
741
- const el5 = dom.createElement("span", "lh-audit__score-icon");
742
- const el6 = dom.createElement("span", "lh-audit__title-and-text");
743
- const el7 = dom.createElement("span", "lh-audit__title");
744
- const el8 = dom.createElement("span", "lh-audit__display-text");
745
- el6.append(" ",el7," ",el8," ");
746
- const el9 = dom.createElement("div", "lh-chevron-container");
747
- el4.append(" ",el5," ",el6," ",el9," ");
748
- el3.append(" ",el4," ");
749
- const el10 = dom.createElement("div", "lh-audit__description");
750
- const el11 = dom.createElement("div", "lh-audit__stackpacks");
751
- el2.append(" ",el3," ",el10," ",el11," ");
752
- el1.append(" ",el2," ");
733
+ const el1 = dom.createElement('div', 'lh-audit');
734
+ const el2 = dom.createElement('details', 'lh-expandable-details');
735
+ const el3 = dom.createElement('summary');
736
+ const el4 = dom.createElement('div', 'lh-audit__header lh-expandable-details__summary');
737
+ const el5 = dom.createElement('span', 'lh-audit__score-icon');
738
+ const el6 = dom.createElement('span', 'lh-audit__title-and-text');
739
+ const el7 = dom.createElement('span', 'lh-audit__title');
740
+ const el8 = dom.createElement('span', 'lh-audit__display-text');
741
+ el6.append(' ', el7, ' ', el8, ' ');
742
+ const el9 = dom.createElement('div', 'lh-chevron-container');
743
+ el4.append(' ', el5, ' ', el6, ' ', el9, ' ');
744
+ el3.append(' ', el4, ' ');
745
+ const el10 = dom.createElement('div', 'lh-audit__description');
746
+ const el11 = dom.createElement('div', 'lh-audit__stackpacks');
747
+ el2.append(' ', el3, ' ', el10, ' ', el11, ' ');
748
+ el1.append(' ', el2, ' ');
753
749
  el0.append(el1);
754
750
  return el0;
755
751
  }
@@ -759,12 +755,12 @@ function createAuditComponent(dom) {
759
755
  */
760
756
  function createCategoryHeaderComponent(dom) {
761
757
  const el0 = dom.createFragment();
762
- const el1 = dom.createElement("div", "lh-category-header");
763
- const el2 = dom.createElement("div", "lh-score__gauge");
758
+ const el1 = dom.createElement('div', 'lh-category-header');
759
+ const el2 = dom.createElement('div', 'lh-score__gauge');
764
760
  el2.setAttribute('role', 'heading');
765
761
  el2.setAttribute('aria-level', '2');
766
- const el3 = dom.createElement("div", "lh-category-header__description");
767
- el1.append(" ",el2," ",el3," ");
762
+ const el3 = dom.createElement('div', 'lh-category-header__description');
763
+ el1.append(' ', el2, ' ', el3, ' ');
768
764
  el0.append(el1);
769
765
  return el0;
770
766
  }
@@ -774,15 +770,15 @@ function createCategoryHeaderComponent(dom) {
774
770
  */
775
771
  function createChevronComponent(dom) {
776
772
  const el0 = dom.createFragment();
777
- const el1 = dom.createElementNS("http://www.w3.org/2000/svg", "svg", "lh-chevron");
773
+ const el1 = dom.createElementNS('http://www.w3.org/2000/svg', 'svg', 'lh-chevron');
778
774
  el1.setAttribute('viewBox', '0 0 100 100');
779
- const el2 = dom.createElementNS("http://www.w3.org/2000/svg", "g", "lh-chevron__lines");
780
- const el3 = dom.createElementNS("http://www.w3.org/2000/svg", "path", "lh-chevron__line lh-chevron__line-left");
775
+ const el2 = dom.createElementNS('http://www.w3.org/2000/svg', 'g', 'lh-chevron__lines');
776
+ const el3 = dom.createElementNS('http://www.w3.org/2000/svg', 'path', 'lh-chevron__line lh-chevron__line-left');
781
777
  el3.setAttribute('d', 'M10 50h40');
782
- const el4 = dom.createElementNS("http://www.w3.org/2000/svg", "path", "lh-chevron__line lh-chevron__line-right");
778
+ const el4 = dom.createElementNS('http://www.w3.org/2000/svg', 'path', 'lh-chevron__line lh-chevron__line-right');
783
779
  el4.setAttribute('d', 'M90 50H50');
784
- el2.append(" ",el3," ",el4," ");
785
- el1.append(" ",el2," ");
780
+ el2.append(' ', el3, ' ', el4, ' ');
781
+ el1.append(' ', el2, ' ');
786
782
  el0.append(el1);
787
783
  return el0;
788
784
  }
@@ -792,22 +788,22 @@ function createChevronComponent(dom) {
792
788
  */
793
789
  function createClumpComponent(dom) {
794
790
  const el0 = dom.createFragment();
795
- const el1 = dom.createElement("div", "lh-audit-group");
796
- const el2 = dom.createElement("details", "lh-clump");
797
- const el3 = dom.createElement("summary");
798
- const el4 = dom.createElement("div", "lh-audit-group__summary");
799
- const el5 = dom.createElement("div", "lh-audit-group__header");
800
- const el6 = dom.createElement("span", "lh-audit-group__title");
801
- const el7 = dom.createElement("span", "lh-audit-group__itemcount");
802
- el5.append(" ",el6," ",el7," "," "," ");
803
- const el8 = dom.createElement("div", "lh-clump-toggle");
804
- const el9 = dom.createElement("span", "lh-clump-toggletext--show");
805
- const el10 = dom.createElement("span", "lh-clump-toggletext--hide");
806
- el8.append(" ",el9," ",el10," ");
807
- el4.append(" ",el5," ",el8," ");
808
- el3.append(" ",el4," ");
809
- el2.append(" ",el3," ");
810
- el1.append(" "," ",el2," ");
791
+ const el1 = dom.createElement('div', 'lh-audit-group');
792
+ const el2 = dom.createElement('details', 'lh-clump');
793
+ const el3 = dom.createElement('summary');
794
+ const el4 = dom.createElement('div', 'lh-audit-group__summary');
795
+ const el5 = dom.createElement('div', 'lh-audit-group__header');
796
+ const el6 = dom.createElement('span', 'lh-audit-group__title');
797
+ const el7 = dom.createElement('span', 'lh-audit-group__itemcount');
798
+ el5.append(' ', el6, ' ', el7, ' ', ' ', ' ');
799
+ const el8 = dom.createElement('div', 'lh-clump-toggle');
800
+ const el9 = dom.createElement('span', 'lh-clump-toggletext--show');
801
+ const el10 = dom.createElement('span', 'lh-clump-toggletext--hide');
802
+ el8.append(' ', el9, ' ', el10, ' ');
803
+ el4.append(' ', el5, ' ', el8, ' ');
804
+ el3.append(' ', el4, ' ');
805
+ el2.append(' ', el3, ' ');
806
+ el1.append(' ', ' ', el2, ' ');
811
807
  el0.append(el1);
812
808
  return el0;
813
809
  }
@@ -817,19 +813,19 @@ function createClumpComponent(dom) {
817
813
  */
818
814
  function createCrcComponent(dom) {
819
815
  const el0 = dom.createFragment();
820
- const el1 = dom.createElement("div", "lh-crc-container");
821
- const el2 = dom.createElement("style");
822
- el2.append("\n .lh-crc .lh-tree-marker {\n width: 12px;\n height: 26px;\n display: block;\n float: left;\n background-position: top left;\n }\n .lh-crc .lh-horiz-down {\n background: url('data:image/svg+xml;utf8,<svg width=\"16\" height=\"26\" viewBox=\"0 0 16 26\" xmlns=\"http://www.w3.org/2000/svg\"><g fill=\"%23D8D8D8\" fill-rule=\"evenodd\"><path d=\"M16 12v2H-2v-2z\"/><path d=\"M9 12v14H7V12z\"/></g></svg>');\n }\n .lh-crc .lh-right {\n background: url('data:image/svg+xml;utf8,<svg width=\"16\" height=\"26\" viewBox=\"0 0 16 26\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M16 12v2H0v-2z\" fill=\"%23D8D8D8\" fill-rule=\"evenodd\"/></svg>');\n }\n .lh-crc .lh-up-right {\n background: url('data:image/svg+xml;utf8,<svg width=\"16\" height=\"26\" viewBox=\"0 0 16 26\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M7 0h2v14H7zm2 12h7v2H9z\" fill=\"%23D8D8D8\" fill-rule=\"evenodd\"/></svg>');\n }\n .lh-crc .lh-vert-right {\n background: url('data:image/svg+xml;utf8,<svg width=\"16\" height=\"26\" viewBox=\"0 0 16 26\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M7 0h2v27H7zm2 12h7v2H9z\" fill=\"%23D8D8D8\" fill-rule=\"evenodd\"/></svg>');\n }\n .lh-crc .lh-vert {\n background: url('data:image/svg+xml;utf8,<svg width=\"16\" height=\"26\" viewBox=\"0 0 16 26\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M7 0h2v26H7z\" fill=\"%23D8D8D8\" fill-rule=\"evenodd\"/></svg>');\n }\n .lh-crc .lh-crc-tree {\n font-size: 14px;\n width: 100%;\n overflow-x: auto;\n }\n .lh-crc .lh-crc-node {\n height: 26px;\n line-height: 26px;\n white-space: nowrap;\n }\n .lh-crc .lh-crc-node__tree-value {\n margin-left: 10px;\n }\n .lh-crc .lh-crc-node__tree-value div {\n display: inline;\n }\n .lh-crc .lh-crc-node__chain-duration {\n font-weight: 700;\n }\n .lh-crc .lh-crc-initial-nav {\n color: #595959;\n font-style: italic;\n }\n .lh-crc__summary-value {\n margin-bottom: 10px;\n }\n ");
823
- const el3 = dom.createElement("div");
824
- const el4 = dom.createElement("div", "lh-crc__summary-value");
825
- const el5 = dom.createElement("span", "lh-crc__longest_duration_label");
826
- const el6 = dom.createElement("b", "lh-crc__longest_duration");
827
- el4.append(" ",el5," ",el6," ");
828
- el3.append(" ",el4," ");
829
- const el7 = dom.createElement("div", "lh-crc");
830
- const el8 = dom.createElement("div", "lh-crc-initial-nav");
831
- el7.append(" ",el8," "," ");
832
- el1.append(" ",el2," ",el3," ",el7," ");
816
+ const el1 = dom.createElement('div', 'lh-crc-container');
817
+ const el2 = dom.createElement('style');
818
+ el2.append('\n .lh-crc .lh-tree-marker {\n width: 12px;\n height: 26px;\n display: block;\n float: left;\n background-position: top left;\n }\n .lh-crc .lh-horiz-down {\n background: url(\'data:image/svg+xml;utf8,<svg width="16" height="26" viewBox="0 0 16 26" xmlns="http://www.w3.org/2000/svg"><g fill="%23D8D8D8" fill-rule="evenodd"><path d="M16 12v2H-2v-2z"/><path d="M9 12v14H7V12z"/></g></svg>\');\n }\n .lh-crc .lh-right {\n background: url(\'data:image/svg+xml;utf8,<svg width="16" height="26" viewBox="0 0 16 26" xmlns="http://www.w3.org/2000/svg"><path d="M16 12v2H0v-2z" fill="%23D8D8D8" fill-rule="evenodd"/></svg>\');\n }\n .lh-crc .lh-up-right {\n background: url(\'data:image/svg+xml;utf8,<svg width="16" height="26" viewBox="0 0 16 26" xmlns="http://www.w3.org/2000/svg"><path d="M7 0h2v14H7zm2 12h7v2H9z" fill="%23D8D8D8" fill-rule="evenodd"/></svg>\');\n }\n .lh-crc .lh-vert-right {\n background: url(\'data:image/svg+xml;utf8,<svg width="16" height="26" viewBox="0 0 16 26" xmlns="http://www.w3.org/2000/svg"><path d="M7 0h2v27H7zm2 12h7v2H9z" fill="%23D8D8D8" fill-rule="evenodd"/></svg>\');\n }\n .lh-crc .lh-vert {\n background: url(\'data:image/svg+xml;utf8,<svg width="16" height="26" viewBox="0 0 16 26" xmlns="http://www.w3.org/2000/svg"><path d="M7 0h2v26H7z" fill="%23D8D8D8" fill-rule="evenodd"/></svg>\');\n }\n .lh-crc .lh-crc-tree {\n font-size: 14px;\n width: 100%;\n overflow-x: auto;\n }\n .lh-crc .lh-crc-node {\n height: 26px;\n line-height: 26px;\n white-space: nowrap;\n }\n .lh-crc .lh-crc-node__tree-value {\n margin-left: 10px;\n }\n .lh-crc .lh-crc-node__tree-value div {\n display: inline;\n }\n .lh-crc .lh-crc-node__chain-duration {\n font-weight: 700;\n }\n .lh-crc .lh-crc-initial-nav {\n color: #595959;\n font-style: italic;\n }\n .lh-crc__summary-value {\n margin-bottom: 10px;\n }\n ');
819
+ const el3 = dom.createElement('div');
820
+ const el4 = dom.createElement('div', 'lh-crc__summary-value');
821
+ const el5 = dom.createElement('span', 'lh-crc__longest_duration_label');
822
+ const el6 = dom.createElement('b', 'lh-crc__longest_duration');
823
+ el4.append(' ', el5, ' ', el6, ' ');
824
+ el3.append(' ', el4, ' ');
825
+ const el7 = dom.createElement('div', 'lh-crc');
826
+ const el8 = dom.createElement('div', 'lh-crc-initial-nav');
827
+ el7.append(' ', el8, ' ', ' ');
828
+ el1.append(' ', el2, ' ', el3, ' ', el7, ' ');
833
829
  el0.append(el1);
834
830
  return el0;
835
831
  }
@@ -839,10 +835,10 @@ function createCrcComponent(dom) {
839
835
  */
840
836
  function createCrcChainComponent(dom) {
841
837
  const el0 = dom.createFragment();
842
- const el1 = dom.createElement("div", "lh-crc-node");
843
- const el2 = dom.createElement("span", "lh-crc-node__tree-marker");
844
- const el3 = dom.createElement("span", "lh-crc-node__tree-value");
845
- el1.append(" ",el2," ",el3," ");
838
+ const el1 = dom.createElement('div', 'lh-crc-node');
839
+ const el2 = dom.createElement('span', 'lh-crc-node__tree-marker');
840
+ const el3 = dom.createElement('span', 'lh-crc-node__tree-value');
841
+ el1.append(' ', el2, ' ', el3, ' ');
846
842
  el0.append(el1);
847
843
  return el0;
848
844
  }
@@ -852,23 +848,22 @@ function createCrcChainComponent(dom) {
852
848
  */
853
849
  function createElementScreenshotComponent(dom) {
854
850
  const el0 = dom.createFragment();
855
- const el1 = dom.createElement("div", "lh-element-screenshot");
856
- const el2 = dom.createElement("div", "lh-element-screenshot__content");
857
- const el3 = dom.createElement("div", "lh-element-screenshot__image");
858
- const el4 = dom.createElement("div", "lh-element-screenshot__mask");
859
- const el5 = dom.createElementNS("http://www.w3.org/2000/svg", "svg");
860
- el5.setAttribute('height', '0');
861
- el5.setAttribute('width', '0');
862
- const el6 = dom.createElementNS("http://www.w3.org/2000/svg", "defs");
863
- const el7 = dom.createElementNS("http://www.w3.org/2000/svg", "clipPath");
864
- el7.setAttribute('clipPathUnits', 'objectBoundingBox');
865
- el6.append(" ",el7," "," ");
866
- el5.append(" ",el6," ");
867
- el4.append(" ",el5," ");
868
- const el8 = dom.createElement("div", "lh-element-screenshot__element-marker");
869
- el3.append(" ",el4," ",el8," ");
870
- el2.append(" ",el3," ");
871
- el1.append(" ",el2," ");
851
+ const el1 = dom.createElement('div', 'lh-element-screenshot');
852
+ const el2 = dom.createElement('div', 'lh-element-screenshot__content');
853
+ const el3 = dom.createElement('div', 'lh-element-screenshot__mask');
854
+ const el4 = dom.createElementNS('http://www.w3.org/2000/svg', 'svg');
855
+ el4.setAttribute('height', '0');
856
+ el4.setAttribute('width', '0');
857
+ const el5 = dom.createElementNS('http://www.w3.org/2000/svg', 'defs');
858
+ const el6 = dom.createElementNS('http://www.w3.org/2000/svg', 'clipPath');
859
+ el6.setAttribute('clipPathUnits', 'objectBoundingBox');
860
+ el5.append(' ', el6, ' ', ' ');
861
+ el4.append(' ', el5, ' ');
862
+ el3.append(' ', el4, ' ');
863
+ const el7 = dom.createElement('div', 'lh-element-screenshot__image');
864
+ const el8 = dom.createElement('div', 'lh-element-screenshot__element-marker');
865
+ el2.append(' ', el3, ' ', el7, ' ', el8, ' ');
866
+ el1.append(' ', el2, ' ');
872
867
  el0.append(el1);
873
868
  return el0;
874
869
  }
@@ -878,23 +873,23 @@ function createElementScreenshotComponent(dom) {
878
873
  */
879
874
  function createFooterComponent(dom) {
880
875
  const el0 = dom.createFragment();
881
- const el1 = dom.createElement("style");
882
- el1.append("\n .lh-footer {\n padding: var(--footer-padding-vertical) calc(var(--default-padding) * 2);\n max-width: var(--report-content-max-width);\n margin: 0 auto;\n }\n .lh-footer .lh-generated {\n text-align: center;\n }\n ");
876
+ const el1 = dom.createElement('style');
877
+ el1.append('\n .lh-footer {\n padding: var(--footer-padding-vertical) calc(var(--default-padding) * 2);\n max-width: var(--report-content-max-width);\n margin: 0 auto;\n }\n .lh-footer .lh-generated {\n text-align: center;\n }\n ');
883
878
  el0.append(el1);
884
- const el2 = dom.createElement("footer", "lh-footer");
885
- const el3 = dom.createElement("ul", "lh-meta__items");
886
- el3.append(" ");
887
- const el4 = dom.createElement("div", "lh-generated");
888
- const el5 = dom.createElement("b");
889
- el5.append("Lighthouse");
890
- const el6 = dom.createElement("span", "lh-footer__version");
891
- const el7 = dom.createElement("a", "lh-footer__version_issue");
879
+ const el2 = dom.createElement('footer', 'lh-footer');
880
+ const el3 = dom.createElement('ul', 'lh-meta__items');
881
+ el3.append(' ');
882
+ const el4 = dom.createElement('div', 'lh-generated');
883
+ const el5 = dom.createElement('b');
884
+ el5.append('Lighthouse');
885
+ const el6 = dom.createElement('span', 'lh-footer__version');
886
+ const el7 = dom.createElement('a', 'lh-footer__version_issue');
892
887
  el7.setAttribute('href', 'https://github.com/GoogleChrome/Lighthouse/issues');
893
888
  el7.setAttribute('target', '_blank');
894
889
  el7.setAttribute('rel', 'noopener');
895
- el7.append("File an issue");
896
- el4.append(" "," Generated by ",el5," ",el6," | ",el7," ");
897
- el2.append(" ",el3," ",el4," ");
890
+ el7.append('File an issue');
891
+ el4.append(' ', ' Generated by ', el5, ' ', el6, ' | ', el7, ' ');
892
+ el2.append(' ', el3, ' ', el4, ' ');
898
893
  el0.append(el2);
899
894
  return el0;
900
895
  }
@@ -904,14 +899,14 @@ function createFooterComponent(dom) {
904
899
  */
905
900
  function createFractionComponent(dom) {
906
901
  const el0 = dom.createFragment();
907
- const el1 = dom.createElement("a", "lh-fraction__wrapper");
908
- const el2 = dom.createElement("div", "lh-fraction__content-wrapper");
909
- const el3 = dom.createElement("div", "lh-fraction__content");
910
- const el4 = dom.createElement("div", "lh-fraction__background");
911
- el3.append(" ",el4," ");
912
- el2.append(" ",el3," ");
913
- const el5 = dom.createElement("div", "lh-fraction__label");
914
- el1.append(" ",el2," ",el5," ");
902
+ const el1 = dom.createElement('a', 'lh-fraction__wrapper');
903
+ const el2 = dom.createElement('div', 'lh-fraction__content-wrapper');
904
+ const el3 = dom.createElement('div', 'lh-fraction__content');
905
+ const el4 = dom.createElement('div', 'lh-fraction__background');
906
+ el3.append(' ', el4, ' ');
907
+ el2.append(' ', el3, ' ');
908
+ const el5 = dom.createElement('div', 'lh-fraction__label');
909
+ el1.append(' ', el2, ' ', el5, ' ');
915
910
  el0.append(el1);
916
911
  return el0;
917
912
  }
@@ -921,25 +916,25 @@ function createFractionComponent(dom) {
921
916
  */
922
917
  function createGaugeComponent(dom) {
923
918
  const el0 = dom.createFragment();
924
- const el1 = dom.createElement("a", "lh-gauge__wrapper");
925
- const el2 = dom.createElement("div", "lh-gauge__svg-wrapper");
926
- const el3 = dom.createElementNS("http://www.w3.org/2000/svg", "svg", "lh-gauge");
919
+ const el1 = dom.createElement('a', 'lh-gauge__wrapper');
920
+ const el2 = dom.createElement('div', 'lh-gauge__svg-wrapper');
921
+ const el3 = dom.createElementNS('http://www.w3.org/2000/svg', 'svg', 'lh-gauge');
927
922
  el3.setAttribute('viewBox', '0 0 120 120');
928
- const el4 = dom.createElementNS("http://www.w3.org/2000/svg", "circle", "lh-gauge-base");
923
+ const el4 = dom.createElementNS('http://www.w3.org/2000/svg', 'circle', 'lh-gauge-base');
929
924
  el4.setAttribute('r', '56');
930
925
  el4.setAttribute('cx', '60');
931
926
  el4.setAttribute('cy', '60');
932
927
  el4.setAttribute('stroke-width', '8');
933
- const el5 = dom.createElementNS("http://www.w3.org/2000/svg", "circle", "lh-gauge-arc");
928
+ const el5 = dom.createElementNS('http://www.w3.org/2000/svg', 'circle', 'lh-gauge-arc');
934
929
  el5.setAttribute('r', '56');
935
930
  el5.setAttribute('cx', '60');
936
931
  el5.setAttribute('cy', '60');
937
932
  el5.setAttribute('stroke-width', '8');
938
- el3.append(" ",el4," ",el5," ");
939
- el2.append(" ",el3," ");
940
- const el6 = dom.createElement("div", "lh-gauge__percentage");
941
- const el7 = dom.createElement("div", "lh-gauge__label");
942
- el1.append(" "," ",el2," ",el6," "," ",el7," ");
933
+ el3.append(' ', el4, ' ', el5, ' ');
934
+ el2.append(' ', el3, ' ');
935
+ const el6 = dom.createElement('div', 'lh-gauge__percentage');
936
+ const el7 = dom.createElement('div', 'lh-gauge__label');
937
+ el1.append(' ', ' ', el2, ' ', el6, ' ', ' ', el7, ' ');
943
938
  el0.append(el1);
944
939
  return el0;
945
940
  }
@@ -949,97 +944,97 @@ function createGaugeComponent(dom) {
949
944
  */
950
945
  function createGaugePwaComponent(dom) {
951
946
  const el0 = dom.createFragment();
952
- const el1 = dom.createElement("style");
953
- el1.append("\n .lh-gauge--pwa .lh-gauge--pwa__component {\n display: none;\n }\n .lh-gauge--pwa__wrapper:not(.lh-badged--all) .lh-gauge--pwa__logo > path {\n /* Gray logo unless everything is passing. */\n fill: #B0B0B0;\n }\n\n .lh-gauge--pwa__disc {\n fill: var(--color-gray-200);\n }\n\n .lh-gauge--pwa__logo--primary-color {\n fill: #304FFE;\n }\n\n .lh-gauge--pwa__logo--secondary-color {\n fill: #3D3D3D;\n }\n .lh-dark .lh-gauge--pwa__logo--secondary-color {\n fill: #D8B6B6;\n }\n\n /* No passing groups. */\n .lh-gauge--pwa__wrapper:not([class*='lh-badged--']) .lh-gauge--pwa__na-line {\n display: inline;\n }\n /* Just optimized. Same n/a line as no passing groups. */\n .lh-gauge--pwa__wrapper.lh-badged--pwa-optimized:not(.lh-badged--pwa-installable) .lh-gauge--pwa__na-line {\n display: inline;\n }\n\n /* Just installable. */\n .lh-gauge--pwa__wrapper.lh-badged--pwa-installable .lh-gauge--pwa__installable-badge {\n display: inline;\n }\n\n /* All passing groups. */\n .lh-gauge--pwa__wrapper.lh-badged--all .lh-gauge--pwa__check-circle {\n display: inline;\n }\n ");
947
+ const el1 = dom.createElement('style');
948
+ el1.append('\n .lh-gauge--pwa .lh-gauge--pwa__component {\n display: none;\n }\n .lh-gauge--pwa__wrapper:not(.lh-badged--all) .lh-gauge--pwa__logo > path {\n /* Gray logo unless everything is passing. */\n fill: #B0B0B0;\n }\n\n .lh-gauge--pwa__disc {\n fill: var(--color-gray-200);\n }\n\n .lh-gauge--pwa__logo--primary-color {\n fill: #304FFE;\n }\n\n .lh-gauge--pwa__logo--secondary-color {\n fill: #3D3D3D;\n }\n .lh-dark .lh-gauge--pwa__logo--secondary-color {\n fill: #D8B6B6;\n }\n\n /* No passing groups. */\n .lh-gauge--pwa__wrapper:not([class*=\'lh-badged--\']) .lh-gauge--pwa__na-line {\n display: inline;\n }\n /* Just optimized. Same n/a line as no passing groups. */\n .lh-gauge--pwa__wrapper.lh-badged--pwa-optimized:not(.lh-badged--pwa-installable) .lh-gauge--pwa__na-line {\n display: inline;\n }\n\n /* Just installable. */\n .lh-gauge--pwa__wrapper.lh-badged--pwa-installable .lh-gauge--pwa__installable-badge {\n display: inline;\n }\n\n /* All passing groups. */\n .lh-gauge--pwa__wrapper.lh-badged--all .lh-gauge--pwa__check-circle {\n display: inline;\n }\n ');
954
949
  el0.append(el1);
955
- const el2 = dom.createElement("a", "lh-gauge__wrapper lh-gauge--pwa__wrapper");
956
- const el3 = dom.createElementNS("http://www.w3.org/2000/svg", "svg", "lh-gauge lh-gauge--pwa");
950
+ const el2 = dom.createElement('a', 'lh-gauge__wrapper lh-gauge--pwa__wrapper');
951
+ const el3 = dom.createElementNS('http://www.w3.org/2000/svg', 'svg', 'lh-gauge lh-gauge--pwa');
957
952
  el3.setAttribute('viewBox', '0 0 60 60');
958
- const el4 = dom.createElementNS("http://www.w3.org/2000/svg", "defs");
959
- const el5 = dom.createElementNS("http://www.w3.org/2000/svg", "linearGradient");
953
+ const el4 = dom.createElementNS('http://www.w3.org/2000/svg', 'defs');
954
+ const el5 = dom.createElementNS('http://www.w3.org/2000/svg', 'linearGradient');
960
955
  el5.setAttribute('id', 'lh-gauge--pwa__check-circle__gradient');
961
956
  el5.setAttribute('x1', '50%');
962
957
  el5.setAttribute('y1', '0%');
963
958
  el5.setAttribute('x2', '50%');
964
959
  el5.setAttribute('y2', '100%');
965
- const el6 = dom.createElementNS("http://www.w3.org/2000/svg", "stop");
960
+ const el6 = dom.createElementNS('http://www.w3.org/2000/svg', 'stop');
966
961
  el6.setAttribute('stop-color', '#00C852');
967
962
  el6.setAttribute('offset', '0%');
968
- const el7 = dom.createElementNS("http://www.w3.org/2000/svg", "stop");
963
+ const el7 = dom.createElementNS('http://www.w3.org/2000/svg', 'stop');
969
964
  el7.setAttribute('stop-color', '#009688');
970
965
  el7.setAttribute('offset', '100%');
971
- el5.append(" ",el6," ",el7," ");
972
- const el8 = dom.createElementNS("http://www.w3.org/2000/svg", "linearGradient");
966
+ el5.append(' ', el6, ' ', el7, ' ');
967
+ const el8 = dom.createElementNS('http://www.w3.org/2000/svg', 'linearGradient');
973
968
  el8.setAttribute('id', 'lh-gauge--pwa__installable__shadow-gradient');
974
969
  el8.setAttribute('x1', '76.056%');
975
970
  el8.setAttribute('x2', '24.111%');
976
971
  el8.setAttribute('y1', '82.995%');
977
972
  el8.setAttribute('y2', '24.735%');
978
- const el9 = dom.createElementNS("http://www.w3.org/2000/svg", "stop");
973
+ const el9 = dom.createElementNS('http://www.w3.org/2000/svg', 'stop');
979
974
  el9.setAttribute('stop-color', '#A5D6A7');
980
975
  el9.setAttribute('offset', '0%');
981
- const el10 = dom.createElementNS("http://www.w3.org/2000/svg", "stop");
976
+ const el10 = dom.createElementNS('http://www.w3.org/2000/svg', 'stop');
982
977
  el10.setAttribute('stop-color', '#80CBC4');
983
978
  el10.setAttribute('offset', '100%');
984
- el8.append(" ",el9," ",el10," ");
985
- const el11 = dom.createElementNS("http://www.w3.org/2000/svg", "g");
979
+ el8.append(' ', el9, ' ', el10, ' ');
980
+ const el11 = dom.createElementNS('http://www.w3.org/2000/svg', 'g');
986
981
  el11.setAttribute('id', 'lh-gauge--pwa__installable-badge');
987
- const el12 = dom.createElementNS("http://www.w3.org/2000/svg", "circle");
982
+ const el12 = dom.createElementNS('http://www.w3.org/2000/svg', 'circle');
988
983
  el12.setAttribute('fill', '#FFFFFF');
989
984
  el12.setAttribute('cx', '10');
990
985
  el12.setAttribute('cy', '10');
991
986
  el12.setAttribute('r', '10');
992
- const el13 = dom.createElementNS("http://www.w3.org/2000/svg", "path");
987
+ const el13 = dom.createElementNS('http://www.w3.org/2000/svg', 'path');
993
988
  el13.setAttribute('fill', '#009688');
994
989
  el13.setAttribute('d', 'M10 4.167A5.835 5.835 0 0 0 4.167 10 5.835 5.835 0 0 0 10 15.833 5.835 5.835 0 0 0 15.833 10 5.835 5.835 0 0 0 10 4.167zm2.917 6.416h-2.334v2.334H9.417v-2.334H7.083V9.417h2.334V7.083h1.166v2.334h2.334v1.166z');
995
- el11.append(" ",el12," ",el13," ");
996
- el4.append(" ",el5," ",el8," ",el11," ");
997
- const el14 = dom.createElementNS("http://www.w3.org/2000/svg", "g");
990
+ el11.append(' ', el12, ' ', el13, ' ');
991
+ el4.append(' ', el5, ' ', el8, ' ', el11, ' ');
992
+ const el14 = dom.createElementNS('http://www.w3.org/2000/svg', 'g');
998
993
  el14.setAttribute('stroke', 'none');
999
994
  el14.setAttribute('fill-rule', 'nonzero');
1000
- const el15 = dom.createElementNS("http://www.w3.org/2000/svg", "circle", "lh-gauge--pwa__disc");
995
+ const el15 = dom.createElementNS('http://www.w3.org/2000/svg', 'circle', 'lh-gauge--pwa__disc');
1001
996
  el15.setAttribute('cx', '30');
1002
997
  el15.setAttribute('cy', '30');
1003
998
  el15.setAttribute('r', '30');
1004
- const el16 = dom.createElementNS("http://www.w3.org/2000/svg", "g", "lh-gauge--pwa__logo");
1005
- const el17 = dom.createElementNS("http://www.w3.org/2000/svg", "path", "lh-gauge--pwa__logo--secondary-color");
999
+ const el16 = dom.createElementNS('http://www.w3.org/2000/svg', 'g', 'lh-gauge--pwa__logo');
1000
+ const el17 = dom.createElementNS('http://www.w3.org/2000/svg', 'path', 'lh-gauge--pwa__logo--secondary-color');
1006
1001
  el17.setAttribute('d', 'M35.66 19.39l.7-1.75h2L37.4 15 38.6 12l3.4 9h-2.51l-.58-1.61z');
1007
- const el18 = dom.createElementNS("http://www.w3.org/2000/svg", "path", "lh-gauge--pwa__logo--primary-color");
1002
+ const el18 = dom.createElementNS('http://www.w3.org/2000/svg', 'path', 'lh-gauge--pwa__logo--primary-color');
1008
1003
  el18.setAttribute('d', 'M33.52 21l3.65-9h-2.42l-2.5 5.82L30.5 12h-1.86l-1.9 5.82-1.35-2.65-1.21 3.72L25.4 21h2.38l1.72-5.2 1.64 5.2z');
1009
- const el19 = dom.createElementNS("http://www.w3.org/2000/svg", "path", "lh-gauge--pwa__logo--secondary-color");
1004
+ const el19 = dom.createElementNS('http://www.w3.org/2000/svg', 'path', 'lh-gauge--pwa__logo--secondary-color');
1010
1005
  el19.setAttribute('fill-rule', 'nonzero');
1011
1006
  el19.setAttribute('d', 'M20.3 17.91h1.48c.45 0 .85-.05 1.2-.15l.39-1.18 1.07-3.3a2.64 2.64 0 0 0-.28-.37c-.55-.6-1.36-.91-2.42-.91H18v9h2.3V17.9zm1.96-3.84c.22.22.33.5.33.87 0 .36-.1.65-.29.87-.2.23-.59.35-1.15.35h-.86v-2.41h.87c.52 0 .89.1 1.1.32z');
1012
- el16.append(" ",el17," ",el18," ",el19," ");
1013
- const el20 = dom.createElementNS("http://www.w3.org/2000/svg", "rect", "lh-gauge--pwa__component lh-gauge--pwa__na-line");
1007
+ el16.append(' ', el17, ' ', el18, ' ', el19, ' ');
1008
+ const el20 = dom.createElementNS('http://www.w3.org/2000/svg', 'rect', 'lh-gauge--pwa__component lh-gauge--pwa__na-line');
1014
1009
  el20.setAttribute('fill', '#FFFFFF');
1015
1010
  el20.setAttribute('x', '20');
1016
1011
  el20.setAttribute('y', '32');
1017
1012
  el20.setAttribute('width', '20');
1018
1013
  el20.setAttribute('height', '4');
1019
1014
  el20.setAttribute('rx', '2');
1020
- const el21 = dom.createElementNS("http://www.w3.org/2000/svg", "g", "lh-gauge--pwa__component lh-gauge--pwa__installable-badge");
1015
+ const el21 = dom.createElementNS('http://www.w3.org/2000/svg', 'g', 'lh-gauge--pwa__component lh-gauge--pwa__installable-badge');
1021
1016
  el21.setAttribute('transform', 'translate(20, 29)');
1022
- const el22 = dom.createElementNS("http://www.w3.org/2000/svg", "path");
1017
+ const el22 = dom.createElementNS('http://www.w3.org/2000/svg', 'path');
1023
1018
  el22.setAttribute('fill', 'url(#lh-gauge--pwa__installable__shadow-gradient)');
1024
1019
  el22.setAttribute('d', 'M33.629 19.487c-4.272 5.453-10.391 9.39-17.415 10.869L3 17.142 17.142 3 33.63 19.487z');
1025
- const el23 = dom.createElementNS("http://www.w3.org/2000/svg", "use");
1020
+ const el23 = dom.createElementNS('http://www.w3.org/2000/svg', 'use');
1026
1021
  el23.setAttribute('href', '#lh-gauge--pwa__installable-badge');
1027
- el21.append(" ",el22," ",el23," ");
1028
- const el24 = dom.createElementNS("http://www.w3.org/2000/svg", "g", "lh-gauge--pwa__component lh-gauge--pwa__check-circle");
1022
+ el21.append(' ', el22, ' ', el23, ' ');
1023
+ const el24 = dom.createElementNS('http://www.w3.org/2000/svg', 'g', 'lh-gauge--pwa__component lh-gauge--pwa__check-circle');
1029
1024
  el24.setAttribute('transform', 'translate(18, 28)');
1030
- const el25 = dom.createElementNS("http://www.w3.org/2000/svg", "circle");
1025
+ const el25 = dom.createElementNS('http://www.w3.org/2000/svg', 'circle');
1031
1026
  el25.setAttribute('fill', '#FFFFFF');
1032
1027
  el25.setAttribute('cx', '12');
1033
1028
  el25.setAttribute('cy', '12');
1034
1029
  el25.setAttribute('r', '12');
1035
- const el26 = dom.createElementNS("http://www.w3.org/2000/svg", "path");
1030
+ const el26 = dom.createElementNS('http://www.w3.org/2000/svg', 'path');
1036
1031
  el26.setAttribute('fill', 'url(#lh-gauge--pwa__check-circle__gradient)');
1037
1032
  el26.setAttribute('d', 'M12 2a10 10 0 1 0 0 20 10 10 0 0 0 0-20zm-2 15l-5-5 1.41-1.41L10 14.17l7.59-7.59L19 8l-9 9z');
1038
- el24.append(" ",el25," ",el26," ");
1039
- el14.append(" "," ",el15," ",el16," "," ",el20," "," ",el21," "," ",el24," ");
1040
- el3.append(" ",el4," ",el14," ");
1041
- const el27 = dom.createElement("div", "lh-gauge__label");
1042
- el2.append(" ",el3," ",el27," ");
1033
+ el24.append(' ', el25, ' ', el26, ' ');
1034
+ el14.append(' ', ' ', el15, ' ', el16, ' ', ' ', el20, ' ', ' ', el21, ' ', ' ', el24, ' ');
1035
+ el3.append(' ', el4, ' ', el14, ' ');
1036
+ const el27 = dom.createElement('div', 'lh-gauge__label');
1037
+ el2.append(' ', el3, ' ', el27, ' ');
1043
1038
  el0.append(el2);
1044
1039
  return el0;
1045
1040
  }
@@ -1049,12 +1044,12 @@ function createGaugePwaComponent(dom) {
1049
1044
  */
1050
1045
  function createHeadingComponent(dom) {
1051
1046
  const el0 = dom.createFragment();
1052
- const el1 = dom.createElement("style");
1053
- el1.append("\n /* CSS Fireworks. Originally by Eddie Lin\n https://codepen.io/paulirish/pen/yEVMbP\n */\n .lh-pyro {\n display: none;\n z-index: 1;\n pointer-events: none;\n }\n .lh-score100 .lh-pyro {\n display: block;\n }\n .lh-score100 .lh-lighthouse stop:first-child {\n stop-color: hsla(200, 12%, 95%, 0);\n }\n .lh-score100 .lh-lighthouse stop:last-child {\n stop-color: hsla(65, 81%, 76%, 1);\n }\n\n .lh-pyro > .lh-pyro-before, .lh-pyro > .lh-pyro-after {\n position: absolute;\n width: 5px;\n height: 5px;\n border-radius: 2.5px;\n box-shadow: 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff;\n animation: 1s bang ease-out infinite backwards, 1s gravity ease-in infinite backwards, 5s position linear infinite backwards;\n animation-delay: 1s, 1s, 1s;\n }\n\n .lh-pyro > .lh-pyro-after {\n animation-delay: 2.25s, 2.25s, 2.25s;\n animation-duration: 1.25s, 1.25s, 6.25s;\n }\n\n @keyframes bang {\n to {\n box-shadow: -70px -115.67px #47ebbc, -28px -99.67px #eb47a4, 58px -31.67px #7eeb47, 13px -141.67px #eb47c5, -19px 6.33px #7347eb, -2px -74.67px #ebd247, 24px -151.67px #eb47e0, 57px -138.67px #b4eb47, -51px -104.67px #479eeb, 62px 8.33px #ebcf47, -93px 0.33px #d547eb, -16px -118.67px #47bfeb, 53px -84.67px #47eb83, 66px -57.67px #eb47bf, -93px -65.67px #91eb47, 30px -13.67px #86eb47, -2px -59.67px #83eb47, -44px 1.33px #eb47eb, 61px -58.67px #47eb73, 5px -22.67px #47e8eb, -66px -28.67px #ebe247, 42px -123.67px #eb5547, -75px 26.33px #7beb47, 15px -52.67px #a147eb, 36px -51.67px #eb8347, -38px -12.67px #eb5547, -46px -59.67px #47eb81, 78px -114.67px #eb47ba, 15px -156.67px #eb47bf, -36px 1.33px #eb4783, -72px -86.67px #eba147, 31px -46.67px #ebe247, -68px 29.33px #47e2eb, -55px 19.33px #ebe047, -56px 27.33px #4776eb, -13px -91.67px #eb5547, -47px -138.67px #47ebc7, -18px -96.67px #eb47ac, 11px -88.67px #4783eb, -67px -28.67px #47baeb, 53px 10.33px #ba47eb, 11px 19.33px #5247eb, -5px -11.67px #eb4791, -68px -4.67px #47eba7, 95px -37.67px #eb478b, -67px -162.67px #eb5d47, -54px -120.67px #eb6847, 49px -12.67px #ebe047, 88px 8.33px #47ebda, 97px 33.33px #eb8147, 6px -71.67px #ebbc47;\n }\n }\n @keyframes gravity {\n to {\n transform: translateY(80px);\n opacity: 0;\n }\n }\n @keyframes position {\n 0%, 19.9% {\n margin-top: 4%;\n margin-left: 47%;\n }\n 20%, 39.9% {\n margin-top: 7%;\n margin-left: 30%;\n }\n 40%, 59.9% {\n margin-top: 6%;\n margin-left: 70%;\n }\n 60%, 79.9% {\n margin-top: 3%;\n margin-left: 20%;\n }\n 80%, 99.9% {\n margin-top: 3%;\n margin-left: 80%;\n }\n }\n ");
1047
+ const el1 = dom.createElement('style');
1048
+ el1.append('\n /* CSS Fireworks. Originally by Eddie Lin\n https://codepen.io/paulirish/pen/yEVMbP\n */\n .lh-pyro {\n display: none;\n z-index: 1;\n pointer-events: none;\n }\n .lh-score100 .lh-pyro {\n display: block;\n }\n .lh-score100 .lh-lighthouse stop:first-child {\n stop-color: hsla(200, 12%, 95%, 0);\n }\n .lh-score100 .lh-lighthouse stop:last-child {\n stop-color: hsla(65, 81%, 76%, 1);\n }\n\n .lh-pyro > .lh-pyro-before, .lh-pyro > .lh-pyro-after {\n position: absolute;\n width: 5px;\n height: 5px;\n border-radius: 2.5px;\n box-shadow: 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff;\n animation: 1s bang ease-out infinite backwards, 1s gravity ease-in infinite backwards, 5s position linear infinite backwards;\n animation-delay: 1s, 1s, 1s;\n }\n\n .lh-pyro > .lh-pyro-after {\n animation-delay: 2.25s, 2.25s, 2.25s;\n animation-duration: 1.25s, 1.25s, 6.25s;\n }\n\n @keyframes bang {\n to {\n box-shadow: -70px -115.67px #47ebbc, -28px -99.67px #eb47a4, 58px -31.67px #7eeb47, 13px -141.67px #eb47c5, -19px 6.33px #7347eb, -2px -74.67px #ebd247, 24px -151.67px #eb47e0, 57px -138.67px #b4eb47, -51px -104.67px #479eeb, 62px 8.33px #ebcf47, -93px 0.33px #d547eb, -16px -118.67px #47bfeb, 53px -84.67px #47eb83, 66px -57.67px #eb47bf, -93px -65.67px #91eb47, 30px -13.67px #86eb47, -2px -59.67px #83eb47, -44px 1.33px #eb47eb, 61px -58.67px #47eb73, 5px -22.67px #47e8eb, -66px -28.67px #ebe247, 42px -123.67px #eb5547, -75px 26.33px #7beb47, 15px -52.67px #a147eb, 36px -51.67px #eb8347, -38px -12.67px #eb5547, -46px -59.67px #47eb81, 78px -114.67px #eb47ba, 15px -156.67px #eb47bf, -36px 1.33px #eb4783, -72px -86.67px #eba147, 31px -46.67px #ebe247, -68px 29.33px #47e2eb, -55px 19.33px #ebe047, -56px 27.33px #4776eb, -13px -91.67px #eb5547, -47px -138.67px #47ebc7, -18px -96.67px #eb47ac, 11px -88.67px #4783eb, -67px -28.67px #47baeb, 53px 10.33px #ba47eb, 11px 19.33px #5247eb, -5px -11.67px #eb4791, -68px -4.67px #47eba7, 95px -37.67px #eb478b, -67px -162.67px #eb5d47, -54px -120.67px #eb6847, 49px -12.67px #ebe047, 88px 8.33px #47ebda, 97px 33.33px #eb8147, 6px -71.67px #ebbc47;\n }\n }\n @keyframes gravity {\n to {\n transform: translateY(80px);\n opacity: 0;\n }\n }\n @keyframes position {\n 0%, 19.9% {\n margin-top: 4%;\n margin-left: 47%;\n }\n 20%, 39.9% {\n margin-top: 7%;\n margin-left: 30%;\n }\n 40%, 59.9% {\n margin-top: 6%;\n margin-left: 70%;\n }\n 60%, 79.9% {\n margin-top: 3%;\n margin-left: 20%;\n }\n 80%, 99.9% {\n margin-top: 3%;\n margin-left: 80%;\n }\n }\n ');
1054
1049
  el0.append(el1);
1055
- const el2 = dom.createElement("div", "lh-header-container");
1056
- const el3 = dom.createElement("div", "lh-scores-wrapper-placeholder");
1057
- el2.append(" ",el3," ");
1050
+ const el2 = dom.createElement('div', 'lh-header-container');
1051
+ const el3 = dom.createElement('div', 'lh-scores-wrapper-placeholder');
1052
+ el2.append(' ', el3, ' ');
1058
1053
  el0.append(el2);
1059
1054
  return el0;
1060
1055
  }
@@ -1064,14 +1059,14 @@ function createHeadingComponent(dom) {
1064
1059
  */
1065
1060
  function createMetricComponent(dom) {
1066
1061
  const el0 = dom.createFragment();
1067
- const el1 = dom.createElement("div", "lh-metric");
1068
- const el2 = dom.createElement("div", "lh-metric__innerwrap");
1069
- const el3 = dom.createElement("div", "lh-metric__icon");
1070
- const el4 = dom.createElement("span", "lh-metric__title");
1071
- const el5 = dom.createElement("div", "lh-metric__value");
1072
- const el6 = dom.createElement("div", "lh-metric__description");
1073
- el2.append(" ",el3," ",el4," ",el5," ",el6," ");
1074
- el1.append(" ",el2," ");
1062
+ const el1 = dom.createElement('div', 'lh-metric');
1063
+ const el2 = dom.createElement('div', 'lh-metric__innerwrap');
1064
+ const el3 = dom.createElement('div', 'lh-metric__icon');
1065
+ const el4 = dom.createElement('span', 'lh-metric__title');
1066
+ const el5 = dom.createElement('div', 'lh-metric__value');
1067
+ const el6 = dom.createElement('div', 'lh-metric__description');
1068
+ el2.append(' ', el3, ' ', el4, ' ', el5, ' ', el6, ' ');
1069
+ el1.append(' ', el2, ' ');
1075
1070
  el0.append(el1);
1076
1071
  return el0;
1077
1072
  }
@@ -1081,31 +1076,31 @@ function createMetricComponent(dom) {
1081
1076
  */
1082
1077
  function createOpportunityComponent(dom) {
1083
1078
  const el0 = dom.createFragment();
1084
- const el1 = dom.createElement("div", "lh-audit lh-audit--load-opportunity");
1085
- const el2 = dom.createElement("details", "lh-expandable-details");
1086
- const el3 = dom.createElement("summary");
1087
- const el4 = dom.createElement("div", "lh-audit__header");
1088
- const el5 = dom.createElement("div", "lh-load-opportunity__cols");
1089
- const el6 = dom.createElement("div", "lh-load-opportunity__col lh-load-opportunity__col--one");
1090
- const el7 = dom.createElement("span", "lh-audit__score-icon");
1091
- const el8 = dom.createElement("div", "lh-audit__title");
1092
- el6.append(" ",el7," ",el8," ");
1093
- const el9 = dom.createElement("div", "lh-load-opportunity__col lh-load-opportunity__col--two");
1094
- const el10 = dom.createElement("div", "lh-load-opportunity__sparkline");
1095
- const el11 = dom.createElement("div", "lh-sparkline");
1096
- const el12 = dom.createElement("div", "lh-sparkline__bar");
1079
+ const el1 = dom.createElement('div', 'lh-audit lh-audit--load-opportunity');
1080
+ const el2 = dom.createElement('details', 'lh-expandable-details');
1081
+ const el3 = dom.createElement('summary');
1082
+ const el4 = dom.createElement('div', 'lh-audit__header');
1083
+ const el5 = dom.createElement('div', 'lh-load-opportunity__cols');
1084
+ const el6 = dom.createElement('div', 'lh-load-opportunity__col lh-load-opportunity__col--one');
1085
+ const el7 = dom.createElement('span', 'lh-audit__score-icon');
1086
+ const el8 = dom.createElement('div', 'lh-audit__title');
1087
+ el6.append(' ', el7, ' ', el8, ' ');
1088
+ const el9 = dom.createElement('div', 'lh-load-opportunity__col lh-load-opportunity__col--two');
1089
+ const el10 = dom.createElement('div', 'lh-load-opportunity__sparkline');
1090
+ const el11 = dom.createElement('div', 'lh-sparkline');
1091
+ const el12 = dom.createElement('div', 'lh-sparkline__bar');
1097
1092
  el11.append(el12);
1098
- el10.append(" ",el11," ");
1099
- const el13 = dom.createElement("div", "lh-audit__display-text");
1100
- const el14 = dom.createElement("div", "lh-chevron-container");
1101
- el9.append(" ",el10," ",el13," ",el14," ");
1102
- el5.append(" ",el6," ",el9," ");
1103
- el4.append(" ",el5," ");
1104
- el3.append(" ",el4," ");
1105
- const el15 = dom.createElement("div", "lh-audit__description");
1106
- const el16 = dom.createElement("div", "lh-audit__stackpacks");
1107
- el2.append(" ",el3," ",el15," ",el16," ");
1108
- el1.append(" ",el2," ");
1093
+ el10.append(' ', el11, ' ');
1094
+ const el13 = dom.createElement('div', 'lh-audit__display-text');
1095
+ const el14 = dom.createElement('div', 'lh-chevron-container');
1096
+ el9.append(' ', el10, ' ', el13, ' ', el14, ' ');
1097
+ el5.append(' ', el6, ' ', el9, ' ');
1098
+ el4.append(' ', el5, ' ');
1099
+ el3.append(' ', el4, ' ');
1100
+ const el15 = dom.createElement('div', 'lh-audit__description');
1101
+ const el16 = dom.createElement('div', 'lh-audit__stackpacks');
1102
+ el2.append(' ', el3, ' ', el15, ' ', el16, ' ');
1103
+ el1.append(' ', el2, ' ');
1109
1104
  el0.append(el1);
1110
1105
  return el0;
1111
1106
  }
@@ -1115,10 +1110,10 @@ function createOpportunityComponent(dom) {
1115
1110
  */
1116
1111
  function createOpportunityHeaderComponent(dom) {
1117
1112
  const el0 = dom.createFragment();
1118
- const el1 = dom.createElement("div", "lh-load-opportunity__header lh-load-opportunity__cols");
1119
- const el2 = dom.createElement("div", "lh-load-opportunity__col lh-load-opportunity__col--one");
1120
- const el3 = dom.createElement("div", "lh-load-opportunity__col lh-load-opportunity__col--two");
1121
- el1.append(" ",el2," ",el3," ");
1113
+ const el1 = dom.createElement('div', 'lh-load-opportunity__header lh-load-opportunity__cols');
1114
+ const el2 = dom.createElement('div', 'lh-load-opportunity__col lh-load-opportunity__col--one');
1115
+ const el3 = dom.createElement('div', 'lh-load-opportunity__col lh-load-opportunity__col--two');
1116
+ el1.append(' ', el2, ' ', el3, ' ');
1122
1117
  el0.append(el1);
1123
1118
  return el0;
1124
1119
  }
@@ -1128,14 +1123,14 @@ function createOpportunityHeaderComponent(dom) {
1128
1123
  */
1129
1124
  function createScorescaleComponent(dom) {
1130
1125
  const el0 = dom.createFragment();
1131
- const el1 = dom.createElement("div", "lh-scorescale");
1132
- const el2 = dom.createElement("span", "lh-scorescale-range lh-scorescale-range--fail");
1133
- el2.append("0–49");
1134
- const el3 = dom.createElement("span", "lh-scorescale-range lh-scorescale-range--average");
1135
- el3.append("50–89");
1136
- const el4 = dom.createElement("span", "lh-scorescale-range lh-scorescale-range--pass");
1137
- el4.append("90–100");
1138
- el1.append(" ",el2," ",el3," ",el4," ");
1126
+ const el1 = dom.createElement('div', 'lh-scorescale');
1127
+ const el2 = dom.createElement('span', 'lh-scorescale-range lh-scorescale-range--fail');
1128
+ el2.append('0–49');
1129
+ const el3 = dom.createElement('span', 'lh-scorescale-range lh-scorescale-range--average');
1130
+ el3.append('50–89');
1131
+ const el4 = dom.createElement('span', 'lh-scorescale-range lh-scorescale-range--pass');
1132
+ el4.append('90–100');
1133
+ el1.append(' ', el2, ' ', el3, ' ', el4, ' ');
1139
1134
  el0.append(el1);
1140
1135
  return el0;
1141
1136
  }
@@ -1145,17 +1140,17 @@ function createScorescaleComponent(dom) {
1145
1140
  */
1146
1141
  function createScoresWrapperComponent(dom) {
1147
1142
  const el0 = dom.createFragment();
1148
- const el1 = dom.createElement("style");
1149
- el1.append("\n .lh-scores-container {\n display: flex;\n flex-direction: column;\n padding: var(--default-padding) 0;\n position: relative;\n width: 100%;\n }\n\n .lh-sticky-header {\n --gauge-circle-size: var(--gauge-circle-size-sm);\n --plugin-badge-size: 16px;\n --plugin-icon-size: 75%;\n --gauge-wrapper-width: 60px;\n --gauge-percentage-font-size: 13px;\n position: fixed;\n left: 0;\n right: 0;\n top: var(--topbar-height);\n font-weight: 500;\n display: none;\n justify-content: center;\n background-color: var(--sticky-header-background-color);\n border-bottom: 1px solid var(--color-gray-200);\n padding-top: var(--score-container-padding);\n padding-bottom: 4px;\n z-index: 1;\n pointer-events: none;\n }\n\n .lh-devtools .lh-sticky-header {\n /* The report within DevTools is placed in a container with overflow, which changes the placement of this header unless we change `position` to `sticky.` */\n position: sticky;\n }\n\n .lh-sticky-header--visible {\n display: grid;\n grid-auto-flow: column;\n pointer-events: auto;\n }\n\n /* Disable the gauge arc animation for the sticky header, so toggling display: none\n does not play the animation. */\n .lh-sticky-header .lh-gauge-arc {\n animation: none;\n }\n\n .lh-sticky-header .lh-gauge__label,\n .lh-sticky-header .lh-fraction__label {\n display: none;\n }\n\n .lh-highlighter {\n width: var(--gauge-wrapper-width);\n height: 1px;\n background-color: var(--highlighter-background-color);\n /* Position at bottom of first gauge in sticky header. */\n position: absolute;\n grid-column: 1;\n bottom: -1px;\n }\n\n .lh-gauge__wrapper:first-of-type {\n contain: none;\n }\n ");
1143
+ const el1 = dom.createElement('style');
1144
+ el1.append('\n .lh-scores-container {\n display: flex;\n flex-direction: column;\n padding: var(--default-padding) 0;\n position: relative;\n width: 100%;\n }\n\n .lh-sticky-header {\n --gauge-circle-size: var(--gauge-circle-size-sm);\n --plugin-badge-size: 16px;\n --plugin-icon-size: 75%;\n --gauge-wrapper-width: 60px;\n --gauge-percentage-font-size: 13px;\n position: fixed;\n left: 0;\n right: 0;\n top: var(--topbar-height);\n font-weight: 500;\n display: none;\n justify-content: center;\n background-color: var(--sticky-header-background-color);\n border-bottom: 1px solid var(--color-gray-200);\n padding-top: var(--score-container-padding);\n padding-bottom: 4px;\n z-index: 1;\n pointer-events: none;\n }\n\n .lh-devtools .lh-sticky-header {\n /* The report within DevTools is placed in a container with overflow, which changes the placement of this header unless we change `position` to `sticky.` */\n position: sticky;\n }\n\n .lh-sticky-header--visible {\n display: grid;\n grid-auto-flow: column;\n pointer-events: auto;\n }\n\n /* Disable the gauge arc animation for the sticky header, so toggling display: none\n does not play the animation. */\n .lh-sticky-header .lh-gauge-arc {\n animation: none;\n }\n\n .lh-sticky-header .lh-gauge__label,\n .lh-sticky-header .lh-fraction__label {\n display: none;\n }\n\n .lh-highlighter {\n width: var(--gauge-wrapper-width);\n height: 1px;\n background-color: var(--highlighter-background-color);\n /* Position at bottom of first gauge in sticky header. */\n position: absolute;\n grid-column: 1;\n bottom: -1px;\n }\n\n .lh-gauge__wrapper:first-of-type {\n contain: none;\n }\n ');
1150
1145
  el0.append(el1);
1151
- const el2 = dom.createElement("div", "lh-scores-wrapper");
1152
- const el3 = dom.createElement("div", "lh-scores-container");
1153
- const el4 = dom.createElement("div", "lh-pyro");
1154
- const el5 = dom.createElement("div", "lh-pyro-before");
1155
- const el6 = dom.createElement("div", "lh-pyro-after");
1156
- el4.append(" ",el5," ",el6," ");
1157
- el3.append(" ",el4," ");
1158
- el2.append(" ",el3," ");
1146
+ const el2 = dom.createElement('div', 'lh-scores-wrapper');
1147
+ const el3 = dom.createElement('div', 'lh-scores-container');
1148
+ const el4 = dom.createElement('div', 'lh-pyro');
1149
+ const el5 = dom.createElement('div', 'lh-pyro-before');
1150
+ const el6 = dom.createElement('div', 'lh-pyro-after');
1151
+ el4.append(' ', el5, ' ', el6, ' ');
1152
+ el3.append(' ', el4, ' ');
1153
+ el2.append(' ', el3, ' ');
1159
1154
  el0.append(el2);
1160
1155
  return el0;
1161
1156
  }
@@ -1165,10 +1160,10 @@ function createScoresWrapperComponent(dom) {
1165
1160
  */
1166
1161
  function createSnippetComponent(dom) {
1167
1162
  const el0 = dom.createFragment();
1168
- const el1 = dom.createElement("div", "lh-snippet");
1169
- const el2 = dom.createElement("style");
1170
- el2.append("\n :root {\n --snippet-highlight-light: #fbf1f2;\n --snippet-highlight-dark: #ffd6d8;\n }\n\n .lh-snippet__header {\n position: relative;\n overflow: hidden;\n padding: 10px;\n border-bottom: none;\n color: var(--snippet-color);\n background-color: var(--snippet-background-color);\n border: 1px solid var(--report-border-color-secondary);\n }\n .lh-snippet__title {\n font-weight: bold;\n float: left;\n }\n .lh-snippet__node {\n float: left;\n margin-left: 4px;\n }\n .lh-snippet__toggle-expand {\n padding: 1px 7px;\n margin-top: -1px;\n margin-right: -7px;\n float: right;\n background: transparent;\n border: none;\n cursor: pointer;\n font-size: 14px;\n color: #0c50c7;\n }\n\n .lh-snippet__snippet {\n overflow: auto;\n border: 1px solid var(--report-border-color-secondary);\n }\n /* Container needed so that all children grow to the width of the scroll container */\n .lh-snippet__snippet-inner {\n display: inline-block;\n min-width: 100%;\n }\n\n .lh-snippet:not(.lh-snippet--expanded) .lh-snippet__show-if-expanded {\n display: none;\n }\n .lh-snippet.lh-snippet--expanded .lh-snippet__show-if-collapsed {\n display: none;\n }\n\n .lh-snippet__line {\n background: white;\n white-space: pre;\n display: flex;\n }\n .lh-snippet__line:not(.lh-snippet__line--message):first-child {\n padding-top: 4px;\n }\n .lh-snippet__line:not(.lh-snippet__line--message):last-child {\n padding-bottom: 4px;\n }\n .lh-snippet__line--content-highlighted {\n background: var(--snippet-highlight-dark);\n }\n .lh-snippet__line--message {\n background: var(--snippet-highlight-light);\n }\n .lh-snippet__line--message .lh-snippet__line-number {\n padding-top: 10px;\n padding-bottom: 10px;\n }\n .lh-snippet__line--message code {\n padding: 10px;\n padding-left: 5px;\n color: var(--color-fail);\n font-family: var(--report-font-family);\n }\n .lh-snippet__line--message code {\n white-space: normal;\n }\n .lh-snippet__line-icon {\n padding-top: 10px;\n display: none;\n }\n .lh-snippet__line--message .lh-snippet__line-icon {\n display: block;\n }\n .lh-snippet__line-icon:before {\n content: \"\";\n display: inline-block;\n vertical-align: middle;\n margin-right: 4px;\n width: var(--score-icon-size);\n height: var(--score-icon-size);\n background-image: var(--fail-icon-url);\n }\n .lh-snippet__line-number {\n flex-shrink: 0;\n width: 40px;\n text-align: right;\n font-family: monospace;\n padding-right: 5px;\n margin-right: 5px;\n color: var(--color-gray-600);\n user-select: none;\n }\n ");
1171
- el1.append(" ",el2," ");
1163
+ const el1 = dom.createElement('div', 'lh-snippet');
1164
+ const el2 = dom.createElement('style');
1165
+ el2.append('\n :root {\n --snippet-highlight-light: #fbf1f2;\n --snippet-highlight-dark: #ffd6d8;\n }\n\n .lh-snippet__header {\n position: relative;\n overflow: hidden;\n padding: 10px;\n border-bottom: none;\n color: var(--snippet-color);\n background-color: var(--snippet-background-color);\n border: 1px solid var(--report-border-color-secondary);\n }\n .lh-snippet__title {\n font-weight: bold;\n float: left;\n }\n .lh-snippet__node {\n float: left;\n margin-left: 4px;\n }\n .lh-snippet__toggle-expand {\n padding: 1px 7px;\n margin-top: -1px;\n margin-right: -7px;\n float: right;\n background: transparent;\n border: none;\n cursor: pointer;\n font-size: 14px;\n color: #0c50c7;\n }\n\n .lh-snippet__snippet {\n overflow: auto;\n border: 1px solid var(--report-border-color-secondary);\n }\n /* Container needed so that all children grow to the width of the scroll container */\n .lh-snippet__snippet-inner {\n display: inline-block;\n min-width: 100%;\n }\n\n .lh-snippet:not(.lh-snippet--expanded) .lh-snippet__show-if-expanded {\n display: none;\n }\n .lh-snippet.lh-snippet--expanded .lh-snippet__show-if-collapsed {\n display: none;\n }\n\n .lh-snippet__line {\n background: white;\n white-space: pre;\n display: flex;\n }\n .lh-snippet__line:not(.lh-snippet__line--message):first-child {\n padding-top: 4px;\n }\n .lh-snippet__line:not(.lh-snippet__line--message):last-child {\n padding-bottom: 4px;\n }\n .lh-snippet__line--content-highlighted {\n background: var(--snippet-highlight-dark);\n }\n .lh-snippet__line--message {\n background: var(--snippet-highlight-light);\n }\n .lh-snippet__line--message .lh-snippet__line-number {\n padding-top: 10px;\n padding-bottom: 10px;\n }\n .lh-snippet__line--message code {\n padding: 10px;\n padding-left: 5px;\n color: var(--color-fail);\n font-family: var(--report-font-family);\n }\n .lh-snippet__line--message code {\n white-space: normal;\n }\n .lh-snippet__line-icon {\n padding-top: 10px;\n display: none;\n }\n .lh-snippet__line--message .lh-snippet__line-icon {\n display: block;\n }\n .lh-snippet__line-icon:before {\n content: "";\n display: inline-block;\n vertical-align: middle;\n margin-right: 4px;\n width: var(--score-icon-size);\n height: var(--score-icon-size);\n background-image: var(--fail-icon-url);\n }\n .lh-snippet__line-number {\n flex-shrink: 0;\n width: 40px;\n text-align: right;\n font-family: monospace;\n padding-right: 5px;\n margin-right: 5px;\n color: var(--color-gray-600);\n user-select: none;\n }\n ');
1166
+ el1.append(' ', el2, ' ');
1172
1167
  el0.append(el1);
1173
1168
  return el0;
1174
1169
  }
@@ -1178,9 +1173,9 @@ function createSnippetComponent(dom) {
1178
1173
  */
1179
1174
  function createSnippetContentComponent(dom) {
1180
1175
  const el0 = dom.createFragment();
1181
- const el1 = dom.createElement("div", "lh-snippet__snippet");
1182
- const el2 = dom.createElement("div", "lh-snippet__snippet-inner");
1183
- el1.append(" ",el2," ");
1176
+ const el1 = dom.createElement('div', 'lh-snippet__snippet');
1177
+ const el2 = dom.createElement('div', 'lh-snippet__snippet-inner');
1178
+ el1.append(' ', el2, ' ');
1184
1179
  el0.append(el1);
1185
1180
  return el0;
1186
1181
  }
@@ -1190,14 +1185,14 @@ function createSnippetContentComponent(dom) {
1190
1185
  */
1191
1186
  function createSnippetHeaderComponent(dom) {
1192
1187
  const el0 = dom.createFragment();
1193
- const el1 = dom.createElement("div", "lh-snippet__header");
1194
- const el2 = dom.createElement("div", "lh-snippet__title");
1195
- const el3 = dom.createElement("div", "lh-snippet__node");
1196
- const el4 = dom.createElement("button", "lh-snippet__toggle-expand");
1197
- const el5 = dom.createElement("span", "lh-snippet__btn-label-collapse lh-snippet__show-if-expanded");
1198
- const el6 = dom.createElement("span", "lh-snippet__btn-label-expand lh-snippet__show-if-collapsed");
1199
- el4.append(" ",el5," ",el6," ");
1200
- el1.append(" ",el2," ",el3," ",el4," ");
1188
+ const el1 = dom.createElement('div', 'lh-snippet__header');
1189
+ const el2 = dom.createElement('div', 'lh-snippet__title');
1190
+ const el3 = dom.createElement('div', 'lh-snippet__node');
1191
+ const el4 = dom.createElement('button', 'lh-snippet__toggle-expand');
1192
+ const el5 = dom.createElement('span', 'lh-snippet__btn-label-collapse lh-snippet__show-if-expanded');
1193
+ const el6 = dom.createElement('span', 'lh-snippet__btn-label-expand lh-snippet__show-if-collapsed');
1194
+ el4.append(' ', el5, ' ', el6, ' ');
1195
+ el1.append(' ', el2, ' ', el3, ' ', el4, ' ');
1201
1196
  el0.append(el1);
1202
1197
  return el0;
1203
1198
  }
@@ -1207,11 +1202,11 @@ function createSnippetHeaderComponent(dom) {
1207
1202
  */
1208
1203
  function createSnippetLineComponent(dom) {
1209
1204
  const el0 = dom.createFragment();
1210
- const el1 = dom.createElement("div", "lh-snippet__line");
1211
- const el2 = dom.createElement("div", "lh-snippet__line-number");
1212
- const el3 = dom.createElement("div", "lh-snippet__line-icon");
1213
- const el4 = dom.createElement("code");
1214
- el1.append(" ",el2," ",el3," ",el4," ");
1205
+ const el1 = dom.createElement('div', 'lh-snippet__line');
1206
+ const el2 = dom.createElement('div', 'lh-snippet__line-number');
1207
+ const el3 = dom.createElement('div', 'lh-snippet__line-icon');
1208
+ const el4 = dom.createElement('code');
1209
+ el1.append(' ', el2, ' ', el3, ' ', el4, ' ');
1215
1210
  el0.append(el1);
1216
1211
  return el0;
1217
1212
  }
@@ -1221,8 +1216,8 @@ function createSnippetLineComponent(dom) {
1221
1216
  */
1222
1217
  function createStylesComponent(dom) {
1223
1218
  const el0 = dom.createFragment();
1224
- const el1 = dom.createElement("style");
1225
- el1.append("/**\n * @license\n * Copyright 2017 The Lighthouse Authors. All Rights Reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS-IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/*\n Naming convention:\n\n If a variable is used for a specific component: --{component}-{property name}-{modifier}\n\n Both {component} and {property name} should be kebab-case. If the target is the entire page,\n use 'report' for the component. The property name should not be abbreviated. Use the\n property name the variable is intended for - if it's used for multiple, a common descriptor\n is fine (ex: 'size' for a variable applied to 'width' and 'height'). If a variable is shared\n across multiple components, either create more variables or just drop the \"{component}-\"\n part of the name. Append any modifiers at the end (ex: 'big', 'dark').\n\n For colors: --color-{hue}-{intensity}\n\n {intensity} is the Material Design tag - 700, A700, etc.\n*/\n.lh-vars {\n /* Palette using Material Design Colors\n * https://www.materialui.co/colors */\n --color-amber-50: #FFF8E1;\n --color-blue-200: #90CAF9;\n --color-blue-900: #0D47A1;\n --color-blue-A700: #2962FF;\n --color-blue-primary: #06f;\n --color-cyan-500: #00BCD4;\n --color-gray-100: #F5F5F5;\n --color-gray-300: #CFCFCF;\n --color-gray-200: #E0E0E0;\n --color-gray-400: #BDBDBD;\n --color-gray-50: #FAFAFA;\n --color-gray-500: #9E9E9E;\n --color-gray-600: #757575;\n --color-gray-700: #616161;\n --color-gray-800: #424242;\n --color-gray-900: #212121;\n --color-gray: #000000;\n --color-green-700: #080;\n --color-green: #0c6;\n --color-lime-400: #D3E156;\n --color-orange-50: #FFF3E0;\n --color-orange-700: #C33300;\n --color-orange: #fa3;\n --color-red-700: #c00;\n --color-red: #f33;\n --color-teal-600: #00897B;\n --color-white: #FFFFFF;\n\n /* Context-specific colors */\n --color-average-secondary: var(--color-orange-700);\n --color-average: var(--color-orange);\n --color-fail-secondary: var(--color-red-700);\n --color-fail: var(--color-red);\n --color-hover: var(--color-gray-50);\n --color-informative: var(--color-blue-900);\n --color-pass-secondary: var(--color-green-700);\n --color-pass: var(--color-green);\n --color-not-applicable: var(--color-gray-600);\n\n /* Component variables */\n --audit-description-padding-left: calc(var(--score-icon-size) + var(--score-icon-margin-left) + var(--score-icon-margin-right));\n --audit-explanation-line-height: 16px;\n --audit-group-margin-bottom: calc(var(--default-padding) * 6);\n --audit-group-padding-vertical: 8px;\n --audit-margin-horizontal: 5px;\n --audit-padding-vertical: 8px;\n --category-padding: calc(var(--default-padding) * 6) var(--edge-gap-padding) calc(var(--default-padding) * 4);\n --chevron-line-stroke: var(--color-gray-600);\n --chevron-size: 12px;\n --default-padding: 8px;\n --edge-gap-padding: calc(var(--default-padding) * 4);\n --env-item-background-color: var(--color-gray-100);\n --env-item-font-size: 28px;\n --env-item-line-height: 36px;\n --env-item-padding: 10px 0px;\n --env-name-min-width: 220px;\n --footer-padding-vertical: 16px;\n --gauge-circle-size-big: 96px;\n --gauge-circle-size: 48px;\n --gauge-circle-size-sm: 32px;\n --gauge-label-font-size-big: 18px;\n --gauge-label-font-size: var(--report-font-size-secondary);\n --gauge-label-line-height-big: 24px;\n --gauge-label-line-height: var(--report-line-height-secondary);\n --gauge-percentage-font-size-big: 38px;\n --gauge-percentage-font-size: var(--report-font-size-secondary);\n --gauge-wrapper-width: 120px;\n --header-line-height: 24px;\n --highlighter-background-color: var(--report-text-color);\n --icon-square-size: calc(var(--score-icon-size) * 0.88);\n --image-preview-size: 48px;\n --link-color: var(--color-blue-primary);\n --locale-selector-background-color: var(--color-white);\n --metric-toggle-lines-fill: #7F7F7F;\n --metric-value-font-size: calc(var(--report-font-size) * 1.8);\n --metrics-toggle-background-color: var(--color-gray-200);\n --plugin-badge-background-color: var(--color-white);\n --plugin-badge-size-big: calc(var(--gauge-circle-size-big) / 2.7);\n --plugin-badge-size: calc(var(--gauge-circle-size) / 2.7);\n --plugin-icon-size: 65%;\n --pwa-icon-margin: 0 var(--default-padding);\n --pwa-icon-size: var(--topbar-logo-size);\n --report-background-color: #fff;\n --report-border-color-secondary: #ebebeb;\n --report-font-family-monospace: 'Roboto Mono', 'Menlo', 'dejavu sans mono', 'Consolas', 'Lucida Console', monospace;\n --report-font-family: Roboto, Helvetica, Arial, sans-serif;\n --report-font-size: 14px;\n --report-font-size-secondary: 12px;\n --report-icon-size: var(--score-icon-background-size);\n --report-line-height: 24px;\n --report-line-height-secondary: 20px;\n --report-monospace-font-size: calc(var(--report-font-size) * 0.85);\n --report-text-color-secondary: var(--color-gray-800);\n --report-text-color: var(--color-gray-900);\n --report-content-max-width: calc(60 * var(--report-font-size)); /* defaults to 840px */\n --report-content-min-width: 360px;\n --report-content-max-width-minus-edge-gap: calc(var(--report-content-max-width) - var(--edge-gap-padding) * 2);\n --score-container-padding: 8px;\n --score-icon-background-size: 24px;\n --score-icon-margin-left: 6px;\n --score-icon-margin-right: 14px;\n --score-icon-margin: 0 var(--score-icon-margin-right) 0 var(--score-icon-margin-left);\n --score-icon-size: 12px;\n --score-icon-size-big: 16px;\n --screenshot-overlay-background: rgba(0, 0, 0, 0.3);\n --section-padding-vertical: calc(var(--default-padding) * 6);\n --snippet-background-color: var(--color-gray-50);\n --snippet-color: #0938C2;\n --sparkline-height: 5px;\n --stackpack-padding-horizontal: 10px;\n --sticky-header-background-color: var(--report-background-color);\n --table-higlight-background-color: hsla(210, 17%, 77%, 0.1);\n --tools-icon-color: var(--color-gray-600);\n --topbar-background-color: var(--color-white);\n --topbar-height: 32px;\n --topbar-logo-size: 24px;\n --topbar-padding: 0 8px;\n --toplevel-warning-background-color: hsla(30, 100%, 75%, 10%);\n --toplevel-warning-message-text-color: var(--color-average-secondary);\n --toplevel-warning-padding: 18px;\n --toplevel-warning-text-color: var(--report-text-color);\n\n /* SVGs */\n --plugin-icon-url-dark: url('data:image/svg+xml;utf8,<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24px\" height=\"24px\" viewBox=\"0 0 24 24\" fill=\"%23FFFFFF\"><path d=\"M0 0h24v24H0z\" fill=\"none\"/><path d=\"M20.5 11H19V7c0-1.1-.9-2-2-2h-4V3.5C13 2.12 11.88 1 10.5 1S8 2.12 8 3.5V5H4c-1.1 0-1.99.9-1.99 2v3.8H3.5c1.49 0 2.7 1.21 2.7 2.7s-1.21 2.7-2.7 2.7H2V20c0 1.1.9 2 2 2h3.8v-1.5c0-1.49 1.21-2.7 2.7-2.7 1.49 0 2.7 1.21 2.7 2.7V22H17c1.1 0 2-.9 2-2v-4h1.5c1.38 0 2.5-1.12 2.5-2.5S21.88 11 20.5 11z\"/></svg>');\n --plugin-icon-url: url('data:image/svg+xml;utf8,<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24px\" height=\"24px\" viewBox=\"0 0 24 24\" fill=\"%23757575\"><path d=\"M0 0h24v24H0z\" fill=\"none\"/><path d=\"M20.5 11H19V7c0-1.1-.9-2-2-2h-4V3.5C13 2.12 11.88 1 10.5 1S8 2.12 8 3.5V5H4c-1.1 0-1.99.9-1.99 2v3.8H3.5c1.49 0 2.7 1.21 2.7 2.7s-1.21 2.7-2.7 2.7H2V20c0 1.1.9 2 2 2h3.8v-1.5c0-1.49 1.21-2.7 2.7-2.7 1.49 0 2.7 1.21 2.7 2.7V22H17c1.1 0 2-.9 2-2v-4h1.5c1.38 0 2.5-1.12 2.5-2.5S21.88 11 20.5 11z\"/></svg>');\n\n --pass-icon-url: url('data:image/svg+xml;utf8,<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 48 48\"><title>check</title><path fill=\"%23178239\" d=\"M24 4C12.95 4 4 12.95 4 24c0 11.04 8.95 20 20 20 11.04 0 20-8.96 20-20 0-11.05-8.96-20-20-20zm-4 30L10 24l2.83-2.83L20 28.34l15.17-15.17L38 16 20 34z\"/></svg>');\n --average-icon-url: url('data:image/svg+xml;utf8,<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 48 48\"><title>info</title><path fill=\"%23E67700\" d=\"M24 4C12.95 4 4 12.95 4 24s8.95 20 20 20 20-8.95 20-20S35.05 4 24 4zm2 30h-4V22h4v12zm0-16h-4v-4h4v4z\"/></svg>');\n --fail-icon-url: url('data:image/svg+xml;utf8,<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 48 48\"><title>warn</title><path fill=\"%23C7221F\" d=\"M2 42h44L24 4 2 42zm24-6h-4v-4h4v4zm0-8h-4v-8h4v8z\"/></svg>');\n\n --pwa-installable-gray-url: url('data:image/svg+xml;utf8,<svg xmlns=\"http://www.w3.org/2000/svg\"><g fill=\"none\" fill-rule=\"nonzero\"><circle fill=\"%23DAE0E3\" cx=\"12\" cy=\"12\" r=\"12\"/><path d=\"M12 5a7 7 0 1 0 0 14 7 7 0 0 0 0-14zm3.5 7.7h-2.8v2.8h-1.4v-2.8H8.5v-1.4h2.8V8.5h1.4v2.8h2.8v1.4z\" fill=\"%23FFF\"/></g></svg>');\n --pwa-optimized-gray-url: url('data:image/svg+xml;utf8,<svg xmlns=\"http://www.w3.org/2000/svg\"><g fill=\"none\" fill-rule=\"evenodd\"><rect fill=\"%23DAE0E3\" width=\"24\" height=\"24\" rx=\"12\"/><path fill=\"%23FFF\" d=\"M12 15.07l3.6 2.18-.95-4.1 3.18-2.76-4.2-.36L12 6.17l-1.64 3.86-4.2.36 3.2 2.76-.96 4.1z\"/><path d=\"M5 5h14v14H5z\"/></g></svg>');\n\n --pwa-installable-gray-url-dark: url('data:image/svg+xml;utf8,<svg xmlns=\"http://www.w3.org/2000/svg\"><g fill=\"none\" fill-rule=\"nonzero\"><circle fill=\"%23424242\" cx=\"12\" cy=\"12\" r=\"12\"/><path d=\"M12 5a7 7 0 1 0 0 14 7 7 0 0 0 0-14zm3.5 7.7h-2.8v2.8h-1.4v-2.8H8.5v-1.4h2.8V8.5h1.4v2.8h2.8v1.4z\" fill=\"%23FFF\"/></g></svg>');\n --pwa-optimized-gray-url-dark: url('data:image/svg+xml;utf8,<svg xmlns=\"http://www.w3.org/2000/svg\"><g fill=\"none\" fill-rule=\"evenodd\"><rect fill=\"%23424242\" width=\"24\" height=\"24\" rx=\"12\"/><path fill=\"%23FFF\" d=\"M12 15.07l3.6 2.18-.95-4.1 3.18-2.76-4.2-.36L12 6.17l-1.64 3.86-4.2.36 3.2 2.76-.96 4.1z\"/><path d=\"M5 5h14v14H5z\"/></g></svg>');\n\n --pwa-installable-color-url: url('data:image/svg+xml;utf8,<svg xmlns=\"http://www.w3.org/2000/svg\"><g fill-rule=\"nonzero\" fill=\"none\"><circle fill=\"%230CCE6B\" cx=\"12\" cy=\"12\" r=\"12\"/><path d=\"M12 5a7 7 0 1 0 0 14 7 7 0 0 0 0-14zm3.5 7.7h-2.8v2.8h-1.4v-2.8H8.5v-1.4h2.8V8.5h1.4v2.8h2.8v1.4z\" fill=\"%23FFF\"/></g></svg>');\n --pwa-optimized-color-url: url('data:image/svg+xml;utf8,<svg xmlns=\"http://www.w3.org/2000/svg\"><g fill=\"none\" fill-rule=\"evenodd\"><rect fill=\"%230CCE6B\" width=\"24\" height=\"24\" rx=\"12\"/><path d=\"M5 5h14v14H5z\"/><path fill=\"%23FFF\" d=\"M12 15.07l3.6 2.18-.95-4.1 3.18-2.76-4.2-.36L12 6.17l-1.64 3.86-4.2.36 3.2 2.76-.96 4.1z\"/></g></svg>');\n\n --swap-locale-icon-url: url('data:image/svg+xml;utf8,<svg xmlns=\"http://www.w3.org/2000/svg\" height=\"24px\" viewBox=\"0 0 24 24\" width=\"24px\" fill=\"#000000\"><path d=\"M0 0h24v24H0V0z\" fill=\"none\"/><path d=\"M12.87 15.07l-2.54-2.51.03-.03c1.74-1.94 2.98-4.17 3.71-6.53H17V4h-7V2H8v2H1v1.99h11.17C11.5 7.92 10.44 9.75 9 11.35 8.07 10.32 7.3 9.19 6.69 8h-2c.73 1.63 1.73 3.17 2.98 4.56l-5.09 5.02L4 19l5-5 3.11 3.11.76-2.04zM18.5 10h-2L12 22h2l1.12-3h4.75L21 22h2l-4.5-12zm-2.62 7l1.62-4.33L19.12 17h-3.24z\"/></svg>');\n}\n\n@media not print {\n .lh-dark {\n /* Pallete */\n --color-gray-200: var(--color-gray-800);\n --color-gray-300: #616161;\n --color-gray-400: var(--color-gray-600);\n --color-gray-700: var(--color-gray-400);\n --color-gray-50: #757575;\n --color-gray-600: var(--color-gray-500);\n --color-green-700: var(--color-green);\n --color-orange-700: var(--color-orange);\n --color-red-700: var(--color-red);\n --color-teal-600: var(--color-cyan-500);\n\n /* Context-specific colors */\n --color-hover: rgba(0, 0, 0, 0.2);\n --color-informative: var(--color-blue-200);\n\n /* Component variables */\n --env-item-background-color: #393535;\n --link-color: var(--color-blue-200);\n --locale-selector-background-color: var(--color-gray-200);\n --plugin-badge-background-color: var(--color-gray-800);\n --report-background-color: var(--color-gray-900);\n --report-border-color-secondary: var(--color-gray-200);\n --report-text-color-secondary: var(--color-gray-400);\n --report-text-color: var(--color-gray-100);\n --snippet-color: var(--color-cyan-500);\n --topbar-background-color: var(--color-gray);\n --toplevel-warning-background-color: hsl(33deg 14% 18%);\n --toplevel-warning-message-text-color: var(--color-orange-700);\n --toplevel-warning-text-color: var(--color-gray-100);\n\n /* SVGs */\n --plugin-icon-url: var(--plugin-icon-url-dark);\n --pwa-installable-gray-url: var(--pwa-installable-gray-url-dark);\n --pwa-optimized-gray-url: var(--pwa-optimized-gray-url-dark);\n }\n}\n\n@media only screen and (max-width: 480px) {\n .lh-vars {\n --audit-group-margin-bottom: 20px;\n --edge-gap-padding: var(--default-padding);\n --env-name-min-width: 120px;\n --gauge-circle-size-big: 96px;\n --gauge-circle-size: 72px;\n --gauge-label-font-size-big: 22px;\n --gauge-label-font-size: 14px;\n --gauge-label-line-height-big: 26px;\n --gauge-label-line-height: 20px;\n --gauge-percentage-font-size-big: 34px;\n --gauge-percentage-font-size: 26px;\n --gauge-wrapper-width: 112px;\n --header-padding: 16px 0 16px 0;\n --image-preview-size: 24px;\n --plugin-icon-size: 75%;\n --pwa-icon-margin: 0 7px 0 -3px;\n --report-font-size: 14px;\n --report-line-height: 20px;\n --score-icon-margin-left: 2px;\n --score-icon-size: 10px;\n --topbar-height: 28px;\n --topbar-logo-size: 20px;\n }\n\n /* Not enough space to adequately show the relative savings bars. */\n .lh-sparkline {\n display: none;\n }\n}\n\n.lh-vars.lh-devtools {\n --audit-explanation-line-height: 14px;\n --audit-group-margin-bottom: 20px;\n --audit-group-padding-vertical: 12px;\n --audit-padding-vertical: 4px;\n --category-padding: 12px;\n --default-padding: 12px;\n --env-name-min-width: 120px;\n --footer-padding-vertical: 8px;\n --gauge-circle-size-big: 72px;\n --gauge-circle-size: 64px;\n --gauge-label-font-size-big: 22px;\n --gauge-label-font-size: 14px;\n --gauge-label-line-height-big: 26px;\n --gauge-label-line-height: 20px;\n --gauge-percentage-font-size-big: 34px;\n --gauge-percentage-font-size: 26px;\n --gauge-wrapper-width: 97px;\n --header-line-height: 20px;\n --header-padding: 16px 0 16px 0;\n --screenshot-overlay-background: transparent;\n --plugin-icon-size: 75%;\n --pwa-icon-margin: 0 7px 0 -3px;\n --report-font-family-monospace: 'Menlo', 'dejavu sans mono', 'Consolas', 'Lucida Console', monospace;\n --report-font-family: '.SFNSDisplay-Regular', 'Helvetica Neue', 'Lucida Grande', sans-serif;\n --report-font-size: 12px;\n --report-line-height: 20px;\n --score-icon-margin-left: 2px;\n --score-icon-size: 10px;\n --section-padding-vertical: 8px;\n}\n\n.lh-devtools.lh-root {\n height: 100%;\n}\n.lh-devtools.lh-root img {\n /* Override devtools default 'min-width: 0' so svg without size in a flexbox isn't collapsed. */\n min-width: auto;\n}\n.lh-devtools .lh-container {\n overflow-y: scroll;\n height: calc(100% - var(--topbar-height));\n}\n@media print {\n .lh-devtools .lh-container {\n overflow: unset;\n }\n}\n.lh-devtools .lh-sticky-header {\n /* This is normally the height of the topbar, but we want it to stick to the top of our scroll container .lh-container` */\n top: 0;\n}\n\n@keyframes fadeIn {\n 0% { opacity: 0;}\n 100% { opacity: 0.6;}\n}\n\n.lh-root *, .lh-root *::before, .lh-root *::after {\n box-sizing: border-box;\n}\n\n.lh-root {\n font-family: var(--report-font-family);\n font-size: var(--report-font-size);\n margin: 0;\n line-height: var(--report-line-height);\n background: var(--report-background-color);\n color: var(--report-text-color);\n}\n\n.lh-root :focus {\n outline: -webkit-focus-ring-color auto 3px;\n}\n.lh-root summary:focus {\n outline: none;\n box-shadow: 0 0 0 1px hsl(217, 89%, 61%);\n}\n\n.lh-root [hidden] {\n display: none !important;\n}\n\n.lh-root pre {\n margin: 0;\n}\n\n.lh-root details > summary {\n cursor: pointer;\n}\n\n.lh-hidden {\n display: none !important;\n}\n\n.lh-container {\n /*\n Text wrapping in the report is so much FUN!\n We have a `word-break: break-word;` globally here to prevent a few common scenarios, namely\n long non-breakable text (usually URLs) found in:\n 1. The footer\n 2. .lh-node (outerHTML)\n 3. .lh-code\n\n With that sorted, the next challenge is appropriate column sizing and text wrapping inside our\n .lh-details tables. Even more fun.\n * We don't want table headers (\"Potential Savings (ms)\") to wrap or their column values, but\n we'd be happy for the URL column to wrap if the URLs are particularly long.\n * We want the narrow columns to remain narrow, providing the most column width for URL\n * We don't want the table to extend past 100% width.\n * Long URLs in the URL column can wrap. Util.getURLDisplayName maxes them out at 64 characters,\n but they do not get any overflow:ellipsis treatment.\n */\n word-break: break-word;\n}\n\n.lh-audit-group a,\n.lh-category-header__description a,\n.lh-audit__description a,\n.lh-warnings a,\n.lh-footer a,\n.lh-table-column--link a {\n color: var(--link-color);\n}\n\n.lh-audit__description, .lh-audit__stackpack {\n --inner-audit-padding-right: var(--stackpack-padding-horizontal);\n padding-left: var(--audit-description-padding-left);\n padding-right: var(--inner-audit-padding-right);\n padding-top: 8px;\n padding-bottom: 8px;\n}\n\n.lh-details {\n margin-top: var(--default-padding);\n margin-bottom: var(--default-padding);\n margin-left: var(--audit-description-padding-left);\n /* whatever the .lh-details side margins are */\n width: 100%;\n}\n\n.lh-audit__stackpack {\n display: flex;\n align-items: center;\n}\n\n.lh-audit__stackpack__img {\n max-width: 30px;\n margin-right: var(--default-padding)\n}\n\n/* Report header */\n\n.lh-report-icon {\n display: flex;\n align-items: center;\n padding: 10px 12px;\n cursor: pointer;\n}\n.lh-report-icon[disabled] {\n opacity: 0.3;\n pointer-events: none;\n}\n\n.lh-report-icon::before {\n content: \"\";\n margin: 4px;\n background-repeat: no-repeat;\n width: var(--report-icon-size);\n height: var(--report-icon-size);\n opacity: 0.7;\n display: inline-block;\n vertical-align: middle;\n}\n.lh-report-icon:hover::before {\n opacity: 1;\n}\n.lh-dark .lh-report-icon::before {\n filter: invert(1);\n}\n.lh-report-icon--print::before {\n background-image: url('data:image/svg+xml;utf8,<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\"><path d=\"M19 8H5c-1.66 0-3 1.34-3 3v6h4v4h12v-4h4v-6c0-1.66-1.34-3-3-3zm-3 11H8v-5h8v5zm3-7c-.55 0-1-.45-1-1s.45-1 1-1 1 .45 1 1-.45 1-1 1zm-1-9H6v4h12V3z\"/><path fill=\"none\" d=\"M0 0h24v24H0z\"/></svg>');\n}\n.lh-report-icon--copy::before {\n background-image: url('data:image/svg+xml;utf8,<svg height=\"24\" viewBox=\"0 0 24 24\" width=\"24\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M0 0h24v24H0z\" fill=\"none\"/><path d=\"M16 1H4c-1.1 0-2 .9-2 2v14h2V3h12V1zm3 4H8c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h11c1.1 0 2-.9 2-2V7c0-1.1-.9-2-2-2zm0 16H8V7h11v14z\"/></svg>');\n}\n.lh-report-icon--open::before {\n background-image: url('data:image/svg+xml;utf8,<svg height=\"24\" viewBox=\"0 0 24 24\" width=\"24\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M0 0h24v24H0z\" fill=\"none\"/><path d=\"M19 4H5c-1.11 0-2 .9-2 2v12c0 1.1.89 2 2 2h4v-2H5V8h14v10h-4v2h4c1.1 0 2-.9 2-2V6c0-1.1-.89-2-2-2zm-7 6l-4 4h3v6h2v-6h3l-4-4z\"/></svg>');\n}\n.lh-report-icon--download::before {\n background-image: url('data:image/svg+xml;utf8,<svg height=\"24\" viewBox=\"0 0 24 24\" width=\"24\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M19 9h-4V3H9v6H5l7 7 7-7zM5 18v2h14v-2H5z\"/><path d=\"M0 0h24v24H0z\" fill=\"none\"/></svg>');\n}\n.lh-report-icon--dark::before {\n background-image:url('data:image/svg+xml;utf8,<svg xmlns=\"http://www.w3.org/2000/svg\" height=\"24\" viewBox=\"0 0 100 125\"><path d=\"M50 23.587c-16.27 0-22.799 12.574-22.799 21.417 0 12.917 10.117 22.451 12.436 32.471h20.726c2.32-10.02 12.436-19.554 12.436-32.471 0-8.843-6.528-21.417-22.799-21.417zM39.637 87.161c0 3.001 1.18 4.181 4.181 4.181h.426l.41 1.231C45.278 94.449 46.042 95 48.019 95h3.963c1.978 0 2.74-.551 3.365-2.427l.409-1.231h.427c3.002 0 4.18-1.18 4.18-4.181V80.91H39.637v6.251zM50 18.265c1.26 0 2.072-.814 2.072-2.073v-9.12C52.072 5.813 51.26 5 50 5c-1.259 0-2.072.813-2.072 2.073v9.12c0 1.259.813 2.072 2.072 2.072zM68.313 23.727c.994.774 2.135.634 2.91-.357l5.614-7.187c.776-.992.636-2.135-.356-2.909-.992-.776-2.135-.636-2.91.357l-5.613 7.186c-.778.993-.636 2.135.355 2.91zM91.157 36.373c-.306-1.222-1.291-1.815-2.513-1.51l-8.85 2.207c-1.222.305-1.814 1.29-1.51 2.512.305 1.223 1.291 1.814 2.513 1.51l8.849-2.206c1.223-.305 1.816-1.291 1.511-2.513zM86.757 60.48l-8.331-3.709c-1.15-.512-2.225-.099-2.736 1.052-.512 1.151-.1 2.224 1.051 2.737l8.33 3.707c1.15.514 2.225.101 2.736-1.05.513-1.149.1-2.223-1.05-2.737zM28.779 23.37c.775.992 1.917 1.131 2.909.357.992-.776 1.132-1.917.357-2.91l-5.615-7.186c-.775-.992-1.917-1.132-2.909-.357s-1.131 1.917-.356 2.909l5.614 7.187zM21.715 39.583c.305-1.223-.288-2.208-1.51-2.513l-8.849-2.207c-1.222-.303-2.208.289-2.513 1.511-.303 1.222.288 2.207 1.511 2.512l8.848 2.206c1.222.304 2.208-.287 2.513-1.509zM21.575 56.771l-8.331 3.711c-1.151.511-1.563 1.586-1.05 2.735.511 1.151 1.586 1.563 2.736 1.052l8.331-3.711c1.151-.511 1.563-1.586 1.05-2.735-.512-1.15-1.585-1.562-2.736-1.052z\"/></svg>');\n}\n.lh-report-icon--treemap::before {\n background-image: url('data:image/svg+xml;utf8,<svg xmlns=\"http://www.w3.org/2000/svg\" height=\"24px\" viewBox=\"0 0 24 24\" width=\"24px\" fill=\"black\"><path d=\"M3 5v14h19V5H3zm2 2h15v4H5V7zm0 10v-4h4v4H5zm6 0v-4h9v4h-9z\"/></svg>');\n}\n.lh-report-icon--date::before {\n background-image: url('data:image/svg+xml;utf8,<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M7 11h2v2H7v-2zm14-5v14a2 2 0 01-2 2H5a2 2 0 01-2-2V6c0-1.1.9-2 2-2h1V2h2v2h8V2h2v2h1a2 2 0 012 2zM5 8h14V6H5v2zm14 12V10H5v10h14zm-4-7h2v-2h-2v2zm-4 0h2v-2h-2v2z\"/></svg>');\n}\n.lh-report-icon--devices::before {\n background-image: url('data:image/svg+xml;utf8,<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M4 6h18V4H4a2 2 0 00-2 2v11H0v3h14v-3H4V6zm19 2h-6a1 1 0 00-1 1v10c0 .6.5 1 1 1h6c.6 0 1-.5 1-1V9c0-.6-.5-1-1-1zm-1 9h-4v-7h4v7z\"/></svg>');\n}\n.lh-report-icon--world::before {\n background-image: url('data:image/svg+xml;utf8,<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 2a10 10 0 1 0 0 20 10 10 0 0 0 0-20zm7 6h-3c-.3-1.3-.8-2.5-1.4-3.6A8 8 0 0 1 18.9 8zm-7-4a14 14 0 0 1 2 4h-4a14 14 0 0 1 2-4zM4.3 14a8.2 8.2 0 0 1 0-4h3.3a16.5 16.5 0 0 0 0 4H4.3zm.8 2h3a14 14 0 0 0 1.3 3.6A8 8 0 0 1 5.1 16zm3-8H5a8 8 0 0 1 4.3-3.6L8 8zM12 20a14 14 0 0 1-2-4h4a14 14 0 0 1-2 4zm2.3-6H9.7a14.7 14.7 0 0 1 0-4h4.6a14.6 14.6 0 0 1 0 4zm.3 5.6c.6-1.2 1-2.4 1.4-3.6h3a8 8 0 0 1-4.4 3.6zm1.8-5.6a16.5 16.5 0 0 0 0-4h3.3a8.2 8.2 0 0 1 0 4h-3.3z\"/></svg>');\n}\n.lh-report-icon--stopwatch::before {\n background-image: url('data:image/svg+xml;utf8,<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M15 1H9v2h6V1zm-4 13h2V8h-2v6zm8.1-6.6L20.5 6l-1.4-1.4L17.7 6A9 9 0 0 0 3 13a9 9 0 1 0 16-5.6zm-7 12.6a7 7 0 1 1 0-14 7 7 0 0 1 0 14z\"/></svg>');\n}\n.lh-report-icon--networkspeed::before {\n background-image: url('data:image/svg+xml;utf8,<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M15.9 5c-.2 0-.3 0-.4.2v.2L10.1 17a2 2 0 0 0-.2 1 2 2 0 0 0 4 .4l2.4-12.9c0-.3-.2-.5-.5-.5zM1 9l2 2c2.9-2.9 6.8-4 10.5-3.6l1.2-2.7C10 3.8 4.7 5.3 1 9zm20 2 2-2a15.4 15.4 0 0 0-5.6-3.6L17 8.2c1.5.7 2.9 1.6 4.1 2.8zm-4 4 2-2a9.9 9.9 0 0 0-2.7-1.9l-.5 3 1.2.9zM5 13l2 2a7.1 7.1 0 0 1 4-2l1.3-2.9C9.7 10.1 7 11 5 13z\"/></svg>');\n}\n.lh-report-icon--samples-one::before {\n background-image: url('data:image/svg+xml;utf8,<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><circle cx=\"7\" cy=\"14\" r=\"3\"/><path d=\"M7 18a4 4 0 1 1 0-8 4 4 0 0 1 0 8zm0-6c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm4-2a4 4 0 1 1 0-8 4 4 0 0 1 0 8zm0-6c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm5.6 17.6a4 4 0 1 1 0-8 4 4 0 0 1 0 8zm0-6c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2z\"/></svg>');\n}\n.lh-report-icon--samples-many::before {\n background-image: url('data:image/svg+xml;utf8,<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M7 18a4 4 0 1 1 0-8 4 4 0 0 1 0 8zm0-6c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm4-2a4 4 0 1 1 0-8 4 4 0 0 1 0 8zm0-6c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm5.6 17.6a4 4 0 1 1 0-8 4 4 0 0 1 0 8zm0-6c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2z\"/><circle cx=\"7\" cy=\"14\" r=\"3\"/><circle cx=\"11\" cy=\"6\" r=\"3\"/></svg>');\n}\n.lh-report-icon--chrome::before {\n background-image: url('data:image/svg+xml;utf8,<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"-50 -50 562 562\"><path d=\"M256 25.6v25.6a204 204 0 0 1 144.8 60 204 204 0 0 1 60 144.8 204 204 0 0 1-60 144.8 204 204 0 0 1-144.8 60 204 204 0 0 1-144.8-60 204 204 0 0 1-60-144.8 204 204 0 0 1 60-144.8 204 204 0 0 1 144.8-60V0a256 256 0 1 0 0 512 256 256 0 0 0 0-512v25.6z\"/><path d=\"M256 179.2v25.6a51.3 51.3 0 0 1 0 102.4 51.3 51.3 0 0 1 0-102.4v-51.2a102.3 102.3 0 1 0-.1 204.7 102.3 102.3 0 0 0 .1-204.7v25.6z\"/><path d=\"M256 204.8h217.6a25.6 25.6 0 0 0 0-51.2H256a25.6 25.6 0 0 0 0 51.2m44.3 76.8L191.5 470.1a25.6 25.6 0 1 0 44.4 25.6l108.8-188.5a25.6 25.6 0 1 0-44.4-25.6m-88.6 0L102.9 93.2a25.7 25.7 0 0 0-35-9.4 25.7 25.7 0 0 0-9.4 35l108.8 188.5a25.7 25.7 0 0 0 35 9.4 25.9 25.9 0 0 0 9.4-35.1\"/></svg>');\n}\n\n\n\n.lh-buttons {\n display: flex;\n flex-wrap: wrap;\n margin: var(--default-padding) 0;\n}\n.lh-button {\n height: 32px;\n border: 1px solid var(--report-border-color-secondary);\n border-radius: 3px;\n color: var(--link-color);\n background-color: var(--report-background-color);\n margin: 5px;\n}\n\n.lh-button:first-of-type {\n margin-left: 0;\n}\n\n/* Node */\n.lh-node__snippet {\n font-family: var(--report-font-family-monospace);\n color: var(--snippet-color);\n font-size: var(--report-monospace-font-size);\n line-height: 20px;\n}\n\n/* Score */\n\n.lh-audit__score-icon {\n width: var(--score-icon-size);\n height: var(--score-icon-size);\n margin: var(--score-icon-margin);\n}\n\n.lh-audit--pass .lh-audit__display-text {\n color: var(--color-pass-secondary);\n}\n.lh-audit--pass .lh-audit__score-icon,\n.lh-scorescale-range--pass::before {\n border-radius: 100%;\n background: var(--color-pass);\n}\n\n.lh-audit--average .lh-audit__display-text {\n color: var(--color-average-secondary);\n}\n.lh-audit--average .lh-audit__score-icon,\n.lh-scorescale-range--average::before {\n background: var(--color-average);\n width: var(--icon-square-size);\n height: var(--icon-square-size);\n}\n\n.lh-audit--fail .lh-audit__display-text {\n color: var(--color-fail-secondary);\n}\n.lh-audit--fail .lh-audit__score-icon,\n.lh-audit--error .lh-audit__score-icon,\n.lh-scorescale-range--fail::before {\n border-left: calc(var(--score-icon-size) / 2) solid transparent;\n border-right: calc(var(--score-icon-size) / 2) solid transparent;\n border-bottom: var(--score-icon-size) solid var(--color-fail);\n}\n\n.lh-audit--manual .lh-audit__display-text,\n.lh-audit--notapplicable .lh-audit__display-text {\n color: var(--color-gray-600);\n}\n.lh-audit--manual .lh-audit__score-icon,\n.lh-audit--notapplicable .lh-audit__score-icon {\n border: calc(0.2 * var(--score-icon-size)) solid var(--color-gray-400);\n border-radius: 100%;\n background: none;\n}\n\n.lh-audit--informative .lh-audit__display-text {\n color: var(--color-gray-600);\n}\n\n.lh-audit--informative .lh-audit__score-icon {\n border: calc(0.2 * var(--score-icon-size)) solid var(--color-gray-400);\n border-radius: 100%;\n}\n\n.lh-audit__description,\n.lh-audit__stackpack {\n color: var(--report-text-color-secondary);\n}\n.lh-audit__adorn {\n border: 1px solid slategray;\n border-radius: 3px;\n margin: 0 3px;\n padding: 0 2px;\n line-height: 1.1;\n display: inline-block;\n font-size: 90%;\n}\n\n.lh-category-header__description {\n text-align: center;\n color: var(--color-gray-700);\n margin: 0px auto;\n max-width: 400px;\n}\n\n\n.lh-audit__display-text,\n.lh-load-opportunity__sparkline,\n.lh-chevron-container {\n margin: 0 var(--audit-margin-horizontal);\n}\n.lh-chevron-container {\n margin-right: 0;\n}\n\n.lh-audit__title-and-text {\n flex: 1;\n}\n\n.lh-audit__title-and-text code {\n color: var(--snippet-color);\n font-size: var(--report-monospace-font-size);\n}\n\n/* Prepend display text with em dash separator. But not in Opportunities. */\n.lh-audit__display-text:not(:empty):before {\n content: '—';\n margin-right: var(--audit-margin-horizontal);\n}\n.lh-audit-group.lh-audit-group--load-opportunities .lh-audit__display-text:not(:empty):before {\n display: none;\n}\n\n/* Expandable Details (Audit Groups, Audits) */\n.lh-audit__header {\n display: flex;\n align-items: center;\n padding: var(--default-padding);\n}\n\n.lh-audit--load-opportunity .lh-audit__header {\n display: block;\n}\n\n\n.lh-metricfilter {\n display: grid;\n justify-content: end;\n align-items: center;\n grid-auto-flow: column;\n gap: 4px;\n color: var(--color-gray-700);\n}\n\n.lh-metricfilter__radio {\n position: absolute;\n left: -9999px;\n}\n.lh-metricfilter input[type='radio']:focus-visible + label {\n outline: -webkit-focus-ring-color auto 1px;\n}\n\n.lh-metricfilter__label {\n display: inline-flex;\n padding: 0 4px;\n height: 16px;\n text-decoration: underline;\n align-items: center;\n cursor: pointer;\n font-size: 90%;\n}\n\n.lh-metricfilter__label--active {\n background: var(--color-blue-primary);\n color: var(--color-white);\n border-radius: 3px;\n text-decoration: none;\n}\n/* Give the 'All' choice a more muted display */\n.lh-metricfilter__label--active[for=\"metric-All\"] {\n background-color: var(--color-blue-200) !important;\n color: black !important;\n}\n\n.lh-metricfilter__text {\n margin-right: 8px;\n}\n\n/* If audits are filtered, hide the itemcount for Passed Audits… */\n.lh-category--filtered .lh-audit-group .lh-audit-group__itemcount {\n display: none;\n}\n\n\n.lh-audit__header:hover {\n background-color: var(--color-hover);\n}\n\n/* We want to hide the browser's default arrow marker on summary elements. Admittedly, it's complicated. */\n.lh-root details > summary {\n /* Blink 89+ and Firefox will hide the arrow when display is changed from (new) default of `list-item` to block. https://chromestatus.com/feature/6730096436051968*/\n display: block;\n}\n/* Safari and Blink <=88 require using the -webkit-details-marker selector */\n.lh-root details > summary::-webkit-details-marker {\n display: none;\n}\n\n/* Perf Metric */\n\n.lh-metrics-container {\n display: grid;\n grid-auto-rows: 1fr;\n grid-template-columns: 1fr 1fr;\n grid-column-gap: var(--report-line-height);\n margin-bottom: var(--default-padding);\n}\n\n.lh-metric {\n border-top: 1px solid var(--report-border-color-secondary);\n}\n\n.lh-category:not(.lh--hoisted-meta) .lh-metric:nth-last-child(-n+2) {\n border-bottom: 1px solid var(--report-border-color-secondary);\n}\n\n.lh-metric__innerwrap {\n display: grid;\n /**\n * Icon -- Metric Name\n * -- Metric Value\n */\n grid-template-columns: calc(var(--score-icon-size) + var(--score-icon-margin-left) + var(--score-icon-margin-right)) 1fr;\n align-items: center;\n padding: var(--default-padding);\n}\n\n.lh-metric__details {\n order: -1;\n}\n\n.lh-metric__title {\n flex: 1;\n}\n\n.lh-calclink {\n padding-left: calc(1ex / 3);\n}\n\n.lh-metric__description {\n display: none;\n grid-column-start: 2;\n grid-column-end: 4;\n color: var(--report-text-color-secondary);\n}\n\n.lh-metric__value {\n font-size: var(--metric-value-font-size);\n margin: calc(var(--default-padding) / 2) 0;\n white-space: nowrap; /* No wrapping between metric value and the icon */\n grid-column-start: 2;\n}\n\n\n@media screen and (max-width: 535px) {\n .lh-metrics-container {\n display: block;\n }\n\n .lh-metric {\n border-bottom: none !important;\n }\n .lh-category:not(.lh--hoisted-meta) .lh-metric:nth-last-child(1) {\n border-bottom: 1px solid var(--report-border-color-secondary) !important;\n }\n\n /* Change the grid to 3 columns for narrow viewport. */\n .lh-metric__innerwrap {\n /**\n * Icon -- Metric Name -- Metric Value\n */\n grid-template-columns: calc(var(--score-icon-size) + var(--score-icon-margin-left) + var(--score-icon-margin-right)) 2fr 1fr;\n }\n .lh-metric__value {\n justify-self: end;\n grid-column-start: unset;\n }\n}\n\n/* No-JS toggle switch */\n/* Keep this selector sync'd w/ `magicSelector` in report-ui-features-test.js */\n .lh-metrics-toggle__input:checked ~ .lh-metrics-container .lh-metric__description {\n display: block;\n}\n\n/* TODO get rid of the SVGS and clean up these some more */\n.lh-metrics-toggle__input {\n opacity: 0;\n position: absolute;\n right: 0;\n top: 0px;\n}\n\n.lh-metrics-toggle__input + div > label > .lh-metrics-toggle__labeltext--hide,\n.lh-metrics-toggle__input:checked + div > label > .lh-metrics-toggle__labeltext--show {\n display: none;\n}\n.lh-metrics-toggle__input:checked + div > label > .lh-metrics-toggle__labeltext--hide {\n display: inline;\n}\n.lh-metrics-toggle__input:focus + div > label {\n outline: -webkit-focus-ring-color auto 3px;\n}\n\n.lh-metrics-toggle__label {\n cursor: pointer;\n font-size: var(--report-font-size-secondary);\n line-height: var(--report-line-height-secondary);\n color: var(--color-gray-700);\n}\n\n/* Pushes the metric description toggle button to the right. */\n.lh-audit-group--metrics .lh-audit-group__header {\n display: flex;\n justify-content: space-between;\n}\n\n.lh-metric__icon,\n.lh-scorescale-range::before {\n content: '';\n width: var(--score-icon-size);\n height: var(--score-icon-size);\n display: inline-block;\n margin: var(--score-icon-margin);\n}\n\n.lh-metric--pass .lh-metric__value {\n color: var(--color-pass-secondary);\n}\n.lh-metric--pass .lh-metric__icon {\n border-radius: 100%;\n background: var(--color-pass);\n}\n\n.lh-metric--average .lh-metric__value {\n color: var(--color-average-secondary);\n}\n.lh-metric--average .lh-metric__icon {\n background: var(--color-average);\n width: var(--icon-square-size);\n height: var(--icon-square-size);\n}\n\n.lh-metric--fail .lh-metric__value {\n color: var(--color-fail-secondary);\n}\n.lh-metric--fail .lh-metric__icon,\n.lh-metric--error .lh-metric__icon {\n border-left: calc(var(--score-icon-size) / 2) solid transparent;\n border-right: calc(var(--score-icon-size) / 2) solid transparent;\n border-bottom: var(--score-icon-size) solid var(--color-fail);\n}\n\n.lh-metric--error .lh-metric__value,\n.lh-metric--error .lh-metric__description {\n color: var(--color-fail-secondary);\n}\n\n/* Perf load opportunity */\n\n.lh-load-opportunity__cols {\n display: flex;\n align-items: flex-start;\n}\n\n.lh-load-opportunity__header .lh-load-opportunity__col {\n color: var(--color-gray-600);\n display: unset;\n line-height: calc(2.3 * var(--report-font-size));\n}\n\n.lh-load-opportunity__col {\n display: flex;\n}\n\n.lh-load-opportunity__col--one {\n flex: 5;\n align-items: center;\n margin-right: 2px;\n}\n.lh-load-opportunity__col--two {\n flex: 4;\n text-align: right;\n}\n\n.lh-audit--load-opportunity .lh-audit__display-text {\n text-align: right;\n flex: 0 0 calc(3 * var(--report-font-size));\n}\n\n\n/* Sparkline */\n\n.lh-load-opportunity__sparkline {\n flex: 1;\n margin-top: calc((var(--report-line-height) - var(--sparkline-height)) / 2);\n}\n\n.lh-sparkline {\n height: var(--sparkline-height);\n width: 100%;\n}\n\n.lh-sparkline__bar {\n height: 100%;\n float: right;\n}\n\n.lh-audit--pass .lh-sparkline__bar {\n background: var(--color-pass);\n}\n\n.lh-audit--average .lh-sparkline__bar {\n background: var(--color-average);\n}\n\n.lh-audit--fail .lh-sparkline__bar {\n background: var(--color-fail);\n}\n\n/* Filmstrip */\n\n.lh-filmstrip-container {\n /* smaller gap between metrics and filmstrip */\n margin: -8px auto 0 auto;\n}\n\n.lh-filmstrip {\n display: grid;\n justify-content: space-between;\n padding-bottom: var(--default-padding);\n width: 100%;\n grid-template-columns: repeat(auto-fit, 60px);\n}\n\n.lh-filmstrip__frame {\n text-align: right;\n position: relative;\n}\n\n.lh-filmstrip__thumbnail {\n border: 1px solid var(--report-border-color-secondary);\n max-height: 100px;\n max-width: 60px;\n}\n\n/* Audit */\n\n.lh-audit {\n border-bottom: 1px solid var(--report-border-color-secondary);\n}\n\n/* Apply border-top to just the first audit. */\n.lh-audit {\n border-top: 1px solid var(--report-border-color-secondary);\n}\n.lh-audit ~ .lh-audit {\n border-top: none;\n}\n\n\n.lh-audit--error .lh-audit__display-text {\n color: var(--color-fail-secondary);\n}\n\n/* Audit Group */\n\n.lh-audit-group {\n margin-bottom: var(--audit-group-margin-bottom);\n position: relative;\n}\n.lh-audit-group--metrics {\n margin-bottom: calc(var(--audit-group-margin-bottom) / 2);\n}\n\n.lh-audit-group__header::before {\n /* By default, groups don't get an icon */\n content: none;\n width: var(--pwa-icon-size);\n height: var(--pwa-icon-size);\n margin: var(--pwa-icon-margin);\n display: inline-block;\n vertical-align: middle;\n}\n\n/* Style the \"over budget\" columns red. */\n.lh-audit-group--budgets #performance-budget tbody tr td:nth-child(4),\n.lh-audit-group--budgets #performance-budget tbody tr td:nth-child(5),\n.lh-audit-group--budgets #timing-budget tbody tr td:nth-child(3) {\n color: var(--color-red-700);\n}\n\n/* Align the \"over budget request count\" text to be close to the \"over budget bytes\" column. */\n.lh-audit-group--budgets .lh-table tbody tr td:nth-child(4){\n text-align: right;\n}\n\n.lh-audit-group--budgets .lh-details--budget {\n width: 100%;\n margin: 0 0 var(--default-padding);\n}\n\n.lh-audit-group--pwa-installable .lh-audit-group__header::before {\n content: '';\n background-image: var(--pwa-installable-gray-url);\n}\n.lh-audit-group--pwa-optimized .lh-audit-group__header::before {\n content: '';\n background-image: var(--pwa-optimized-gray-url);\n}\n.lh-audit-group--pwa-installable.lh-badged .lh-audit-group__header::before {\n background-image: var(--pwa-installable-color-url);\n}\n.lh-audit-group--pwa-optimized.lh-badged .lh-audit-group__header::before {\n background-image: var(--pwa-optimized-color-url);\n}\n\n.lh-audit-group--metrics .lh-audit-group__summary {\n margin-top: 0;\n margin-bottom: 0;\n}\n\n.lh-audit-group__summary {\n display: flex;\n justify-content: space-between;\n align-items: center;\n}\n\n.lh-audit-group__header .lh-chevron {\n margin-top: calc((var(--report-line-height) - 5px) / 2);\n}\n\n.lh-audit-group__header {\n letter-spacing: 0.8px;\n padding: var(--default-padding);\n padding-left: 0;\n}\n\n.lh-audit-group__header, .lh-audit-group__summary {\n font-size: var(--report-font-size-secondary);\n line-height: var(--report-line-height-secondary);\n color: var(--color-gray-700);\n}\n\n.lh-audit-group__title {\n text-transform: uppercase;\n font-weight: 500;\n}\n\n.lh-audit-group__itemcount {\n color: var(--color-gray-600);\n}\n\n.lh-audit-group__footer {\n color: var(--color-gray-600);\n display: block;\n margin-top: var(--default-padding);\n}\n\n.lh-details,\n.lh-category-header__description,\n.lh-load-opportunity__header,\n.lh-audit-group__footer {\n font-size: var(--report-font-size-secondary);\n line-height: var(--report-line-height-secondary);\n}\n\n.lh-audit-explanation {\n margin: var(--audit-padding-vertical) 0 calc(var(--audit-padding-vertical) / 2) var(--audit-margin-horizontal);\n line-height: var(--audit-explanation-line-height);\n display: inline-block;\n}\n\n.lh-audit--fail .lh-audit-explanation {\n color: var(--color-fail-secondary);\n}\n\n/* Report */\n.lh-list > div:not(:last-child) {\n padding-bottom: 20px;\n}\n\n.lh-header-container {\n display: block;\n margin: 0 auto;\n position: relative;\n word-wrap: break-word;\n}\n\n.lh-header-container .lh-scores-wrapper {\n border-bottom: 1px solid var(--color-gray-200);\n}\n\n\n.lh-report {\n min-width: var(--report-content-min-width);\n}\n\n.lh-exception {\n font-size: large;\n}\n\n.lh-code {\n white-space: normal;\n margin-top: 0;\n font-size: var(--report-monospace-font-size);\n}\n\n.lh-warnings {\n --item-margin: calc(var(--report-line-height) / 6);\n color: var(--color-average-secondary);\n margin: var(--audit-padding-vertical) 0;\n padding: var(--default-padding)\n var(--default-padding)\n var(--default-padding)\n calc(var(--audit-description-padding-left));\n background-color: var(--toplevel-warning-background-color);\n}\n.lh-warnings span {\n font-weight: bold;\n}\n\n.lh-warnings--toplevel {\n --item-margin: calc(var(--header-line-height) / 4);\n color: var(--toplevel-warning-text-color);\n margin-left: auto;\n margin-right: auto;\n max-width: var(--report-content-max-width-minus-edge-gap);\n padding: var(--toplevel-warning-padding);\n border-radius: 8px;\n}\n\n.lh-warnings__msg {\n color: var(--toplevel-warning-message-text-color);\n margin: 0;\n}\n\n.lh-warnings ul {\n margin: 0;\n}\n.lh-warnings li {\n margin: var(--item-margin) 0;\n}\n.lh-warnings li:last-of-type {\n margin-bottom: 0;\n}\n\n.lh-scores-header {\n display: flex;\n flex-wrap: wrap;\n justify-content: center;\n}\n.lh-scores-header__solo {\n padding: 0;\n border: 0;\n}\n\n/* Gauge */\n\n.lh-gauge__wrapper--pass {\n color: var(--color-pass-secondary);\n fill: var(--color-pass);\n stroke: var(--color-pass);\n}\n\n.lh-gauge__wrapper--average {\n color: var(--color-average-secondary);\n fill: var(--color-average);\n stroke: var(--color-average);\n}\n\n.lh-gauge__wrapper--fail {\n color: var(--color-fail-secondary);\n fill: var(--color-fail);\n stroke: var(--color-fail);\n}\n\n.lh-gauge__wrapper--not-applicable {\n color: var(--color-not-applicable);\n fill: var(--color-not-applicable);\n stroke: var(--color-not-applicable);\n}\n\n.lh-fraction__wrapper .lh-fraction__content::before {\n content: '';\n height: var(--score-icon-size);\n width: var(--score-icon-size);\n margin: var(--score-icon-margin);\n display: inline-block;\n}\n.lh-fraction__wrapper--pass .lh-fraction__content {\n color: var(--color-pass-secondary);\n}\n.lh-fraction__wrapper--pass .lh-fraction__background {\n background-color: var(--color-pass);\n}\n.lh-fraction__wrapper--pass .lh-fraction__content::before {\n background-color: var(--color-pass);\n border-radius: 50%;\n}\n.lh-fraction__wrapper--average .lh-fraction__content {\n color: var(--color-average-secondary);\n}\n.lh-fraction__wrapper--average .lh-fraction__background,\n.lh-fraction__wrapper--average .lh-fraction__content::before {\n background-color: var(--color-average);\n}\n.lh-fraction__wrapper--fail .lh-fraction__content {\n color: var(--color-fail);\n}\n.lh-fraction__wrapper--fail .lh-fraction__background {\n background-color: var(--color-fail);\n}\n.lh-fraction__wrapper--fail .lh-fraction__content::before {\n border-left: calc(var(--score-icon-size) / 2) solid transparent;\n border-right: calc(var(--score-icon-size) / 2) solid transparent;\n border-bottom: var(--score-icon-size) solid var(--color-fail);\n}\n.lh-fraction__wrapper--null .lh-fraction__content {\n color: var(--color-gray-700);\n}\n.lh-fraction__wrapper--null .lh-fraction__background {\n background-color: var(--color-gray-700);\n}\n.lh-fraction__wrapper--null .lh-fraction__content::before {\n border-radius: 50%;\n border: calc(0.2 * var(--score-icon-size)) solid var(--color-gray-700);\n}\n\n.lh-fraction__background {\n position: absolute;\n height: 100%;\n width: 100%;\n border-radius: calc(var(--gauge-circle-size) / 2);\n opacity: 0.1;\n z-index: -1;\n}\n\n.lh-fraction__content-wrapper {\n height: var(--gauge-circle-size);\n display: flex;\n align-items: center;\n}\n\n.lh-fraction__content {\n display: flex;\n position: relative;\n align-items: center;\n justify-content: center;\n font-size: calc(0.3 * var(--gauge-circle-size));\n line-height: calc(0.4 * var(--gauge-circle-size));\n width: max-content;\n min-width: calc(1.5 * var(--gauge-circle-size));\n padding: calc(0.1 * var(--gauge-circle-size)) calc(0.2 * var(--gauge-circle-size));\n --score-icon-size: calc(0.21 * var(--gauge-circle-size));\n --score-icon-margin: 0 calc(0.15 * var(--gauge-circle-size)) 0 0;\n}\n\n.lh-gauge {\n stroke-linecap: round;\n width: var(--gauge-circle-size);\n height: var(--gauge-circle-size);\n}\n\n.lh-category .lh-gauge {\n --gauge-circle-size: var(--gauge-circle-size-big);\n}\n\n.lh-gauge-base {\n opacity: 0.1;\n}\n\n.lh-gauge-arc {\n fill: none;\n transform-origin: 50% 50%;\n animation: load-gauge var(--transition-length) ease forwards;\n animation-delay: 250ms;\n}\n\n.lh-gauge__svg-wrapper {\n position: relative;\n height: var(--gauge-circle-size);\n}\n.lh-category .lh-gauge__svg-wrapper,\n.lh-category .lh-fraction__wrapper {\n --gauge-circle-size: var(--gauge-circle-size-big);\n}\n\n/* The plugin badge overlay */\n.lh-gauge__wrapper--plugin .lh-gauge__svg-wrapper::before {\n width: var(--plugin-badge-size);\n height: var(--plugin-badge-size);\n background-color: var(--plugin-badge-background-color);\n background-image: var(--plugin-icon-url);\n background-repeat: no-repeat;\n background-size: var(--plugin-icon-size);\n background-position: 58% 50%;\n content: \"\";\n position: absolute;\n right: -6px;\n bottom: 0px;\n display: block;\n z-index: 100;\n box-shadow: 0 0 4px rgba(0,0,0,.2);\n border-radius: 25%;\n}\n.lh-category .lh-gauge__wrapper--plugin .lh-gauge__svg-wrapper::before {\n width: var(--plugin-badge-size-big);\n height: var(--plugin-badge-size-big);\n}\n\n@keyframes load-gauge {\n from { stroke-dasharray: 0 352; }\n}\n\n.lh-gauge__percentage {\n width: 100%;\n height: var(--gauge-circle-size);\n position: absolute;\n font-family: var(--report-font-family-monospace);\n font-size: calc(var(--gauge-circle-size) * 0.34 + 1.3px);\n line-height: 0;\n text-align: center;\n top: calc(var(--score-container-padding) + var(--gauge-circle-size) / 2);\n}\n\n.lh-category .lh-gauge__percentage {\n --gauge-circle-size: var(--gauge-circle-size-big);\n --gauge-percentage-font-size: var(--gauge-percentage-font-size-big);\n}\n\n.lh-gauge__wrapper,\n.lh-fraction__wrapper {\n position: relative;\n display: flex;\n align-items: center;\n flex-direction: column;\n text-decoration: none;\n padding: var(--score-container-padding);\n\n --transition-length: 1s;\n\n /* Contain the layout style paint & layers during animation*/\n contain: content;\n will-change: opacity; /* Only using for layer promotion */\n}\n\n.lh-gauge__label,\n.lh-fraction__label {\n font-size: var(--gauge-label-font-size);\n font-weight: 500;\n line-height: var(--gauge-label-line-height);\n margin-top: 10px;\n text-align: center;\n color: var(--report-text-color);\n word-break: keep-all;\n}\n\n/* TODO(#8185) use more BEM (.lh-gauge__label--big) instead of relying on descendant selector */\n.lh-category .lh-gauge__label,\n.lh-category .lh-fraction__label {\n --gauge-label-font-size: var(--gauge-label-font-size-big);\n --gauge-label-line-height: var(--gauge-label-line-height-big);\n margin-top: 14px;\n}\n\n.lh-scores-header .lh-gauge__wrapper,\n.lh-scores-header .lh-fraction__wrapper,\n.lh-scores-header .lh-gauge--pwa__wrapper,\n.lh-sticky-header .lh-gauge__wrapper,\n.lh-sticky-header .lh-fraction__wrapper,\n.lh-sticky-header .lh-gauge--pwa__wrapper {\n width: var(--gauge-wrapper-width);\n}\n\n.lh-scorescale {\n display: inline-flex;\n\n gap: calc(var(--default-padding) * 4);\n margin: 16px auto 0 auto;\n font-size: var(--report-font-size-secondary);\n color: var(--color-gray-700);\n\n}\n\n.lh-scorescale-range {\n display: flex;\n align-items: center;\n font-family: var(--report-font-family-monospace);\n white-space: nowrap;\n}\n\n.lh-category-header__finalscreenshot .lh-scorescale {\n border: 0;\n display: flex;\n justify-content: center;\n}\n\n.lh-category-header__finalscreenshot .lh-scorescale-range {\n font-family: unset;\n font-size: 12px;\n}\n\n.lh-scorescale-wrap {\n display: contents;\n}\n\n/* Hide category score gauages if it's a single category report */\n.lh-header--solo-category .lh-scores-wrapper {\n display: none;\n}\n\n\n.lh-categories {\n width: 100%;\n overflow: hidden;\n}\n\n.lh-category {\n padding: var(--category-padding);\n max-width: var(--report-content-max-width);\n margin: 0 auto;\n\n --sticky-header-height: calc(var(--gauge-circle-size-sm) + var(--score-container-padding) * 2);\n --topbar-plus-sticky-header: calc(var(--topbar-height) + var(--sticky-header-height));\n scroll-margin-top: var(--topbar-plus-sticky-header);\n\n /* Faster recalc style & layout of the report. https://web.dev/content-visibility/ */\n content-visibility: auto;\n contain-intrinsic-size: 1000px;\n}\n\n.lh-category-wrapper {\n border-bottom: 1px solid var(--color-gray-200);\n}\n.lh-category-wrapper:last-of-type {\n border-bottom: 0;\n}\n\n.lh-category-header {\n margin-bottom: var(--section-padding-vertical);\n}\n\n.lh-category-header .lh-score__gauge {\n max-width: 400px;\n width: auto;\n margin: 0px auto;\n}\n\n.lh-category-header__finalscreenshot {\n display: grid;\n grid-template: none / 1fr 1px 1fr;\n justify-items: center;\n align-items: center;\n gap: var(--report-line-height);\n min-height: 288px;\n margin-bottom: var(--default-padding);\n}\n\n.lh-final-ss-image {\n /* constrain the size of the image to not be too large */\n max-height: calc(var(--gauge-circle-size-big) * 2.8);\n max-width: calc(var(--gauge-circle-size-big) * 3.5);\n border: 1px solid var(--color-gray-200);\n padding: 4px;\n border-radius: 3px;\n display: block;\n}\n\n.lh-category-headercol--separator {\n background: var(--color-gray-200);\n width: 1px;\n height: var(--gauge-circle-size-big);\n}\n\n@media screen and (max-width: 780px) {\n .lh-category-header__finalscreenshot {\n grid-template: 1fr 1fr / none\n }\n .lh-category-headercol--separator {\n display: none;\n }\n}\n\n\n/* 964 fits the min-width of the filmstrip */\n@media screen and (max-width: 964px) {\n .lh-report {\n margin-left: 0;\n width: 100%;\n }\n}\n\n@media print {\n body {\n -webkit-print-color-adjust: exact; /* print background colors */\n }\n .lh-container {\n display: block;\n }\n .lh-report {\n margin-left: 0;\n padding-top: 0;\n }\n .lh-categories {\n margin-top: 0;\n }\n}\n\n.lh-table {\n border-collapse: collapse;\n /* Can't assign padding to table, so shorten the width instead. */\n width: calc(100% - var(--audit-description-padding-left) - var(--stackpack-padding-horizontal));\n border: 1px solid var(--report-border-color-secondary);\n\n}\n\n.lh-table thead th {\n font-weight: normal;\n color: var(--color-gray-600);\n /* See text-wrapping comment on .lh-container. */\n word-break: normal;\n}\n\n.lh-row--even {\n background-color: var(--table-higlight-background-color);\n}\n.lh-row--hidden {\n display: none;\n}\n\n.lh-table th,\n.lh-table td {\n padding: var(--default-padding);\n}\n\n.lh-table tr {\n vertical-align: middle;\n}\n\n/* Looks unnecessary, but mostly for keeping the <th>s left-aligned */\n.lh-table-column--text,\n.lh-table-column--source-location,\n.lh-table-column--url,\n/* .lh-table-column--thumbnail, */\n/* .lh-table-column--empty,*/\n.lh-table-column--code,\n.lh-table-column--node {\n text-align: left;\n}\n\n.lh-table-column--code {\n min-width: 100px;\n}\n\n.lh-table-column--bytes,\n.lh-table-column--timespanMs,\n.lh-table-column--ms,\n.lh-table-column--numeric {\n text-align: right;\n word-break: normal;\n}\n\n\n\n.lh-table .lh-table-column--thumbnail {\n width: var(--image-preview-size);\n}\n\n.lh-table-column--url {\n min-width: 250px;\n}\n\n.lh-table-column--text {\n min-width: 80px;\n}\n\n/* Keep columns narrow if they follow the URL column */\n/* 12% was determined to be a decent narrow width, but wide enough for column headings */\n.lh-table-column--url + th.lh-table-column--bytes,\n.lh-table-column--url + .lh-table-column--bytes + th.lh-table-column--bytes,\n.lh-table-column--url + .lh-table-column--ms,\n.lh-table-column--url + .lh-table-column--ms + th.lh-table-column--bytes,\n.lh-table-column--url + .lh-table-column--bytes + th.lh-table-column--timespanMs {\n width: 12%;\n}\n\n.lh-text__url-host {\n display: inline;\n}\n\n.lh-text__url-host {\n margin-left: calc(var(--report-font-size) / 2);\n opacity: 0.6;\n font-size: 90%\n}\n\n.lh-thumbnail {\n object-fit: cover;\n width: var(--image-preview-size);\n height: var(--image-preview-size);\n display: block;\n}\n\n.lh-unknown pre {\n overflow: scroll;\n border: solid 1px var(--color-gray-200);\n}\n\n.lh-text__url > a {\n color: inherit;\n text-decoration: none;\n}\n\n.lh-text__url > a:hover {\n text-decoration: underline dotted #999;\n}\n\n.lh-sub-item-row {\n margin-left: 20px;\n margin-bottom: 0;\n color: var(--color-gray-700);\n}\n.lh-sub-item-row td {\n padding-top: 4px;\n padding-bottom: 4px;\n padding-left: 20px;\n}\n\n/* Chevron\n https://codepen.io/paulirish/pen/LmzEmK\n */\n.lh-chevron {\n --chevron-angle: 42deg;\n /* Edge doesn't support transform: rotate(calc(...)), so we define it here */\n --chevron-angle-right: -42deg;\n width: var(--chevron-size);\n height: var(--chevron-size);\n margin-top: calc((var(--report-line-height) - 12px) / 2);\n}\n\n.lh-chevron__lines {\n transition: transform 0.4s;\n transform: translateY(var(--report-line-height));\n}\n.lh-chevron__line {\n stroke: var(--chevron-line-stroke);\n stroke-width: var(--chevron-size);\n stroke-linecap: square;\n transform-origin: 50%;\n transform: rotate(var(--chevron-angle));\n transition: transform 300ms, stroke 300ms;\n}\n\n.lh-expandable-details .lh-chevron__line-right,\n.lh-expandable-details[open] .lh-chevron__line-left {\n transform: rotate(var(--chevron-angle-right));\n}\n\n.lh-expandable-details[open] .lh-chevron__line-right {\n transform: rotate(var(--chevron-angle));\n}\n\n\n.lh-expandable-details[open] .lh-chevron__lines {\n transform: translateY(calc(var(--chevron-size) * -1));\n}\n\n.lh-expandable-details[open] {\n animation: 300ms openDetails forwards;\n padding-bottom: var(--default-padding);\n}\n\n@keyframes openDetails {\n from {\n outline: 1px solid var(--report-background-color);\n }\n to {\n outline: 1px solid;\n box-shadow: 0 2px 4px rgba(0, 0, 0, .24);\n }\n}\n\n@media screen and (max-width: 780px) {\n /* no black outline if we're not confident the entire table can be displayed within bounds */\n .lh-expandable-details[open] {\n animation: none;\n }\n}\n\n.lh-expandable-details[open] summary, details.lh-clump > summary {\n border-bottom: 1px solid var(--report-border-color-secondary);\n}\ndetails.lh-clump[open] > summary {\n border-bottom-width: 0;\n}\n\n\n\ndetails .lh-clump-toggletext--hide,\ndetails[open] .lh-clump-toggletext--show { display: none; }\ndetails[open] .lh-clump-toggletext--hide { display: block;}\n\n\n/* Tooltip */\n.lh-tooltip-boundary {\n position: relative;\n}\n\n.lh-tooltip {\n position: absolute;\n display: none; /* Don't retain these layers when not needed */\n opacity: 0;\n background: #ffffff;\n white-space: pre-line; /* Render newlines in the text */\n min-width: 246px;\n max-width: 275px;\n padding: 15px;\n border-radius: 5px;\n text-align: initial;\n line-height: 1.4;\n}\n/* shrink tooltips to not be cutoff on left edge of narrow viewports\n 45vw is chosen to be ~= width of the left column of metrics\n*/\n@media screen and (max-width: 535px) {\n .lh-tooltip {\n min-width: 45vw;\n padding: 3vw;\n }\n}\n\n.lh-tooltip-boundary:hover .lh-tooltip {\n display: block;\n animation: fadeInTooltip 250ms;\n animation-fill-mode: forwards;\n animation-delay: 850ms;\n bottom: 100%;\n z-index: 1;\n will-change: opacity;\n right: 0;\n pointer-events: none;\n}\n\n.lh-tooltip::before {\n content: \"\";\n border: solid transparent;\n border-bottom-color: #fff;\n border-width: 10px;\n position: absolute;\n bottom: -20px;\n right: 6px;\n transform: rotate(180deg);\n pointer-events: none;\n}\n\n@keyframes fadeInTooltip {\n 0% { opacity: 0; }\n 75% { opacity: 1; }\n 100% { opacity: 1; filter: drop-shadow(1px 0px 1px #aaa) drop-shadow(0px 2px 4px hsla(206, 6%, 25%, 0.15)); pointer-events: auto; }\n}\n\n/* Element screenshot */\n.lh-element-screenshot {\n float: left;\n margin-right: 20px;\n}\n.lh-element-screenshot__content {\n overflow: hidden;\n min-width: 110px;\n display: flex;\n justify-content: center;\n background-color: var(--report-background-color);\n}\n.lh-element-screenshot__image {\n position: relative;\n /* Set by ElementScreenshotRenderer.installFullPageScreenshotCssVariable */\n background-image: var(--element-screenshot-url);\n outline: 2px solid #777;\n background-color: white;\n background-repeat: no-repeat;\n}\n.lh-element-screenshot__mask {\n position: absolute;\n background: #555;\n opacity: 0.8;\n}\n.lh-element-screenshot__element-marker {\n position: absolute;\n outline: 2px solid var(--color-lime-400);\n}\n.lh-element-screenshot__overlay {\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n z-index: 2000; /* .lh-topbar is 1000 */\n background: var(--screenshot-overlay-background);\n display: flex;\n align-items: center;\n justify-content: center;\n cursor: zoom-out;\n}\n\n.lh-element-screenshot__overlay .lh-element-screenshot {\n margin-right: 0; /* clearing margin used in thumbnail case */\n outline: 1px solid var(--color-gray-700);\n}\n\n.lh-screenshot-overlay--enabled .lh-element-screenshot {\n cursor: zoom-out;\n}\n.lh-screenshot-overlay--enabled .lh-node .lh-element-screenshot {\n cursor: zoom-in;\n}\n\n\n.lh-meta__items {\n --meta-icon-size: calc(var(--report-icon-size) * 0.667);\n padding: var(--default-padding);\n display: grid;\n grid-template-columns: 1fr 1fr 1fr;\n background-color: var(--env-item-background-color);\n border-radius: 3px;\n margin: 0 0 var(--default-padding) 0;\n font-size: 12px;\n column-gap: var(--default-padding);\n color: var(--color-gray-700);\n}\n\n.lh-meta__item {\n display: block;\n list-style-type: none;\n position: relative;\n padding: 0 0 0 calc(var(--meta-icon-size) + var(--default-padding) * 2);\n cursor: unset; /* disable pointer cursor from report-icon */\n}\n\n.lh-meta__item.lh-tooltip-boundary {\n text-decoration: dotted underline var(--color-gray-500);\n cursor: help;\n}\n\n.lh-meta__item.lh-report-icon::before {\n position: absolute;\n left: var(--default-padding);\n width: var(--meta-icon-size);\n height: var(--meta-icon-size);\n}\n\n.lh-meta__item.lh-report-icon:hover::before {\n opacity: 0.7;\n}\n\n.lh-meta__item .lh-tooltip {\n color: var(--color-gray-800);\n}\n\n.lh-meta__item .lh-tooltip::before {\n right: auto; /* Set the tooltip arrow to the leftside */\n left: 6px;\n}\n\n/* Change the grid for narrow viewport. */\n@media screen and (max-width: 640px) {\n .lh-meta__items {\n grid-template-columns: 1fr 1fr;\n }\n}\n@media screen and (max-width: 535px) {\n .lh-meta__items {\n display: block;\n }\n}\n\n\n/*# sourceURL=report-styles.css */\n");
1219
+ const el1 = dom.createElement('style');
1220
+ el1.append('/**\n * @license\n * Copyright 2017 The Lighthouse Authors. All Rights Reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the "License");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an "AS-IS" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/*\n Naming convention:\n\n If a variable is used for a specific component: --{component}-{property name}-{modifier}\n\n Both {component} and {property name} should be kebab-case. If the target is the entire page,\n use \'report\' for the component. The property name should not be abbreviated. Use the\n property name the variable is intended for - if it\'s used for multiple, a common descriptor\n is fine (ex: \'size\' for a variable applied to \'width\' and \'height\'). If a variable is shared\n across multiple components, either create more variables or just drop the "{component}-"\n part of the name. Append any modifiers at the end (ex: \'big\', \'dark\').\n\n For colors: --color-{hue}-{intensity}\n\n {intensity} is the Material Design tag - 700, A700, etc.\n*/\n.lh-vars {\n /* Palette using Material Design Colors\n * https://www.materialui.co/colors */\n --color-amber-50: #FFF8E1;\n --color-blue-200: #90CAF9;\n --color-blue-900: #0D47A1;\n --color-blue-A700: #2962FF;\n --color-blue-primary: #06f;\n --color-cyan-500: #00BCD4;\n --color-gray-100: #F5F5F5;\n --color-gray-300: #CFCFCF;\n --color-gray-200: #E0E0E0;\n --color-gray-400: #BDBDBD;\n --color-gray-50: #FAFAFA;\n --color-gray-500: #9E9E9E;\n --color-gray-600: #757575;\n --color-gray-700: #616161;\n --color-gray-800: #424242;\n --color-gray-900: #212121;\n --color-gray: #000000;\n --color-green-700: #080;\n --color-green: #0c6;\n --color-lime-400: #D3E156;\n --color-orange-50: #FFF3E0;\n --color-orange-700: #C33300;\n --color-orange: #fa3;\n --color-red-700: #c00;\n --color-red: #f33;\n --color-teal-600: #00897B;\n --color-white: #FFFFFF;\n\n /* Context-specific colors */\n --color-average-secondary: var(--color-orange-700);\n --color-average: var(--color-orange);\n --color-fail-secondary: var(--color-red-700);\n --color-fail: var(--color-red);\n --color-hover: var(--color-gray-50);\n --color-informative: var(--color-blue-900);\n --color-pass-secondary: var(--color-green-700);\n --color-pass: var(--color-green);\n --color-not-applicable: var(--color-gray-600);\n\n /* Component variables */\n --audit-description-padding-left: calc(var(--score-icon-size) + var(--score-icon-margin-left) + var(--score-icon-margin-right));\n --audit-explanation-line-height: 16px;\n --audit-group-margin-bottom: calc(var(--default-padding) * 6);\n --audit-group-padding-vertical: 8px;\n --audit-margin-horizontal: 5px;\n --audit-padding-vertical: 8px;\n --category-padding: calc(var(--default-padding) * 6) var(--edge-gap-padding) calc(var(--default-padding) * 4);\n --chevron-line-stroke: var(--color-gray-600);\n --chevron-size: 12px;\n --default-padding: 8px;\n --edge-gap-padding: calc(var(--default-padding) * 4);\n --env-item-background-color: var(--color-gray-100);\n --env-item-font-size: 28px;\n --env-item-line-height: 36px;\n --env-item-padding: 10px 0px;\n --env-name-min-width: 220px;\n --footer-padding-vertical: 16px;\n --gauge-circle-size-big: 96px;\n --gauge-circle-size: 48px;\n --gauge-circle-size-sm: 32px;\n --gauge-label-font-size-big: 18px;\n --gauge-label-font-size: var(--report-font-size-secondary);\n --gauge-label-line-height-big: 24px;\n --gauge-label-line-height: var(--report-line-height-secondary);\n --gauge-percentage-font-size-big: 38px;\n --gauge-percentage-font-size: var(--report-font-size-secondary);\n --gauge-wrapper-width: 120px;\n --header-line-height: 24px;\n --highlighter-background-color: var(--report-text-color);\n --icon-square-size: calc(var(--score-icon-size) * 0.88);\n --image-preview-size: 48px;\n --link-color: var(--color-blue-primary);\n --locale-selector-background-color: var(--color-white);\n --metric-toggle-lines-fill: #7F7F7F;\n --metric-value-font-size: calc(var(--report-font-size) * 1.8);\n --metrics-toggle-background-color: var(--color-gray-200);\n --plugin-badge-background-color: var(--color-white);\n --plugin-badge-size-big: calc(var(--gauge-circle-size-big) / 2.7);\n --plugin-badge-size: calc(var(--gauge-circle-size) / 2.7);\n --plugin-icon-size: 65%;\n --pwa-icon-margin: 0 var(--default-padding);\n --pwa-icon-size: var(--topbar-logo-size);\n --report-background-color: #fff;\n --report-border-color-secondary: #ebebeb;\n --report-font-family-monospace: \'Roboto Mono\', \'Menlo\', \'dejavu sans mono\', \'Consolas\', \'Lucida Console\', monospace;\n --report-font-family: Roboto, Helvetica, Arial, sans-serif;\n --report-font-size: 14px;\n --report-font-size-secondary: 12px;\n --report-icon-size: var(--score-icon-background-size);\n --report-line-height: 24px;\n --report-line-height-secondary: 20px;\n --report-monospace-font-size: calc(var(--report-font-size) * 0.85);\n --report-text-color-secondary: var(--color-gray-800);\n --report-text-color: var(--color-gray-900);\n --report-content-max-width: calc(60 * var(--report-font-size)); /* defaults to 840px */\n --report-content-min-width: 360px;\n --report-content-max-width-minus-edge-gap: calc(var(--report-content-max-width) - var(--edge-gap-padding) * 2);\n --score-container-padding: 8px;\n --score-icon-background-size: 24px;\n --score-icon-margin-left: 6px;\n --score-icon-margin-right: 14px;\n --score-icon-margin: 0 var(--score-icon-margin-right) 0 var(--score-icon-margin-left);\n --score-icon-size: 12px;\n --score-icon-size-big: 16px;\n --screenshot-overlay-background: rgba(0, 0, 0, 0.3);\n --section-padding-vertical: calc(var(--default-padding) * 6);\n --snippet-background-color: var(--color-gray-50);\n --snippet-color: #0938C2;\n --sparkline-height: 5px;\n --stackpack-padding-horizontal: 10px;\n --sticky-header-background-color: var(--report-background-color);\n --table-higlight-background-color: hsla(210, 17%, 77%, 0.1);\n --tools-icon-color: var(--color-gray-600);\n --topbar-background-color: var(--color-white);\n --topbar-height: 32px;\n --topbar-logo-size: 24px;\n --topbar-padding: 0 8px;\n --toplevel-warning-background-color: hsla(30, 100%, 75%, 10%);\n --toplevel-warning-message-text-color: var(--color-average-secondary);\n --toplevel-warning-padding: 18px;\n --toplevel-warning-text-color: var(--report-text-color);\n\n /* SVGs */\n --plugin-icon-url-dark: url(\'data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="24px" height="24px" viewBox="0 0 24 24" fill="%23FFFFFF"><path d="M0 0h24v24H0z" fill="none"/><path d="M20.5 11H19V7c0-1.1-.9-2-2-2h-4V3.5C13 2.12 11.88 1 10.5 1S8 2.12 8 3.5V5H4c-1.1 0-1.99.9-1.99 2v3.8H3.5c1.49 0 2.7 1.21 2.7 2.7s-1.21 2.7-2.7 2.7H2V20c0 1.1.9 2 2 2h3.8v-1.5c0-1.49 1.21-2.7 2.7-2.7 1.49 0 2.7 1.21 2.7 2.7V22H17c1.1 0 2-.9 2-2v-4h1.5c1.38 0 2.5-1.12 2.5-2.5S21.88 11 20.5 11z"/></svg>\');\n --plugin-icon-url: url(\'data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="24px" height="24px" viewBox="0 0 24 24" fill="%23757575"><path d="M0 0h24v24H0z" fill="none"/><path d="M20.5 11H19V7c0-1.1-.9-2-2-2h-4V3.5C13 2.12 11.88 1 10.5 1S8 2.12 8 3.5V5H4c-1.1 0-1.99.9-1.99 2v3.8H3.5c1.49 0 2.7 1.21 2.7 2.7s-1.21 2.7-2.7 2.7H2V20c0 1.1.9 2 2 2h3.8v-1.5c0-1.49 1.21-2.7 2.7-2.7 1.49 0 2.7 1.21 2.7 2.7V22H17c1.1 0 2-.9 2-2v-4h1.5c1.38 0 2.5-1.12 2.5-2.5S21.88 11 20.5 11z"/></svg>\');\n\n --pass-icon-url: url(\'data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 48"><title>check</title><path fill="%23178239" d="M24 4C12.95 4 4 12.95 4 24c0 11.04 8.95 20 20 20 11.04 0 20-8.96 20-20 0-11.05-8.96-20-20-20zm-4 30L10 24l2.83-2.83L20 28.34l15.17-15.17L38 16 20 34z"/></svg>\');\n --average-icon-url: url(\'data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 48"><title>info</title><path fill="%23E67700" d="M24 4C12.95 4 4 12.95 4 24s8.95 20 20 20 20-8.95 20-20S35.05 4 24 4zm2 30h-4V22h4v12zm0-16h-4v-4h4v4z"/></svg>\');\n --fail-icon-url: url(\'data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 48"><title>warn</title><path fill="%23C7221F" d="M2 42h44L24 4 2 42zm24-6h-4v-4h4v4zm0-8h-4v-8h4v8z"/></svg>\');\n\n --pwa-installable-gray-url: url(\'data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg"><g fill="none" fill-rule="nonzero"><circle fill="%23DAE0E3" cx="12" cy="12" r="12"/><path d="M12 5a7 7 0 1 0 0 14 7 7 0 0 0 0-14zm3.5 7.7h-2.8v2.8h-1.4v-2.8H8.5v-1.4h2.8V8.5h1.4v2.8h2.8v1.4z" fill="%23FFF"/></g></svg>\');\n --pwa-optimized-gray-url: url(\'data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg"><g fill="none" fill-rule="evenodd"><rect fill="%23DAE0E3" width="24" height="24" rx="12"/><path fill="%23FFF" d="M12 15.07l3.6 2.18-.95-4.1 3.18-2.76-4.2-.36L12 6.17l-1.64 3.86-4.2.36 3.2 2.76-.96 4.1z"/><path d="M5 5h14v14H5z"/></g></svg>\');\n\n --pwa-installable-gray-url-dark: url(\'data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg"><g fill="none" fill-rule="nonzero"><circle fill="%23424242" cx="12" cy="12" r="12"/><path d="M12 5a7 7 0 1 0 0 14 7 7 0 0 0 0-14zm3.5 7.7h-2.8v2.8h-1.4v-2.8H8.5v-1.4h2.8V8.5h1.4v2.8h2.8v1.4z" fill="%23FFF"/></g></svg>\');\n --pwa-optimized-gray-url-dark: url(\'data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg"><g fill="none" fill-rule="evenodd"><rect fill="%23424242" width="24" height="24" rx="12"/><path fill="%23FFF" d="M12 15.07l3.6 2.18-.95-4.1 3.18-2.76-4.2-.36L12 6.17l-1.64 3.86-4.2.36 3.2 2.76-.96 4.1z"/><path d="M5 5h14v14H5z"/></g></svg>\');\n\n --pwa-installable-color-url: url(\'data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg"><g fill-rule="nonzero" fill="none"><circle fill="%230CCE6B" cx="12" cy="12" r="12"/><path d="M12 5a7 7 0 1 0 0 14 7 7 0 0 0 0-14zm3.5 7.7h-2.8v2.8h-1.4v-2.8H8.5v-1.4h2.8V8.5h1.4v2.8h2.8v1.4z" fill="%23FFF"/></g></svg>\');\n --pwa-optimized-color-url: url(\'data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg"><g fill="none" fill-rule="evenodd"><rect fill="%230CCE6B" width="24" height="24" rx="12"/><path d="M5 5h14v14H5z"/><path fill="%23FFF" d="M12 15.07l3.6 2.18-.95-4.1 3.18-2.76-4.2-.36L12 6.17l-1.64 3.86-4.2.36 3.2 2.76-.96 4.1z"/></g></svg>\');\n\n --swap-locale-icon-url: url(\'data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px" fill="#000000"><path d="M0 0h24v24H0V0z" fill="none"/><path d="M12.87 15.07l-2.54-2.51.03-.03c1.74-1.94 2.98-4.17 3.71-6.53H17V4h-7V2H8v2H1v1.99h11.17C11.5 7.92 10.44 9.75 9 11.35 8.07 10.32 7.3 9.19 6.69 8h-2c.73 1.63 1.73 3.17 2.98 4.56l-5.09 5.02L4 19l5-5 3.11 3.11.76-2.04zM18.5 10h-2L12 22h2l1.12-3h4.75L21 22h2l-4.5-12zm-2.62 7l1.62-4.33L19.12 17h-3.24z"/></svg>\');\n}\n\n@media not print {\n .lh-dark {\n /* Pallete */\n --color-gray-200: var(--color-gray-800);\n --color-gray-300: #616161;\n --color-gray-400: var(--color-gray-600);\n --color-gray-700: var(--color-gray-400);\n --color-gray-50: #757575;\n --color-gray-600: var(--color-gray-500);\n --color-green-700: var(--color-green);\n --color-orange-700: var(--color-orange);\n --color-red-700: var(--color-red);\n --color-teal-600: var(--color-cyan-500);\n\n /* Context-specific colors */\n --color-hover: rgba(0, 0, 0, 0.2);\n --color-informative: var(--color-blue-200);\n\n /* Component variables */\n --env-item-background-color: #393535;\n --link-color: var(--color-blue-200);\n --locale-selector-background-color: var(--color-gray-200);\n --plugin-badge-background-color: var(--color-gray-800);\n --report-background-color: var(--color-gray-900);\n --report-border-color-secondary: var(--color-gray-200);\n --report-text-color-secondary: var(--color-gray-400);\n --report-text-color: var(--color-gray-100);\n --snippet-color: var(--color-cyan-500);\n --topbar-background-color: var(--color-gray);\n --toplevel-warning-background-color: hsl(33deg 14% 18%);\n --toplevel-warning-message-text-color: var(--color-orange-700);\n --toplevel-warning-text-color: var(--color-gray-100);\n\n /* SVGs */\n --plugin-icon-url: var(--plugin-icon-url-dark);\n --pwa-installable-gray-url: var(--pwa-installable-gray-url-dark);\n --pwa-optimized-gray-url: var(--pwa-optimized-gray-url-dark);\n }\n}\n\n@media only screen and (max-width: 480px) {\n .lh-vars {\n --audit-group-margin-bottom: 20px;\n --edge-gap-padding: var(--default-padding);\n --env-name-min-width: 120px;\n --gauge-circle-size-big: 96px;\n --gauge-circle-size: 72px;\n --gauge-label-font-size-big: 22px;\n --gauge-label-font-size: 14px;\n --gauge-label-line-height-big: 26px;\n --gauge-label-line-height: 20px;\n --gauge-percentage-font-size-big: 34px;\n --gauge-percentage-font-size: 26px;\n --gauge-wrapper-width: 112px;\n --header-padding: 16px 0 16px 0;\n --image-preview-size: 24px;\n --plugin-icon-size: 75%;\n --pwa-icon-margin: 0 7px 0 -3px;\n --report-font-size: 14px;\n --report-line-height: 20px;\n --score-icon-margin-left: 2px;\n --score-icon-size: 10px;\n --topbar-height: 28px;\n --topbar-logo-size: 20px;\n }\n\n /* Not enough space to adequately show the relative savings bars. */\n .lh-sparkline {\n display: none;\n }\n}\n\n.lh-vars.lh-devtools {\n --audit-explanation-line-height: 14px;\n --audit-group-margin-bottom: 20px;\n --audit-group-padding-vertical: 12px;\n --audit-padding-vertical: 4px;\n --category-padding: 12px;\n --default-padding: 12px;\n --env-name-min-width: 120px;\n --footer-padding-vertical: 8px;\n --gauge-circle-size-big: 72px;\n --gauge-circle-size: 64px;\n --gauge-label-font-size-big: 22px;\n --gauge-label-font-size: 14px;\n --gauge-label-line-height-big: 26px;\n --gauge-label-line-height: 20px;\n --gauge-percentage-font-size-big: 34px;\n --gauge-percentage-font-size: 26px;\n --gauge-wrapper-width: 97px;\n --header-line-height: 20px;\n --header-padding: 16px 0 16px 0;\n --screenshot-overlay-background: transparent;\n --plugin-icon-size: 75%;\n --pwa-icon-margin: 0 7px 0 -3px;\n --report-font-family-monospace: \'Menlo\', \'dejavu sans mono\', \'Consolas\', \'Lucida Console\', monospace;\n --report-font-family: \'.SFNSDisplay-Regular\', \'Helvetica Neue\', \'Lucida Grande\', sans-serif;\n --report-font-size: 12px;\n --report-line-height: 20px;\n --score-icon-margin-left: 2px;\n --score-icon-size: 10px;\n --section-padding-vertical: 8px;\n}\n\n.lh-devtools.lh-root {\n height: 100%;\n}\n.lh-devtools.lh-root img {\n /* Override devtools default \'min-width: 0\' so svg without size in a flexbox isn\'t collapsed. */\n min-width: auto;\n}\n.lh-devtools .lh-container {\n overflow-y: scroll;\n height: calc(100% - var(--topbar-height));\n}\n@media print {\n .lh-devtools .lh-container {\n overflow: unset;\n }\n}\n.lh-devtools .lh-sticky-header {\n /* This is normally the height of the topbar, but we want it to stick to the top of our scroll container .lh-container` */\n top: 0;\n}\n.lh-devtools .lh-element-screenshot__overlay {\n position: absolute;\n}\n\n@keyframes fadeIn {\n 0% { opacity: 0;}\n 100% { opacity: 0.6;}\n}\n\n.lh-root *, .lh-root *::before, .lh-root *::after {\n box-sizing: border-box;\n}\n\n.lh-root {\n font-family: var(--report-font-family);\n font-size: var(--report-font-size);\n margin: 0;\n line-height: var(--report-line-height);\n background: var(--report-background-color);\n color: var(--report-text-color);\n}\n\n.lh-root :focus {\n outline: -webkit-focus-ring-color auto 3px;\n}\n.lh-root summary:focus {\n outline: none;\n box-shadow: 0 0 0 1px hsl(217, 89%, 61%);\n}\n\n.lh-root [hidden] {\n display: none !important;\n}\n\n.lh-root pre {\n margin: 0;\n}\n\n.lh-root details > summary {\n cursor: pointer;\n}\n\n.lh-hidden {\n display: none !important;\n}\n\n.lh-container {\n /*\n Text wrapping in the report is so much FUN!\n We have a `word-break: break-word;` globally here to prevent a few common scenarios, namely\n long non-breakable text (usually URLs) found in:\n 1. The footer\n 2. .lh-node (outerHTML)\n 3. .lh-code\n\n With that sorted, the next challenge is appropriate column sizing and text wrapping inside our\n .lh-details tables. Even more fun.\n * We don\'t want table headers ("Potential Savings (ms)") to wrap or their column values, but\n we\'d be happy for the URL column to wrap if the URLs are particularly long.\n * We want the narrow columns to remain narrow, providing the most column width for URL\n * We don\'t want the table to extend past 100% width.\n * Long URLs in the URL column can wrap. Util.getURLDisplayName maxes them out at 64 characters,\n but they do not get any overflow:ellipsis treatment.\n */\n word-break: break-word;\n}\n\n.lh-audit-group a,\n.lh-category-header__description a,\n.lh-audit__description a,\n.lh-warnings a,\n.lh-footer a,\n.lh-table-column--link a {\n color: var(--link-color);\n}\n\n.lh-audit__description, .lh-audit__stackpack {\n --inner-audit-padding-right: var(--stackpack-padding-horizontal);\n padding-left: var(--audit-description-padding-left);\n padding-right: var(--inner-audit-padding-right);\n padding-top: 8px;\n padding-bottom: 8px;\n}\n\n.lh-details {\n margin-top: var(--default-padding);\n margin-bottom: var(--default-padding);\n margin-left: var(--audit-description-padding-left);\n /* whatever the .lh-details side margins are */\n width: 100%;\n}\n\n.lh-audit__stackpack {\n display: flex;\n align-items: center;\n}\n\n.lh-audit__stackpack__img {\n max-width: 30px;\n margin-right: var(--default-padding)\n}\n\n/* Report header */\n\n.lh-report-icon {\n display: flex;\n align-items: center;\n padding: 10px 12px;\n cursor: pointer;\n}\n.lh-report-icon[disabled] {\n opacity: 0.3;\n pointer-events: none;\n}\n\n.lh-report-icon::before {\n content: "";\n margin: 4px;\n background-repeat: no-repeat;\n width: var(--report-icon-size);\n height: var(--report-icon-size);\n opacity: 0.7;\n display: inline-block;\n vertical-align: middle;\n}\n.lh-report-icon:hover::before {\n opacity: 1;\n}\n.lh-dark .lh-report-icon::before {\n filter: invert(1);\n}\n.lh-report-icon--print::before {\n background-image: url(\'data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M19 8H5c-1.66 0-3 1.34-3 3v6h4v4h12v-4h4v-6c0-1.66-1.34-3-3-3zm-3 11H8v-5h8v5zm3-7c-.55 0-1-.45-1-1s.45-1 1-1 1 .45 1 1-.45 1-1 1zm-1-9H6v4h12V3z"/><path fill="none" d="M0 0h24v24H0z"/></svg>\');\n}\n.lh-report-icon--copy::before {\n background-image: url(\'data:image/svg+xml;utf8,<svg height="24" viewBox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg"><path d="M0 0h24v24H0z" fill="none"/><path d="M16 1H4c-1.1 0-2 .9-2 2v14h2V3h12V1zm3 4H8c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h11c1.1 0 2-.9 2-2V7c0-1.1-.9-2-2-2zm0 16H8V7h11v14z"/></svg>\');\n}\n.lh-report-icon--open::before {\n background-image: url(\'data:image/svg+xml;utf8,<svg height="24" viewBox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg"><path d="M0 0h24v24H0z" fill="none"/><path d="M19 4H5c-1.11 0-2 .9-2 2v12c0 1.1.89 2 2 2h4v-2H5V8h14v10h-4v2h4c1.1 0 2-.9 2-2V6c0-1.1-.89-2-2-2zm-7 6l-4 4h3v6h2v-6h3l-4-4z"/></svg>\');\n}\n.lh-report-icon--download::before {\n background-image: url(\'data:image/svg+xml;utf8,<svg height="24" viewBox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg"><path d="M19 9h-4V3H9v6H5l7 7 7-7zM5 18v2h14v-2H5z"/><path d="M0 0h24v24H0z" fill="none"/></svg>\');\n}\n.lh-report-icon--dark::before {\n background-image:url(\'data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" height="24" viewBox="0 0 100 125"><path d="M50 23.587c-16.27 0-22.799 12.574-22.799 21.417 0 12.917 10.117 22.451 12.436 32.471h20.726c2.32-10.02 12.436-19.554 12.436-32.471 0-8.843-6.528-21.417-22.799-21.417zM39.637 87.161c0 3.001 1.18 4.181 4.181 4.181h.426l.41 1.231C45.278 94.449 46.042 95 48.019 95h3.963c1.978 0 2.74-.551 3.365-2.427l.409-1.231h.427c3.002 0 4.18-1.18 4.18-4.181V80.91H39.637v6.251zM50 18.265c1.26 0 2.072-.814 2.072-2.073v-9.12C52.072 5.813 51.26 5 50 5c-1.259 0-2.072.813-2.072 2.073v9.12c0 1.259.813 2.072 2.072 2.072zM68.313 23.727c.994.774 2.135.634 2.91-.357l5.614-7.187c.776-.992.636-2.135-.356-2.909-.992-.776-2.135-.636-2.91.357l-5.613 7.186c-.778.993-.636 2.135.355 2.91zM91.157 36.373c-.306-1.222-1.291-1.815-2.513-1.51l-8.85 2.207c-1.222.305-1.814 1.29-1.51 2.512.305 1.223 1.291 1.814 2.513 1.51l8.849-2.206c1.223-.305 1.816-1.291 1.511-2.513zM86.757 60.48l-8.331-3.709c-1.15-.512-2.225-.099-2.736 1.052-.512 1.151-.1 2.224 1.051 2.737l8.33 3.707c1.15.514 2.225.101 2.736-1.05.513-1.149.1-2.223-1.05-2.737zM28.779 23.37c.775.992 1.917 1.131 2.909.357.992-.776 1.132-1.917.357-2.91l-5.615-7.186c-.775-.992-1.917-1.132-2.909-.357s-1.131 1.917-.356 2.909l5.614 7.187zM21.715 39.583c.305-1.223-.288-2.208-1.51-2.513l-8.849-2.207c-1.222-.303-2.208.289-2.513 1.511-.303 1.222.288 2.207 1.511 2.512l8.848 2.206c1.222.304 2.208-.287 2.513-1.509zM21.575 56.771l-8.331 3.711c-1.151.511-1.563 1.586-1.05 2.735.511 1.151 1.586 1.563 2.736 1.052l8.331-3.711c1.151-.511 1.563-1.586 1.05-2.735-.512-1.15-1.585-1.562-2.736-1.052z"/></svg>\');\n}\n.lh-report-icon--treemap::before {\n background-image: url(\'data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px" fill="black"><path d="M3 5v14h19V5H3zm2 2h15v4H5V7zm0 10v-4h4v4H5zm6 0v-4h9v4h-9z"/></svg>\');\n}\n.lh-report-icon--date::before {\n background-image: url(\'data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M7 11h2v2H7v-2zm14-5v14a2 2 0 01-2 2H5a2 2 0 01-2-2V6c0-1.1.9-2 2-2h1V2h2v2h8V2h2v2h1a2 2 0 012 2zM5 8h14V6H5v2zm14 12V10H5v10h14zm-4-7h2v-2h-2v2zm-4 0h2v-2h-2v2z"/></svg>\');\n}\n.lh-report-icon--devices::before {\n background-image: url(\'data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M4 6h18V4H4a2 2 0 00-2 2v11H0v3h14v-3H4V6zm19 2h-6a1 1 0 00-1 1v10c0 .6.5 1 1 1h6c.6 0 1-.5 1-1V9c0-.6-.5-1-1-1zm-1 9h-4v-7h4v7z"/></svg>\');\n}\n.lh-report-icon--world::before {\n background-image: url(\'data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M12 2a10 10 0 1 0 0 20 10 10 0 0 0 0-20zm7 6h-3c-.3-1.3-.8-2.5-1.4-3.6A8 8 0 0 1 18.9 8zm-7-4a14 14 0 0 1 2 4h-4a14 14 0 0 1 2-4zM4.3 14a8.2 8.2 0 0 1 0-4h3.3a16.5 16.5 0 0 0 0 4H4.3zm.8 2h3a14 14 0 0 0 1.3 3.6A8 8 0 0 1 5.1 16zm3-8H5a8 8 0 0 1 4.3-3.6L8 8zM12 20a14 14 0 0 1-2-4h4a14 14 0 0 1-2 4zm2.3-6H9.7a14.7 14.7 0 0 1 0-4h4.6a14.6 14.6 0 0 1 0 4zm.3 5.6c.6-1.2 1-2.4 1.4-3.6h3a8 8 0 0 1-4.4 3.6zm1.8-5.6a16.5 16.5 0 0 0 0-4h3.3a8.2 8.2 0 0 1 0 4h-3.3z"/></svg>\');\n}\n.lh-report-icon--stopwatch::before {\n background-image: url(\'data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M15 1H9v2h6V1zm-4 13h2V8h-2v6zm8.1-6.6L20.5 6l-1.4-1.4L17.7 6A9 9 0 0 0 3 13a9 9 0 1 0 16-5.6zm-7 12.6a7 7 0 1 1 0-14 7 7 0 0 1 0 14z"/></svg>\');\n}\n.lh-report-icon--networkspeed::before {\n background-image: url(\'data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M15.9 5c-.2 0-.3 0-.4.2v.2L10.1 17a2 2 0 0 0-.2 1 2 2 0 0 0 4 .4l2.4-12.9c0-.3-.2-.5-.5-.5zM1 9l2 2c2.9-2.9 6.8-4 10.5-3.6l1.2-2.7C10 3.8 4.7 5.3 1 9zm20 2 2-2a15.4 15.4 0 0 0-5.6-3.6L17 8.2c1.5.7 2.9 1.6 4.1 2.8zm-4 4 2-2a9.9 9.9 0 0 0-2.7-1.9l-.5 3 1.2.9zM5 13l2 2a7.1 7.1 0 0 1 4-2l1.3-2.9C9.7 10.1 7 11 5 13z"/></svg>\');\n}\n.lh-report-icon--samples-one::before {\n background-image: url(\'data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><circle cx="7" cy="14" r="3"/><path d="M7 18a4 4 0 1 1 0-8 4 4 0 0 1 0 8zm0-6c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm4-2a4 4 0 1 1 0-8 4 4 0 0 1 0 8zm0-6c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm5.6 17.6a4 4 0 1 1 0-8 4 4 0 0 1 0 8zm0-6c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2z"/></svg>\');\n}\n.lh-report-icon--samples-many::before {\n background-image: url(\'data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M7 18a4 4 0 1 1 0-8 4 4 0 0 1 0 8zm0-6c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm4-2a4 4 0 1 1 0-8 4 4 0 0 1 0 8zm0-6c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm5.6 17.6a4 4 0 1 1 0-8 4 4 0 0 1 0 8zm0-6c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2z"/><circle cx="7" cy="14" r="3"/><circle cx="11" cy="6" r="3"/></svg>\');\n}\n.lh-report-icon--chrome::before {\n background-image: url(\'data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="-50 -50 562 562"><path d="M256 25.6v25.6a204 204 0 0 1 144.8 60 204 204 0 0 1 60 144.8 204 204 0 0 1-60 144.8 204 204 0 0 1-144.8 60 204 204 0 0 1-144.8-60 204 204 0 0 1-60-144.8 204 204 0 0 1 60-144.8 204 204 0 0 1 144.8-60V0a256 256 0 1 0 0 512 256 256 0 0 0 0-512v25.6z"/><path d="M256 179.2v25.6a51.3 51.3 0 0 1 0 102.4 51.3 51.3 0 0 1 0-102.4v-51.2a102.3 102.3 0 1 0-.1 204.7 102.3 102.3 0 0 0 .1-204.7v25.6z"/><path d="M256 204.8h217.6a25.6 25.6 0 0 0 0-51.2H256a25.6 25.6 0 0 0 0 51.2m44.3 76.8L191.5 470.1a25.6 25.6 0 1 0 44.4 25.6l108.8-188.5a25.6 25.6 0 1 0-44.4-25.6m-88.6 0L102.9 93.2a25.7 25.7 0 0 0-35-9.4 25.7 25.7 0 0 0-9.4 35l108.8 188.5a25.7 25.7 0 0 0 35 9.4 25.9 25.9 0 0 0 9.4-35.1"/></svg>\');\n}\n\n\n\n.lh-buttons {\n display: flex;\n flex-wrap: wrap;\n margin: var(--default-padding) 0;\n}\n.lh-button {\n height: 32px;\n border: 1px solid var(--report-border-color-secondary);\n border-radius: 3px;\n color: var(--link-color);\n background-color: var(--report-background-color);\n margin: 5px;\n}\n\n.lh-button:first-of-type {\n margin-left: 0;\n}\n\n/* Node */\n.lh-node__snippet {\n font-family: var(--report-font-family-monospace);\n color: var(--snippet-color);\n font-size: var(--report-monospace-font-size);\n line-height: 20px;\n}\n\n/* Score */\n\n.lh-audit__score-icon {\n width: var(--score-icon-size);\n height: var(--score-icon-size);\n margin: var(--score-icon-margin);\n}\n\n.lh-audit--pass .lh-audit__display-text {\n color: var(--color-pass-secondary);\n}\n.lh-audit--pass .lh-audit__score-icon,\n.lh-scorescale-range--pass::before {\n border-radius: 100%;\n background: var(--color-pass);\n}\n\n.lh-audit--average .lh-audit__display-text {\n color: var(--color-average-secondary);\n}\n.lh-audit--average .lh-audit__score-icon,\n.lh-scorescale-range--average::before {\n background: var(--color-average);\n width: var(--icon-square-size);\n height: var(--icon-square-size);\n}\n\n.lh-audit--fail .lh-audit__display-text {\n color: var(--color-fail-secondary);\n}\n.lh-audit--fail .lh-audit__score-icon,\n.lh-audit--error .lh-audit__score-icon,\n.lh-scorescale-range--fail::before {\n border-left: calc(var(--score-icon-size) / 2) solid transparent;\n border-right: calc(var(--score-icon-size) / 2) solid transparent;\n border-bottom: var(--score-icon-size) solid var(--color-fail);\n}\n\n.lh-audit--manual .lh-audit__display-text,\n.lh-audit--notapplicable .lh-audit__display-text {\n color: var(--color-gray-600);\n}\n.lh-audit--manual .lh-audit__score-icon,\n.lh-audit--notapplicable .lh-audit__score-icon {\n border: calc(0.2 * var(--score-icon-size)) solid var(--color-gray-400);\n border-radius: 100%;\n background: none;\n}\n\n.lh-audit--informative .lh-audit__display-text {\n color: var(--color-gray-600);\n}\n\n.lh-audit--informative .lh-audit__score-icon {\n border: calc(0.2 * var(--score-icon-size)) solid var(--color-gray-400);\n border-radius: 100%;\n}\n\n.lh-audit__description,\n.lh-audit__stackpack {\n color: var(--report-text-color-secondary);\n}\n.lh-audit__adorn {\n border: 1px solid slategray;\n border-radius: 3px;\n margin: 0 3px;\n padding: 0 2px;\n line-height: 1.1;\n display: inline-block;\n font-size: 90%;\n}\n\n.lh-category-header__description {\n text-align: center;\n color: var(--color-gray-700);\n margin: 0px auto;\n max-width: 400px;\n}\n\n\n.lh-audit__display-text,\n.lh-load-opportunity__sparkline,\n.lh-chevron-container {\n margin: 0 var(--audit-margin-horizontal);\n}\n.lh-chevron-container {\n margin-right: 0;\n}\n\n.lh-audit__title-and-text {\n flex: 1;\n}\n\n.lh-audit__title-and-text code {\n color: var(--snippet-color);\n font-size: var(--report-monospace-font-size);\n}\n\n/* Prepend display text with em dash separator. But not in Opportunities. */\n.lh-audit__display-text:not(:empty):before {\n content: \'—\';\n margin-right: var(--audit-margin-horizontal);\n}\n.lh-audit-group.lh-audit-group--load-opportunities .lh-audit__display-text:not(:empty):before {\n display: none;\n}\n\n/* Expandable Details (Audit Groups, Audits) */\n.lh-audit__header {\n display: flex;\n align-items: center;\n padding: var(--default-padding);\n}\n\n.lh-audit--load-opportunity .lh-audit__header {\n display: block;\n}\n\n\n.lh-metricfilter {\n display: grid;\n justify-content: end;\n align-items: center;\n grid-auto-flow: column;\n gap: 4px;\n color: var(--color-gray-700);\n}\n\n.lh-metricfilter__radio {\n position: absolute;\n left: -9999px;\n}\n.lh-metricfilter input[type=\'radio\']:focus-visible + label {\n outline: -webkit-focus-ring-color auto 1px;\n}\n\n.lh-metricfilter__label {\n display: inline-flex;\n padding: 0 4px;\n height: 16px;\n text-decoration: underline;\n align-items: center;\n cursor: pointer;\n font-size: 90%;\n}\n\n.lh-metricfilter__label--active {\n background: var(--color-blue-primary);\n color: var(--color-white);\n border-radius: 3px;\n text-decoration: none;\n}\n/* Give the \'All\' choice a more muted display */\n.lh-metricfilter__label--active[for="metric-All"] {\n background-color: var(--color-blue-200) !important;\n color: black !important;\n}\n\n.lh-metricfilter__text {\n margin-right: 8px;\n}\n\n/* If audits are filtered, hide the itemcount for Passed Audits… */\n.lh-category--filtered .lh-audit-group .lh-audit-group__itemcount {\n display: none;\n}\n\n\n.lh-audit__header:hover {\n background-color: var(--color-hover);\n}\n\n/* We want to hide the browser\'s default arrow marker on summary elements. Admittedly, it\'s complicated. */\n.lh-root details > summary {\n /* Blink 89+ and Firefox will hide the arrow when display is changed from (new) default of `list-item` to block. https://chromestatus.com/feature/6730096436051968*/\n display: block;\n}\n/* Safari and Blink <=88 require using the -webkit-details-marker selector */\n.lh-root details > summary::-webkit-details-marker {\n display: none;\n}\n\n/* Perf Metric */\n\n.lh-metrics-container {\n display: grid;\n grid-auto-rows: 1fr;\n grid-template-columns: 1fr 1fr;\n grid-column-gap: var(--report-line-height);\n margin-bottom: var(--default-padding);\n}\n\n.lh-metric {\n border-top: 1px solid var(--report-border-color-secondary);\n}\n\n.lh-metric:nth-last-child(-n+2) {\n border-bottom: 1px solid var(--report-border-color-secondary);\n}\n\n\n.lh-metric__innerwrap {\n display: grid;\n /**\n * Icon -- Metric Name\n * -- Metric Value\n */\n grid-template-columns: calc(var(--score-icon-size) + var(--score-icon-margin-left) + var(--score-icon-margin-right)) 1fr;\n align-items: center;\n padding: var(--default-padding);\n}\n\n.lh-metric__details {\n order: -1;\n}\n\n.lh-metric__title {\n flex: 1;\n}\n\n.lh-calclink {\n padding-left: calc(1ex / 3);\n}\n\n.lh-metric__description {\n display: none;\n grid-column-start: 2;\n grid-column-end: 4;\n color: var(--report-text-color-secondary);\n}\n\n.lh-metric__value {\n font-size: var(--metric-value-font-size);\n margin: calc(var(--default-padding) / 2) 0;\n white-space: nowrap; /* No wrapping between metric value and the icon */\n grid-column-start: 2;\n}\n\n\n@media screen and (max-width: 535px) {\n .lh-metrics-container {\n display: block;\n }\n\n .lh-metric {\n border-bottom: none !important;\n }\n .lh-metric:nth-last-child(1) {\n border-bottom: 1px solid var(--report-border-color-secondary) !important;\n }\n\n /* Change the grid to 3 columns for narrow viewport. */\n .lh-metric__innerwrap {\n /**\n * Icon -- Metric Name -- Metric Value\n */\n grid-template-columns: calc(var(--score-icon-size) + var(--score-icon-margin-left) + var(--score-icon-margin-right)) 2fr 1fr;\n }\n .lh-metric__value {\n justify-self: end;\n grid-column-start: unset;\n }\n}\n\n/* No-JS toggle switch */\n/* Keep this selector sync\'d w/ `magicSelector` in report-ui-features-test.js */\n .lh-metrics-toggle__input:checked ~ .lh-metrics-container .lh-metric__description {\n display: block;\n}\n\n/* TODO get rid of the SVGS and clean up these some more */\n.lh-metrics-toggle__input {\n opacity: 0;\n position: absolute;\n right: 0;\n top: 0px;\n}\n\n.lh-metrics-toggle__input + div > label > .lh-metrics-toggle__labeltext--hide,\n.lh-metrics-toggle__input:checked + div > label > .lh-metrics-toggle__labeltext--show {\n display: none;\n}\n.lh-metrics-toggle__input:checked + div > label > .lh-metrics-toggle__labeltext--hide {\n display: inline;\n}\n.lh-metrics-toggle__input:focus + div > label {\n outline: -webkit-focus-ring-color auto 3px;\n}\n\n.lh-metrics-toggle__label {\n cursor: pointer;\n font-size: var(--report-font-size-secondary);\n line-height: var(--report-line-height-secondary);\n color: var(--color-gray-700);\n}\n\n/* Pushes the metric description toggle button to the right. */\n.lh-audit-group--metrics .lh-audit-group__header {\n display: flex;\n justify-content: space-between;\n}\n\n.lh-metric__icon,\n.lh-scorescale-range::before {\n content: \'\';\n width: var(--score-icon-size);\n height: var(--score-icon-size);\n display: inline-block;\n margin: var(--score-icon-margin);\n}\n\n.lh-metric--pass .lh-metric__value {\n color: var(--color-pass-secondary);\n}\n.lh-metric--pass .lh-metric__icon {\n border-radius: 100%;\n background: var(--color-pass);\n}\n\n.lh-metric--average .lh-metric__value {\n color: var(--color-average-secondary);\n}\n.lh-metric--average .lh-metric__icon {\n background: var(--color-average);\n width: var(--icon-square-size);\n height: var(--icon-square-size);\n}\n\n.lh-metric--fail .lh-metric__value {\n color: var(--color-fail-secondary);\n}\n.lh-metric--fail .lh-metric__icon,\n.lh-metric--error .lh-metric__icon {\n border-left: calc(var(--score-icon-size) / 2) solid transparent;\n border-right: calc(var(--score-icon-size) / 2) solid transparent;\n border-bottom: var(--score-icon-size) solid var(--color-fail);\n}\n\n.lh-metric--error .lh-metric__value,\n.lh-metric--error .lh-metric__description {\n color: var(--color-fail-secondary);\n}\n\n/* Perf load opportunity */\n\n.lh-load-opportunity__cols {\n display: flex;\n align-items: flex-start;\n}\n\n.lh-load-opportunity__header .lh-load-opportunity__col {\n color: var(--color-gray-600);\n display: unset;\n line-height: calc(2.3 * var(--report-font-size));\n}\n\n.lh-load-opportunity__col {\n display: flex;\n}\n\n.lh-load-opportunity__col--one {\n flex: 5;\n align-items: center;\n margin-right: 2px;\n}\n.lh-load-opportunity__col--two {\n flex: 4;\n text-align: right;\n}\n\n.lh-audit--load-opportunity .lh-audit__display-text {\n text-align: right;\n flex: 0 0 calc(3 * var(--report-font-size));\n}\n\n\n/* Sparkline */\n\n.lh-load-opportunity__sparkline {\n flex: 1;\n margin-top: calc((var(--report-line-height) - var(--sparkline-height)) / 2);\n}\n\n.lh-sparkline {\n height: var(--sparkline-height);\n width: 100%;\n}\n\n.lh-sparkline__bar {\n height: 100%;\n float: right;\n}\n\n.lh-audit--pass .lh-sparkline__bar {\n background: var(--color-pass);\n}\n\n.lh-audit--average .lh-sparkline__bar {\n background: var(--color-average);\n}\n\n.lh-audit--fail .lh-sparkline__bar {\n background: var(--color-fail);\n}\n\n/* Filmstrip */\n\n.lh-filmstrip-container {\n /* smaller gap between metrics and filmstrip */\n margin: -8px auto 0 auto;\n}\n\n.lh-filmstrip {\n display: grid;\n justify-content: space-between;\n padding-bottom: var(--default-padding);\n width: 100%;\n grid-template-columns: repeat(auto-fit, 60px);\n}\n\n.lh-filmstrip__frame {\n text-align: right;\n position: relative;\n}\n\n.lh-filmstrip__thumbnail {\n border: 1px solid var(--report-border-color-secondary);\n max-height: 100px;\n max-width: 60px;\n}\n\n/* Audit */\n\n.lh-audit {\n border-bottom: 1px solid var(--report-border-color-secondary);\n}\n\n/* Apply border-top to just the first audit. */\n.lh-audit {\n border-top: 1px solid var(--report-border-color-secondary);\n}\n.lh-audit ~ .lh-audit {\n border-top: none;\n}\n\n\n.lh-audit--error .lh-audit__display-text {\n color: var(--color-fail-secondary);\n}\n\n/* Audit Group */\n\n.lh-audit-group {\n margin-bottom: var(--audit-group-margin-bottom);\n position: relative;\n}\n.lh-audit-group--metrics {\n margin-bottom: calc(var(--audit-group-margin-bottom) / 2);\n}\n\n.lh-audit-group__header::before {\n /* By default, groups don\'t get an icon */\n content: none;\n width: var(--pwa-icon-size);\n height: var(--pwa-icon-size);\n margin: var(--pwa-icon-margin);\n display: inline-block;\n vertical-align: middle;\n}\n\n/* Style the "over budget" columns red. */\n.lh-audit-group--budgets #performance-budget tbody tr td:nth-child(4),\n.lh-audit-group--budgets #performance-budget tbody tr td:nth-child(5),\n.lh-audit-group--budgets #timing-budget tbody tr td:nth-child(3) {\n color: var(--color-red-700);\n}\n\n/* Align the "over budget request count" text to be close to the "over budget bytes" column. */\n.lh-audit-group--budgets .lh-table tbody tr td:nth-child(4){\n text-align: right;\n}\n\n.lh-audit-group--budgets .lh-details--budget {\n width: 100%;\n margin: 0 0 var(--default-padding);\n}\n\n.lh-audit-group--pwa-installable .lh-audit-group__header::before {\n content: \'\';\n background-image: var(--pwa-installable-gray-url);\n}\n.lh-audit-group--pwa-optimized .lh-audit-group__header::before {\n content: \'\';\n background-image: var(--pwa-optimized-gray-url);\n}\n.lh-audit-group--pwa-installable.lh-badged .lh-audit-group__header::before {\n background-image: var(--pwa-installable-color-url);\n}\n.lh-audit-group--pwa-optimized.lh-badged .lh-audit-group__header::before {\n background-image: var(--pwa-optimized-color-url);\n}\n\n.lh-audit-group--metrics .lh-audit-group__summary {\n margin-top: 0;\n margin-bottom: 0;\n}\n\n.lh-audit-group__summary {\n display: flex;\n justify-content: space-between;\n align-items: center;\n}\n\n.lh-audit-group__header .lh-chevron {\n margin-top: calc((var(--report-line-height) - 5px) / 2);\n}\n\n.lh-audit-group__header {\n letter-spacing: 0.8px;\n padding: var(--default-padding);\n padding-left: 0;\n}\n\n.lh-audit-group__header, .lh-audit-group__summary {\n font-size: var(--report-font-size-secondary);\n line-height: var(--report-line-height-secondary);\n color: var(--color-gray-700);\n}\n\n.lh-audit-group__title {\n text-transform: uppercase;\n font-weight: 500;\n}\n\n.lh-audit-group__itemcount {\n color: var(--color-gray-600);\n}\n\n.lh-audit-group__footer {\n color: var(--color-gray-600);\n display: block;\n margin-top: var(--default-padding);\n}\n\n.lh-details,\n.lh-category-header__description,\n.lh-load-opportunity__header,\n.lh-audit-group__footer {\n font-size: var(--report-font-size-secondary);\n line-height: var(--report-line-height-secondary);\n}\n\n.lh-audit-explanation {\n margin: var(--audit-padding-vertical) 0 calc(var(--audit-padding-vertical) / 2) var(--audit-margin-horizontal);\n line-height: var(--audit-explanation-line-height);\n display: inline-block;\n}\n\n.lh-audit--fail .lh-audit-explanation {\n color: var(--color-fail-secondary);\n}\n\n/* Report */\n.lh-list > :not(:last-child) {\n margin-bottom: calc(var(--default-padding) * 2);\n}\n\n.lh-header-container {\n display: block;\n margin: 0 auto;\n position: relative;\n word-wrap: break-word;\n}\n\n.lh-header-container .lh-scores-wrapper {\n border-bottom: 1px solid var(--color-gray-200);\n}\n\n\n.lh-report {\n min-width: var(--report-content-min-width);\n}\n\n.lh-exception {\n font-size: large;\n}\n\n.lh-code {\n white-space: normal;\n margin-top: 0;\n font-size: var(--report-monospace-font-size);\n}\n\n.lh-warnings {\n --item-margin: calc(var(--report-line-height) / 6);\n color: var(--color-average-secondary);\n margin: var(--audit-padding-vertical) 0;\n padding: var(--default-padding)\n var(--default-padding)\n var(--default-padding)\n calc(var(--audit-description-padding-left));\n background-color: var(--toplevel-warning-background-color);\n}\n.lh-warnings span {\n font-weight: bold;\n}\n\n.lh-warnings--toplevel {\n --item-margin: calc(var(--header-line-height) / 4);\n color: var(--toplevel-warning-text-color);\n margin-left: auto;\n margin-right: auto;\n max-width: var(--report-content-max-width-minus-edge-gap);\n padding: var(--toplevel-warning-padding);\n border-radius: 8px;\n}\n\n.lh-warnings__msg {\n color: var(--toplevel-warning-message-text-color);\n margin: 0;\n}\n\n.lh-warnings ul {\n margin: 0;\n}\n.lh-warnings li {\n margin: var(--item-margin) 0;\n}\n.lh-warnings li:last-of-type {\n margin-bottom: 0;\n}\n\n.lh-scores-header {\n display: flex;\n flex-wrap: wrap;\n justify-content: center;\n}\n.lh-scores-header__solo {\n padding: 0;\n border: 0;\n}\n\n/* Gauge */\n\n.lh-gauge__wrapper--pass {\n color: var(--color-pass-secondary);\n fill: var(--color-pass);\n stroke: var(--color-pass);\n}\n\n.lh-gauge__wrapper--average {\n color: var(--color-average-secondary);\n fill: var(--color-average);\n stroke: var(--color-average);\n}\n\n.lh-gauge__wrapper--fail {\n color: var(--color-fail-secondary);\n fill: var(--color-fail);\n stroke: var(--color-fail);\n}\n\n.lh-gauge__wrapper--not-applicable {\n color: var(--color-not-applicable);\n fill: var(--color-not-applicable);\n stroke: var(--color-not-applicable);\n}\n\n.lh-fraction__wrapper .lh-fraction__content::before {\n content: \'\';\n height: var(--score-icon-size);\n width: var(--score-icon-size);\n margin: var(--score-icon-margin);\n display: inline-block;\n}\n.lh-fraction__wrapper--pass .lh-fraction__content {\n color: var(--color-pass-secondary);\n}\n.lh-fraction__wrapper--pass .lh-fraction__background {\n background-color: var(--color-pass);\n}\n.lh-fraction__wrapper--pass .lh-fraction__content::before {\n background-color: var(--color-pass);\n border-radius: 50%;\n}\n.lh-fraction__wrapper--average .lh-fraction__content {\n color: var(--color-average-secondary);\n}\n.lh-fraction__wrapper--average .lh-fraction__background,\n.lh-fraction__wrapper--average .lh-fraction__content::before {\n background-color: var(--color-average);\n}\n.lh-fraction__wrapper--fail .lh-fraction__content {\n color: var(--color-fail);\n}\n.lh-fraction__wrapper--fail .lh-fraction__background {\n background-color: var(--color-fail);\n}\n.lh-fraction__wrapper--fail .lh-fraction__content::before {\n border-left: calc(var(--score-icon-size) / 2) solid transparent;\n border-right: calc(var(--score-icon-size) / 2) solid transparent;\n border-bottom: var(--score-icon-size) solid var(--color-fail);\n}\n.lh-fraction__wrapper--null .lh-fraction__content {\n color: var(--color-gray-700);\n}\n.lh-fraction__wrapper--null .lh-fraction__background {\n background-color: var(--color-gray-700);\n}\n.lh-fraction__wrapper--null .lh-fraction__content::before {\n border-radius: 50%;\n border: calc(0.2 * var(--score-icon-size)) solid var(--color-gray-700);\n}\n\n.lh-fraction__background {\n position: absolute;\n height: 100%;\n width: 100%;\n border-radius: calc(var(--gauge-circle-size) / 2);\n opacity: 0.1;\n z-index: -1;\n}\n\n.lh-fraction__content-wrapper {\n height: var(--gauge-circle-size);\n display: flex;\n align-items: center;\n}\n\n.lh-fraction__content {\n display: flex;\n position: relative;\n align-items: center;\n justify-content: center;\n font-size: calc(0.3 * var(--gauge-circle-size));\n line-height: calc(0.4 * var(--gauge-circle-size));\n width: max-content;\n min-width: calc(1.5 * var(--gauge-circle-size));\n padding: calc(0.1 * var(--gauge-circle-size)) calc(0.2 * var(--gauge-circle-size));\n --score-icon-size: calc(0.21 * var(--gauge-circle-size));\n --score-icon-margin: 0 calc(0.15 * var(--gauge-circle-size)) 0 0;\n}\n\n.lh-gauge {\n stroke-linecap: round;\n width: var(--gauge-circle-size);\n height: var(--gauge-circle-size);\n}\n\n.lh-category .lh-gauge {\n --gauge-circle-size: var(--gauge-circle-size-big);\n}\n\n.lh-gauge-base {\n opacity: 0.1;\n}\n\n.lh-gauge-arc {\n fill: none;\n transform-origin: 50% 50%;\n animation: load-gauge var(--transition-length) ease forwards;\n animation-delay: 250ms;\n}\n\n.lh-gauge__svg-wrapper {\n position: relative;\n height: var(--gauge-circle-size);\n}\n.lh-category .lh-gauge__svg-wrapper,\n.lh-category .lh-fraction__wrapper {\n --gauge-circle-size: var(--gauge-circle-size-big);\n}\n\n/* The plugin badge overlay */\n.lh-gauge__wrapper--plugin .lh-gauge__svg-wrapper::before {\n width: var(--plugin-badge-size);\n height: var(--plugin-badge-size);\n background-color: var(--plugin-badge-background-color);\n background-image: var(--plugin-icon-url);\n background-repeat: no-repeat;\n background-size: var(--plugin-icon-size);\n background-position: 58% 50%;\n content: "";\n position: absolute;\n right: -6px;\n bottom: 0px;\n display: block;\n z-index: 100;\n box-shadow: 0 0 4px rgba(0,0,0,.2);\n border-radius: 25%;\n}\n.lh-category .lh-gauge__wrapper--plugin .lh-gauge__svg-wrapper::before {\n width: var(--plugin-badge-size-big);\n height: var(--plugin-badge-size-big);\n}\n\n@keyframes load-gauge {\n from { stroke-dasharray: 0 352; }\n}\n\n.lh-gauge__percentage {\n width: 100%;\n height: var(--gauge-circle-size);\n position: absolute;\n font-family: var(--report-font-family-monospace);\n font-size: calc(var(--gauge-circle-size) * 0.34 + 1.3px);\n line-height: 0;\n text-align: center;\n top: calc(var(--score-container-padding) + var(--gauge-circle-size) / 2);\n}\n\n.lh-category .lh-gauge__percentage {\n --gauge-circle-size: var(--gauge-circle-size-big);\n --gauge-percentage-font-size: var(--gauge-percentage-font-size-big);\n}\n\n.lh-gauge__wrapper,\n.lh-fraction__wrapper {\n position: relative;\n display: flex;\n align-items: center;\n flex-direction: column;\n text-decoration: none;\n padding: var(--score-container-padding);\n\n --transition-length: 1s;\n\n /* Contain the layout style paint & layers during animation*/\n contain: content;\n will-change: opacity; /* Only using for layer promotion */\n}\n\n.lh-gauge__label,\n.lh-fraction__label {\n font-size: var(--gauge-label-font-size);\n font-weight: 500;\n line-height: var(--gauge-label-line-height);\n margin-top: 10px;\n text-align: center;\n color: var(--report-text-color);\n word-break: keep-all;\n}\n\n/* TODO(#8185) use more BEM (.lh-gauge__label--big) instead of relying on descendant selector */\n.lh-category .lh-gauge__label,\n.lh-category .lh-fraction__label {\n --gauge-label-font-size: var(--gauge-label-font-size-big);\n --gauge-label-line-height: var(--gauge-label-line-height-big);\n margin-top: 14px;\n}\n\n.lh-scores-header .lh-gauge__wrapper,\n.lh-scores-header .lh-fraction__wrapper,\n.lh-scores-header .lh-gauge--pwa__wrapper,\n.lh-sticky-header .lh-gauge__wrapper,\n.lh-sticky-header .lh-fraction__wrapper,\n.lh-sticky-header .lh-gauge--pwa__wrapper {\n width: var(--gauge-wrapper-width);\n}\n\n.lh-scorescale {\n display: inline-flex;\n\n gap: calc(var(--default-padding) * 4);\n margin: 16px auto 0 auto;\n font-size: var(--report-font-size-secondary);\n color: var(--color-gray-700);\n\n}\n\n.lh-scorescale-range {\n display: flex;\n align-items: center;\n font-family: var(--report-font-family-monospace);\n white-space: nowrap;\n}\n\n.lh-category-header__finalscreenshot .lh-scorescale {\n border: 0;\n display: flex;\n justify-content: center;\n}\n\n.lh-category-header__finalscreenshot .lh-scorescale-range {\n font-family: unset;\n font-size: 12px;\n}\n\n.lh-scorescale-wrap {\n display: contents;\n}\n\n/* Hide category score gauages if it\'s a single category report */\n.lh-header--solo-category .lh-scores-wrapper {\n display: none;\n}\n\n\n.lh-categories {\n width: 100%;\n overflow: hidden;\n}\n\n.lh-category {\n padding: var(--category-padding);\n max-width: var(--report-content-max-width);\n margin: 0 auto;\n\n --sticky-header-height: calc(var(--gauge-circle-size-sm) + var(--score-container-padding) * 2);\n --topbar-plus-sticky-header: calc(var(--topbar-height) + var(--sticky-header-height));\n scroll-margin-top: var(--topbar-plus-sticky-header);\n\n /* Faster recalc style & layout of the report. https://web.dev/content-visibility/ */\n content-visibility: auto;\n contain-intrinsic-size: 1000px;\n}\n\n.lh-category-wrapper {\n border-bottom: 1px solid var(--color-gray-200);\n}\n\n.lh-category-header {\n margin-bottom: var(--section-padding-vertical);\n}\n\n.lh-category-header .lh-score__gauge {\n max-width: 400px;\n width: auto;\n margin: 0px auto;\n}\n\n.lh-category-header__finalscreenshot {\n display: grid;\n grid-template: none / 1fr 1px 1fr;\n justify-items: center;\n align-items: center;\n gap: var(--report-line-height);\n min-height: 288px;\n margin-bottom: var(--default-padding);\n}\n\n.lh-final-ss-image {\n /* constrain the size of the image to not be too large */\n max-height: calc(var(--gauge-circle-size-big) * 2.8);\n max-width: calc(var(--gauge-circle-size-big) * 3.5);\n border: 1px solid var(--color-gray-200);\n padding: 4px;\n border-radius: 3px;\n display: block;\n}\n\n.lh-category-headercol--separator {\n background: var(--color-gray-200);\n width: 1px;\n height: var(--gauge-circle-size-big);\n}\n\n@media screen and (max-width: 780px) {\n .lh-category-header__finalscreenshot {\n grid-template: 1fr 1fr / none\n }\n .lh-category-headercol--separator {\n display: none;\n }\n}\n\n\n/* 964 fits the min-width of the filmstrip */\n@media screen and (max-width: 964px) {\n .lh-report {\n margin-left: 0;\n width: 100%;\n }\n}\n\n@media print {\n body {\n -webkit-print-color-adjust: exact; /* print background colors */\n }\n .lh-container {\n display: block;\n }\n .lh-report {\n margin-left: 0;\n padding-top: 0;\n }\n .lh-categories {\n margin-top: 0;\n }\n}\n\n.lh-table {\n border-collapse: collapse;\n /* Can\'t assign padding to table, so shorten the width instead. */\n width: calc(100% - var(--audit-description-padding-left) - var(--stackpack-padding-horizontal));\n border: 1px solid var(--report-border-color-secondary);\n\n}\n\n.lh-table thead th {\n font-weight: normal;\n color: var(--color-gray-600);\n /* See text-wrapping comment on .lh-container. */\n word-break: normal;\n}\n\n.lh-row--even {\n background-color: var(--table-higlight-background-color);\n}\n.lh-row--hidden {\n display: none;\n}\n\n.lh-table th,\n.lh-table td {\n padding: var(--default-padding);\n}\n\n.lh-table tr {\n vertical-align: middle;\n}\n\n/* Looks unnecessary, but mostly for keeping the <th>s left-aligned */\n.lh-table-column--text,\n.lh-table-column--source-location,\n.lh-table-column--url,\n/* .lh-table-column--thumbnail, */\n/* .lh-table-column--empty,*/\n.lh-table-column--code,\n.lh-table-column--node {\n text-align: left;\n}\n\n.lh-table-column--code {\n min-width: 100px;\n}\n\n.lh-table-column--bytes,\n.lh-table-column--timespanMs,\n.lh-table-column--ms,\n.lh-table-column--numeric {\n text-align: right;\n word-break: normal;\n}\n\n\n\n.lh-table .lh-table-column--thumbnail {\n width: var(--image-preview-size);\n}\n\n.lh-table-column--url {\n min-width: 250px;\n}\n\n.lh-table-column--text {\n min-width: 80px;\n}\n\n/* Keep columns narrow if they follow the URL column */\n/* 12% was determined to be a decent narrow width, but wide enough for column headings */\n.lh-table-column--url + th.lh-table-column--bytes,\n.lh-table-column--url + .lh-table-column--bytes + th.lh-table-column--bytes,\n.lh-table-column--url + .lh-table-column--ms,\n.lh-table-column--url + .lh-table-column--ms + th.lh-table-column--bytes,\n.lh-table-column--url + .lh-table-column--bytes + th.lh-table-column--timespanMs {\n width: 12%;\n}\n\n.lh-text__url-host {\n display: inline;\n}\n\n.lh-text__url-host {\n margin-left: calc(var(--report-font-size) / 2);\n opacity: 0.6;\n font-size: 90%\n}\n\n.lh-thumbnail {\n object-fit: cover;\n width: var(--image-preview-size);\n height: var(--image-preview-size);\n display: block;\n}\n\n.lh-unknown pre {\n overflow: scroll;\n border: solid 1px var(--color-gray-200);\n}\n\n.lh-text__url > a {\n color: inherit;\n text-decoration: none;\n}\n\n.lh-text__url > a:hover {\n text-decoration: underline dotted #999;\n}\n\n.lh-sub-item-row {\n margin-left: 20px;\n margin-bottom: 0;\n color: var(--color-gray-700);\n}\n.lh-sub-item-row td {\n padding-top: 4px;\n padding-bottom: 4px;\n padding-left: 20px;\n}\n\n/* Chevron\n https://codepen.io/paulirish/pen/LmzEmK\n */\n.lh-chevron {\n --chevron-angle: 42deg;\n /* Edge doesn\'t support transform: rotate(calc(...)), so we define it here */\n --chevron-angle-right: -42deg;\n width: var(--chevron-size);\n height: var(--chevron-size);\n margin-top: calc((var(--report-line-height) - 12px) / 2);\n}\n\n.lh-chevron__lines {\n transition: transform 0.4s;\n transform: translateY(var(--report-line-height));\n}\n.lh-chevron__line {\n stroke: var(--chevron-line-stroke);\n stroke-width: var(--chevron-size);\n stroke-linecap: square;\n transform-origin: 50%;\n transform: rotate(var(--chevron-angle));\n transition: transform 300ms, stroke 300ms;\n}\n\n.lh-expandable-details .lh-chevron__line-right,\n.lh-expandable-details[open] .lh-chevron__line-left {\n transform: rotate(var(--chevron-angle-right));\n}\n\n.lh-expandable-details[open] .lh-chevron__line-right {\n transform: rotate(var(--chevron-angle));\n}\n\n\n.lh-expandable-details[open] .lh-chevron__lines {\n transform: translateY(calc(var(--chevron-size) * -1));\n}\n\n.lh-expandable-details[open] {\n animation: 300ms openDetails forwards;\n padding-bottom: var(--default-padding);\n}\n\n@keyframes openDetails {\n from {\n outline: 1px solid var(--report-background-color);\n }\n to {\n outline: 1px solid;\n box-shadow: 0 2px 4px rgba(0, 0, 0, .24);\n }\n}\n\n@media screen and (max-width: 780px) {\n /* no black outline if we\'re not confident the entire table can be displayed within bounds */\n .lh-expandable-details[open] {\n animation: none;\n }\n}\n\n.lh-expandable-details[open] summary, details.lh-clump > summary {\n border-bottom: 1px solid var(--report-border-color-secondary);\n}\ndetails.lh-clump[open] > summary {\n border-bottom-width: 0;\n}\n\n\n\ndetails .lh-clump-toggletext--hide,\ndetails[open] .lh-clump-toggletext--show { display: none; }\ndetails[open] .lh-clump-toggletext--hide { display: block;}\n\n\n/* Tooltip */\n.lh-tooltip-boundary {\n position: relative;\n}\n\n.lh-tooltip {\n position: absolute;\n display: none; /* Don\'t retain these layers when not needed */\n opacity: 0;\n background: #ffffff;\n white-space: pre-line; /* Render newlines in the text */\n min-width: 246px;\n max-width: 275px;\n padding: 15px;\n border-radius: 5px;\n text-align: initial;\n line-height: 1.4;\n}\n/* shrink tooltips to not be cutoff on left edge of narrow viewports\n 45vw is chosen to be ~= width of the left column of metrics\n*/\n@media screen and (max-width: 535px) {\n .lh-tooltip {\n min-width: 45vw;\n padding: 3vw;\n }\n}\n\n.lh-tooltip-boundary:hover .lh-tooltip {\n display: block;\n animation: fadeInTooltip 250ms;\n animation-fill-mode: forwards;\n animation-delay: 850ms;\n bottom: 100%;\n z-index: 1;\n will-change: opacity;\n right: 0;\n pointer-events: none;\n}\n\n.lh-tooltip::before {\n content: "";\n border: solid transparent;\n border-bottom-color: #fff;\n border-width: 10px;\n position: absolute;\n bottom: -20px;\n right: 6px;\n transform: rotate(180deg);\n pointer-events: none;\n}\n\n@keyframes fadeInTooltip {\n 0% { opacity: 0; }\n 75% { opacity: 1; }\n 100% { opacity: 1; filter: drop-shadow(1px 0px 1px #aaa) drop-shadow(0px 2px 4px hsla(206, 6%, 25%, 0.15)); pointer-events: auto; }\n}\n\n/* Element screenshot */\n.lh-element-screenshot {\n position: relative;\n overflow: hidden;\n float: left;\n margin-right: 20px;\n}\n.lh-element-screenshot__content {\n overflow: hidden;\n}\n.lh-element-screenshot__image {\n /* Set by ElementScreenshotRenderer.installFullPageScreenshotCssVariable */\n background-image: var(--element-screenshot-url);\n outline: 2px solid #777;\n background-color: white;\n background-repeat: no-repeat;\n}\n.lh-element-screenshot__mask {\n position: absolute;\n background: #555;\n opacity: 0.8;\n}\n.lh-element-screenshot__element-marker {\n position: absolute;\n outline: 2px solid var(--color-lime-400);\n}\n.lh-element-screenshot__overlay {\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n z-index: 2000; /* .lh-topbar is 1000 */\n background: var(--screenshot-overlay-background);\n display: flex;\n align-items: center;\n justify-content: center;\n cursor: zoom-out;\n}\n\n.lh-element-screenshot__overlay .lh-element-screenshot {\n margin-right: 0; /* clearing margin used in thumbnail case */\n outline: 1px solid var(--color-gray-700);\n}\n\n.lh-screenshot-overlay--enabled .lh-element-screenshot {\n cursor: zoom-out;\n}\n.lh-screenshot-overlay--enabled .lh-node .lh-element-screenshot {\n cursor: zoom-in;\n}\n\n\n.lh-meta__items {\n --meta-icon-size: calc(var(--report-icon-size) * 0.667);\n padding: var(--default-padding);\n display: grid;\n grid-template-columns: 1fr 1fr 1fr;\n background-color: var(--env-item-background-color);\n border-radius: 3px;\n margin: 0 0 var(--default-padding) 0;\n font-size: 12px;\n column-gap: var(--default-padding);\n color: var(--color-gray-700);\n}\n\n.lh-meta__item {\n display: block;\n list-style-type: none;\n position: relative;\n padding: 0 0 0 calc(var(--meta-icon-size) + var(--default-padding) * 2);\n cursor: unset; /* disable pointer cursor from report-icon */\n}\n\n.lh-meta__item.lh-tooltip-boundary {\n text-decoration: dotted underline var(--color-gray-500);\n cursor: help;\n}\n\n.lh-meta__item.lh-report-icon::before {\n position: absolute;\n left: var(--default-padding);\n width: var(--meta-icon-size);\n height: var(--meta-icon-size);\n}\n\n.lh-meta__item.lh-report-icon:hover::before {\n opacity: 0.7;\n}\n\n.lh-meta__item .lh-tooltip {\n color: var(--color-gray-800);\n}\n\n.lh-meta__item .lh-tooltip::before {\n right: auto; /* Set the tooltip arrow to the leftside */\n left: 6px;\n}\n\n/* Change the grid for narrow viewport. */\n@media screen and (max-width: 640px) {\n .lh-meta__items {\n grid-template-columns: 1fr 1fr;\n }\n}\n@media screen and (max-width: 535px) {\n .lh-meta__items {\n display: block;\n }\n}\n\n\n/*# sourceURL=report-styles.css */\n');
1226
1221
  el0.append(el1);
1227
1222
  return el0;
1228
1223
  }
@@ -1232,214 +1227,214 @@ function createStylesComponent(dom) {
1232
1227
  */
1233
1228
  function createTopbarComponent(dom) {
1234
1229
  const el0 = dom.createFragment();
1235
- const el1 = dom.createElement("style");
1236
- el1.append("\n .lh-topbar {\n position: sticky;\n top: 0;\n left: 0;\n right: 0;\n z-index: 1000;\n display: flex;\n align-items: center;\n height: var(--topbar-height);\n padding: var(--topbar-padding);\n font-size: var(--report-font-size-secondary);\n background-color: var(--topbar-background-color);\n border-bottom: 1px solid var(--color-gray-200);\n }\n\n .lh-topbar__logo {\n width: var(--topbar-logo-size);\n height: var(--topbar-logo-size);\n user-select: none;\n flex: none;\n }\n\n .lh-topbar__url {\n margin: var(--topbar-padding);\n text-decoration: none;\n color: var(--report-text-color);\n text-overflow: ellipsis;\n overflow: hidden;\n white-space: nowrap;\n }\n\n .lh-tools {\n display: flex;\n align-items: center;\n margin-left: auto;\n will-change: transform;\n min-width: var(--report-icon-size);\n }\n .lh-tools__button {\n width: var(--report-icon-size);\n min-width: 24px;\n height: var(--report-icon-size);\n cursor: pointer;\n margin-right: 5px;\n /* This is actually a button element, but we want to style it like a transparent div. */\n display: flex;\n background: none;\n color: inherit;\n border: none;\n padding: 0;\n font: inherit;\n outline: inherit;\n }\n .lh-tools__button svg {\n fill: var(--tools-icon-color);\n }\n .lh-dark .lh-tools__button svg {\n filter: invert(1);\n }\n .lh-tools__button.lh-active + .lh-tools__dropdown {\n opacity: 1;\n clip: rect(-1px, 194px, 242px, -3px);\n visibility: visible;\n }\n .lh-tools__dropdown {\n position: absolute;\n background-color: var(--report-background-color);\n border: 1px solid var(--report-border-color);\n border-radius: 3px;\n padding: calc(var(--default-padding) / 2) 0;\n cursor: pointer;\n top: 36px;\n right: 0;\n box-shadow: 1px 1px 3px #ccc;\n min-width: 125px;\n clip: rect(0, 164px, 0, 0);\n visibility: hidden;\n opacity: 0;\n transition: all 200ms cubic-bezier(0,0,0.2,1);\n }\n .lh-tools__dropdown a {\n color: currentColor;\n text-decoration: none;\n white-space: nowrap;\n padding: 0 6px;\n line-height: 2;\n }\n .lh-tools__dropdown a:hover,\n .lh-tools__dropdown a:focus {\n background-color: var(--color-gray-200);\n outline: none;\n }\n /* save-gist option hidden in report. */\n .lh-tools__dropdown a[data-action='save-gist'] {\n display: none;\n }\n\n .lh-locale-selector {\n width: 100%;\n color: var(--report-text-color);\n background-color: var(--locale-selector-background-color);\n padding: 2px;\n }\n .lh-tools-locale {\n display: flex;\n align-items: center;\n flex-direction: row-reverse;\n }\n .lh-tools-locale__selector-wrapper {\n transition: opacity 0.15s;\n opacity: 0;\n max-width: 200px;\n }\n .lh-button.lh-tool-locale__button {\n height: var(--topbar-height);\n color: var(--tools-icon-color);\n padding: calc(var(--default-padding) / 2);\n }\n .lh-tool-locale__button.lh-active + .lh-tools-locale__selector-wrapper {\n opacity: 1;\n clip: rect(-1px, 194px, 242px, -3px);\n visibility: visible;\n margin: 0 4px;\n }\n\n @media screen and (max-width: 964px) {\n .lh-tools__dropdown {\n right: 0;\n left: initial;\n }\n }\n @media print {\n .lh-topbar {\n position: static;\n margin-left: 0;\n }\n\n .lh-tools__dropdown {\n display: none;\n }\n }\n ");
1230
+ const el1 = dom.createElement('style');
1231
+ el1.append('\n .lh-topbar {\n position: sticky;\n top: 0;\n left: 0;\n right: 0;\n z-index: 1000;\n display: flex;\n align-items: center;\n height: var(--topbar-height);\n padding: var(--topbar-padding);\n font-size: var(--report-font-size-secondary);\n background-color: var(--topbar-background-color);\n border-bottom: 1px solid var(--color-gray-200);\n }\n\n .lh-topbar__logo {\n width: var(--topbar-logo-size);\n height: var(--topbar-logo-size);\n user-select: none;\n flex: none;\n }\n\n .lh-topbar__url {\n margin: var(--topbar-padding);\n text-decoration: none;\n color: var(--report-text-color);\n text-overflow: ellipsis;\n overflow: hidden;\n white-space: nowrap;\n }\n\n .lh-tools {\n display: flex;\n align-items: center;\n margin-left: auto;\n will-change: transform;\n min-width: var(--report-icon-size);\n }\n .lh-tools__button {\n width: var(--report-icon-size);\n min-width: 24px;\n height: var(--report-icon-size);\n cursor: pointer;\n margin-right: 5px;\n /* This is actually a button element, but we want to style it like a transparent div. */\n display: flex;\n background: none;\n color: inherit;\n border: none;\n padding: 0;\n font: inherit;\n outline: inherit;\n }\n .lh-tools__button svg {\n fill: var(--tools-icon-color);\n }\n .lh-dark .lh-tools__button svg {\n filter: invert(1);\n }\n .lh-tools__button.lh-active + .lh-tools__dropdown {\n opacity: 1;\n clip: rect(-1px, 194px, 242px, -3px);\n visibility: visible;\n }\n .lh-tools__dropdown {\n position: absolute;\n background-color: var(--report-background-color);\n border: 1px solid var(--report-border-color);\n border-radius: 3px;\n padding: calc(var(--default-padding) / 2) 0;\n cursor: pointer;\n top: 36px;\n right: 0;\n box-shadow: 1px 1px 3px #ccc;\n min-width: 125px;\n clip: rect(0, 164px, 0, 0);\n visibility: hidden;\n opacity: 0;\n transition: all 200ms cubic-bezier(0,0,0.2,1);\n }\n .lh-tools__dropdown a {\n color: currentColor;\n text-decoration: none;\n white-space: nowrap;\n padding: 0 6px;\n line-height: 2;\n }\n .lh-tools__dropdown a:hover,\n .lh-tools__dropdown a:focus {\n background-color: var(--color-gray-200);\n outline: none;\n }\n /* save-gist option hidden in report. */\n .lh-tools__dropdown a[data-action=\'save-gist\'] {\n display: none;\n }\n\n .lh-locale-selector {\n width: 100%;\n color: var(--report-text-color);\n background-color: var(--locale-selector-background-color);\n padding: 2px;\n }\n .lh-tools-locale {\n display: flex;\n align-items: center;\n flex-direction: row-reverse;\n }\n .lh-tools-locale__selector-wrapper {\n transition: opacity 0.15s;\n opacity: 0;\n max-width: 200px;\n }\n .lh-button.lh-tool-locale__button {\n height: var(--topbar-height);\n color: var(--tools-icon-color);\n padding: calc(var(--default-padding) / 2);\n }\n .lh-tool-locale__button.lh-active + .lh-tools-locale__selector-wrapper {\n opacity: 1;\n clip: rect(-1px, 194px, 242px, -3px);\n visibility: visible;\n margin: 0 4px;\n }\n\n @media screen and (max-width: 964px) {\n .lh-tools__dropdown {\n right: 0;\n left: initial;\n }\n }\n @media print {\n .lh-topbar {\n position: static;\n margin-left: 0;\n }\n\n .lh-tools__dropdown {\n display: none;\n }\n }\n ');
1237
1232
  el0.append(el1);
1238
- const el2 = dom.createElement("div", "lh-topbar");
1239
- const el3 = dom.createElementNS("http://www.w3.org/2000/svg", "svg", "lh-topbar__logo");
1233
+ const el2 = dom.createElement('div', 'lh-topbar');
1234
+ const el3 = dom.createElementNS('http://www.w3.org/2000/svg', 'svg', 'lh-topbar__logo');
1240
1235
  el3.setAttribute('viewBox', '0 0 24 24');
1241
- const el4 = dom.createElementNS("http://www.w3.org/2000/svg", "defs");
1242
- const el5 = dom.createElementNS("http://www.w3.org/2000/svg", "linearGradient");
1236
+ const el4 = dom.createElementNS('http://www.w3.org/2000/svg', 'defs');
1237
+ const el5 = dom.createElementNS('http://www.w3.org/2000/svg', 'linearGradient');
1243
1238
  el5.setAttribute('x1', '57.456%');
1244
1239
  el5.setAttribute('y1', '13.086%');
1245
1240
  el5.setAttribute('x2', '18.259%');
1246
1241
  el5.setAttribute('y2', '72.322%');
1247
1242
  el5.setAttribute('id', 'lh-topbar__logo--a');
1248
- const el6 = dom.createElementNS("http://www.w3.org/2000/svg", "stop");
1243
+ const el6 = dom.createElementNS('http://www.w3.org/2000/svg', 'stop');
1249
1244
  el6.setAttribute('stop-color', '#262626');
1250
1245
  el6.setAttribute('stop-opacity', '.1');
1251
1246
  el6.setAttribute('offset', '0%');
1252
- const el7 = dom.createElementNS("http://www.w3.org/2000/svg", "stop");
1247
+ const el7 = dom.createElementNS('http://www.w3.org/2000/svg', 'stop');
1253
1248
  el7.setAttribute('stop-color', '#262626');
1254
1249
  el7.setAttribute('stop-opacity', '0');
1255
1250
  el7.setAttribute('offset', '100%');
1256
- el5.append(" ",el6," ",el7," ");
1257
- const el8 = dom.createElementNS("http://www.w3.org/2000/svg", "linearGradient");
1251
+ el5.append(' ', el6, ' ', el7, ' ');
1252
+ const el8 = dom.createElementNS('http://www.w3.org/2000/svg', 'linearGradient');
1258
1253
  el8.setAttribute('x1', '100%');
1259
1254
  el8.setAttribute('y1', '50%');
1260
1255
  el8.setAttribute('x2', '0%');
1261
1256
  el8.setAttribute('y2', '50%');
1262
1257
  el8.setAttribute('id', 'lh-topbar__logo--b');
1263
- const el9 = dom.createElementNS("http://www.w3.org/2000/svg", "stop");
1258
+ const el9 = dom.createElementNS('http://www.w3.org/2000/svg', 'stop');
1264
1259
  el9.setAttribute('stop-color', '#262626');
1265
1260
  el9.setAttribute('stop-opacity', '.1');
1266
1261
  el9.setAttribute('offset', '0%');
1267
- const el10 = dom.createElementNS("http://www.w3.org/2000/svg", "stop");
1262
+ const el10 = dom.createElementNS('http://www.w3.org/2000/svg', 'stop');
1268
1263
  el10.setAttribute('stop-color', '#262626');
1269
1264
  el10.setAttribute('stop-opacity', '0');
1270
1265
  el10.setAttribute('offset', '100%');
1271
- el8.append(" ",el9," ",el10," ");
1272
- const el11 = dom.createElementNS("http://www.w3.org/2000/svg", "linearGradient");
1266
+ el8.append(' ', el9, ' ', el10, ' ');
1267
+ const el11 = dom.createElementNS('http://www.w3.org/2000/svg', 'linearGradient');
1273
1268
  el11.setAttribute('x1', '58.764%');
1274
1269
  el11.setAttribute('y1', '65.756%');
1275
1270
  el11.setAttribute('x2', '36.939%');
1276
1271
  el11.setAttribute('y2', '50.14%');
1277
1272
  el11.setAttribute('id', 'lh-topbar__logo--c');
1278
- const el12 = dom.createElementNS("http://www.w3.org/2000/svg", "stop");
1273
+ const el12 = dom.createElementNS('http://www.w3.org/2000/svg', 'stop');
1279
1274
  el12.setAttribute('stop-color', '#262626');
1280
1275
  el12.setAttribute('stop-opacity', '.1');
1281
1276
  el12.setAttribute('offset', '0%');
1282
- const el13 = dom.createElementNS("http://www.w3.org/2000/svg", "stop");
1277
+ const el13 = dom.createElementNS('http://www.w3.org/2000/svg', 'stop');
1283
1278
  el13.setAttribute('stop-color', '#262626');
1284
1279
  el13.setAttribute('stop-opacity', '0');
1285
1280
  el13.setAttribute('offset', '100%');
1286
- el11.append(" ",el12," ",el13," ");
1287
- const el14 = dom.createElementNS("http://www.w3.org/2000/svg", "linearGradient");
1281
+ el11.append(' ', el12, ' ', el13, ' ');
1282
+ const el14 = dom.createElementNS('http://www.w3.org/2000/svg', 'linearGradient');
1288
1283
  el14.setAttribute('x1', '41.635%');
1289
1284
  el14.setAttribute('y1', '20.358%');
1290
1285
  el14.setAttribute('x2', '72.863%');
1291
1286
  el14.setAttribute('y2', '85.424%');
1292
1287
  el14.setAttribute('id', 'lh-topbar__logo--d');
1293
- const el15 = dom.createElementNS("http://www.w3.org/2000/svg", "stop");
1288
+ const el15 = dom.createElementNS('http://www.w3.org/2000/svg', 'stop');
1294
1289
  el15.setAttribute('stop-color', '#FFF');
1295
1290
  el15.setAttribute('stop-opacity', '.1');
1296
1291
  el15.setAttribute('offset', '0%');
1297
- const el16 = dom.createElementNS("http://www.w3.org/2000/svg", "stop");
1292
+ const el16 = dom.createElementNS('http://www.w3.org/2000/svg', 'stop');
1298
1293
  el16.setAttribute('stop-color', '#FFF');
1299
1294
  el16.setAttribute('stop-opacity', '0');
1300
1295
  el16.setAttribute('offset', '100%');
1301
- el14.append(" ",el15," ",el16," ");
1302
- el4.append(" ",el5," ",el8," ",el11," ",el14," ");
1303
- const el17 = dom.createElementNS("http://www.w3.org/2000/svg", "g");
1296
+ el14.append(' ', el15, ' ', el16, ' ');
1297
+ el4.append(' ', el5, ' ', el8, ' ', el11, ' ', el14, ' ');
1298
+ const el17 = dom.createElementNS('http://www.w3.org/2000/svg', 'g');
1304
1299
  el17.setAttribute('fill', 'none');
1305
1300
  el17.setAttribute('fill-rule', 'evenodd');
1306
- const el18 = dom.createElementNS("http://www.w3.org/2000/svg", "path");
1301
+ const el18 = dom.createElementNS('http://www.w3.org/2000/svg', 'path');
1307
1302
  el18.setAttribute('d', 'M12 3l4.125 2.625v3.75H18v2.25h-1.688l1.5 9.375H6.188l1.5-9.375H6v-2.25h1.875V5.648L12 3zm2.201 9.938L9.54 14.633 9 18.028l5.625-2.062-.424-3.028zM12.005 5.67l-1.88 1.207v2.498h3.75V6.86l-1.87-1.19z');
1308
1303
  el18.setAttribute('fill', '#F44B21');
1309
- const el19 = dom.createElementNS("http://www.w3.org/2000/svg", "path");
1304
+ const el19 = dom.createElementNS('http://www.w3.org/2000/svg', 'path');
1310
1305
  el19.setAttribute('fill', '#FFF');
1311
1306
  el19.setAttribute('d', 'M14.201 12.938L9.54 14.633 9 18.028l5.625-2.062z');
1312
- const el20 = dom.createElementNS("http://www.w3.org/2000/svg", "path");
1307
+ const el20 = dom.createElementNS('http://www.w3.org/2000/svg', 'path');
1313
1308
  el20.setAttribute('d', 'M6 18c-2.042 0-3.95-.01-5.813 0l1.5-9.375h4.326L6 18z');
1314
1309
  el20.setAttribute('fill', 'url(#lh-topbar__logo--a)');
1315
1310
  el20.setAttribute('fill-rule', 'nonzero');
1316
1311
  el20.setAttribute('transform', 'translate(6 3)');
1317
- const el21 = dom.createElementNS("http://www.w3.org/2000/svg", "path");
1312
+ const el21 = dom.createElementNS('http://www.w3.org/2000/svg', 'path');
1318
1313
  el21.setAttribute('fill', '#FFF176');
1319
1314
  el21.setAttribute('fill-rule', 'nonzero');
1320
1315
  el21.setAttribute('d', 'M13.875 9.375v-2.56l-1.87-1.19-1.88 1.207v2.543z');
1321
- const el22 = dom.createElementNS("http://www.w3.org/2000/svg", "path");
1316
+ const el22 = dom.createElementNS('http://www.w3.org/2000/svg', 'path');
1322
1317
  el22.setAttribute('fill', 'url(#lh-topbar__logo--b)');
1323
1318
  el22.setAttribute('fill-rule', 'nonzero');
1324
1319
  el22.setAttribute('d', 'M0 6.375h6v2.25H0z');
1325
1320
  el22.setAttribute('transform', 'translate(6 3)');
1326
- const el23 = dom.createElementNS("http://www.w3.org/2000/svg", "path");
1321
+ const el23 = dom.createElementNS('http://www.w3.org/2000/svg', 'path');
1327
1322
  el23.setAttribute('fill', 'url(#lh-topbar__logo--c)');
1328
1323
  el23.setAttribute('fill-rule', 'nonzero');
1329
1324
  el23.setAttribute('d', 'M6 6.375H1.875v-3.75L6 0z');
1330
1325
  el23.setAttribute('transform', 'translate(6 3)');
1331
- const el24 = dom.createElementNS("http://www.w3.org/2000/svg", "path");
1326
+ const el24 = dom.createElementNS('http://www.w3.org/2000/svg', 'path');
1332
1327
  el24.setAttribute('fill', 'url(#lh-topbar__logo--d)');
1333
1328
  el24.setAttribute('fill-rule', 'nonzero');
1334
1329
  el24.setAttribute('d', 'M6 0l4.125 2.625v3.75H12v2.25h-1.688l1.5 9.375H.188l1.5-9.375H0v-2.25h1.875V2.648z');
1335
1330
  el24.setAttribute('transform', 'translate(6 3)');
1336
- el17.append(" ",el18," ",el19," ",el20," ",el21," ",el22," ",el23," ",el24," ");
1337
- el3.append(" ",el4," ",el17," ");
1338
- const el25 = dom.createElement("a", "lh-topbar__url");
1331
+ el17.append(' ', el18, ' ', el19, ' ', el20, ' ', el21, ' ', el22, ' ', el23, ' ', el24, ' ');
1332
+ el3.append(' ', el4, ' ', el17, ' ');
1333
+ const el25 = dom.createElement('a', 'lh-topbar__url');
1339
1334
  el25.setAttribute('href', '');
1340
1335
  el25.setAttribute('target', '_blank');
1341
1336
  el25.setAttribute('rel', 'noopener');
1342
- const el26 = dom.createElement("div", "lh-tools");
1343
- const el27 = dom.createElement("div", "lh-tools-locale lh-hidden");
1344
- const el28 = dom.createElement("button", "lh-button lh-tool-locale__button");
1337
+ const el26 = dom.createElement('div', 'lh-tools');
1338
+ const el27 = dom.createElement('div', 'lh-tools-locale lh-hidden');
1339
+ const el28 = dom.createElement('button', 'lh-button lh-tool-locale__button');
1345
1340
  el28.setAttribute('id', 'lh-button__swap-locales');
1346
1341
  el28.setAttribute('title', 'Show Language Picker');
1347
1342
  el28.setAttribute('aria-label', 'Toggle language picker');
1348
1343
  el28.setAttribute('aria-haspopup', 'menu');
1349
1344
  el28.setAttribute('aria-expanded', 'false');
1350
1345
  el28.setAttribute('aria-controls', 'lh-tools-locale__selector-wrapper');
1351
- const el29 = dom.createElementNS("http://www.w3.org/2000/svg", "svg");
1346
+ const el29 = dom.createElementNS('http://www.w3.org/2000/svg', 'svg');
1352
1347
  el29.setAttribute('width', '20px');
1353
1348
  el29.setAttribute('height', '20px');
1354
1349
  el29.setAttribute('viewBox', '0 0 24 24');
1355
1350
  el29.setAttribute('fill', 'currentColor');
1356
- const el30 = dom.createElementNS("http://www.w3.org/2000/svg", "path");
1351
+ const el30 = dom.createElementNS('http://www.w3.org/2000/svg', 'path');
1357
1352
  el30.setAttribute('d', 'M0 0h24v24H0V0z');
1358
1353
  el30.setAttribute('fill', 'none');
1359
- const el31 = dom.createElementNS("http://www.w3.org/2000/svg", "path");
1354
+ const el31 = dom.createElementNS('http://www.w3.org/2000/svg', 'path');
1360
1355
  el31.setAttribute('d', 'M12.87 15.07l-2.54-2.51.03-.03c1.74-1.94 2.98-4.17 3.71-6.53H17V4h-7V2H8v2H1v1.99h11.17C11.5 7.92 10.44 9.75 9 11.35 8.07 10.32 7.3 9.19 6.69 8h-2c.73 1.63 1.73 3.17 2.98 4.56l-5.09 5.02L4 19l5-5 3.11 3.11.76-2.04zM18.5 10h-2L12 22h2l1.12-3h4.75L21 22h2l-4.5-12zm-2.62 7l1.62-4.33L19.12 17h-3.24z');
1361
- el29.append(el30,el31);
1362
- el28.append(" ",el29," ");
1363
- const el32 = dom.createElement("div", "lh-tools-locale__selector-wrapper");
1356
+ el29.append(el30, el31);
1357
+ el28.append(' ', el29, ' ');
1358
+ const el32 = dom.createElement('div', 'lh-tools-locale__selector-wrapper');
1364
1359
  el32.setAttribute('id', 'lh-tools-locale__selector-wrapper');
1365
1360
  el32.setAttribute('role', 'menu');
1366
1361
  el32.setAttribute('aria-labelledby', 'lh-button__swap-locales');
1367
1362
  el32.setAttribute('aria-hidden', 'true');
1368
- el32.append(" "," ");
1369
- el27.append(" ",el28," ",el32," ");
1370
- const el33 = dom.createElement("button", "lh-tools__button");
1363
+ el32.append(' ', ' ');
1364
+ el27.append(' ', el28, ' ', el32, ' ');
1365
+ const el33 = dom.createElement('button', 'lh-tools__button');
1371
1366
  el33.setAttribute('id', 'lh-tools-button');
1372
1367
  el33.setAttribute('title', 'Tools menu');
1373
1368
  el33.setAttribute('aria-label', 'Toggle report tools menu');
1374
1369
  el33.setAttribute('aria-haspopup', 'menu');
1375
1370
  el33.setAttribute('aria-expanded', 'false');
1376
1371
  el33.setAttribute('aria-controls', 'lh-tools-dropdown');
1377
- const el34 = dom.createElementNS("http://www.w3.org/2000/svg", "svg");
1372
+ const el34 = dom.createElementNS('http://www.w3.org/2000/svg', 'svg');
1378
1373
  el34.setAttribute('width', '100%');
1379
1374
  el34.setAttribute('height', '100%');
1380
1375
  el34.setAttribute('viewBox', '0 0 24 24');
1381
- const el35 = dom.createElementNS("http://www.w3.org/2000/svg", "path");
1376
+ const el35 = dom.createElementNS('http://www.w3.org/2000/svg', 'path');
1382
1377
  el35.setAttribute('d', 'M0 0h24v24H0z');
1383
1378
  el35.setAttribute('fill', 'none');
1384
- const el36 = dom.createElementNS("http://www.w3.org/2000/svg", "path");
1379
+ const el36 = dom.createElementNS('http://www.w3.org/2000/svg', 'path');
1385
1380
  el36.setAttribute('d', 'M12 8c1.1 0 2-.9 2-2s-.9-2-2-2-2 .9-2 2 .9 2 2 2zm0 2c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm0 6c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2z');
1386
- el34.append(" ",el35," ",el36," ");
1387
- el33.append(" ",el34," ");
1388
- const el37 = dom.createElement("div", "lh-tools__dropdown");
1381
+ el34.append(' ', el35, ' ', el36, ' ');
1382
+ el33.append(' ', el34, ' ');
1383
+ const el37 = dom.createElement('div', 'lh-tools__dropdown');
1389
1384
  el37.setAttribute('id', 'lh-tools-dropdown');
1390
1385
  el37.setAttribute('role', 'menu');
1391
1386
  el37.setAttribute('aria-labelledby', 'lh-tools-button');
1392
- const el38 = dom.createElement("a", "lh-report-icon lh-report-icon--print");
1387
+ const el38 = dom.createElement('a', 'lh-report-icon lh-report-icon--print');
1393
1388
  el38.setAttribute('role', 'menuitem');
1394
1389
  el38.setAttribute('tabindex', '-1');
1395
1390
  el38.setAttribute('href', '#');
1396
1391
  el38.setAttribute('data-i18n', 'dropdownPrintSummary');
1397
1392
  el38.setAttribute('data-action', 'print-summary');
1398
- const el39 = dom.createElement("a", "lh-report-icon lh-report-icon--print");
1393
+ const el39 = dom.createElement('a', 'lh-report-icon lh-report-icon--print');
1399
1394
  el39.setAttribute('role', 'menuitem');
1400
1395
  el39.setAttribute('tabindex', '-1');
1401
1396
  el39.setAttribute('href', '#');
1402
1397
  el39.setAttribute('data-i18n', 'dropdownPrintExpanded');
1403
1398
  el39.setAttribute('data-action', 'print-expanded');
1404
- const el40 = dom.createElement("a", "lh-report-icon lh-report-icon--copy");
1399
+ const el40 = dom.createElement('a', 'lh-report-icon lh-report-icon--copy');
1405
1400
  el40.setAttribute('role', 'menuitem');
1406
1401
  el40.setAttribute('tabindex', '-1');
1407
1402
  el40.setAttribute('href', '#');
1408
1403
  el40.setAttribute('data-i18n', 'dropdownCopyJSON');
1409
1404
  el40.setAttribute('data-action', 'copy');
1410
- const el41 = dom.createElement("a", "lh-report-icon lh-report-icon--download lh-hidden");
1405
+ const el41 = dom.createElement('a', 'lh-report-icon lh-report-icon--download lh-hidden');
1411
1406
  el41.setAttribute('role', 'menuitem');
1412
1407
  el41.setAttribute('tabindex', '-1');
1413
1408
  el41.setAttribute('href', '#');
1414
1409
  el41.setAttribute('data-i18n', 'dropdownSaveHTML');
1415
1410
  el41.setAttribute('data-action', 'save-html');
1416
- const el42 = dom.createElement("a", "lh-report-icon lh-report-icon--download");
1411
+ const el42 = dom.createElement('a', 'lh-report-icon lh-report-icon--download');
1417
1412
  el42.setAttribute('role', 'menuitem');
1418
1413
  el42.setAttribute('tabindex', '-1');
1419
1414
  el42.setAttribute('href', '#');
1420
1415
  el42.setAttribute('data-i18n', 'dropdownSaveJSON');
1421
1416
  el42.setAttribute('data-action', 'save-json');
1422
- const el43 = dom.createElement("a", "lh-report-icon lh-report-icon--open");
1417
+ const el43 = dom.createElement('a', 'lh-report-icon lh-report-icon--open');
1423
1418
  el43.setAttribute('role', 'menuitem');
1424
1419
  el43.setAttribute('tabindex', '-1');
1425
1420
  el43.setAttribute('href', '#');
1426
1421
  el43.setAttribute('data-i18n', 'dropdownViewer');
1427
1422
  el43.setAttribute('data-action', 'open-viewer');
1428
- const el44 = dom.createElement("a", "lh-report-icon lh-report-icon--open");
1423
+ const el44 = dom.createElement('a', 'lh-report-icon lh-report-icon--open');
1429
1424
  el44.setAttribute('role', 'menuitem');
1430
1425
  el44.setAttribute('tabindex', '-1');
1431
1426
  el44.setAttribute('href', '#');
1432
1427
  el44.setAttribute('data-i18n', 'dropdownSaveGist');
1433
1428
  el44.setAttribute('data-action', 'save-gist');
1434
- const el45 = dom.createElement("a", "lh-report-icon lh-report-icon--dark");
1429
+ const el45 = dom.createElement('a', 'lh-report-icon lh-report-icon--dark');
1435
1430
  el45.setAttribute('role', 'menuitem');
1436
1431
  el45.setAttribute('tabindex', '-1');
1437
1432
  el45.setAttribute('href', '#');
1438
1433
  el45.setAttribute('data-i18n', 'dropdownDarkTheme');
1439
1434
  el45.setAttribute('data-action', 'toggle-dark');
1440
- el37.append(" ",el38," ",el39," ",el40," "," ",el41," ",el42," ",el43," ",el44," ",el45," ");
1441
- el26.append(" ",el27," ",el33," ",el37," ");
1442
- el2.append(" "," ",el3," ",el25," ",el26," ");
1435
+ el37.append(' ', el38, ' ', el39, ' ', el40, ' ', ' ', el41, ' ', el42, ' ', el43, ' ', el44, ' ', el45, ' ');
1436
+ el26.append(' ', el27, ' ', el33, ' ', el37, ' ');
1437
+ el2.append(' ', ' ', el3, ' ', el25, ' ', el26, ' ');
1443
1438
  el0.append(el2);
1444
1439
  return el0;
1445
1440
  }
@@ -1449,10 +1444,10 @@ function createTopbarComponent(dom) {
1449
1444
  */
1450
1445
  function createWarningsToplevelComponent(dom) {
1451
1446
  const el0 = dom.createFragment();
1452
- const el1 = dom.createElement("div", "lh-warnings lh-warnings--toplevel");
1453
- const el2 = dom.createElement("p", "lh-warnings__msg");
1454
- const el3 = dom.createElement("ul");
1455
- el1.append(" ",el2," ",el3," ");
1447
+ const el1 = dom.createElement('div', 'lh-warnings lh-warnings--toplevel');
1448
+ const el2 = dom.createElement('p', 'lh-warnings__msg');
1449
+ const el3 = dom.createElement('ul');
1450
+ el1.append(' ', el2, ' ', el3, ' ');
1456
1451
  el0.append(el1);
1457
1452
  return el0;
1458
1453
  }
@@ -2558,356 +2553,6 @@ class CriticalRequestChainRenderer {
2558
2553
  // Alias b/c the name is really long.
2559
2554
  const CRCRenderer = CriticalRequestChainRenderer;
2560
2555
 
2561
- /**
2562
- * @license Copyright 2019 The Lighthouse Authors. All Rights Reserved.
2563
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
2564
- * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
2565
- */
2566
-
2567
- /** @enum {number} */
2568
- const LineVisibility = {
2569
- /** Show regardless of whether the snippet is collapsed or expanded */
2570
- ALWAYS: 0,
2571
- WHEN_COLLAPSED: 1,
2572
- WHEN_EXPANDED: 2,
2573
- };
2574
-
2575
- /** @enum {number} */
2576
- const LineContentType = {
2577
- /** A line of content */
2578
- CONTENT_NORMAL: 0,
2579
- /** A line of content that's emphasized by setting the CSS background color */
2580
- CONTENT_HIGHLIGHTED: 1,
2581
- /** Use when some lines are hidden, shows the "..." placeholder */
2582
- PLACEHOLDER: 2,
2583
- /** A message about a line of content or the snippet in general */
2584
- MESSAGE: 3,
2585
- };
2586
-
2587
- /** @typedef {{
2588
- content: string;
2589
- lineNumber: string | number;
2590
- contentType: LineContentType;
2591
- truncated?: boolean;
2592
- visibility?: LineVisibility;
2593
- }} LineDetails */
2594
-
2595
- const classNamesByContentType = {
2596
- [LineContentType.CONTENT_NORMAL]: ['lh-snippet__line--content'],
2597
- [LineContentType.CONTENT_HIGHLIGHTED]: [
2598
- 'lh-snippet__line--content',
2599
- 'lh-snippet__line--content-highlighted',
2600
- ],
2601
- [LineContentType.PLACEHOLDER]: ['lh-snippet__line--placeholder'],
2602
- [LineContentType.MESSAGE]: ['lh-snippet__line--message'],
2603
- };
2604
-
2605
- /**
2606
- * @param {LH.Audit.Details.SnippetValue['lines']} lines
2607
- * @param {number} lineNumber
2608
- * @return {{line?: LH.Audit.Details.SnippetValue['lines'][0], previousLine?: LH.Audit.Details.SnippetValue['lines'][0]}}
2609
- */
2610
- function getLineAndPreviousLine(lines, lineNumber) {
2611
- return {
2612
- line: lines.find(l => l.lineNumber === lineNumber),
2613
- previousLine: lines.find(l => l.lineNumber === lineNumber - 1),
2614
- };
2615
- }
2616
-
2617
- /**
2618
- * @param {LH.Audit.Details.SnippetValue["lineMessages"]} messages
2619
- * @param {number} lineNumber
2620
- */
2621
- function getMessagesForLineNumber(messages, lineNumber) {
2622
- return messages.filter(h => h.lineNumber === lineNumber);
2623
- }
2624
-
2625
- /**
2626
- * @param {LH.Audit.Details.SnippetValue} details
2627
- * @return {LH.Audit.Details.SnippetValue['lines']}
2628
- */
2629
- function getLinesWhenCollapsed(details) {
2630
- const SURROUNDING_LINES_TO_SHOW_WHEN_COLLAPSED = 2;
2631
- return Util.filterRelevantLines(
2632
- details.lines,
2633
- details.lineMessages,
2634
- SURROUNDING_LINES_TO_SHOW_WHEN_COLLAPSED
2635
- );
2636
- }
2637
-
2638
- /**
2639
- * Render snippet of text with line numbers and annotations.
2640
- * By default we only show a few lines around each annotation and the user
2641
- * can click "Expand snippet" to show more.
2642
- * Content lines with annotations are highlighted.
2643
- */
2644
- class SnippetRenderer {
2645
- /**
2646
- * @param {DOM} dom
2647
- * @param {LH.Audit.Details.SnippetValue} details
2648
- * @param {DetailsRenderer} detailsRenderer
2649
- * @param {function} toggleExpandedFn
2650
- * @return {DocumentFragment}
2651
- */
2652
- static renderHeader(dom, details, detailsRenderer, toggleExpandedFn) {
2653
- const linesWhenCollapsed = getLinesWhenCollapsed(details);
2654
- const canExpand = linesWhenCollapsed.length < details.lines.length;
2655
-
2656
- const header = dom.createComponent('snippetHeader');
2657
- dom.find('.lh-snippet__title', header).textContent = details.title;
2658
-
2659
- const {
2660
- snippetCollapseButtonLabel,
2661
- snippetExpandButtonLabel,
2662
- } = Util.i18n.strings;
2663
- dom.find(
2664
- '.lh-snippet__btn-label-collapse',
2665
- header
2666
- ).textContent = snippetCollapseButtonLabel;
2667
- dom.find(
2668
- '.lh-snippet__btn-label-expand',
2669
- header
2670
- ).textContent = snippetExpandButtonLabel;
2671
-
2672
- const toggleExpandButton = dom.find('.lh-snippet__toggle-expand', header);
2673
- // If we're already showing all the available lines of the snippet, we don't need an
2674
- // expand/collapse button and can remove it from the DOM.
2675
- // If we leave the button in though, wire up the click listener to toggle visibility!
2676
- if (!canExpand) {
2677
- toggleExpandButton.remove();
2678
- } else {
2679
- toggleExpandButton.addEventListener('click', () => toggleExpandedFn());
2680
- }
2681
-
2682
- // We only show the source node of the snippet in DevTools because then the user can
2683
- // access the full element detail. Just being able to see the outer HTML isn't very useful.
2684
- if (details.node && dom.isDevTools()) {
2685
- const nodeContainer = dom.find('.lh-snippet__node', header);
2686
- nodeContainer.appendChild(detailsRenderer.renderNode(details.node));
2687
- }
2688
-
2689
- return header;
2690
- }
2691
-
2692
- /**
2693
- * Renders a line (text content, message, or placeholder) as a DOM element.
2694
- * @param {DOM} dom
2695
- * @param {DocumentFragment} tmpl
2696
- * @param {LineDetails} lineDetails
2697
- * @return {Element}
2698
- */
2699
- static renderSnippetLine(
2700
- dom,
2701
- tmpl,
2702
- {content, lineNumber, truncated, contentType, visibility}
2703
- ) {
2704
- const clonedTemplate = dom.createComponent('snippetLine');
2705
- const contentLine = dom.find('.lh-snippet__line', clonedTemplate);
2706
- const {classList} = contentLine;
2707
-
2708
- classNamesByContentType[contentType].forEach(typeClass =>
2709
- classList.add(typeClass)
2710
- );
2711
-
2712
- if (visibility === LineVisibility.WHEN_COLLAPSED) {
2713
- classList.add('lh-snippet__show-if-collapsed');
2714
- } else if (visibility === LineVisibility.WHEN_EXPANDED) {
2715
- classList.add('lh-snippet__show-if-expanded');
2716
- }
2717
-
2718
- const lineContent = content + (truncated ? '…' : '');
2719
- const lineContentEl = dom.find('.lh-snippet__line code', contentLine);
2720
- if (contentType === LineContentType.MESSAGE) {
2721
- lineContentEl.appendChild(dom.convertMarkdownLinkSnippets(lineContent));
2722
- } else {
2723
- lineContentEl.textContent = lineContent;
2724
- }
2725
-
2726
- dom.find(
2727
- '.lh-snippet__line-number',
2728
- contentLine
2729
- ).textContent = lineNumber.toString();
2730
-
2731
- return contentLine;
2732
- }
2733
-
2734
- /**
2735
- * @param {DOM} dom
2736
- * @param {DocumentFragment} tmpl
2737
- * @param {{message: string}} message
2738
- * @return {Element}
2739
- */
2740
- static renderMessage(dom, tmpl, message) {
2741
- return SnippetRenderer.renderSnippetLine(dom, tmpl, {
2742
- lineNumber: ' ',
2743
- content: message.message,
2744
- contentType: LineContentType.MESSAGE,
2745
- });
2746
- }
2747
-
2748
- /**
2749
- * @param {DOM} dom
2750
- * @param {DocumentFragment} tmpl
2751
- * @param {LineVisibility} visibility
2752
- * @return {Element}
2753
- */
2754
- static renderOmittedLinesPlaceholder(dom, tmpl, visibility) {
2755
- return SnippetRenderer.renderSnippetLine(dom, tmpl, {
2756
- lineNumber: '…',
2757
- content: '',
2758
- visibility,
2759
- contentType: LineContentType.PLACEHOLDER,
2760
- });
2761
- }
2762
-
2763
- /**
2764
- * @param {DOM} dom
2765
- * @param {DocumentFragment} tmpl
2766
- * @param {LH.Audit.Details.SnippetValue} details
2767
- * @return {DocumentFragment}
2768
- */
2769
- static renderSnippetContent(dom, tmpl, details) {
2770
- const template = dom.createComponent('snippetContent');
2771
- const snippetEl = dom.find('.lh-snippet__snippet-inner', template);
2772
-
2773
- // First render messages that don't belong to specific lines
2774
- details.generalMessages.forEach(m =>
2775
- snippetEl.append(SnippetRenderer.renderMessage(dom, tmpl, m))
2776
- );
2777
- // Then render the lines and their messages, as well as placeholders where lines are omitted
2778
- snippetEl.append(SnippetRenderer.renderSnippetLines(dom, tmpl, details));
2779
-
2780
- return template;
2781
- }
2782
-
2783
- /**
2784
- * @param {DOM} dom
2785
- * @param {DocumentFragment} tmpl
2786
- * @param {LH.Audit.Details.SnippetValue} details
2787
- * @return {DocumentFragment}
2788
- */
2789
- static renderSnippetLines(dom, tmpl, details) {
2790
- const {lineMessages, generalMessages, lineCount, lines} = details;
2791
- const linesWhenCollapsed = getLinesWhenCollapsed(details);
2792
- const hasOnlyGeneralMessages =
2793
- generalMessages.length > 0 && lineMessages.length === 0;
2794
-
2795
- const lineContainer = dom.createFragment();
2796
-
2797
- // When a line is not shown in the collapsed state we try to see if we also need an
2798
- // omitted lines placeholder for the expanded state, rather than rendering two separate
2799
- // placeholders.
2800
- let hasPendingOmittedLinesPlaceholderForCollapsedState = false;
2801
-
2802
- for (let lineNumber = 1; lineNumber <= lineCount; lineNumber++) {
2803
- const {line, previousLine} = getLineAndPreviousLine(lines, lineNumber);
2804
- const {
2805
- line: lineWhenCollapsed,
2806
- previousLine: previousLineWhenCollapsed,
2807
- } = getLineAndPreviousLine(linesWhenCollapsed, lineNumber);
2808
-
2809
- const showLineWhenCollapsed = !!lineWhenCollapsed;
2810
- const showPreviousLineWhenCollapsed = !!previousLineWhenCollapsed;
2811
-
2812
- // If we went from showing lines in the collapsed state to not showing them
2813
- // we need to render a placeholder
2814
- if (showPreviousLineWhenCollapsed && !showLineWhenCollapsed) {
2815
- hasPendingOmittedLinesPlaceholderForCollapsedState = true;
2816
- }
2817
- // If we are back to lines being visible in the collapsed and the placeholder
2818
- // hasn't been rendered yet then render it now
2819
- if (
2820
- showLineWhenCollapsed &&
2821
- hasPendingOmittedLinesPlaceholderForCollapsedState
2822
- ) {
2823
- lineContainer.append(
2824
- SnippetRenderer.renderOmittedLinesPlaceholder(
2825
- dom,
2826
- tmpl,
2827
- LineVisibility.WHEN_COLLAPSED
2828
- )
2829
- );
2830
- hasPendingOmittedLinesPlaceholderForCollapsedState = false;
2831
- }
2832
-
2833
- // Render omitted lines placeholder if we have not already rendered one for this gap
2834
- const isFirstOmittedLineWhenExpanded = !line && !!previousLine;
2835
- const isFirstLineOverallAndIsOmittedWhenExpanded =
2836
- !line && lineNumber === 1;
2837
- if (
2838
- isFirstOmittedLineWhenExpanded ||
2839
- isFirstLineOverallAndIsOmittedWhenExpanded
2840
- ) {
2841
- // In the collapsed state we don't show omitted lines placeholders around
2842
- // the edges of the snippet
2843
- const hasRenderedAllLinesVisibleWhenCollapsed = !linesWhenCollapsed.some(
2844
- l => l.lineNumber > lineNumber
2845
- );
2846
- const onlyShowWhenExpanded =
2847
- hasRenderedAllLinesVisibleWhenCollapsed || lineNumber === 1;
2848
- lineContainer.append(
2849
- SnippetRenderer.renderOmittedLinesPlaceholder(
2850
- dom,
2851
- tmpl,
2852
- onlyShowWhenExpanded
2853
- ? LineVisibility.WHEN_EXPANDED
2854
- : LineVisibility.ALWAYS
2855
- )
2856
- );
2857
- hasPendingOmittedLinesPlaceholderForCollapsedState = false;
2858
- }
2859
-
2860
- if (!line) {
2861
- // Can't render the line if we don't know its content (instead we've rendered a placeholder)
2862
- continue;
2863
- }
2864
-
2865
- // Now render the line and any messages
2866
- const messages = getMessagesForLineNumber(lineMessages, lineNumber);
2867
- const highlightLine = messages.length > 0 || hasOnlyGeneralMessages;
2868
- const contentLineDetails = Object.assign({}, line, {
2869
- contentType: highlightLine
2870
- ? LineContentType.CONTENT_HIGHLIGHTED
2871
- : LineContentType.CONTENT_NORMAL,
2872
- visibility: lineWhenCollapsed
2873
- ? LineVisibility.ALWAYS
2874
- : LineVisibility.WHEN_EXPANDED,
2875
- });
2876
- lineContainer.append(
2877
- SnippetRenderer.renderSnippetLine(dom, tmpl, contentLineDetails)
2878
- );
2879
-
2880
- messages.forEach(message => {
2881
- lineContainer.append(SnippetRenderer.renderMessage(dom, tmpl, message));
2882
- });
2883
- }
2884
-
2885
- return lineContainer;
2886
- }
2887
-
2888
- /**
2889
- * @param {DOM} dom
2890
- * @param {LH.Audit.Details.SnippetValue} details
2891
- * @param {DetailsRenderer} detailsRenderer
2892
- * @return {!Element}
2893
- */
2894
- static render(dom, details, detailsRenderer) {
2895
- const tmpl = dom.createComponent('snippet');
2896
- const snippetEl = dom.find('.lh-snippet', tmpl);
2897
-
2898
- const header = SnippetRenderer.renderHeader(
2899
- dom,
2900
- details,
2901
- detailsRenderer,
2902
- () => snippetEl.classList.toggle('lh-snippet--expanded')
2903
- );
2904
- const content = SnippetRenderer.renderSnippetContent(dom, tmpl, details);
2905
- snippetEl.append(header, content);
2906
-
2907
- return snippetEl;
2908
- }
2909
- }
2910
-
2911
2556
  /**
2912
2557
  * @license Copyright 2020 The Lighthouse Authors. All Rights Reserved.
2913
2558
  * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
@@ -3142,6 +2787,9 @@ class ElementScreenshotRenderer {
3142
2787
  {width: screenshot.width, height: screenshot.height}
3143
2788
  );
3144
2789
 
2790
+ const contentEl = dom.find('div.lh-element-screenshot__content', containerEl);
2791
+ contentEl.style.top = `-${elementPreviewSizeDC.height}px`;
2792
+
3145
2793
  const imageEl = dom.find('div.lh-element-screenshot__image', containerEl);
3146
2794
  imageEl.style.width = elementPreviewSizeDC.width + 'px';
3147
2795
  imageEl.style.height = elementPreviewSizeDC.height + 'px';
@@ -3239,8 +2887,9 @@ class DetailsRenderer {
3239
2887
  * @return {Element}
3240
2888
  */
3241
2889
  _renderBytes(details) {
3242
- // TODO: handle displayUnit once we have something other than 'KiB'
3243
- const value = Util.i18n.formatBytesToKiB(details.value, details.granularity || 0.1);
2890
+ // TODO: handle displayUnit once we have something other than 'kb'
2891
+ // Note that 'kb' is historical and actually represents KiB.
2892
+ const value = Util.i18n.formatBytesToKiB(details.value, details.granularity);
3244
2893
  const textEl = this._renderText(value);
3245
2894
  textEl.title = Util.i18n.formatBytes(details.value);
3246
2895
  return textEl;
@@ -3251,11 +2900,9 @@ class DetailsRenderer {
3251
2900
  * @return {Element}
3252
2901
  */
3253
2902
  _renderMilliseconds(details) {
3254
- let value;
2903
+ let value = Util.i18n.formatMilliseconds(details.value, details.granularity);
3255
2904
  if (details.displayUnit === 'duration') {
3256
2905
  value = Util.i18n.formatDuration(details.value);
3257
- } else {
3258
- value = Util.i18n.formatMilliseconds(details.value, details.granularity || 10);
3259
2906
  }
3260
2907
 
3261
2908
  return this._renderText(value);
@@ -3334,7 +2981,7 @@ class DetailsRenderer {
3334
2981
  * @return {Element}
3335
2982
  */
3336
2983
  _renderNumeric(details) {
3337
- const value = Util.i18n.formatNumber(details.value, details.granularity || 0.1);
2984
+ const value = Util.i18n.formatNumber(details.value, details.granularity);
3338
2985
  const element = this._dom.createElement('div', 'lh-numeric');
3339
2986
  element.textContent = value;
3340
2987
  return element;
@@ -3633,15 +3280,16 @@ class DetailsRenderer {
3633
3280
  }
3634
3281
 
3635
3282
  /**
3636
- * @param {LH.Audit.Details.List} details
3283
+ * @param {LH.FormattedIcu<LH.Audit.Details.List>} details
3637
3284
  * @return {Element}
3638
3285
  */
3639
3286
  _renderList(details) {
3640
3287
  const listContainer = this._dom.createElement('div', 'lh-list');
3641
3288
 
3642
3289
  details.items.forEach(item => {
3643
- const snippetEl = SnippetRenderer.render(this._dom, item, this);
3644
- listContainer.appendChild(snippetEl);
3290
+ const listItem = this.render(item);
3291
+ if (!listItem) return;
3292
+ listContainer.append(listItem);
3645
3293
  });
3646
3294
 
3647
3295
  return listContainer;
@@ -3785,7 +3433,9 @@ class I18n {
3785
3433
  // When testing, use a locale with more exciting numeric formatting.
3786
3434
  if (locale === 'en-XA') locale = 'de';
3787
3435
 
3788
- this._locale = locale;
3436
+ this._numberDateLocale = locale;
3437
+ this._numberFormatter = new Intl.NumberFormat(locale);
3438
+ this._percentFormatter = new Intl.NumberFormat(locale, {style: 'percent'});
3789
3439
  this._strings = strings;
3790
3440
  }
3791
3441
 
@@ -3793,58 +3443,15 @@ class I18n {
3793
3443
  return this._strings;
3794
3444
  }
3795
3445
 
3796
- /**
3797
- * @param {number} number
3798
- * @param {number|undefined} granularity
3799
- * @param {Intl.NumberFormatOptions=} opts
3800
- * @return {string}
3801
- */
3802
- _formatNumberWithGranularity(number, granularity, opts = {}) {
3803
- if (granularity !== undefined) {
3804
- const log10 = -Math.log10(granularity);
3805
- if (!Number.isInteger(log10)) {
3806
- console.warn(`granularity of ${granularity} is invalid. Using 1 instead`);
3807
- granularity = 1;
3808
- }
3809
-
3810
- if (granularity < 1) {
3811
- opts = {...opts};
3812
- opts.minimumFractionDigits = opts.maximumFractionDigits = Math.ceil(log10);
3813
- }
3814
-
3815
- number = Math.round(number / granularity) * granularity;
3816
-
3817
- // Avoid displaying a negative value that rounds to zero as "0".
3818
- if (Object.is(number, -0)) number = 0;
3819
- } else if (Math.abs(number) < 0.0005) {
3820
- // Also avoids "-0".
3821
- number = 0;
3822
- }
3823
-
3824
- return new Intl.NumberFormat(this._locale, opts).format(number).replace(' ', NBSP2);
3825
- }
3826
-
3827
3446
  /**
3828
3447
  * Format number.
3829
3448
  * @param {number} number
3830
- * @param {number=} granularity Controls how coarse the displayed value is.
3831
- * If undefined, the number will be displayed as described
3832
- * by the Intl defaults: tinyurl.com/7s67w5x7
3449
+ * @param {number=} granularity Number of decimal places to include. Defaults to 0.1.
3833
3450
  * @return {string}
3834
3451
  */
3835
- formatNumber(number, granularity) {
3836
- return this._formatNumberWithGranularity(number, granularity);
3837
- }
3838
-
3839
- /**
3840
- * Format integer.
3841
- * Just like {@link formatNumber} but uses a granularity of 1, rounding to the nearest
3842
- * whole number.
3843
- * @param {number} number
3844
- * @return {string}
3845
- */
3846
- formatInteger(number) {
3847
- return this._formatNumberWithGranularity(number, 1);
3452
+ formatNumber(number, granularity = 0.1) {
3453
+ const coarseValue = Math.round(number / granularity) * granularity;
3454
+ return this._numberFormatter.format(coarseValue);
3848
3455
  }
3849
3456
 
3850
3457
  /**
@@ -3853,99 +3460,92 @@ class I18n {
3853
3460
  * @return {string}
3854
3461
  */
3855
3462
  formatPercent(number) {
3856
- return new Intl.NumberFormat(this._locale, {style: 'percent'}).format(number);
3463
+ return this._percentFormatter.format(number);
3857
3464
  }
3858
3465
 
3859
3466
  /**
3860
3467
  * @param {number} size
3861
- * @param {number=} granularity Controls how coarse the displayed value is.
3862
- * If undefined, the number will be displayed in full.
3468
+ * @param {number=} granularity Controls how coarse the displayed value is, defaults to 0.1
3863
3469
  * @return {string}
3864
3470
  */
3865
- formatBytesToKiB(size, granularity = undefined) {
3866
- return this._formatNumberWithGranularity(size / KiB, granularity) + `${NBSP2}KiB`;
3471
+ formatBytesToKiB(size, granularity = 0.1) {
3472
+ const formatter = this._byteFormatterForGranularity(granularity);
3473
+ const kbs = formatter.format(Math.round(size / 1024 / granularity) * granularity);
3474
+ return `${kbs}${NBSP2}KiB`;
3867
3475
  }
3868
3476
 
3869
3477
  /**
3870
3478
  * @param {number} size
3871
- * @param {number=} granularity Controls how coarse the displayed value is.
3872
- * If undefined, the number will be displayed in full.
3479
+ * @param {number=} granularity Controls how coarse the displayed value is, defaults to 0.1
3873
3480
  * @return {string}
3874
3481
  */
3875
- formatBytesToMiB(size, granularity = undefined) {
3876
- return this._formatNumberWithGranularity(size / MiB, granularity) + `${NBSP2}MiB`;
3482
+ formatBytesToMiB(size, granularity = 0.1) {
3483
+ const formatter = this._byteFormatterForGranularity(granularity);
3484
+ const kbs = formatter.format(Math.round(size / (1024 ** 2) / granularity) * granularity);
3485
+ return `${kbs}${NBSP2}MiB`;
3877
3486
  }
3878
3487
 
3879
3488
  /**
3880
3489
  * @param {number} size
3881
- * @param {number=} granularity Controls how coarse the displayed value is.
3882
- * If undefined, the number will be displayed in full.
3490
+ * @param {number=} granularity Controls how coarse the displayed value is, defaults to 1
3883
3491
  * @return {string}
3884
3492
  */
3885
3493
  formatBytes(size, granularity = 1) {
3886
- return this._formatNumberWithGranularity(size, granularity, {
3887
- style: 'unit',
3888
- unit: 'byte',
3889
- unitDisplay: 'long',
3890
- });
3494
+ const formatter = this._byteFormatterForGranularity(granularity);
3495
+ const kbs = formatter.format(Math.round(size / granularity) * granularity);
3496
+ return `${kbs}${NBSP2}bytes`;
3891
3497
  }
3892
3498
 
3893
3499
  /**
3894
3500
  * @param {number} size
3895
- * @param {number=} granularity Controls how coarse the displayed value is.
3896
- * If undefined, the number will be displayed in full.
3501
+ * @param {number=} granularity Controls how coarse the displayed value is, defaults to 0.1
3897
3502
  * @return {string}
3898
3503
  */
3899
- formatBytesWithBestUnit(size, granularity = undefined) {
3504
+ formatBytesWithBestUnit(size, granularity = 0.1) {
3900
3505
  if (size >= MiB) return this.formatBytesToMiB(size, granularity);
3901
3506
  if (size >= KiB) return this.formatBytesToKiB(size, granularity);
3902
- return this._formatNumberWithGranularity(size, granularity, {
3903
- style: 'unit',
3904
- unit: 'byte',
3905
- unitDisplay: 'narrow',
3906
- });
3507
+ return this.formatNumber(size, granularity) + '\xa0B';
3907
3508
  }
3908
3509
 
3909
3510
  /**
3910
- * @param {number} size
3911
- * @param {number=} granularity Controls how coarse the displayed value is.
3912
- * If undefined, the number will be displayed in full.
3913
- * @return {string}
3511
+ * Format bytes with a constant number of fractional digits, i.e. for a granularity of 0.1, 10 becomes '10.0'
3512
+ * @param {number} granularity Controls how coarse the displayed value is
3513
+ * @return {Intl.NumberFormat}
3914
3514
  */
3915
- formatKbps(size, granularity = undefined) {
3916
- return this._formatNumberWithGranularity(size, granularity, {
3917
- style: 'unit',
3918
- unit: 'kilobit-per-second',
3919
- unitDisplay: 'short',
3515
+ _byteFormatterForGranularity(granularity) {
3516
+ // assume any granularity above 1 will not contain fractional parts, i.e. will never be 1.5
3517
+ let numberOfFractionDigits = 0;
3518
+ if (granularity < 1) {
3519
+ numberOfFractionDigits = -Math.floor(Math.log10(granularity));
3520
+ }
3521
+
3522
+ return new Intl.NumberFormat(this._numberDateLocale, {
3523
+ ...this._numberFormatter.resolvedOptions(),
3524
+ maximumFractionDigits: numberOfFractionDigits,
3525
+ minimumFractionDigits: numberOfFractionDigits,
3920
3526
  });
3921
3527
  }
3922
3528
 
3923
3529
  /**
3924
3530
  * @param {number} ms
3925
- * @param {number=} granularity Controls how coarse the displayed value is.
3926
- * If undefined, the number will be displayed in full.
3531
+ * @param {number=} granularity Controls how coarse the displayed value is, defaults to 10
3927
3532
  * @return {string}
3928
3533
  */
3929
- formatMilliseconds(ms, granularity = undefined) {
3930
- return this._formatNumberWithGranularity(ms, granularity, {
3931
- style: 'unit',
3932
- unit: 'millisecond',
3933
- unitDisplay: 'short',
3934
- });
3534
+ formatMilliseconds(ms, granularity = 10) {
3535
+ const coarseTime = Math.round(ms / granularity) * granularity;
3536
+ return coarseTime === 0
3537
+ ? `${this._numberFormatter.format(0)}${NBSP2}ms`
3538
+ : `${this._numberFormatter.format(coarseTime)}${NBSP2}ms`;
3935
3539
  }
3936
3540
 
3937
3541
  /**
3938
3542
  * @param {number} ms
3939
- * @param {number=} granularity Controls how coarse the displayed value is.
3940
- * If undefined, the number will be displayed in full.
3543
+ * @param {number=} granularity Controls how coarse the displayed value is, defaults to 0.1
3941
3544
  * @return {string}
3942
3545
  */
3943
- formatSeconds(ms, granularity = undefined) {
3944
- return this._formatNumberWithGranularity(ms / 1000, granularity, {
3945
- style: 'unit',
3946
- unit: 'second',
3947
- unitDisplay: 'short',
3948
- });
3546
+ formatSeconds(ms, granularity = 0.1) {
3547
+ const coarseTime = Math.round(ms / 1000 / granularity) * granularity;
3548
+ return `${this._numberFormatter.format(coarseTime)}${NBSP2}s`;
3949
3549
  }
3950
3550
 
3951
3551
  /**
@@ -3965,10 +3565,10 @@ class I18n {
3965
3565
  // and https://github.com/GoogleChrome/lighthouse/pull/9822
3966
3566
  let formatter;
3967
3567
  try {
3968
- formatter = new Intl.DateTimeFormat(this._locale, options);
3568
+ formatter = new Intl.DateTimeFormat(this._numberDateLocale, options);
3969
3569
  } catch (err) {
3970
3570
  options.timeZone = 'UTC';
3971
- formatter = new Intl.DateTimeFormat(this._locale, options);
3571
+ formatter = new Intl.DateTimeFormat(this._numberDateLocale, options);
3972
3572
  }
3973
3573
 
3974
3574
  return formatter.format(new Date(date));
@@ -3980,10 +3580,6 @@ class I18n {
3980
3580
  * @return {string}
3981
3581
  */
3982
3582
  formatDuration(timeInMilliseconds) {
3983
- // There is a proposal for a Intl.DurationFormat.
3984
- // https://github.com/tc39/proposal-intl-duration-format
3985
- // Until then, we do things a bit more manually.
3986
-
3987
3583
  let timeInSeconds = timeInMilliseconds / 1000;
3988
3584
  if (Math.round(timeInSeconds) === 0) {
3989
3585
  return 'None';
@@ -3992,24 +3588,19 @@ class I18n {
3992
3588
  /** @type {Array<string>} */
3993
3589
  const parts = [];
3994
3590
  /** @type {Record<string, number>} */
3995
- const unitToSecondsPer = {
3996
- day: 60 * 60 * 24,
3997
- hour: 60 * 60,
3998
- minute: 60,
3999
- second: 1,
3591
+ const unitLabels = {
3592
+ d: 60 * 60 * 24,
3593
+ h: 60 * 60,
3594
+ m: 60,
3595
+ s: 1,
4000
3596
  };
4001
3597
 
4002
- Object.keys(unitToSecondsPer).forEach(unit => {
4003
- const secondsPerUnit = unitToSecondsPer[unit];
4004
- const numberOfUnits = Math.floor(timeInSeconds / secondsPerUnit);
3598
+ Object.keys(unitLabels).forEach(label => {
3599
+ const unit = unitLabels[label];
3600
+ const numberOfUnits = Math.floor(timeInSeconds / unit);
4005
3601
  if (numberOfUnits > 0) {
4006
- timeInSeconds -= numberOfUnits * secondsPerUnit;
4007
- const part = this._formatNumberWithGranularity(numberOfUnits, 1, {
4008
- style: 'unit',
4009
- unit,
4010
- unitDisplay: 'narrow',
4011
- });
4012
- parts.push(part);
3602
+ timeInSeconds -= numberOfUnits * unit;
3603
+ parts.push(`${numberOfUnits}\xa0${label}`);
4013
3604
  }
4014
3605
  });
4015
3606
 
@@ -5061,7 +4652,7 @@ function computeWindowNameSuffix(json) {
5061
4652
  // @ts-expect-error - If this is a v2 LHR, use old `generatedTime`.
5062
4653
  const fallbackFetchTime = /** @type {string} */ (json.generatedTime);
5063
4654
  const fetchTime = json.fetchTime || fallbackFetchTime;
5064
- return `${json.lighthouseVersion}-${json.finalUrl}-${fetchTime}`;
4655
+ return `${json.lighthouseVersion}-${json.requestedUrl}-${fetchTime}`;
5065
4656
  }
5066
4657
 
5067
4658
  /**
@@ -5143,6 +4734,7 @@ function openTreemap(json) {
5143
4734
  /** @type {LH.Treemap.Options} */
5144
4735
  const treemapOptions = {
5145
4736
  lhr: {
4737
+ requestedUrl: json.requestedUrl,
5146
4738
  finalUrl: json.finalUrl,
5147
4739
  audits: {
5148
4740
  'script-treemap-data': json.audits['script-treemap-data'],