chrome-devtools-frontend 1.0.1012379 → 1.0.1013298

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (35) hide show
  1. package/config/gni/devtools_grd_files.gni +3 -0
  2. package/front_end/core/host/UserMetrics.ts +4 -2
  3. package/front_end/core/i18n/locales/en-US.json +38 -2
  4. package/front_end/core/i18n/locales/en-XL.json +38 -2
  5. package/front_end/core/root/Runtime.ts +1 -0
  6. package/front_end/core/sdk/CSSFontFace.ts +6 -0
  7. package/front_end/entrypoints/main/MainImpl.ts +4 -0
  8. package/front_end/generated/InspectorBackendCommands.js +2 -0
  9. package/front_end/generated/protocol.ts +16 -0
  10. package/front_end/panels/application/AppManifestView.ts +12 -1
  11. package/front_end/panels/application/DOMStorageItemsView.ts +5 -5
  12. package/front_end/panels/application/components/ProtocolHandlersView.ts +182 -0
  13. package/front_end/panels/application/components/components.ts +2 -0
  14. package/front_end/panels/application/components/protocolHandlersView.css +39 -0
  15. package/front_end/panels/profiler/HeapSnapshotView.ts +3 -1
  16. package/front_end/panels/sources/NavigatorView.ts +50 -22
  17. package/front_end/panels/sources/SourcesNavigator.ts +45 -1
  18. package/front_end/panels/sources/SourcesPanel.ts +26 -4
  19. package/front_end/panels/sources/navigatorTree.css +4 -0
  20. package/front_end/panels/sources/sourcesNavigator.css +10 -0
  21. package/front_end/third_party/lighthouse/lighthouse-dt-bundle.js +15 -15
  22. package/front_end/third_party/lighthouse/report/bundle.d.ts +23 -2
  23. package/front_end/third_party/lighthouse/report/bundle.js +45 -19
  24. package/front_end/third_party/lighthouse/report-assets/report-generator.mjs +1 -1
  25. package/front_end/ui/components/linear_memory_inspector/LinearMemoryViewer.ts +16 -11
  26. package/front_end/ui/components/linear_memory_inspector/linearMemoryInspector.css +4 -0
  27. package/front_end/ui/components/panel_feedback/PreviewToggle.ts +35 -14
  28. package/front_end/ui/components/panel_feedback/previewToggle.css +21 -1
  29. package/front_end/ui/legacy/ContextMenu.ts +11 -2
  30. package/package.json +1 -1
  31. package/scripts/build/ninja/devtools_entrypoint.gni +3 -3
  32. package/scripts/build/ninja/wasm.gni +25 -0
  33. package/scripts/build/wasm-as.py +87 -0
  34. package/scripts/build/wasm_sourcemap.mjs +22 -0
  35. package/scripts/eslint_rules/lib/lit_template_result_or_nothing.js +6 -0
@@ -0,0 +1,39 @@
1
+ /*
2
+ * Copyright (c) 2022 The Chromium Authors. All rights reserved.
3
+ * Use of this source code is governed by a BSD-style license that can be
4
+ * found in the LICENSE file.
5
+ */
6
+
7
+ .devtools-link {
8
+ color: var(--color-link);
9
+ text-decoration: underline;
10
+ cursor: pointer;
11
+ padding: 2px 0; /* adjust focus ring size */
12
+ }
13
+
14
+ input.devtools-text-input[type="text"] {
15
+ padding: 3px 6px;
16
+ margin-left: 4px;
17
+ margin-right: 4px;
18
+ width: 250px;
19
+ height: 25px;
20
+ }
21
+
22
+ .protocol-handlers-row {
23
+ margin: 10px 0 2px 18px;
24
+ }
25
+
26
+ .inline-icon {
27
+ vertical-align: text-bottom;
28
+ }
29
+
30
+ @media (forced-colors: active) {
31
+ .devtools-link:not(.devtools-link-prevent-click) {
32
+ color: linktext;
33
+ }
34
+
35
+ .devtools-link:focus-visible {
36
+ background: Highlight;
37
+ color: HighlightText;
38
+ }
39
+ }
@@ -181,7 +181,9 @@ const UIStrings = {
181
181
  heapSnapshotProfilesShowMemory:
182
182
  'Heap snapshot profiles show memory distribution among your page\'s JavaScript objects and related DOM nodes.',
183
183
  /**
184
- *@description Text in Heap Snapshot View of a profiler tool
184
+ *@description Label for a checkbox in the heap snapshot view of the profiler tool. The "heap snapshot" contains the
185
+ * current state of JavaScript memory. With this checkbox enabled, the snapshot also includes internal data that is
186
+ * specific to Chrome (hence implementation-specific).
185
187
  */
186
188
  exposeInternals: 'Expose internals (includes additional implementation-specific details)',
187
189
  /**
@@ -32,6 +32,7 @@ import * as Common from '../../core/common/common.js';
32
32
  import * as Host from '../../core/host/host.js';
33
33
  import * as i18n from '../../core/i18n/i18n.js';
34
34
  import * as Platform from '../../core/platform/platform.js';
35
+ import * as Root from '../../core/root/root.js';
35
36
  import * as SDK from '../../core/sdk/sdk.js';
36
37
  import * as Bindings from '../../models/bindings/bindings.js';
37
38
  import * as Persistence from '../../models/persistence/persistence.js';
@@ -64,10 +65,18 @@ const UIStrings = {
64
65
  /**
65
66
  *@description Text in Navigator View of the Sources panel
66
67
  */
68
+ authoredTooltip: 'Contains original sources',
69
+ /**
70
+ *@description Text in Navigator View of the Sources panel
71
+ */
67
72
  deployed: 'Deployed',
68
73
  /**
69
74
  *@description Text in Navigator View of the Sources panel
70
75
  */
76
+ deployedTooltip: 'Contains final sources the browser sees',
77
+ /**
78
+ *@description Text in Navigator View of the Sources panel
79
+ */
71
80
  areYouSureYouWantToExcludeThis: 'Are you sure you want to exclude this folder?',
72
81
  /**
73
82
  *@description Text in Navigator View of the Sources panel
@@ -162,7 +171,7 @@ export class NavigatorView extends UI.Widget.VBox implements SDK.TargetManager.O
162
171
  // TODO(crbug.com/1172300) Ignored during the jsdoc to ts migration)
163
172
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
164
173
  private navigatorGroupByFolderSetting: Common.Settings.Setting<any>;
165
- private navigatorGroupByAuthoredSetting: Common.Settings.Setting<boolean>;
174
+ private navigatorGroupByAuthoredExperiment?: string;
166
175
  private workspaceInternal!: Workspace.Workspace.WorkspaceImpl;
167
176
  private lastSelectedUISourceCode?: Workspace.UISourceCode.UISourceCode;
168
177
  private groupByFrame?: boolean;
@@ -173,7 +182,7 @@ export class NavigatorView extends UI.Widget.VBox implements SDK.TargetManager.O
173
182
  // TODO(crbug.com/1172300) Ignored during the jsdoc to ts migration)
174
183
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
175
184
  private groupByFolder?: any;
176
- constructor() {
185
+ constructor(enableAuthoredGrouping?: boolean) {
177
186
  super(true);
178
187
 
179
188
  this.placeholder = null;
@@ -198,9 +207,9 @@ export class NavigatorView extends UI.Widget.VBox implements SDK.TargetManager.O
198
207
 
199
208
  this.navigatorGroupByFolderSetting = Common.Settings.Settings.instance().moduleSetting('navigatorGroupByFolder');
200
209
  this.navigatorGroupByFolderSetting.addChangeListener(this.groupingChanged.bind(this));
201
- this.navigatorGroupByAuthoredSetting =
202
- Common.Settings.Settings.instance().moduleSetting('navigatorGroupByAuthored');
203
- this.navigatorGroupByAuthoredSetting.addChangeListener(this.groupingChanged.bind(this));
210
+ if (enableAuthoredGrouping) {
211
+ this.navigatorGroupByAuthoredExperiment = Root.Runtime.ExperimentName.AUTHORED_DEPLOYED_GROUPING;
212
+ }
204
213
 
205
214
  this.initGrouping();
206
215
 
@@ -686,8 +695,9 @@ export class NavigatorView extends UI.Widget.VBox implements SDK.TargetManager.O
686
695
  NavigatorTreeNode {
687
696
  if (this.groupByAuthored && isAuthored) {
688
697
  if (!this.authoredNode) {
689
- this.authoredNode =
690
- new NavigatorGroupTreeNode(this, null, 'group:Authored', Types.Authored, UIStrings.authored);
698
+ this.authoredNode = new NavigatorGroupTreeNode(
699
+ this, null, 'group:Authored', Types.Authored, i18nString(UIStrings.authored),
700
+ i18nString(UIStrings.authoredTooltip));
691
701
  this.rootNode.appendChild(this.authoredNode);
692
702
  this.authoredNode.treeNode().expand();
693
703
  }
@@ -712,8 +722,9 @@ export class NavigatorView extends UI.Widget.VBox implements SDK.TargetManager.O
712
722
  private rootOrDeployedNode(): NavigatorTreeNode {
713
723
  if (this.groupByAuthored) {
714
724
  if (!this.deployedNode) {
715
- this.deployedNode =
716
- new NavigatorGroupTreeNode(this, null, 'group:Deployed', Types.Deployed, UIStrings.deployed);
725
+ this.deployedNode = new NavigatorGroupTreeNode(
726
+ this, null, 'group:Deployed', Types.Deployed, i18nString(UIStrings.deployed),
727
+ i18nString(UIStrings.deployedTooltip));
717
728
  this.rootNode.appendChild(this.deployedNode);
718
729
  }
719
730
  return this.deployedNode;
@@ -1007,10 +1018,17 @@ export class NavigatorView extends UI.Widget.VBox implements SDK.TargetManager.O
1007
1018
  }
1008
1019
  }
1009
1020
 
1021
+ /**
1022
+ * Subclasses can override to listen to grouping changes.
1023
+ */
1024
+ onGroupingChanged(): void {
1025
+ }
1026
+
1010
1027
  private groupingChanged(): void {
1011
1028
  this.reset(true);
1012
1029
  this.initGrouping();
1013
1030
  // Reset the workspace to repopulate filesystem folders.
1031
+ this.onGroupingChanged();
1014
1032
  this.resetWorkspace(Workspace.Workspace.WorkspaceImpl.instance());
1015
1033
  this.workspaceInternal.uiSourceCodes().forEach(this.addUISourceCode.bind(this));
1016
1034
  }
@@ -1019,7 +1037,11 @@ export class NavigatorView extends UI.Widget.VBox implements SDK.TargetManager.O
1019
1037
  this.groupByFrame = true;
1020
1038
  this.groupByDomain = this.navigatorGroupByFolderSetting.get();
1021
1039
  this.groupByFolder = this.groupByDomain;
1022
- this.groupByAuthored = this.navigatorGroupByAuthoredSetting.get();
1040
+ if (this.navigatorGroupByAuthoredExperiment) {
1041
+ this.groupByAuthored = Root.Runtime.experiments.isEnabled(this.navigatorGroupByAuthoredExperiment);
1042
+ } else {
1043
+ this.groupByAuthored = false;
1044
+ }
1023
1045
  }
1024
1046
 
1025
1047
  private resetForTest(): void {
@@ -1130,14 +1152,18 @@ export class NavigatorFolderTreeElement extends UI.TreeOutline.TreeElement {
1130
1152
 
1131
1153
  setNode(node: NavigatorTreeNode): void {
1132
1154
  this.node = node;
1133
- const paths = [];
1134
- let currentNode: NavigatorTreeNode|null = node;
1135
- while (currentNode && !currentNode.isRoot()) {
1136
- paths.push(currentNode.title);
1137
- currentNode = currentNode.parent;
1138
- }
1139
- paths.reverse();
1140
- this.tooltip = paths.join('/');
1155
+ if (node.tooltip) {
1156
+ this.tooltip = node.tooltip;
1157
+ } else {
1158
+ const paths = [];
1159
+ let currentNode: NavigatorTreeNode|null = node;
1160
+ while (currentNode && !currentNode.isRoot() && currentNode.type === node.type) {
1161
+ paths.push(currentNode.title);
1162
+ currentNode = currentNode.parent;
1163
+ }
1164
+ paths.reverse();
1165
+ this.tooltip = paths.join('/');
1166
+ }
1141
1167
  UI.ARIAUtils.setAccessibleName(this.listItemElement, `${this.title}, ${this.nodeType}`);
1142
1168
  }
1143
1169
 
@@ -1303,12 +1329,14 @@ export class NavigatorTreeNode {
1303
1329
  isMerged: boolean;
1304
1330
  parent!: NavigatorTreeNode|null;
1305
1331
  title!: string;
1332
+ tooltip?: string;
1306
1333
 
1307
- constructor(navigatorView: NavigatorView, id: string, type: string) {
1334
+ constructor(navigatorView: NavigatorView, id: string, type: string, tooltip?: string) {
1308
1335
  this.id = id;
1309
1336
  this.navigatorView = navigatorView;
1310
1337
  this.type = type;
1311
1338
  this.childrenInternal = new Map();
1339
+ this.tooltip = tooltip;
1312
1340
 
1313
1341
  this.populated = false;
1314
1342
  this.isMerged = false;
@@ -1719,9 +1747,9 @@ export class NavigatorGroupTreeNode extends NavigatorTreeNode {
1719
1747
  private hoverCallback?: ((arg0: boolean) => void);
1720
1748
  private treeElement?: NavigatorFolderTreeElement;
1721
1749
  constructor(
1722
- navigatorView: NavigatorView, project: Workspace.Workspace.Project|null, id: string, type: string,
1723
- title: string) {
1724
- super(navigatorView, id, type);
1750
+ navigatorView: NavigatorView, project: Workspace.Workspace.Project|null, id: string, type: string, title: string,
1751
+ tooltip?: string) {
1752
+ super(navigatorView, id, type, tooltip);
1725
1753
  this.project = project;
1726
1754
  this.title = title;
1727
1755
  this.populate();
@@ -32,14 +32,17 @@ import * as Common from '../../core/common/common.js';
32
32
  import * as Host from '../../core/host/host.js';
33
33
  import * as i18n from '../../core/i18n/i18n.js';
34
34
  import * as Platform from '../../core/platform/platform.js';
35
+ import * as Root from '../../core/root/root.js';
35
36
  import * as SDK from '../../core/sdk/sdk.js';
36
37
  import * as Persistence from '../../models/persistence/persistence.js';
37
38
  import * as Workspace from '../../models/workspace/workspace.js';
39
+ import * as Feedback from '../../ui/components/panel_feedback/panel_feedback.js';
38
40
  import * as UI from '../../ui/legacy/legacy.js';
39
41
  import * as Snippets from '../snippets/snippets.js';
40
42
 
41
43
  import type {NavigatorUISourceCodeTreeNode} from './NavigatorView.js';
42
44
  import {NavigatorView} from './NavigatorView.js';
45
+ import sourcesNavigatorStyles from './sourcesNavigator.css.js';
43
46
 
44
47
  const UIStrings = {
45
48
  /**
@@ -100,20 +103,61 @@ const UIStrings = {
100
103
  *@description Text to save content as a specific file type
101
104
  */
102
105
  saveAs: 'Save as...',
106
+ /**
107
+ *@description Description of the new experimental Authored/Deployed view
108
+ */
109
+ authoredDescription: 'Group files by Authored/Deployed',
103
110
  };
104
111
  const str_ = i18n.i18n.registerUIStrings('panels/sources/SourcesNavigator.ts', UIStrings);
105
112
  const i18nString = i18n.i18n.getLocalizedString.bind(undefined, str_);
106
113
  let networkNavigatorViewInstance: NetworkNavigatorView;
107
114
 
108
115
  export class NetworkNavigatorView extends NavigatorView {
116
+ private previewToggle: Feedback.PreviewToggle.PreviewToggle;
109
117
  private constructor() {
110
- super();
118
+ super(true);
111
119
  SDK.TargetManager.TargetManager.instance().addEventListener(
112
120
  SDK.TargetManager.Events.InspectedURLChanged, this.inspectedURLChanged, this);
113
121
 
122
+ this.previewToggle = new Feedback.PreviewToggle.PreviewToggle();
123
+ this.onGroupingChanged();
124
+
125
+ const div = UI.Fragment.html`<div class="border-container"></div>`;
126
+ div.append(this.previewToggle);
127
+ this.contentElement.prepend(div);
128
+
114
129
  // Record the sources tool load time after the file navigator has loaded.
115
130
  Host.userMetrics.panelLoaded('sources', 'DevTools.Launch.Sources');
116
131
  }
132
+
133
+ onGroupingChanged(): void {
134
+ // Setting the data will re-render it.
135
+ this.previewToggle.data = {
136
+ name: i18nString(UIStrings.authoredDescription),
137
+ helperText: null,
138
+ experiment: Root.Runtime.ExperimentName.AUTHORED_DEPLOYED_GROUPING,
139
+ learnMoreURL: 'https://goo.gle/authored-deployed',
140
+ feedbackURL: 'https://goo.gle/authored-deployed-feedback',
141
+ onChangeCallback: this.onAuthoredDeployedChanged,
142
+ };
143
+ }
144
+
145
+ wasShown(): void {
146
+ this.registerCSSFiles([sourcesNavigatorStyles]);
147
+ super.wasShown();
148
+ }
149
+
150
+ private onAuthoredDeployedChanged(checked: boolean): void {
151
+ Host.userMetrics.experimentChanged(Root.Runtime.ExperimentName.AUTHORED_DEPLOYED_GROUPING, checked);
152
+ // Need to signal to the NavigatorView that grouping has changed. Unfortunately,
153
+ // it can't listen to an experiment, and this class doesn't directly interact
154
+ // with it, so we will convince it a different grouping setting changed. When we switch
155
+ // from using an experiment to a setting, it will listen to that setting and we
156
+ // won't need to do this.
157
+ const groupByFolderSetting = Common.Settings.Settings.instance().moduleSetting('navigatorGroupByFolder');
158
+ groupByFolderSetting.set(groupByFolderSetting.get());
159
+ }
160
+
117
161
  static instance(opts: {
118
162
  forceNew: boolean|null,
119
163
  } = {forceNew: null}): NetworkNavigatorView {
@@ -32,10 +32,12 @@ import * as Common from '../../core/common/common.js';
32
32
  import * as Host from '../../core/host/host.js';
33
33
  import * as i18n from '../../core/i18n/i18n.js';
34
34
  import * as Platform from '../../core/platform/platform.js';
35
+ import * as Root from '../../core/root/root.js';
35
36
  import * as SDK from '../../core/sdk/sdk.js';
36
37
  import * as Bindings from '../../models/bindings/bindings.js';
37
38
  import * as Extensions from '../../models/extensions/extensions.js';
38
39
  import * as Workspace from '../../models/workspace/workspace.js';
40
+ import * as IconButton from '../../ui/components/icon_button/icon_button.js';
39
41
  import * as ObjectUI from '../../ui/legacy/components/object_ui/object_ui.js';
40
42
  import * as UI from '../../ui/legacy/legacy.js';
41
43
  import * as Snippets from '../snippets/snippets.js';
@@ -108,7 +110,7 @@ const UIStrings = {
108
110
  /**
109
111
  *@description Text in Sources Panel of the Sources panel
110
112
  */
111
- groupByAuthored: 'Group by Authored/Deployed (experimental)',
113
+ groupByAuthored: 'Group by Authored/Deployed',
112
114
  /**
113
115
  *@description Text for pausing the debugger on exceptions
114
116
  */
@@ -547,16 +549,36 @@ export class SourcesPanel extends UI.Panel.Panel implements UI.ContextMenu.Provi
547
549
  }
548
550
  }
549
551
 
552
+ private toggleAuthoredDeployedExperiment(): void {
553
+ const experiment = Root.Runtime.ExperimentName.AUTHORED_DEPLOYED_GROUPING;
554
+ const checked = Root.Runtime.experiments.isEnabled(experiment);
555
+ Root.Runtime.experiments.setEnabled(experiment, !checked);
556
+ Host.userMetrics.experimentChanged(experiment, checked);
557
+ // Need to signal to the NavigatorView that grouping has changed. Unfortunately,
558
+ // it can't listen to an experiment, and this class doesn't directly interact
559
+ // with it, so we will convince it a different grouping setting changed. When we switch
560
+ // from using an experiment to a setting, it will listen to that setting and we
561
+ // won't need to do this.
562
+ const groupByFolderSetting = Common.Settings.Settings.instance().moduleSetting('navigatorGroupByFolder');
563
+ groupByFolderSetting.set(groupByFolderSetting.get());
564
+ }
565
+
550
566
  private populateNavigatorMenu(contextMenu: UI.ContextMenu.ContextMenu): void {
551
567
  const groupByFolderSetting = Common.Settings.Settings.instance().moduleSetting('navigatorGroupByFolder');
552
568
  contextMenu.appendItemsAtLocation('navigatorMenu');
553
569
  contextMenu.viewSection().appendCheckboxItem(
554
570
  i18nString(UIStrings.groupByFolder), () => groupByFolderSetting.set(!groupByFolderSetting.get()),
555
571
  groupByFolderSetting.get());
556
- const groupByAuthoredSetting = Common.Settings.Settings.instance().moduleSetting('navigatorGroupByAuthored');
572
+ const previewIcon = new IconButton.Icon.Icon();
573
+ const experiment = Root.Runtime.ExperimentName.AUTHORED_DEPLOYED_GROUPING;
574
+ previewIcon.data = {
575
+ iconName: 'ic_preview_feature',
576
+ color: 'var(--icon-color)',
577
+ width: '14px',
578
+ };
557
579
  contextMenu.viewSection().appendCheckboxItem(
558
- i18nString(UIStrings.groupByAuthored), () => groupByAuthoredSetting.set(!groupByAuthoredSetting.get()),
559
- groupByAuthoredSetting.get());
580
+ i18nString(UIStrings.groupByAuthored), this.toggleAuthoredDeployedExperiment,
581
+ Root.Runtime.experiments.isEnabled(experiment), false, previewIcon);
560
582
  }
561
583
 
562
584
  setIgnoreExecutionLineEvents(ignoreExecutionLineEvents: boolean): void {
@@ -91,6 +91,10 @@
91
91
  background-color: var(--override-folder-tree-item-color);
92
92
  }
93
93
 
94
+ .navigator-folder-tree-item.force-white-icons {
95
+ --icon-color: var(--override-force-white-icons-background);
96
+ }
97
+
94
98
  .navigator-sm-folder-tree-item .icon,
95
99
  .navigator-fs-tree-item .icon,
96
100
  .navigator-fs-folder-tree-item .icon {
@@ -0,0 +1,10 @@
1
+ /*
2
+ * Copyright 2022 The Chromium Authors. All rights reserved.
3
+ * Use of this source code is governed by a BSD-style license that can be
4
+ * found in the LICENSE file.
5
+ */
6
+
7
+ .border-container {
8
+ border-bottom: 1px solid var(--color-details-hairline);
9
+ flex-shrink: 0;
10
+ }
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Lighthouse v9.6.1 202d605b30c6223dcbba24244da76a9ee7293d6b (May 11 2022)
2
+ * Lighthouse v9.6.2 bf2665f0c6dfe20f969f2891b42d23650c10fcfd (Jun 08 2022)
3
3
  *
4
4
  * Automated auditing, performance metrics, and best practices for the web.
5
5
  *
@@ -98,16 +98,16 @@ for(var r in t)t.hasOwnProperty(r)&&(e[r]=t[r])})(e,t)};return function(e,t){fun
98
98
  return t?Cn({},e||{},t||{},Object.keys(e).reduce((function(r,a){return r[a]=Cn({},e[a],t[a]||{}),r}),{})):e}(e[a],t[a]),r}),Cn({},e)):e}var In=function(e){function FormatError(t,r){var a=e.call(this,t)||this;return a.variableId=r,a}return Dn(FormatError,e),FormatError}(Error);function createDefaultFormatters(){return{getNumberFormat:function(){for(var e,t=[],r=0;r<arguments.length;r++)t[r]=arguments[r];return new((e=Intl.NumberFormat).bind.apply(e,[void 0].concat(t)))},getDateTimeFormat:function(){for(var e,t=[],r=0;r<arguments.length;r++)t[r]=arguments[r];return new((e=Intl.DateTimeFormat).bind.apply(e,[void 0].concat(t)))},getPluralRules:function(){for(var e,t=[],r=0;r<arguments.length;r++)t[r]=arguments[r];return new((e=Intl.PluralRules).bind.apply(e,[void 0].concat(t)))}}}var Nn=function(){function IntlMessageFormat(e,t,r,a){var n=this;if(void 0===t&&(t=IntlMessageFormat.defaultLocale),this.format=function(e){try{return formatPatterns(n.pattern,e)}catch(e){
99
99
  throw e.variableId?new Error("The intl string context variable '"+e.variableId+"' was not provided to the string '"+n.message+"'"):e}},"string"==typeof e){if(!IntlMessageFormat.__parse)throw new TypeError("IntlMessageFormat.__parse must be set to process `message` of type `string`");this.ast=IntlMessageFormat.__parse(e)}else this.ast=e;if(this.message=e,!this.ast||"messageFormatPattern"!==this.ast.type)throw new TypeError("A message must be provided as a String or AST.");var i=mergeConfigs(IntlMessageFormat.formats,r);this.locale=resolveLocale(t||[]);var o=a&&a.formatters||createDefaultFormatters();this.pattern=new En(t,i,o).compile(this.ast)}return IntlMessageFormat.prototype.resolvedOptions=function(){return{locale:this.locale}},IntlMessageFormat.prototype.getAst=function(){return this.ast},IntlMessageFormat.defaultLocale="en",IntlMessageFormat.__parse=void 0,IntlMessageFormat.formats={number:{currency:{style:"currency"},percent:{style:"percent"}},date:{short:{month:"numeric",
100
100
  day:"numeric",year:"2-digit"},medium:{month:"short",day:"numeric",year:"numeric"},long:{month:"long",day:"numeric",year:"numeric"},full:{weekday:"long",month:"long",day:"numeric",year:"numeric"}},time:{short:{hour:"numeric",minute:"numeric"},medium:{hour:"numeric",minute:"numeric",second:"numeric"},long:{hour:"numeric",minute:"numeric",second:"numeric",timeZoneName:"short"},full:{hour:"numeric",minute:"numeric",second:"numeric",timeZoneName:"short"}}},IntlMessageFormat}();Nn.__parse=Sn.parse;var Ln=getAugmentedNamespace(Object.freeze({__proto__:null,default:Nn,createDefaultFormatters,IntlMessageFormat:Nn}));var Mn={isObjectOfUnknownValues:function isObjectOfUnknownValues$1(e){return"object"==typeof e&&null!==e&&!Array.isArray(e)},isObjectOrArrayOfUnknownValues:function isObjectOrArrayOfUnknownValues$1(e){return"object"==typeof e&&null!==e}},Pn=getAugmentedNamespace(Object.freeze({__proto__:null,default:{}}))
101
- ;const On=Ln,{isObjectOfUnknownValues:Fn,isObjectOrArrayOfUnknownValues:Un}=Mn,jn=Pn.default||Pn,Bn="en-US",$n=["ar-XB.json","ar.json","bg.json","ca.json","cs.json","da.json","de.json","el.json","en-GB.json","en-US.ctc.json","en-US.json","en-XA.json","en-XL.ctc.json","en-XL.json","es-419.json","es.json","fi.json","fil.json","fr.json","he.json","hi.json","hr.json","hu.json","id.json","it.json","ja.json","ko.json","lt.json","lv.json","nl.json","no.json","pl.json","pt-PT.json","pt.json","ro.json","ru.json","sk.json","sl.json","sr-Latn.json","sr.json","sv.json","ta.json","te.json","th.json","tr.json","uk.json","vi.json","zh-HK.json","zh-TW.json","zh.json"].filter((e=>e.endsWith(".json")&&!e.endsWith(".ctc.json"))).map((e=>e.replace(".json",""))).sort(),qn=/ | [^\s]+$/,zn={number:{bytes:{maximumFractionDigits:0},milliseconds:{maximumFractionDigits:0},seconds:{minimumFractionDigits:1,maximumFractionDigits:1},extendedPercent:{maximumFractionDigits:2,style:"percent"}}}
102
- ;function collectAllCustomElementsFromICU(e,t=new Map){for(const r of e)if("argumentElement"===r.type&&(t.set(r.id,r),r.format&&"pluralFormat"===r.format.type))for(const e of r.format.options)collectAllCustomElementsFromICU(e.value.elements,t);return t}function formatMessage$1(e,t={},r){const a="en-XA"===r||"en-XL"===r?"de-DE":r,n=new(On.IntlMessageFormat||On)(e,a,zn),i=function _preformatValues(e,t,r){const a=[...collectAllCustomElementsFromICU(e.getAst().elements).values()],n={};for(const{id:e,format:i}of a){if(e&&e in t==0)throw new Error(`ICU Message "${r}" contains a value reference ("${e}") that wasn't provided`);const a=t[e];if(i&&"numberFormat"===i.type){if("number"!=typeof a)throw new Error(`ICU Message "${r}" contains a numeric reference ("${e}") but provided value was not a number`);"milliseconds"===i.style?n[e]=10*Math.round(a/10):"seconds"===i.style&&"timeInMs"===e?n[e]=Math.round(a/100)/10:"bytes"===i.style?n[e]=a/1024:n[e]=a}else n[e]=a}
103
- for(const e of Object.keys(t))if(!(e in n)){if("errorCode"!==e)throw new Error(`Provided value "${e}" does not match any placeholder in ICU message "${r}"`);n.errorCode=t.errorCode}return n}(n,t,e);return n.format(i)}function isIcuMessage$2(e){if(!Fn(e))return!1;const{i18nId:t,values:r,formattedDefault:a}=e;if("string"!=typeof t)return!1;if("string"!=typeof a)return!1;if(void 0!==r){if(!Fn(r))return!1;for(const e of Object.values(r))if("string"!=typeof e&&"number"!=typeof e)return!1}return qn.test(t)}function getFormatted(e,t){if(isIcuMessage$2(e))return function _localizeIcuMessage(e,t){const r=_getLocaleMessages(t)[e.i18nId];return r?formatMessage$1(r.message,e.values,t):e.formattedDefault}(e,t);if("string"==typeof e)return e;throw new Error("Attempted to format invalid icuMessage type")}function _formatPathAsString(e){let t="";for(const r of e)if(/^[a-z]+$/i.test(r))t.length&&(t+="."),t+=r;else{if(/]|"|'|\s/.test(r))throw new Error(`Cannot handle "${r}" in i18n`);t+=`[${r}]`}
104
- return t}function _getLocaleMessages(e){const t=jn[e];if(!t){if(e===Bn)return{};throw new Error(`Unsupported locale '${e}'`)}return t}function getIcuMessageIdParts(e){if(!qn.test(e))throw Error(`"${e}" does not appear to be a valid ICU message id`);const[t,r]=e.split(" | ");return{filename:t,key:r}}var Vn={DEFAULT_LOCALE:Bn,_formatPathAsString,collectAllCustomElementsFromICU,isIcuMessage:isIcuMessage$2,getFormatted,getRendererFormattedStrings:function getRendererFormattedStrings(e){const t=_getLocaleMessages(e),r=Object.keys(t).filter((e=>e.startsWith("report/"))),a={};for(const e of r){const{filename:r,key:n}=getIcuMessageIdParts(e);if(!r.endsWith("util.js"))throw new Error(`Unexpected message: ${e}`);a[n]=t[e].message}return a},replaceIcuMessages:function replaceIcuMessages(e,t){const r={};return function replaceInObject(e,r,a=[]){if(Un(e))for(const[n,i]of Object.entries(e)){const o=a.concat([n]);if(isIcuMessage$2(i)){
105
- const a=getFormatted(i,t),s=r[i.i18nId]||[],c=_formatPathAsString(o);s.push(i.values?{values:i.values,path:c}:c),e[n]=a,r[i.i18nId]=s}else replaceInObject(i,r,o)}}(e,r),r},hasLocale:function hasLocale(e){if(e===Bn)return!0;const t=Intl.NumberFormat.supportedLocalesOf([e]).length>0,r=Boolean(jn[e]);return t&&r},registerLocaleData:function registerLocaleData(e,t){jn[e]=t},formatMessage:formatMessage$1,getIcuMessageIdParts,getAvailableLocales:function getAvailableLocales$1(){return[...new Set([...Object.keys(jn),Bn])].sort()},getCanonicalLocales:function getCanonicalLocales(){return $n}};const Wn=globalThis.URL;var Gn=getAugmentedNamespace(Object.freeze({__proto__:null,URL:Wn}));const Hn=wn,Yn=bn,Kn=Gn;var Jn={LH_ROOT:"",readJson(e,t){const r=t?Yn.dirname(Kn.fileURLToPath(t.url)):"";return e=Yn.resolve(r,e),JSON.parse(Hn.readFileSync(e,"utf-8"))}};const Xn=bn,Zn=function lookupClosestLocale(e,t){if("string"==typeof e&&t[e])return e
106
- ;for(var r=[].concat(e||[]),a=0,n=r.length;a<n;++a)for(var i=r[a].split("-");i.length;){var o=i.join("-");if(t[o])return o;i.pop()}},{getAvailableLocales:Qn}=Vn,ei=on.default,{LH_ROOT:ti}=Jn,{isIcuMessage:ri,formatMessage:ai,DEFAULT_LOCALE:ni}=Vn,ii={ms:"{timeInMs, number, milliseconds} ms",seconds:"{timeInMs, number, seconds} s",displayValueByteSavings:"Potential savings of {wastedBytes, number, bytes} KiB",displayValueMsSavings:"Potential savings of {wastedMs, number, milliseconds} ms",displayValueElementsFound:"{nodeCount, plural, =1 {1 element found} other {# elements found}}",columnURL:"URL",columnSize:"Size",columnResourceSize:"Resource Size",columnTransferSize:"Transfer Size",columnCacheTTL:"Cache TTL",columnWastedBytes:"Potential Savings",columnWastedMs:"Potential Savings",columnBlockingTime:"Main-Thread Blocking Time",columnTimeSpent:"Time Spent",columnLocation:"Location",columnResourceType:"Resource Type",columnRequests:"Requests",columnName:"Name",columnSource:"Source",
107
- columnOverBudget:"Over Budget",columnElement:"Element",columnStartTime:"Start Time",columnDuration:"Duration",columnFailingElem:"Failing Elements",columnDescription:"Description",totalResourceType:"Total",documentResourceType:"Document",scriptResourceType:"Script",stylesheetResourceType:"Stylesheet",imageResourceType:"Image",mediaResourceType:"Media",fontResourceType:"Font",otherResourceType:"Other",thirdPartyResourceType:"Third-party",otherResourcesLabel:"Other resources",firstContentfulPaintMetric:"First Contentful Paint",interactiveMetric:"Time to Interactive",firstMeaningfulPaintMetric:"First Meaningful Paint",totalBlockingTimeMetric:"Total Blocking Time",maxPotentialFIDMetric:"Max Potential First Input Delay",speedIndexMetric:"Speed Index",largestContentfulPaintMetric:"Largest Contentful Paint",cumulativeLayoutShiftMetric:"Cumulative Layout Shift",interactionToNextPaint:"Interaction to Next Paint",itemSeverityLow:"Low",itemSeverityMedium:"Medium",itemSeverityHigh:"High"}
108
- ;function createIcuMessageFn(e,t){const r={...ii,...t};return(a,n)=>{const i=Object.keys(r).find((e=>r[e]===a));if(!i)throw new Error(`Could not locate: ${a}`);const o=i in t?e:"lighthouse-core/lib/i18n/i18n.js";return{i18nId:`${Xn.relative(ti,o).replace(/\\/g,"/")} | ${i}`,values:n,formattedDefault:ai(a,n,ni)}}}var oi={UIStrings:ii,lookupLocale:function lookupLocale(e,t){if("object"!=typeof Intl)throw new Error("Lighthouse must be run in Node with `Intl` support. See https://nodejs.org/api/intl.html for help");const r=Intl.getCanonicalLocales(e),a=Intl.NumberFormat.supportedLocalesOf(r),n=t||Qn(),i=Object.fromEntries(n.map((e=>[e,{}]))),o=Zn(a,i);return o||(0===Intl.NumberFormat.supportedLocalesOf("es").length&&ei.warn("i18n","Requested locale not available in this version of node. The `full-icu` npm module can provide additional locales. For help, see https://github.com/GoogleChrome/lighthouse/blob/master/readme.md#how-do-i-get-localized-lighthouse-results-via-the-cli"),
109
- ei.warn("i18n",`locale(s) '${e}' not available. Falling back to default '${ni}'`)),o||ni},createIcuMessageFn,isStringOrIcuMessage:function isStringOrIcuMessage(e){return"string"==typeof e||ri(e)},createMessageInstanceIdFn:createIcuMessageFn};const si=on.default,ci=mn,li=hn,ui={warningSlowHostCpu:"The tested device appears to have a slower CPU than Lighthouse expects. This can negatively affect your performance score. Learn more about [calibrating an appropriate CPU slowdown multiplier](https://github.com/GoogleChrome/lighthouse/blob/master/docs/throttling.md#cpu-throttling)."},di=oi.createMessageInstanceIdFn("lighthouse-core/gather/driver/environment.js",ui);function getSlowHostCpuWarning(e){const{settings:t,baseArtifacts:r}=e,{throttling:a,throttlingMethod:n}=t,i=ci.defaultSettings.throttling;if("cli"!==t.channel)return;const o="simulate"===n||"devtools"===n,s=a.cpuSlowdownMultiplier===i.cpuSlowdownMultiplier;return!o||!s||r.BenchmarkIndex>1e3?void 0:di(ui.warningSlowHostCpu)}
110
- var mi={UIStrings:ui,getBrowserVersion:async function getBrowserVersion$3(e){const t={msg:"Getting browser version",id:"lh:gather:getVersion"};si.time(t,"verbose");const r=await e.sendCommand("Browser.getVersion"),a=r.product.match(/\/(\d+)/),n=a?parseInt(a[1]):0;return si.timeEnd(t),Object.assign(r,{milestone:n})},getBenchmarkIndex:async function getBenchmarkIndex$2(e){const t={msg:"Benchmarking machine",id:"lh:gather:getBenchmarkIndex"};si.time(t);const r=await e.evaluate(li.computeBenchmarkIndex,{args:[]});return si.timeEnd(t),r},getSlowHostCpuWarning,getEnvironmentWarnings:function getEnvironmentWarnings$2(e){return[getSlowHostCpuWarning(e)].filter((e=>!!e))}};
101
+ ;const On=Ln,{isObjectOfUnknownValues:Fn,isObjectOrArrayOfUnknownValues:Un}=Mn,jn=Pn.default||Pn,Bn="en-US",$n=["ar-XB.json","ar.json","bg.json","ca.json","cs.json","da.json","de.json","el.json","en-GB.json","en-US.json","en-XA.json","en-XL.json","es-419.json","es.json","fi.json","fil.json","fr.json","he.json","hi.json","hr.json","hu.json","id.json","it.json","ja.json","ko.json","lt.json","lv.json","nl.json","no.json","pl.json","pt-PT.json","pt.json","ro.json","ru.json","sk.json","sl.json","sr-Latn.json","sr.json","sv.json","ta.json","te.json","th.json","tr.json","uk.json","vi.json","zh-HK.json","zh-TW.json","zh.json"].filter((e=>e.endsWith(".json")&&!e.endsWith(".ctc.json"))).map((e=>e.replace(".json",""))).sort(),qn=/ | [^\s]+$/,zn={number:{bytes:{maximumFractionDigits:0},milliseconds:{maximumFractionDigits:0},seconds:{minimumFractionDigits:1,maximumFractionDigits:1},extendedPercent:{maximumFractionDigits:2,style:"percent"}}};function collectAllCustomElementsFromICU(e,t=new Map){
102
+ for(const r of e)if("argumentElement"===r.type&&(t.set(r.id,r),r.format&&"pluralFormat"===r.format.type))for(const e of r.format.options)collectAllCustomElementsFromICU(e.value.elements,t);return t}function formatMessage$1(e,t={},r){const a="en-XA"===r||"en-XL"===r?"de-DE":r,n=new(On.IntlMessageFormat||On)(e,a,zn),i=function _preformatValues(e,t,r){const a=[...collectAllCustomElementsFromICU(e.getAst().elements).values()],n={};for(const{id:e,format:i}of a){if(e&&e in t==0)throw new Error(`ICU Message "${r}" contains a value reference ("${e}") that wasn't provided`);const a=t[e];if(i&&"numberFormat"===i.type){if("number"!=typeof a)throw new Error(`ICU Message "${r}" contains a numeric reference ("${e}") but provided value was not a number`);"milliseconds"===i.style?n[e]=10*Math.round(a/10):"seconds"===i.style&&"timeInMs"===e?n[e]=Math.round(a/100)/10:"bytes"===i.style?n[e]=a/1024:n[e]=a}else n[e]=a}for(const e of Object.keys(t))if(!(e in n)){
103
+ if("errorCode"!==e)throw new Error(`Provided value "${e}" does not match any placeholder in ICU message "${r}"`);n.errorCode=t.errorCode}return n}(n,t,e);return n.format(i)}function isIcuMessage$2(e){if(!Fn(e))return!1;const{i18nId:t,values:r,formattedDefault:a}=e;if("string"!=typeof t)return!1;if("string"!=typeof a)return!1;if(void 0!==r){if(!Fn(r))return!1;for(const e of Object.values(r))if("string"!=typeof e&&"number"!=typeof e)return!1}return qn.test(t)}function getFormatted(e,t){if(isIcuMessage$2(e))return function _localizeIcuMessage(e,t){const r=_getLocaleMessages(t)[e.i18nId];return r?formatMessage$1(r.message,e.values,t):e.formattedDefault}(e,t);if("string"==typeof e)return e;throw new Error("Attempted to format invalid icuMessage type")}function _formatPathAsString(e){let t="";for(const r of e)if(/^[a-z]+$/i.test(r))t.length&&(t+="."),t+=r;else{if(/]|"|'|\s/.test(r))throw new Error(`Cannot handle "${r}" in i18n`);t+=`[${r}]`}return t}function _getLocaleMessages(e){
104
+ const t=jn[e];if(!t){if(e===Bn)return{};throw new Error(`Unsupported locale '${e}'`)}return t}function getIcuMessageIdParts(e){if(!qn.test(e))throw Error(`"${e}" does not appear to be a valid ICU message id`);const[t,r]=e.split(" | ");return{filename:t,key:r}}var Vn={DEFAULT_LOCALE:Bn,_formatPathAsString,collectAllCustomElementsFromICU,isIcuMessage:isIcuMessage$2,getFormatted,getRendererFormattedStrings:function getRendererFormattedStrings(e){const t=_getLocaleMessages(e),r=Object.keys(t).filter((e=>e.startsWith("report/"))),a={};for(const e of r){const{filename:r,key:n}=getIcuMessageIdParts(e);if(!r.endsWith("util.js"))throw new Error(`Unexpected message: ${e}`);a[n]=t[e].message}return a},replaceIcuMessages:function replaceIcuMessages(e,t){const r={};return function replaceInObject(e,r,a=[]){if(Un(e))for(const[n,i]of Object.entries(e)){const o=a.concat([n]);if(isIcuMessage$2(i)){const a=getFormatted(i,t),s=r[i.i18nId]||[],c=_formatPathAsString(o);s.push(i.values?{values:i.values,
105
+ path:c}:c),e[n]=a,r[i.i18nId]=s}else replaceInObject(i,r,o)}}(e,r),r},hasLocale:function hasLocale(e){if(e===Bn)return!0;const t=Intl.NumberFormat.supportedLocalesOf([e]).length>0,r=Boolean(jn[e]);return t&&r},registerLocaleData:function registerLocaleData(e,t){jn[e]=t},formatMessage:formatMessage$1,getIcuMessageIdParts,getAvailableLocales:function getAvailableLocales$1(){return[...new Set([...Object.keys(jn),Bn])].sort()},getCanonicalLocales:function getCanonicalLocales(){return $n}};const Wn=globalThis.URL;var Gn=getAugmentedNamespace(Object.freeze({__proto__:null,URL:Wn}));const Hn=wn,Yn=bn,Kn=Gn;var Jn={LH_ROOT:"",readJson(e,t){const r=t?Yn.dirname(Kn.fileURLToPath(t.url)):"";return e=Yn.resolve(r,e),JSON.parse(Hn.readFileSync(e,"utf-8"))}};const Xn=bn,Zn=function lookupClosestLocale(e,t){if("string"==typeof e&&t[e])return e;for(var r=[].concat(e||[]),a=0,n=r.length;a<n;++a)for(var i=r[a].split("-");i.length;){var o=i.join("-");if(t[o])return o;i.pop()}
106
+ },{getAvailableLocales:Qn}=Vn,ei=on.default,{LH_ROOT:ti}=Jn,{isIcuMessage:ri,formatMessage:ai,DEFAULT_LOCALE:ni}=Vn,ii={ms:"{timeInMs, number, milliseconds} ms",seconds:"{timeInMs, number, seconds} s",displayValueByteSavings:"Potential savings of {wastedBytes, number, bytes} KiB",displayValueMsSavings:"Potential savings of {wastedMs, number, milliseconds} ms",displayValueElementsFound:"{nodeCount, plural, =1 {1 element found} other {# elements found}}",columnURL:"URL",columnSize:"Size",columnResourceSize:"Resource Size",columnTransferSize:"Transfer Size",columnCacheTTL:"Cache TTL",columnWastedBytes:"Potential Savings",columnWastedMs:"Potential Savings",columnBlockingTime:"Main-Thread Blocking Time",columnTimeSpent:"Time Spent",columnLocation:"Location",columnResourceType:"Resource Type",columnRequests:"Requests",columnName:"Name",columnSource:"Source",columnOverBudget:"Over Budget",columnElement:"Element",columnStartTime:"Start Time",columnDuration:"Duration",
107
+ columnFailingElem:"Failing Elements",columnDescription:"Description",totalResourceType:"Total",documentResourceType:"Document",scriptResourceType:"Script",stylesheetResourceType:"Stylesheet",imageResourceType:"Image",mediaResourceType:"Media",fontResourceType:"Font",otherResourceType:"Other",thirdPartyResourceType:"Third-party",otherResourcesLabel:"Other resources",firstContentfulPaintMetric:"First Contentful Paint",interactiveMetric:"Time to Interactive",firstMeaningfulPaintMetric:"First Meaningful Paint",totalBlockingTimeMetric:"Total Blocking Time",maxPotentialFIDMetric:"Max Potential First Input Delay",speedIndexMetric:"Speed Index",largestContentfulPaintMetric:"Largest Contentful Paint",cumulativeLayoutShiftMetric:"Cumulative Layout Shift",interactionToNextPaint:"Interaction to Next Paint",itemSeverityLow:"Low",itemSeverityMedium:"Medium",itemSeverityHigh:"High"};function createIcuMessageFn(e,t){const r={...ii,...t};return(a,n)=>{const i=Object.keys(r).find((e=>r[e]===a))
108
+ ;if(!i)throw new Error(`Could not locate: ${a}`);const o=i in t?e:"lighthouse-core/lib/i18n/i18n.js";return{i18nId:`${Xn.relative(ti,o).replace(/\\/g,"/")} | ${i}`,values:n,formattedDefault:ai(a,n,ni)}}}var oi={UIStrings:ii,lookupLocale:function lookupLocale(e,t){if("object"!=typeof Intl)throw new Error("Lighthouse must be run in Node with `Intl` support. See https://nodejs.org/api/intl.html for help");const r=Intl.getCanonicalLocales(e),a=Intl.NumberFormat.supportedLocalesOf(r),n=t||Qn(),i=Object.fromEntries(n.map((e=>[e,{}]))),o=Zn(a,i);return o||(0===Intl.NumberFormat.supportedLocalesOf("es").length&&ei.warn("i18n","Requested locale not available in this version of node. The `full-icu` npm module can provide additional locales. For help, see https://github.com/GoogleChrome/lighthouse/blob/master/readme.md#how-do-i-get-localized-lighthouse-results-via-the-cli"),ei.warn("i18n",`locale(s) '${e}' not available. Falling back to default '${ni}'`)),o||ni},createIcuMessageFn,
109
+ isStringOrIcuMessage:function isStringOrIcuMessage(e){return"string"==typeof e||ri(e)},createMessageInstanceIdFn:createIcuMessageFn};const si=on.default,ci=mn,li=hn,ui={warningSlowHostCpu:"The tested device appears to have a slower CPU than Lighthouse expects. This can negatively affect your performance score. Learn more about [calibrating an appropriate CPU slowdown multiplier](https://github.com/GoogleChrome/lighthouse/blob/master/docs/throttling.md#cpu-throttling)."},di=oi.createMessageInstanceIdFn("lighthouse-core/gather/driver/environment.js",ui);function getSlowHostCpuWarning(e){const{settings:t,baseArtifacts:r}=e,{throttling:a,throttlingMethod:n}=t,i=ci.defaultSettings.throttling;if("cli"!==t.channel)return;const o="simulate"===n||"devtools"===n,s=a.cpuSlowdownMultiplier===i.cpuSlowdownMultiplier;return!o||!s||r.BenchmarkIndex>1e3?void 0:di(ui.warningSlowHostCpu)}var mi={UIStrings:ui,getBrowserVersion:async function getBrowserVersion$3(e){const t={msg:"Getting browser version",
110
+ id:"lh:gather:getVersion"};si.time(t,"verbose");const r=await e.sendCommand("Browser.getVersion"),a=r.product.match(/\/(\d+)/),n=a?parseInt(a[1]):0;return si.timeEnd(t),Object.assign(r,{milestone:n})},getBenchmarkIndex:async function getBenchmarkIndex$2(e){const t={msg:"Benchmarking machine",id:"lh:gather:getBenchmarkIndex"};si.time(t);const r=await e.evaluate(li.computeBenchmarkIndex,{args:[]});return si.timeEnd(t),r},getSlowHostCpuWarning,getEnvironmentWarnings:function getEnvironmentWarnings$2(e){return[getSlowHostCpuWarning(e)].filter((e=>!!e))}};
111
111
  /**
112
112
  * @license Copyright 2020 Google Inc. All Rights Reserved.
113
113
  * 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
@@ -130,8 +130,8 @@ code:"CHROME_INTERSTITIAL_ERROR",message:bi.pageLoadFailedInterstitial,lhrRuntim
130
130
  ERRORED_REQUIRED_ARTIFACT:{code:"ERRORED_REQUIRED_ARTIFACT",message:bi.erroredRequiredArtifact}};LighthouseError$2.errors=Ei,LighthouseError$2.NO_ERROR="NO_ERROR",LighthouseError$2.UNKNOWN_ERROR="UNKNOWN_ERROR",vi.exports=LighthouseError$2,vi.exports.UIStrings=bi;const xi="…",_i="data:image/jpeg;base64,",Ai={label:"pass",minScore:.9},Ri={label:"average",minScore:.5},ki={label:"fail"},Di={label:"error"},Ci=["com","co","gov","edu","ac","org","go","gob","or","net","in","ne","nic","gouv","web","spb","blog","jus","kiev","mil","wi","qc","ca","bel","on"];class Util$3{static i18n=null;static get PASS_THRESHOLD(){return.9}static get MS_DISPLAY_VALUE(){return"%10d ms"}static prepareReportResult(e){const t=JSON.parse(JSON.stringify(e));t.configSettings.locale||(t.configSettings.locale="en"),t.configSettings.formFactor||(t.configSettings.formFactor=t.configSettings.emulatedFormFactor)
131
131
  ;for(const e of Object.values(t.audits))if("not_applicable"!==e.scoreDisplayMode&&"not-applicable"!==e.scoreDisplayMode||(e.scoreDisplayMode="notApplicable"),e.details&&(void 0!==e.details.type&&"diagnostic"!==e.details.type||(e.details.type="debugdata"),"filmstrip"===e.details.type))for(const t of e.details.items)t.data.startsWith(_i)||(t.data=_i+t.data);if("object"!=typeof t.categories)throw new Error("No categories provided.");const r=new Map,[a]=t.lighthouseVersion.split(".").map(Number),n=t.categories.performance;if(a<9&&n){t.categoryGroups||(t.categoryGroups={}),t.categoryGroups.hidden={title:""};for(const e of n.auditRefs)e.group?["load-opportunities","diagnostics"].includes(e.group)&&delete e.group:e.group="hidden"}for(const e of Object.values(t.categories))e.auditRefs.forEach((e=>{e.relevantAudits&&e.relevantAudits.forEach((t=>{const a=r.get(t)||[];a.push(e),r.set(t,a)}))})),e.auditRefs.forEach((e=>{const a=t.audits[e.id];e.result=a,
132
132
  r.has(e.id)&&(e.relevantMetrics=r.get(e.id)),t.stackPacks&&t.stackPacks.forEach((t=>{t.descriptions[e.id]&&(e.stackPacks=e.stackPacks||[],e.stackPacks.push({title:t.title,iconDataURL:t.iconDataURL,description:t.descriptions[e.id]}))}))}));return t}static showAsPassed(e){switch(e.scoreDisplayMode){case"manual":case"notApplicable":return!0;case"error":case"informative":return!1;case"numeric":case"binary":default:return Number(e.score)>=Ai.minScore}}static calculateRating(e,t){if("manual"===t||"notApplicable"===t)return Ai.label;if("error"===t)return Di.label;if(null===e)return ki.label;let r=ki.label;return e>=Ai.minScore?r=Ai.label:e>=Ri.minScore&&(r=Ri.label),r}static splitMarkdownCodeSpans(e){const t=[],r=e.split(/`(.*?)`/g);for(let e=0;e<r.length;e++){const a=r[e];if(!a)continue;const n=e%2!=0;t.push({isCode:n,text:a})}return t}static splitMarkdownLink(e){const t=[],r=e.split(/\[([^\]]+?)\]\((https?:\/\/.*?)\)/g);for(;r.length;){const[e,a,n]=r.splice(0,3);e&&t.push({isLink:!1,text:e
133
- }),a&&n&&t.push({isLink:!0,text:a,linkHref:n})}return t}static getURLDisplayName(e,t){const r=void 0!==(t=t||{numPathParts:void 0,preserveQuery:void 0,preserveHost:void 0}).numPathParts?t.numPathParts:2,a=void 0===t.preserveQuery||t.preserveQuery,n=t.preserveHost||!1;let i;if("about:"===e.protocol||"data:"===e.protocol)i=e.href;else{i=e.pathname;const t=i.split("/").filter((e=>e.length));r&&t.length>r&&(i=xi+t.slice(-1*r).join("/")),n&&(i=`${e.host}/${i.replace(/^\//,"")}`),a&&(i=`${i}${e.search}`)}if(i=i.replace(/([a-f0-9]{7})[a-f0-9]{13}[a-f0-9]*/g,"$1…"),i=i.replace(/([a-zA-Z0-9-_]{9})(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])[a-zA-Z0-9-_]{10,}/g,"$1…"),i=i.replace(/(\d{3})\d{6,}/g,"$1…"),i=i.replace(/\u2026+/g,xi),i.length>64&&i.includes("?")&&(i=i.replace(/\?([^=]*)(=)?.*/,"?$1$2…"),i.length>64&&(i=i.replace(/\?.*/,"?…"))),i.length>64){const e=i.lastIndexOf(".");i=e>=0?i.slice(0,63-(i.length-e))+`…${i.slice(e)}`:i.slice(0,63)+xi}return i}static parseURL(e){const t=new URL(e);return{
134
- file:Util$3.getURLDisplayName(t),hostname:t.hostname,origin:t.origin}}static createOrReturnURL(e){return e instanceof URL?e:new URL(e)}static getTld(e){const t=e.split(".").slice(-2);return Ci.includes(t[0])?`.${t.join(".")}`:`.${t[t.length-1]}`}static getRootDomain(e){const t=Util$3.createOrReturnURL(e).hostname,r=Util$3.getTld(t).split(".");return t.split(".").slice(-r.length).join(".")}static getEmulationDescriptions(e){let t,r,a;const n=e.throttling;switch(e.throttlingMethod){case"provided":a=r=t=Util$3.i18n.strings.throttlingProvided;break;case"devtools":{const{cpuSlowdownMultiplier:e,requestLatencyMs:i}=n;t=`${Util$3.i18n.formatNumber(e)}x slowdown (DevTools)`,r=`${Util$3.i18n.formatNumber(i)} ms HTTP RTT, ${Util$3.i18n.formatNumber(n.downloadThroughputKbps)} Kbps down, ${Util$3.i18n.formatNumber(n.uploadThroughputKbps)} Kbps up (DevTools)`
133
+ }),a&&n&&t.push({isLink:!0,text:a,linkHref:n})}return t}static getURLDisplayName(e,t){const r=void 0!==(t=t||{numPathParts:void 0,preserveQuery:void 0,preserveHost:void 0}).numPathParts?t.numPathParts:2,a=void 0===t.preserveQuery||t.preserveQuery,n=t.preserveHost||!1;let i;if("about:"===e.protocol||"data:"===e.protocol)i=e.href;else{i=e.pathname;const t=i.split("/").filter((e=>e.length));r&&t.length>r&&(i=xi+t.slice(-1*r).join("/")),n&&(i=`${e.host}/${i.replace(/^\//,"")}`),a&&(i=`${i}${e.search}`)}if("data:"!==e.protocol&&(i=i.replace(/([a-f0-9]{7})[a-f0-9]{13}[a-f0-9]*/g,"$1…"),i=i.replace(/([a-zA-Z0-9-_]{9})(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])[a-zA-Z0-9-_]{10,}/g,"$1…"),i=i.replace(/(\d{3})\d{6,}/g,"$1…"),i=i.replace(/\u2026+/g,xi),i.length>64&&i.includes("?")&&(i=i.replace(/\?([^=]*)(=)?.*/,"?$1$2…"),i.length>64&&(i=i.replace(/\?.*/,"?…")))),i.length>64){const e=i.lastIndexOf(".");i=e>=0?i.slice(0,63-(i.length-e))+`…${i.slice(e)}`:i.slice(0,63)+xi}return i}static parseURL(e){
134
+ const t=new URL(e);return{file:Util$3.getURLDisplayName(t),hostname:t.hostname,origin:t.origin}}static createOrReturnURL(e){return e instanceof URL?e:new URL(e)}static getTld(e){const t=e.split(".").slice(-2);return Ci.includes(t[0])?`.${t.join(".")}`:`.${t[t.length-1]}`}static getRootDomain(e){const t=Util$3.createOrReturnURL(e).hostname,r=Util$3.getTld(t).split(".");return t.split(".").slice(-r.length).join(".")}static getEmulationDescriptions(e){let t,r,a;const n=e.throttling;switch(e.throttlingMethod){case"provided":a=r=t=Util$3.i18n.strings.throttlingProvided;break;case"devtools":{const{cpuSlowdownMultiplier:e,requestLatencyMs:i}=n;t=`${Util$3.i18n.formatNumber(e)}x slowdown (DevTools)`,r=`${Util$3.i18n.formatNumber(i)} ms HTTP RTT, ${Util$3.i18n.formatNumber(n.downloadThroughputKbps)} Kbps down, ${Util$3.i18n.formatNumber(n.uploadThroughputKbps)} Kbps up (DevTools)`
135
135
  ;a=(()=>562.5===i&&n.downloadThroughputKbps===1638.4*.9&&675===n.uploadThroughputKbps)()?Util$3.i18n.strings.runtimeSlow4g:Util$3.i18n.strings.runtimeCustom;break}case"simulate":{const{cpuSlowdownMultiplier:e,rttMs:i,throughputKbps:o}=n;t=`${Util$3.i18n.formatNumber(e)}x slowdown (Simulated)`,r=`${Util$3.i18n.formatNumber(i)} ms TCP RTT, ${Util$3.i18n.formatNumber(o)} Kbps throughput (Simulated)`;a=(()=>150===i&&1638.4===o)()?Util$3.i18n.strings.runtimeSlow4g:Util$3.i18n.strings.runtimeCustom;break}default:a=t=r=Util$3.i18n.strings.runtimeUnknown}return{deviceEmulation:{mobile:Util$3.i18n.strings.runtimeMobileEmulation,desktop:Util$3.i18n.strings.runtimeDesktopEmulation}[e.formFactor]||Util$3.i18n.strings.runtimeNoEmulation,cpuThrottling:t,networkThrottling:r,summary:a}}static filterRelevantLines(e,t,r){if(0===t.length)return e.slice(0,2*r+1);const a=new Set;return(t=t.sort(((e,t)=>(e.lineNumber||0)-(t.lineNumber||0)))).forEach((({lineNumber:e})=>{let t=e-r,n=e+r;for(;t<1;)t++,n++
136
136
  ;a.has(t-3-1)&&(t-=3);for(let e=t;e<=n;e++){const t=e;a.add(t)}})),e.filter((e=>a.has(e.lineNumber)))}static isPluginCategory(e){return e.startsWith("lighthouse-plugin-")}static shouldDisplayAsFraction(e){return"timespan"===e||"snapshot"===e}static calculateCategoryFraction(e){let t=0,r=0,a=0,n=0;for(const i of e.auditRefs){const e=Util$3.showAsPassed(i.result);"hidden"!==i.group&&"manual"!==i.result.scoreDisplayMode&&"notApplicable"!==i.result.scoreDisplayMode&&("informative"!==i.result.scoreDisplayMode?(++t,n+=i.weight,e&&r++):e||++a)}return{numPassed:r,numPassableAudits:t,numInformative:a,totalWeight:n}}}Util$3.reportJson=null,Util$3.getUniqueSuffix=(()=>{let e=0;return function(){return e++}})();const Ii={varianceDisclaimer:"Values are estimated and may vary. The [performance score is calculated](https://web.dev/performance-scoring/) directly from these metrics.",calculatorLink:"See calculator.",showRelevantAudits:"Show audits relevant to:",
137
137
  opportunityResourceColumnLabel:"Opportunity",opportunitySavingsColumnLabel:"Estimated Savings",errorMissingAuditInfo:"Report error: no audit information",errorLabel:"Error!",warningHeader:"Warnings: ",warningAuditsGroupTitle:"Passed audits but with warnings",passedAuditsGroupTitle:"Passed audits",notApplicableAuditsGroupTitle:"Not applicable",manualAuditsGroupTitle:"Additional items to manually check",toplevelWarningsMessage:"There were issues affecting this run of Lighthouse:",crcInitialNavigation:"Initial Navigation",crcLongestDurationLabel:"Maximum critical path latency:",snippetExpandButtonLabel:"Expand snippet",snippetCollapseButtonLabel:"Collapse snippet",lsPerformanceCategoryDescription:"[Lighthouse](https://developers.google.com/web/tools/lighthouse/) analysis of the current page on an emulated mobile network. Values are estimated and may vary.",labDataTitle:"Lab Data",thirdPartyResourcesLabel:"Show 3rd-party resources",viewTreemapLabel:"View Treemap",
@@ -164,7 +164,7 @@ on(e,t){if("protocolevent"!==e)throw new Error('Only supports "protocolevent" ev
164
164
  t.result})));else{const e=t.error?.message;co.formatProtocol("disowned method <= browser "+(e?"ERR":"OK"),{method:"UNKNOWN",params:e||t.result},"verbose")}}emitProtocolEvent(e){if(!this._eventEmitter)throw new Error("Attempted to emit event after connection disposed.");this._eventEmitter.emit("protocolevent",e)}dispose(){this._eventEmitter&&(this._eventEmitter.removeAllListeners(),this._eventEmitter=null)}};const mo=gi,po=yi,ho=vi.exports,{fetchResponseBodyFromCache:go}=Xi,fo=Zi.EventEmitter,yo=on.default,vo=Qi,bo=oo,{getBrowserVersion:wo}=mi,So=3e4;var To=class Driver$5{_eventEmitter=new fo;_devtoolsLog=new vo(/^(Page|Network)\./);_domainEnabledCounts=new Map;_nextProtocolTimeout=So;online=!0;executionContext=new po(this);defaultSession=this;fetcher=new mo(this.defaultSession,this.executionContext);constructor(e){this._connection=e,this.on("Target.attachedToTarget",(e=>{this._handleTargetAttached(e).catch(this._handleEventError)})),this.on("Page.frameNavigated",(e=>{
165
165
  e.frame.parentId||this.sendCommand("Target.setAutoAttach",{flatten:!0,autoAttach:!0,waitForDebuggerOnStart:!0}).catch(this._handleEventError)})),e.on("protocolevent",this._handleProtocolEvent.bind(this)),this.evaluate=this.executionContext.evaluate.bind(this.executionContext),this.evaluateAsync=this.executionContext.evaluateAsync.bind(this.executionContext)}static get traceCategories(){return bo.getDefaultTraceCategories()}async getBrowserVersion(){return wo(this)}async connect(){const e={msg:"Connecting to browser",id:"lh:init:connect"};yo.time(e),await this._connection.connect(),yo.timeEnd(e)}disconnect(){return this._connection.disconnect()}dispose(){return this.disconnect()}wsEndpoint(){return this._connection.wsEndpoint()}on(e,t){if(null===this._eventEmitter)throw new Error("connect() must be called before attempting to listen to events.");yo.formatProtocol("listen for event =>",{method:e},"verbose"),this._eventEmitter.on(e,t)}once(e,t){
166
166
  if(null===this._eventEmitter)throw new Error("connect() must be called before attempting to listen to events.");yo.formatProtocol("listen once for event =>",{method:e},"verbose"),this._eventEmitter.once(e,t)}off(e,t){if(null===this._eventEmitter)throw new Error("connect() must be called before attempting to remove an event listener.");this._eventEmitter.removeListener(e,t)}addProtocolMessageListener(e){this._connection.on("protocolevent",e)}removeProtocolMessageListener(e){this._connection.off("protocolevent",e)}setTargetInfo(e){}addSessionAttachedListener(e){}removeSessionAttachedListener(e){}_shouldToggleDomain(e,t,r){const a=e+(t||""),n=(this._domainEnabledCounts.get(a)||0)+(r?1:-1);return this._domainEnabledCounts.set(a,Math.max(0,n)),r&&1===n||!r&&0===n?(yo.verbose("Driver",`${e}.${r?"enable":"disable"}`),!0):(n<0&&yo.error("Driver",`Attempted to disable domain '${e}' when already disabled.`),!1)}hasNextProtocolTimeout(){return this._nextProtocolTimeout!==So}
167
- getNextProtocolTimeout(){return this._nextProtocolTimeout}setNextProtocolTimeout(e){this._nextProtocolTimeout=e}_handleProtocolEvent(e){this._devtoolsLog.record(e),this._eventEmitter.emit(e.method,e.params)}_handleEventError(e){yo.error("Driver","Unhandled event error",e.message)}async _handleTargetAttached(e){"iframe"===e.targetInfo.type?(await this.sendCommandToSession("Network.enable",e.sessionId),await this.sendCommandToSession("Target.setAutoAttach",e.sessionId,{autoAttach:!0,flatten:!0,waitForDebuggerOnStart:!0}),await this.sendCommandToSession("Runtime.runIfWaitingForDebugger",e.sessionId)):await this.sendCommandToSession("Runtime.runIfWaitingForDebugger",e.sessionId)}sendCommandToSession(e,t,...r){const a=this._nextProtocolTimeout;let n;this._nextProtocolTimeout=So;const i=new Promise(((t,r)=>{a!==1/0&&(n=setTimeout(r,a,new ho(ho.errors.PROTOCOL_TIMEOUT,{protocolMethod:e})))}));return Promise.race([this._innerSendCommand(e,t,...r),i]).finally((()=>{n&&clearTimeout(n)}))}
167
+ getNextProtocolTimeout(){return this._nextProtocolTimeout}setNextProtocolTimeout(e){this._nextProtocolTimeout=e}_handleProtocolEvent(e){this._devtoolsLog.record(e),this._eventEmitter.emit(e.method,e.params)}_handleEventError(e){yo.error("Driver","Unhandled event error",e.message)}async _handleTargetAttached(e){"iframe"===e.targetInfo.type?await Promise.all([this.sendCommandToSession("Network.enable",e.sessionId),this.sendCommandToSession("Target.setAutoAttach",e.sessionId,{autoAttach:!0,flatten:!0,waitForDebuggerOnStart:!0}),this.sendCommandToSession("Runtime.runIfWaitingForDebugger",e.sessionId)]):await this.sendCommandToSession("Runtime.runIfWaitingForDebugger",e.sessionId)}sendCommandToSession(e,t,...r){const a=this._nextProtocolTimeout;let n;this._nextProtocolTimeout=So;const i=new Promise(((t,r)=>{a!==1/0&&(n=setTimeout(r,a,new ho(ho.errors.PROTOCOL_TIMEOUT,{protocolMethod:e})))}));return Promise.race([this._innerSendCommand(e,t,...r),i]).finally((()=>{n&&clearTimeout(n)}))}
168
168
  sendCommand(e,...t){return this.sendCommandToSession(e,void 0,...t)}_innerSendCommand(e,t,...r){const a=/^(\w+)\.(enable|disable)$/.exec(e);if(a){const e="enable"===a[2];if(!this._shouldToggleDomain(a[1],t,e))return Promise.resolve()}return this._connection.sendCommand(e,t,...r)}isDomainEnabled(e){return!!this._domainEnabledCounts.get(e)}async getRequestContent(e,t=1e3){return go(this.defaultSession,e,t)}scrollTo(e){const t=`window.scrollTo(${e.x}, ${e.y})`;return this.executionContext.evaluateAsync(t,{useIsolation:!0})}getScrollPosition(){return this.executionContext.evaluateAsync("({x: window.scrollX, y: window.scrollY})",{useIsolation:!0})}async beginTrace(e){const t=e?.additionalTraceCategories&&e.additionalTraceCategories.split(",")||[],r=bo.getDefaultTraceCategories().concat(t),a=Array.from(new Set(r));if(this.isDomainEnabled("CSS"))throw new Error("CSS domain enabled when starting trace");if(this.isDomainEnabled("DOM"))throw new Error("DOM domain enabled when starting trace")
169
169
  ;return this.sendCommand("Page.enable").then((e=>this.sendCommand("Tracing.start",{categories:a.join(","),options:"sampling-frequency=10000"})))}endTrace(){return bo.endTraceAndCollectEvents(this.defaultSession)}beginDevtoolsLog(){this._devtoolsLog.reset(),this._devtoolsLog.beginRecording()}endDevtoolsLog(){return this._devtoolsLog.endRecording(),this._devtoolsLog.messages}};const Eo=la;class ArbitraryEqualityMap$1{constructor(){this._equalsFn=ArbitraryEqualityMap$1.deepEquals,this._entries=[]}setEqualityFn(e){this._equalsFn=e}has(e){return-1!==this._findIndexOf(e)}get(e){return this._entries[this._findIndexOf(e)]?.value}set(e,t){let r=this._findIndexOf(e);-1===r&&(r=this._entries.length),this._entries[r]={key:e,value:t}}_findIndexOf(e){for(let t=0;t<this._entries.length;t++)if(this._equalsFn(e,this._entries[t].key))return t;return-1}static deepEquals(e,t){return Eo(e,t)}}const xo=ArbitraryEqualityMap$1,_o=on.default;var Ao=function makeComputedArtifact$J(e,t){return Object.assign(e,{
170
170
  request:(r,a)=>{const n=t?Object.fromEntries(t.map((e=>[e,r[e]]))):r,i=a.computedCache,o=e.name,s=i.get(o)||new xo;i.set(o,s);const c=s.get(n);if(c)return c;const l={msg:`Computing artifact: ${o}`,id:`lh:computed:${o}`};_o.time(l,"verbose");const u=e.compute_(n,a);return s.set(n,u),u.then((()=>_o.timeEnd(l))).catch((()=>_o.timeEnd(l))),u}})};const Ro=on.default,ko=Ki,Do=Zi.EventEmitter;class NetworkRecorder$2 extends Do{constructor(){super(),this._records=[],this._recordsById=new Map,this._mainSessionId=null}getRawRecords(){return Array.from(this._records)}on(e,t){return super.on(e,t)}once(e,t){return super.once(e,t)}onRequestStarted(e){this._records.push(e),this._recordsById.set(e.requestId,e),this.emit("requeststarted",e)}onRequestFinished(e){this.emit("requestloaded",e)}onRequestWillBeSent(e){const t=e.params,r=this._findRealRequestAndSetSession(t.requestId,e.sessionId);if(!r){const r=new ko;return r.onRequestWillBeSent(t),r.sessionId=e.sessionId,this.onRequestStarted(r),
@@ -178,7 +178,7 @@ if(!Number.isFinite(r.receiveHeadersEnd)||r.receiveHeadersEnd<0)return;if(!Numbe
178
178
  static estimateRTTByOrigin(e,t){const{forceCoarseEstimates:r=!1,coarseEstimateMultiplier:a=.3,useDownloadEstimates:n=!0,useSendStartEstimates:i=!0,useHeadersEndEstimates:o=!0}=t||{};let s=NetworkAnalyzer$b._estimateRTTByOriginViaTCPTiming(e);if(!s.size||r){s=new Map;const t=NetworkAnalyzer$b._estimateRTTByOriginViaDownloadTiming(e),r=NetworkAnalyzer$b._estimateRTTByOriginViaSendStartTiming(e),c=NetworkAnalyzer$b._estimateRTTByOriginViaHeadersEndTiming(e);for(const[e,r]of t.entries())n&&s.set(e,r);for(const[e,t]of r.entries()){if(!i)continue;const r=s.get(e)||[];s.set(e,r.concat(t))}for(const[e,t]of c.entries()){if(!o)continue;const r=s.get(e)||[];s.set(e,r.concat(t))}for(const e of s.values())e.forEach(((t,r)=>e[r]=t*a))}if(!s.size)throw new Error("No timing information available");return NetworkAnalyzer$b.summarize(s)}static estimateServerResponseTimeByOrigin(e,t){let r=(t||{}).rttByOrigin;if(!r){r=new Map;const a=NetworkAnalyzer$b.estimateRTTByOrigin(e,t)
179
179
  ;for(const[e,t]of a.entries())r.set(e,t.min)}const a=NetworkAnalyzer$b._estimateResponseTimeByOrigin(e,r);return NetworkAnalyzer$b.summarize(a)}static estimateThroughput(e){let t=0;const r=e.reduce(((e,r)=>("data"===r.parsedURL?.scheme||r.failed||!r.finished||r.statusCode>300||!r.transferSize||(t+=r.transferSize,e.push({time:r.responseReceivedTime,isStart:!0}),e.push({time:r.endTime,isStart:!1})),e)),[]).sort(((e,t)=>e.time-t.time));if(!r.length)return 1/0;let a=0,n=0,i=0;return r.forEach((e=>{e.isStart?(0===a&&(n=e.time),a++):(a--,0===a&&(i+=e.time-n))})),8*t/i}static findMainDocument(e,t){const r=NetworkAnalyzer$b.findOptionalMainDocument(e,t);if(!r)throw new Error("Unable to identify the main resource");return r}static findOptionalMainDocument(e,t){if(t){const r=e.find((e=>t.startsWith(e.url)&&Po.equalWithExcludedFragments(e.url,t)));if(r)return r}const r=e.filter((e=>e.resourceType===Mo.TYPES.Document));if(r.length)return r.reduce(((e,t)=>t.startTime<e.startTime?t:e))}
180
180
  static resolveRedirects(e){for(;e.redirectDestination;)e=e.redirectDestination;return e}}var Fo=NetworkAnalyzer$b;const Uo=vi.exports,jo=Fo;function getNetworkError(e){if(!e)return new Uo(Uo.errors.NO_DOCUMENT_REQUEST);if(e.failed){const t=e.localizedFailDescription;return"net::ERR_NAME_NOT_RESOLVED"===t||"net::ERR_NAME_RESOLUTION_FAILED"===t||t.startsWith("net::ERR_DNS_")?new Uo(Uo.errors.DNS_FAILURE):new Uo(Uo.errors.FAILED_DOCUMENT_REQUEST,{errorDetails:t})}return e.hasErrorStatusCode()?new Uo(Uo.errors.ERRORED_DOCUMENT_REQUEST,{statusCode:`${e.statusCode}`}):void 0}function getInterstitialError(e,t){if(!e)return;return t.find((e=>e.documentURL.startsWith("chrome-error://")))&&e.failed?e.localizedFailDescription.startsWith("net::ERR_CERT")?new Uo(Uo.errors.INSECURE_DOCUMENT_REQUEST,{securityMessages:e.localizedFailDescription}):new Uo(Uo.errors.CHROME_INTERSTITIAL_ERROR):void 0}function getNonHtmlError(e){if(e)return"text/html"!==e.mimeType?new Uo(Uo.errors.NOT_HTML,{
181
- mimeType:e.mimeType}):void 0}var Bo={getNetworkError,getInterstitialError,getPageLoadError:function getPageLoadError$2(e,t){const{url:r,loadFailureMode:a,networkRecords:n}=t;let i,o;try{i=jo.findMainDocument(n,r)}catch(e){}i&&(o=jo.resolveRedirects(i));const s=getNetworkError(i),c=getInterstitialError(i,n),l=getNonHtmlError(o);if("ignore"!==a)return c||(s||(l||e))},getNonHtmlError};var $o=getAugmentedNamespace(Object.freeze({__proto__:null,version:"9.6.1"}));const{version:qo}=$o,zo={latency:0,downloadThroughput:0,uploadThroughput:0,offline:!1},Vo={rate:1};function parseUseragentIntoMetadata(e,t){const r=e.match(/Chrome\/([\d.]+)/)?.[1]||"99.0.1234.0",[a]=r.split(".",1),n="mobile"===t;return{brands:[{brand:"Chromium",version:a},{brand:"Google Chrome",version:a},{brand:"Lighthouse",version:qo}],fullVersion:r,...n?{platform:"Android",platformVersion:"6.0",architecture:"",model:"Moto G4"}:{platform:"macOS",platformVersion:"10.15.7",architecture:"x86",model:""},mobile:n}}
181
+ mimeType:e.mimeType}):void 0}var Bo={getNetworkError,getInterstitialError,getPageLoadError:function getPageLoadError$2(e,t){const{url:r,loadFailureMode:a,networkRecords:n}=t;let i,o;try{i=jo.findMainDocument(n,r)}catch(e){}i&&(o=jo.resolveRedirects(i));const s=getNetworkError(i),c=getInterstitialError(i,n),l=getNonHtmlError(o);if("ignore"!==a)return c||(s||(l||e))},getNonHtmlError};var $o=getAugmentedNamespace(Object.freeze({__proto__:null,version:"9.6.2"}));const{version:qo}=$o,zo={latency:0,downloadThroughput:0,uploadThroughput:0,offline:!1},Vo={rate:1};function parseUseragentIntoMetadata(e,t){const r=e.match(/Chrome\/([\d.]+)/)?.[1]||"99.0.1234.0",[a]=r.split(".",1),n="mobile"===t;return{brands:[{brand:"Chromium",version:a},{brand:"Google Chrome",version:a},{brand:"Lighthouse",version:qo}],fullVersion:r,...n?{platform:"Android",platformVersion:"6.0",architecture:"",model:"Moto G4"}:{platform:"macOS",platformVersion:"10.15.7",architecture:"x86",model:""},mobile:n}}
182
182
  function enableNetworkThrottling(e,t){const r={offline:!1,latency:t.requestLatencyMs||0,downloadThroughput:t.downloadThroughputKbps||0,uploadThroughput:t.uploadThroughputKbps||0};return r.downloadThroughput=Math.floor(1024*r.downloadThroughput/8),r.uploadThroughput=Math.floor(1024*r.uploadThroughput/8),e.sendCommand("Network.emulateNetworkConditions",r)}function clearNetworkThrottling(e){return e.sendCommand("Network.emulateNetworkConditions",zo)}function enableCPUThrottling(e,t){const r=t.cpuSlowdownMultiplier;return e.sendCommand("Emulation.setCPUThrottlingRate",{rate:r})}function clearCPUThrottling(e){return e.sendCommand("Emulation.setCPUThrottlingRate",Vo)}var Wo={emulate:async function emulate(e,t){if(!1!==t.emulatedUserAgent){const r=t.emulatedUserAgent;await e.sendCommand("Network.setUserAgentOverride",{userAgent:r,userAgentMetadata:parseUseragentIntoMetadata(r,t.formFactor)})}if(!0!==t.screenEmulation.disabled){
183
183
  const{width:r,height:a,deviceScaleFactor:n,mobile:i}=t.screenEmulation,o={width:r,height:a,deviceScaleFactor:n,mobile:i};await e.sendCommand("Emulation.setDeviceMetricsOverride",o),await e.sendCommand("Emulation.setTouchEmulationEnabled",{enabled:o.mobile})}},throttle:async function throttle(e,t){if("devtools"!==t.throttlingMethod)return clearNetworkThrottling(e);await Promise.all([enableNetworkThrottling(e,t.throttling),enableCPUThrottling(e,t.throttling)])},clearThrottling:async function clearThrottling(e){await Promise.all([clearNetworkThrottling(e),clearCPUThrottling(e)])},enableNetworkThrottling,clearNetworkThrottling,enableCPUThrottling,clearCPUThrottling};const Go=on.default,Ho={
184
184
  warningData:"{locationCount, plural,\n =1 {There may be stored data affecting loading performance in this location: {locations}. Audit this page in an incognito window to prevent those resources from affecting your scores.}\n other {There may be stored data affecting loading performance in these locations: {locations}. Audit this page in an incognito window to prevent those resources from affecting your scores.}\n }"},Yo=oi.createMessageInstanceIdFn("lighthouse-core/gather/driver/storage.js",Ho);var Ko={clearDataForOrigin:async function clearDataForOrigin(e,t){const r={msg:"Cleaning origin data",id:"lh:storage:clearDataForOrigin"};Go.time(r);const a=new URL(t).origin,n=["file_systems","shader_cache","service_workers","cache_storage"].join(",");e.setNextProtocolTimeout(5e3);try{await e.sendCommand("Storage.clearDataForOrigin",{origin:a,storageTypes:n})}catch(e){if("PROTOCOL_TIMEOUT"!==e.code)throw e;Go.warn("Driver","clearDataForOrigin timed out")}finally{Go.timeEnd(r)}},
@@ -286,7 +286,9 @@ export class ReportUIFeatures {
286
286
  */
287
287
  _saveFile(blob: Blob | File): void;
288
288
  }
289
- export function format(_: any): void;
289
+ export namespace format {
290
+ export { registerLocaleData };
291
+ }
290
292
  /**
291
293
  * @license Copyright 2021 The Lighthouse Authors. All Rights Reserved.
292
294
  * 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
@@ -298,7 +300,16 @@ export function format(_: any): void;
298
300
  * @return {HTMLElement}
299
301
  */
300
302
  export function renderReport(lhr: LH.Result, opts?: LH.Renderer.Options): HTMLElement;
301
- export function swapLocale(_: any): void;
303
+ /**
304
+ * Returns a new LHR with all strings changed to the new requestedLocale.
305
+ * @param {LH.Result} lhr
306
+ * @param {LH.Locale} requestedLocale
307
+ * @return {{lhr: LH.Result, missingIcuMessageIds: string[]}}
308
+ */
309
+ export function swapLocale(lhr: LH.Result, requestedLocale: LH.Locale): {
310
+ lhr: LH.Result;
311
+ missingIcuMessageIds: string[];
312
+ };
302
313
  /**
303
314
  * @license
304
315
  * Copyright 2017 The Lighthouse Authors. All Rights Reserved.
@@ -569,6 +580,16 @@ declare class TopbarFeatures {
569
580
  */
570
581
  _updateStickyHeader(): void;
571
582
  }
583
+ /**
584
+ * Populate the i18n string lookup dict with locale data
585
+ * Used when the host environment selects the locale and serves lighthouse the intended locale file
586
+ * @see https://docs.google.com/document/d/1jnt3BqKB-4q3AE94UWFA0Gqspx8Sd_jivlB7gQMlmfk/edit
587
+ * @param {LH.Locale} locale
588
+ * @param {Record<string, {message: string}>} lhlMessages
589
+ */
590
+ declare function registerLocaleData(locale: LH.Locale, lhlMessages: Record<string, {
591
+ message: string;
592
+ }>): void;
572
593
  declare class DetailsRenderer {
573
594
  /**
574
595
  * @param {DOM} dom