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.
- package/changelog.md +70 -0
- package/dist/report/bundle.esm.js +400 -808
- package/dist/report/flow.js +22 -27
- package/dist/report/standalone.js +18 -23
- package/flow-report/src/summary/category.tsx +1 -1
- package/jest.config.js +1 -1
- package/lighthouse-cli/.eslintrc.cjs +4 -3
- package/lighthouse-cli/bin.js +1 -0
- package/lighthouse-cli/cli-flags.js +4 -3
- package/lighthouse-cli/commands/commands.js +1 -0
- package/lighthouse-cli/commands/list-audits.js +1 -0
- package/lighthouse-cli/commands/list-locales.js +1 -0
- package/lighthouse-cli/commands/list-trace-categories.js +1 -0
- package/lighthouse-cli/index.js +1 -0
- package/lighthouse-cli/printer.js +1 -0
- package/lighthouse-cli/run.js +24 -9
- package/lighthouse-cli/sentry-prompt.js +1 -0
- package/lighthouse-cli/test/smokehouse/core-tests.js +1 -0
- package/lighthouse-cli/test/smokehouse/frontends/back-compat-util.js +1 -0
- package/lighthouse-cli/test/smokehouse/frontends/lib.js +1 -0
- package/lighthouse-cli/test/smokehouse/frontends/node.js +1 -0
- package/lighthouse-cli/test/smokehouse/frontends/smokehouse-bin.js +1 -0
- package/lighthouse-cli/test/smokehouse/lib/child-process-error.js +1 -0
- package/lighthouse-cli/test/smokehouse/lib/concurrent-mapper.js +1 -0
- package/lighthouse-cli/test/smokehouse/lib/local-console.js +1 -0
- package/lighthouse-cli/test/smokehouse/lighthouse-runners/bundle.js +23 -109
- package/lighthouse-cli/test/smokehouse/lighthouse-runners/cli.js +3 -2
- package/lighthouse-cli/test/smokehouse/lighthouse-runners/devtools.js +19 -28
- package/lighthouse-cli/test/smokehouse/report-assert.js +4 -3
- package/lighthouse-cli/test/smokehouse/smokehouse.js +1 -1
- package/lighthouse-cli/test/smokehouse/version-check-test.js +3 -0
- package/lighthouse-cli/test/smokehouse/version-check.js +1 -0
- package/lighthouse-core/audits/accessibility/accesskeys.js +1 -1
- package/lighthouse-core/audits/accessibility/aria-allowed-attr.js +1 -1
- package/lighthouse-core/audits/accessibility/aria-command-name.js +1 -1
- package/lighthouse-core/audits/accessibility/aria-hidden-body.js +1 -1
- package/lighthouse-core/audits/accessibility/aria-hidden-focus.js +1 -1
- package/lighthouse-core/audits/accessibility/aria-input-field-name.js +1 -1
- package/lighthouse-core/audits/accessibility/aria-meter-name.js +1 -1
- package/lighthouse-core/audits/accessibility/aria-progressbar-name.js +1 -1
- package/lighthouse-core/audits/accessibility/aria-required-attr.js +1 -1
- package/lighthouse-core/audits/accessibility/aria-required-children.js +1 -1
- package/lighthouse-core/audits/accessibility/aria-required-parent.js +1 -1
- package/lighthouse-core/audits/accessibility/aria-roles.js +1 -1
- package/lighthouse-core/audits/accessibility/aria-toggle-field-name.js +1 -1
- package/lighthouse-core/audits/accessibility/aria-tooltip-name.js +1 -1
- package/lighthouse-core/audits/accessibility/aria-treeitem-name.js +1 -1
- package/lighthouse-core/audits/accessibility/aria-valid-attr-value.js +1 -1
- package/lighthouse-core/audits/accessibility/aria-valid-attr.js +1 -1
- package/lighthouse-core/audits/accessibility/button-name.js +1 -1
- package/lighthouse-core/audits/accessibility/bypass.js +1 -1
- package/lighthouse-core/audits/accessibility/color-contrast.js +1 -1
- package/lighthouse-core/audits/accessibility/definition-list.js +1 -1
- package/lighthouse-core/audits/accessibility/dlitem.js +1 -1
- package/lighthouse-core/audits/accessibility/document-title.js +1 -1
- package/lighthouse-core/audits/accessibility/duplicate-id-active.js +1 -1
- package/lighthouse-core/audits/accessibility/duplicate-id-aria.js +1 -1
- package/lighthouse-core/audits/accessibility/form-field-multiple-labels.js +1 -1
- package/lighthouse-core/audits/accessibility/frame-title.js +1 -1
- package/lighthouse-core/audits/accessibility/heading-order.js +1 -1
- package/lighthouse-core/audits/accessibility/html-has-lang.js +1 -1
- package/lighthouse-core/audits/accessibility/html-lang-valid.js +1 -1
- package/lighthouse-core/audits/accessibility/image-alt.js +1 -1
- package/lighthouse-core/audits/accessibility/input-image-alt.js +1 -1
- package/lighthouse-core/audits/accessibility/label.js +1 -1
- package/lighthouse-core/audits/accessibility/link-name.js +1 -1
- package/lighthouse-core/audits/accessibility/list.js +1 -1
- package/lighthouse-core/audits/accessibility/listitem.js +5 -5
- package/lighthouse-core/audits/accessibility/meta-refresh.js +1 -1
- package/lighthouse-core/audits/accessibility/meta-viewport.js +1 -1
- package/lighthouse-core/audits/accessibility/object-alt.js +1 -1
- package/lighthouse-core/audits/accessibility/tabindex.js +1 -1
- package/lighthouse-core/audits/accessibility/td-headers-attr.js +1 -1
- package/lighthouse-core/audits/accessibility/th-has-data-cells.js +1 -1
- package/lighthouse-core/audits/accessibility/valid-lang.js +1 -1
- package/lighthouse-core/audits/accessibility/video-caption.js +1 -1
- package/lighthouse-core/audits/byte-efficiency/byte-efficiency-audit.js +1 -2
- package/lighthouse-core/audits/byte-efficiency/duplicated-javascript.js +12 -11
- package/lighthouse-core/audits/byte-efficiency/efficient-animated-content.js +1 -1
- package/lighthouse-core/audits/byte-efficiency/legacy-javascript.js +24 -22
- package/lighthouse-core/audits/byte-efficiency/offscreen-images.js +2 -3
- package/lighthouse-core/audits/byte-efficiency/render-blocking-resources.js +3 -2
- package/lighthouse-core/audits/byte-efficiency/unminified-css.js +5 -3
- package/lighthouse-core/audits/byte-efficiency/unminified-javascript.js +11 -10
- package/lighthouse-core/audits/byte-efficiency/unused-css-rules.js +1 -0
- package/lighthouse-core/audits/byte-efficiency/unused-javascript.js +8 -11
- package/lighthouse-core/audits/byte-efficiency/uses-responsive-images.js +1 -1
- package/lighthouse-core/audits/byte-efficiency/uses-text-compression.js +1 -1
- package/lighthouse-core/audits/deprecations.js +598 -8
- package/lighthouse-core/audits/diagnostics.js +3 -4
- package/lighthouse-core/audits/dobetterweb/doctype.js +9 -20
- package/lighthouse-core/audits/dobetterweb/geolocation-on-start.js +1 -1
- package/lighthouse-core/audits/dobetterweb/no-document-write.js +1 -1
- package/lighthouse-core/audits/dobetterweb/notification-on-start.js +1 -1
- package/lighthouse-core/audits/dobetterweb/uses-http2.js +1 -2
- package/lighthouse-core/audits/dobetterweb/uses-passive-event-listeners.js +1 -1
- package/lighthouse-core/audits/errors-in-console.js +2 -2
- package/lighthouse-core/audits/long-tasks.js +2 -3
- package/lighthouse-core/audits/metrics/experimental-interaction-to-next-paint.js +3 -1
- package/lighthouse-core/audits/metrics/first-contentful-paint-3g.js +2 -2
- package/lighthouse-core/audits/metrics/first-contentful-paint.js +2 -3
- package/lighthouse-core/audits/metrics/first-meaningful-paint.js +2 -3
- package/lighthouse-core/audits/metrics/interactive.js +2 -3
- package/lighthouse-core/audits/metrics/largest-contentful-paint.js +2 -3
- package/lighthouse-core/audits/metrics/max-potential-fid.js +2 -3
- package/lighthouse-core/audits/metrics/speed-index.js +2 -3
- package/lighthouse-core/audits/metrics/total-blocking-time.js +2 -3
- package/lighthouse-core/audits/metrics.js +2 -3
- package/lighthouse-core/audits/no-unload-listeners.js +15 -7
- package/lighthouse-core/audits/predictive-perf.js +1 -2
- package/lighthouse-core/audits/preload-lcp-image.js +3 -3
- package/lighthouse-core/audits/redirects.js +1 -1
- package/lighthouse-core/audits/script-treemap-data.js +45 -45
- package/lighthouse-core/audits/seo/http-status-code.js +4 -2
- package/lighthouse-core/audits/seo/link-text.js +0 -2
- package/lighthouse-core/audits/server-response-time.js +17 -2
- package/lighthouse-core/audits/service-worker.js +2 -7
- package/lighthouse-core/audits/timing-budget.js +2 -3
- package/lighthouse-core/audits/uses-rel-preconnect.js +1 -1
- package/lighthouse-core/audits/uses-rel-preload.js +1 -1
- package/lighthouse-core/audits/valid-source-maps.js +14 -12
- package/lighthouse-core/audits/violation-audit.js +1 -1
- package/lighthouse-core/audits/work-during-interaction.js +280 -0
- package/lighthouse-core/computed/critical-request-chains.js +9 -5
- package/lighthouse-core/computed/js-bundles.js +11 -11
- package/lighthouse-core/computed/main-resource.js +2 -3
- package/lighthouse-core/computed/metrics/first-contentful-paint-all-frames.js +1 -1
- package/lighthouse-core/computed/metrics/first-contentful-paint.js +1 -1
- package/lighthouse-core/computed/metrics/first-meaningful-paint.js +1 -1
- package/lighthouse-core/computed/metrics/interactive.js +1 -1
- package/lighthouse-core/computed/metrics/lantern-first-contentful-paint.js +1 -1
- package/lighthouse-core/computed/metrics/lantern-first-meaningful-paint.js +1 -1
- package/lighthouse-core/computed/metrics/lantern-interactive.js +1 -1
- package/lighthouse-core/computed/metrics/lantern-largest-contentful-paint.js +1 -1
- package/lighthouse-core/computed/metrics/lantern-max-potential-fid.js +1 -1
- package/lighthouse-core/computed/metrics/lantern-metric.js +5 -3
- package/lighthouse-core/computed/metrics/lantern-speed-index.js +1 -1
- package/lighthouse-core/computed/metrics/lantern-total-blocking-time.js +1 -1
- package/lighthouse-core/computed/metrics/largest-contentful-paint-all-frames.js +1 -1
- package/lighthouse-core/computed/metrics/largest-contentful-paint.js +1 -1
- package/lighthouse-core/computed/metrics/max-potential-fid.js +1 -1
- package/lighthouse-core/computed/metrics/metric.js +0 -1
- package/lighthouse-core/computed/metrics/responsiveness.js +12 -9
- package/lighthouse-core/computed/metrics/speed-index.js +1 -1
- package/lighthouse-core/computed/metrics/timing-summary.js +6 -13
- package/lighthouse-core/computed/metrics/total-blocking-time.js +1 -1
- package/lighthouse-core/computed/module-duplication.js +5 -6
- package/lighthouse-core/computed/page-dependency-graph.js +28 -55
- package/lighthouse-core/computed/resource-summary.js +5 -5
- package/lighthouse-core/computed/unused-css.js +7 -6
- package/lighthouse-core/computed/unused-javascript-summary.js +36 -16
- package/lighthouse-core/config/budget.js +2 -2
- package/lighthouse-core/config/default-config.js +1 -2
- package/lighthouse-core/config/metrics-to-audits.js +5 -0
- package/lighthouse-core/fraggle-rock/api.js +1 -1
- package/lighthouse-core/fraggle-rock/config/default-config.js +8 -5
- package/lighthouse-core/fraggle-rock/gather/base-artifacts.js +3 -6
- package/lighthouse-core/fraggle-rock/gather/driver.js +2 -2
- package/lighthouse-core/fraggle-rock/gather/navigation-runner.js +26 -51
- package/lighthouse-core/fraggle-rock/gather/runner-helpers.js +3 -0
- package/lighthouse-core/fraggle-rock/gather/session.js +2 -2
- package/lighthouse-core/fraggle-rock/gather/snapshot-runner.js +4 -5
- package/lighthouse-core/fraggle-rock/gather/timespan-runner.js +6 -6
- package/lighthouse-core/gather/connections/cri.js +0 -1
- package/lighthouse-core/gather/driver/execution-context.js +2 -4
- package/lighthouse-core/gather/driver/navigation.js +9 -9
- package/lighthouse-core/gather/driver/network-monitor.js +3 -16
- package/lighthouse-core/gather/driver.js +1 -6
- package/lighthouse-core/gather/fetcher.js +210 -34
- package/lighthouse-core/gather/gather-runner.js +17 -13
- package/lighthouse-core/gather/gatherers/accessibility.js +4 -16
- package/lighthouse-core/gather/gatherers/console-messages.js +2 -4
- package/lighthouse-core/gather/gatherers/dobetterweb/doctype.js +2 -4
- package/lighthouse-core/gather/gatherers/full-page-screenshot.js +2 -3
- package/lighthouse-core/gather/gatherers/js-usage.js +87 -12
- package/lighthouse-core/gather/gatherers/link-elements.js +14 -12
- package/lighthouse-core/gather/gatherers/main-document-content.js +8 -8
- package/lighthouse-core/gather/gatherers/script-elements.js +56 -7
- package/lighthouse-core/gather/gatherers/seo/robots-txt.js +30 -2
- package/lighthouse-core/gather/gatherers/source-maps.js +1 -3
- package/lighthouse-core/gather/gatherers/trace-elements.js +21 -2
- package/lighthouse-core/gather/gatherers/web-app-manifest.js +2 -2
- package/lighthouse-core/index.js +2 -26
- package/lighthouse-core/lib/cdt/generated/SourceMap.js +1 -1
- package/lighthouse-core/lib/dependency-graph/simulator/network-analyzer.js +29 -8
- package/lighthouse-core/lib/navigation-error.js +4 -13
- package/lighthouse-core/lib/script-helpers.js +6 -11
- package/lighthouse-core/lib/url-shim.js +2 -2
- package/lighthouse-core/runner.js +5 -0
- package/lighthouse-core/scripts/manual-chrome-launcher.js +1 -0
- package/lighthouse-core/util-commonjs.js +24 -28
- package/package.json +12 -12
- package/readme.md +1 -1
- package/report/.eslintrc.cjs +1 -3
- package/report/assets/styles.css +10 -12
- package/report/assets/templates.html +9 -10
- package/report/clients/bundle.js +1 -0
- package/report/clients/standalone.js +1 -0
- package/report/generator/report-generator.js +21 -46
- package/report/renderer/api.js +1 -0
- package/report/renderer/category-renderer.js +1 -0
- package/report/renderer/components.js +304 -303
- package/report/renderer/crc-details-renderer.js +1 -0
- package/report/renderer/details-renderer.js +10 -10
- package/report/renderer/dom.js +1 -0
- package/report/renderer/drop-down-menu.js +1 -0
- package/report/renderer/element-screenshot-renderer.js +4 -0
- package/report/renderer/features-util.js +1 -0
- package/report/renderer/i18n.js +62 -118
- package/report/renderer/logger.js +1 -0
- package/report/renderer/open-tab.js +3 -1
- package/report/renderer/performance-category-renderer.js +1 -0
- package/report/renderer/pwa-category-renderer.js +1 -0
- package/report/renderer/report-renderer.js +1 -0
- package/report/renderer/report-ui-features.js +1 -0
- package/report/renderer/snippet-renderer.js +1 -0
- package/report/renderer/swap-locale-feature.js +1 -0
- package/report/renderer/text-encoding.js +1 -0
- package/report/renderer/topbar-features.js +1 -0
- package/report/renderer/util.js +24 -27
- package/report/test/clients/bundle-test.js +4 -0
- package/report/test/generator/file-namer-test.js +1 -0
- package/report/test/generator/report-generator-test.js +20 -25
- package/report/test/renderer/category-renderer-test.js +3 -0
- package/report/test/renderer/components-test.js +3 -0
- package/report/test/renderer/crc-details-renderer-test.js +3 -0
- package/report/test/renderer/details-renderer-test.js +12 -58
- package/report/test/renderer/dom-test.js +3 -0
- package/report/test/renderer/element-screenshot-renderer-test.js +6 -3
- package/report/test/renderer/i18n-test.js +25 -70
- package/report/test/renderer/performance-category-renderer-test.js +4 -11
- package/report/test/renderer/pwa-category-renderer-test.js +3 -0
- package/report/test/renderer/report-renderer-axe-test.js +3 -0
- package/report/test/renderer/report-renderer-test.js +3 -0
- package/report/test/renderer/report-ui-features-test.js +3 -0
- package/report/test/renderer/snippet-renderer-test.js +3 -0
- package/report/test/renderer/text-encoding-test.js +3 -0
- package/report/test/renderer/util-test.js +5 -2
- package/report/test-assets/faux-psi.js +1 -2
- package/shared/localization/locales/en-US.json +260 -53
- package/shared/localization/locales/en-XL.json +260 -53
- package/shared/test/localization/format-test.js +2 -0
- package/shared/test/localization/locales-test.js +2 -0
- package/shared/test/localization/swap-locale-test.js +2 -0
- package/third-party/chromium-synchronization/inspector-issueAdded-types-test.js +2 -0
- package/third-party/chromium-synchronization/installability-errors-test.js +2 -0
- package/tsconfig.json +0 -1
- package/types/artifacts.d.ts +9 -48
- package/types/config.d.ts +0 -2
- package/types/externs.d.ts +2 -2
- package/types/gatherer.d.ts +2 -1
- package/types/global-lh.d.ts +0 -3
- package/types/lhr/audit-details.d.ts +3 -1
- package/types/lhr/lhr.d.ts +2 -2
- package/types/lhr/treemap.d.ts +1 -0
- package/lighthouse-core/audits/script-elements-test-audit.js +0 -30
- package/lighthouse-core/gather/gatherers/scripts.js +0 -154
- package/report/test/.eslintrc.cjs +0 -11
- 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
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
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.
|
|
435
|
-
`${Util.i18n.
|
|
436
|
-
`${Util.i18n.
|
|
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.
|
|
451
|
-
`${Util.i18n.
|
|
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
|
|
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(
|
|
716
|
-
el1.append(
|
|
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(
|
|
719
|
-
const el3 = dom.createElement(
|
|
720
|
-
const el4 = dom.createElement(
|
|
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(
|
|
724
|
-
el5.append(
|
|
725
|
-
const el6 = dom.createElement(
|
|
726
|
-
el3.append(
|
|
727
|
-
el2.append(
|
|
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(
|
|
738
|
-
const el2 = dom.createElement(
|
|
739
|
-
const el3 = dom.createElement(
|
|
740
|
-
const el4 = dom.createElement(
|
|
741
|
-
const el5 = dom.createElement(
|
|
742
|
-
const el6 = dom.createElement(
|
|
743
|
-
const el7 = dom.createElement(
|
|
744
|
-
const el8 = dom.createElement(
|
|
745
|
-
el6.append(
|
|
746
|
-
const el9 = dom.createElement(
|
|
747
|
-
el4.append(
|
|
748
|
-
el3.append(
|
|
749
|
-
const el10 = dom.createElement(
|
|
750
|
-
const el11 = dom.createElement(
|
|
751
|
-
el2.append(
|
|
752
|
-
el1.append(
|
|
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(
|
|
763
|
-
const el2 = dom.createElement(
|
|
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(
|
|
767
|
-
el1.append(
|
|
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(
|
|
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(
|
|
780
|
-
const el3 = dom.createElementNS(
|
|
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(
|
|
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(
|
|
785
|
-
el1.append(
|
|
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(
|
|
796
|
-
const el2 = dom.createElement(
|
|
797
|
-
const el3 = dom.createElement(
|
|
798
|
-
const el4 = dom.createElement(
|
|
799
|
-
const el5 = dom.createElement(
|
|
800
|
-
const el6 = dom.createElement(
|
|
801
|
-
const el7 = dom.createElement(
|
|
802
|
-
el5.append(
|
|
803
|
-
const el8 = dom.createElement(
|
|
804
|
-
const el9 = dom.createElement(
|
|
805
|
-
const el10 = dom.createElement(
|
|
806
|
-
el8.append(
|
|
807
|
-
el4.append(
|
|
808
|
-
el3.append(
|
|
809
|
-
el2.append(
|
|
810
|
-
el1.append(
|
|
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(
|
|
821
|
-
const el2 = dom.createElement(
|
|
822
|
-
el2.append(
|
|
823
|
-
const el3 = dom.createElement(
|
|
824
|
-
const el4 = dom.createElement(
|
|
825
|
-
const el5 = dom.createElement(
|
|
826
|
-
const el6 = dom.createElement(
|
|
827
|
-
el4.append(
|
|
828
|
-
el3.append(
|
|
829
|
-
const el7 = dom.createElement(
|
|
830
|
-
const el8 = dom.createElement(
|
|
831
|
-
el7.append(
|
|
832
|
-
el1.append(
|
|
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(
|
|
843
|
-
const el2 = dom.createElement(
|
|
844
|
-
const el3 = dom.createElement(
|
|
845
|
-
el1.append(
|
|
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(
|
|
856
|
-
const el2 = dom.createElement(
|
|
857
|
-
const el3 = dom.createElement(
|
|
858
|
-
const el4 = dom.
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
el5.
|
|
862
|
-
const el6 = dom.createElementNS(
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
const el8 = dom.createElement(
|
|
869
|
-
|
|
870
|
-
|
|
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(
|
|
882
|
-
el1.append(
|
|
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(
|
|
885
|
-
const el3 = dom.createElement(
|
|
886
|
-
el3.append(
|
|
887
|
-
const el4 = dom.createElement(
|
|
888
|
-
const el5 = dom.createElement(
|
|
889
|
-
el5.append(
|
|
890
|
-
const el6 = dom.createElement(
|
|
891
|
-
const el7 = dom.createElement(
|
|
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(
|
|
896
|
-
el4.append(
|
|
897
|
-
el2.append(
|
|
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(
|
|
908
|
-
const el2 = dom.createElement(
|
|
909
|
-
const el3 = dom.createElement(
|
|
910
|
-
const el4 = dom.createElement(
|
|
911
|
-
el3.append(
|
|
912
|
-
el2.append(
|
|
913
|
-
const el5 = dom.createElement(
|
|
914
|
-
el1.append(
|
|
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(
|
|
925
|
-
const el2 = dom.createElement(
|
|
926
|
-
const el3 = dom.createElementNS(
|
|
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(
|
|
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(
|
|
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(
|
|
939
|
-
el2.append(
|
|
940
|
-
const el6 = dom.createElement(
|
|
941
|
-
const el7 = dom.createElement(
|
|
942
|
-
el1.append(
|
|
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(
|
|
953
|
-
el1.append(
|
|
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(
|
|
956
|
-
const el3 = dom.createElementNS(
|
|
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(
|
|
959
|
-
const el5 = dom.createElementNS(
|
|
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(
|
|
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(
|
|
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(
|
|
972
|
-
const el8 = dom.createElementNS(
|
|
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(
|
|
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(
|
|
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(
|
|
985
|
-
const el11 = dom.createElementNS(
|
|
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(
|
|
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(
|
|
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(
|
|
996
|
-
el4.append(
|
|
997
|
-
const el14 = dom.createElementNS(
|
|
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(
|
|
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(
|
|
1005
|
-
const el17 = dom.createElementNS(
|
|
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(
|
|
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(
|
|
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(
|
|
1013
|
-
const el20 = dom.createElementNS(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
1028
|
-
const el24 = dom.createElementNS(
|
|
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(
|
|
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(
|
|
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(
|
|
1039
|
-
el14.append(
|
|
1040
|
-
el3.append(
|
|
1041
|
-
const el27 = dom.createElement(
|
|
1042
|
-
el2.append(
|
|
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(
|
|
1053
|
-
el1.append(
|
|
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(
|
|
1056
|
-
const el3 = dom.createElement(
|
|
1057
|
-
el2.append(
|
|
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(
|
|
1068
|
-
const el2 = dom.createElement(
|
|
1069
|
-
const el3 = dom.createElement(
|
|
1070
|
-
const el4 = dom.createElement(
|
|
1071
|
-
const el5 = dom.createElement(
|
|
1072
|
-
const el6 = dom.createElement(
|
|
1073
|
-
el2.append(
|
|
1074
|
-
el1.append(
|
|
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(
|
|
1085
|
-
const el2 = dom.createElement(
|
|
1086
|
-
const el3 = dom.createElement(
|
|
1087
|
-
const el4 = dom.createElement(
|
|
1088
|
-
const el5 = dom.createElement(
|
|
1089
|
-
const el6 = dom.createElement(
|
|
1090
|
-
const el7 = dom.createElement(
|
|
1091
|
-
const el8 = dom.createElement(
|
|
1092
|
-
el6.append(
|
|
1093
|
-
const el9 = dom.createElement(
|
|
1094
|
-
const el10 = dom.createElement(
|
|
1095
|
-
const el11 = dom.createElement(
|
|
1096
|
-
const el12 = dom.createElement(
|
|
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(
|
|
1099
|
-
const el13 = dom.createElement(
|
|
1100
|
-
const el14 = dom.createElement(
|
|
1101
|
-
el9.append(
|
|
1102
|
-
el5.append(
|
|
1103
|
-
el4.append(
|
|
1104
|
-
el3.append(
|
|
1105
|
-
const el15 = dom.createElement(
|
|
1106
|
-
const el16 = dom.createElement(
|
|
1107
|
-
el2.append(
|
|
1108
|
-
el1.append(
|
|
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(
|
|
1119
|
-
const el2 = dom.createElement(
|
|
1120
|
-
const el3 = dom.createElement(
|
|
1121
|
-
el1.append(
|
|
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(
|
|
1132
|
-
const el2 = dom.createElement(
|
|
1133
|
-
el2.append(
|
|
1134
|
-
const el3 = dom.createElement(
|
|
1135
|
-
el3.append(
|
|
1136
|
-
const el4 = dom.createElement(
|
|
1137
|
-
el4.append(
|
|
1138
|
-
el1.append(
|
|
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(
|
|
1149
|
-
el1.append(
|
|
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(
|
|
1152
|
-
const el3 = dom.createElement(
|
|
1153
|
-
const el4 = dom.createElement(
|
|
1154
|
-
const el5 = dom.createElement(
|
|
1155
|
-
const el6 = dom.createElement(
|
|
1156
|
-
el4.append(
|
|
1157
|
-
el3.append(
|
|
1158
|
-
el2.append(
|
|
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(
|
|
1169
|
-
const el2 = dom.createElement(
|
|
1170
|
-
el2.append(
|
|
1171
|
-
el1.append(
|
|
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(
|
|
1182
|
-
const el2 = dom.createElement(
|
|
1183
|
-
el1.append(
|
|
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(
|
|
1194
|
-
const el2 = dom.createElement(
|
|
1195
|
-
const el3 = dom.createElement(
|
|
1196
|
-
const el4 = dom.createElement(
|
|
1197
|
-
const el5 = dom.createElement(
|
|
1198
|
-
const el6 = dom.createElement(
|
|
1199
|
-
el4.append(
|
|
1200
|
-
el1.append(
|
|
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(
|
|
1211
|
-
const el2 = dom.createElement(
|
|
1212
|
-
const el3 = dom.createElement(
|
|
1213
|
-
const el4 = dom.createElement(
|
|
1214
|
-
el1.append(
|
|
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(
|
|
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(
|
|
1236
|
-
el1.append(
|
|
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(
|
|
1239
|
-
const el3 = dom.createElementNS(
|
|
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(
|
|
1242
|
-
const el5 = dom.createElementNS(
|
|
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(
|
|
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(
|
|
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(
|
|
1257
|
-
const el8 = dom.createElementNS(
|
|
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(
|
|
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(
|
|
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(
|
|
1272
|
-
const el11 = dom.createElementNS(
|
|
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(
|
|
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(
|
|
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(
|
|
1287
|
-
const el14 = dom.createElementNS(
|
|
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(
|
|
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(
|
|
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(
|
|
1302
|
-
el4.append(
|
|
1303
|
-
const el17 = dom.createElementNS(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
1337
|
-
el3.append(
|
|
1338
|
-
const el25 = dom.createElement(
|
|
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(
|
|
1343
|
-
const el27 = dom.createElement(
|
|
1344
|
-
const el28 = dom.createElement(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
1363
|
-
const el32 = dom.createElement(
|
|
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(
|
|
1370
|
-
const el33 = dom.createElement(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
1387
|
-
el33.append(
|
|
1388
|
-
const el37 = dom.createElement(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
1441
|
-
el26.append(
|
|
1442
|
-
el2.append(
|
|
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(
|
|
1453
|
-
const el2 = dom.createElement(
|
|
1454
|
-
const el3 = dom.createElement(
|
|
1455
|
-
el1.append(
|
|
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 '
|
|
3243
|
-
|
|
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
|
|
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
|
|
3644
|
-
|
|
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.
|
|
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
|
|
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
|
-
|
|
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
|
|
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 =
|
|
3866
|
-
|
|
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 =
|
|
3876
|
-
|
|
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
|
-
|
|
3887
|
-
|
|
3888
|
-
|
|
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 =
|
|
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.
|
|
3903
|
-
style: 'unit',
|
|
3904
|
-
unit: 'byte',
|
|
3905
|
-
unitDisplay: 'narrow',
|
|
3906
|
-
});
|
|
3507
|
+
return this.formatNumber(size, granularity) + '\xa0B';
|
|
3907
3508
|
}
|
|
3908
3509
|
|
|
3909
3510
|
/**
|
|
3910
|
-
*
|
|
3911
|
-
* @param {number
|
|
3912
|
-
*
|
|
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
|
-
|
|
3916
|
-
|
|
3917
|
-
|
|
3918
|
-
|
|
3919
|
-
|
|
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 =
|
|
3930
|
-
|
|
3931
|
-
|
|
3932
|
-
|
|
3933
|
-
|
|
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 =
|
|
3944
|
-
|
|
3945
|
-
|
|
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.
|
|
3568
|
+
formatter = new Intl.DateTimeFormat(this._numberDateLocale, options);
|
|
3969
3569
|
} catch (err) {
|
|
3970
3570
|
options.timeZone = 'UTC';
|
|
3971
|
-
formatter = new Intl.DateTimeFormat(this.
|
|
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
|
|
3996
|
-
|
|
3997
|
-
|
|
3998
|
-
|
|
3999
|
-
|
|
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(
|
|
4003
|
-
const
|
|
4004
|
-
const numberOfUnits = Math.floor(timeInSeconds /
|
|
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 *
|
|
4007
|
-
|
|
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.
|
|
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'],
|