chrome-devtools-frontend 1.0.1635876 → 1.0.1638082

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 (93) hide show
  1. package/.agents/skills/verification/SKILL.md +1 -1
  2. package/front_end/core/common/Color.ts +0 -4
  3. package/front_end/core/i18n/collect-ui-strings.js +3 -3
  4. package/front_end/core/root/Runtime.ts +5 -0
  5. package/front_end/core/sdk/SourceMap.ts +8 -3
  6. package/front_end/generated/ARIAProperties.js +17 -0
  7. package/front_end/generated/InspectorBackendCommands.ts +7 -5
  8. package/front_end/generated/SupportedCSSProperties.js +1 -0
  9. package/front_end/generated/protocol.ts +40 -2
  10. package/front_end/models/ai_assistance/AiConversation.ts +0 -8
  11. package/front_end/models/ai_assistance/AiHistoryStorage.ts +0 -1
  12. package/front_end/models/ai_assistance/AiUtils.ts +9 -0
  13. package/front_end/models/ai_assistance/agents/AccessibilityAgent.ts +17 -36
  14. package/front_end/models/ai_assistance/agents/AiAgent.ts +34 -10
  15. package/front_end/models/ai_assistance/agents/ContextSelectionAgent.ts +6 -0
  16. package/front_end/models/ai_assistance/agents/GreenDevAgent.ts +0 -2
  17. package/front_end/models/ai_assistance/agents/NetworkAgent.snapshot.txt +19 -0
  18. package/front_end/models/ai_assistance/agents/NetworkAgent.ts +6 -0
  19. package/front_end/models/ai_assistance/agents/PerformanceAgent.ts +20 -2
  20. package/front_end/models/ai_assistance/ai_assistance.ts +0 -2
  21. package/front_end/models/bindings/CompilerScriptMapping.ts +12 -4
  22. package/front_end/models/breakpoints/BreakpointManager.ts +54 -2
  23. package/front_end/models/greendev/Prototypes.ts +0 -7
  24. package/front_end/models/issues_manager/EmailVerificationRequestIssue.ts +293 -0
  25. package/front_end/models/issues_manager/IssuesManager.ts +5 -0
  26. package/front_end/models/issues_manager/descriptions/emailVerificationRequestDnsFetchFailed.md +1 -0
  27. package/front_end/models/issues_manager/descriptions/emailVerificationRequestDnsInvalidRecord.md +1 -0
  28. package/front_end/models/issues_manager/descriptions/emailVerificationRequestInvalidEmail.md +1 -0
  29. package/front_end/models/issues_manager/descriptions/emailVerificationRequestKeyBindingSigningFailed.md +1 -0
  30. package/front_end/models/issues_manager/descriptions/emailVerificationRequestRpOriginIsOpaque.md +1 -0
  31. package/front_end/models/issues_manager/descriptions/emailVerificationRequestTokenHttpNotFound.md +1 -0
  32. package/front_end/models/issues_manager/descriptions/emailVerificationRequestTokenInvalidContentType.md +1 -0
  33. package/front_end/models/issues_manager/descriptions/emailVerificationRequestTokenInvalidResponse.md +1 -0
  34. package/front_end/models/issues_manager/descriptions/emailVerificationRequestTokenInvalidSdJwt.md +1 -0
  35. package/front_end/models/issues_manager/descriptions/emailVerificationRequestTokenMalformedSdJwt.md +1 -0
  36. package/front_end/models/issues_manager/descriptions/emailVerificationRequestTokenNoResponse.md +1 -0
  37. package/front_end/models/issues_manager/descriptions/emailVerificationRequestUserLoggedOut.md +1 -0
  38. package/front_end/models/issues_manager/descriptions/emailVerificationRequestWellKnownAccountsEndpointCrossOrigin.md +1 -0
  39. package/front_end/models/issues_manager/descriptions/emailVerificationRequestWellKnownHttpNotFound.md +1 -0
  40. package/front_end/models/issues_manager/descriptions/emailVerificationRequestWellKnownInvalidContentType.md +1 -0
  41. package/front_end/models/issues_manager/descriptions/emailVerificationRequestWellKnownInvalidResponse.md +1 -0
  42. package/front_end/models/issues_manager/descriptions/emailVerificationRequestWellKnownIssuanceEndpointCrossOrigin.md +1 -0
  43. package/front_end/models/issues_manager/descriptions/emailVerificationRequestWellKnownListEmpty.md +1 -0
  44. package/front_end/models/issues_manager/descriptions/emailVerificationRequestWellKnownMissingAccountsEndpoint.md +1 -0
  45. package/front_end/models/issues_manager/descriptions/emailVerificationRequestWellKnownMissingIssuanceEndpoint.md +1 -0
  46. package/front_end/models/issues_manager/descriptions/emailVerificationRequestWellKnownNoResponse.md +1 -0
  47. package/front_end/models/issues_manager/descriptions/emailVerificationRequestWellKnownUnsupportedSigningAlgorithm.md +1 -0
  48. package/front_end/models/issues_manager/issues_manager.ts +2 -0
  49. package/front_end/models/javascript_metadata/NativeFunctions.js +1739 -1734
  50. package/front_end/models/stack_trace/DetailedErrorStackParser.ts +9 -1
  51. package/front_end/models/trace/lantern/core/NetworkAnalyzer.ts +21 -25
  52. package/front_end/panels/ai_assistance/AiAssistancePanel.ts +11 -75
  53. package/front_end/panels/ai_assistance/components/AccessibilityAgentMarkdownRenderer.ts +10 -3
  54. package/front_end/panels/ai_assistance/components/ChatMessage.ts +66 -1
  55. package/front_end/panels/application/preloading/components/UsedPreloadingView.ts +4 -4
  56. package/front_end/panels/console/ConsoleViewMessage.ts +0 -90
  57. package/front_end/panels/elements/StylePropertiesSection.ts +6 -2
  58. package/front_end/panels/elements/StylesSidebarPane.ts +9 -0
  59. package/front_end/panels/elements/elements-meta.ts +14 -0
  60. package/front_end/panels/network/NetworkLogView.ts +4 -1
  61. package/front_end/panels/network/RequestHeadersView.ts +55 -19
  62. package/front_end/panels/recorder/components/ReplaySection.ts +28 -16
  63. package/front_end/panels/recorder/converters/LighthouseConverter.snapshot.txt +47 -0
  64. package/front_end/panels/recorder/converters/PuppeteerConverter.snapshot.txt +49 -0
  65. package/front_end/panels/recorder/converters/PuppeteerReplayConverter.snapshot.txt +33 -0
  66. package/front_end/panels/settings/SettingsScreen.ts +1 -2
  67. package/front_end/panels/sources/BreakpointsView.ts +23 -42
  68. package/front_end/panels/sources/DebuggerPlugin.ts +12 -5
  69. package/front_end/panels/sources/PersistenceActions.ts +21 -7
  70. package/front_end/panels/timeline/TimelineDetailsView.ts +36 -0
  71. package/front_end/third_party/chromium/README.chromium +1 -1
  72. package/front_end/third_party/lighthouse/lighthouse-dt-bundle.js +2 -2
  73. package/front_end/third_party/puppeteer-replay/README.chromium +2 -2
  74. package/front_end/third_party/puppeteer-replay/package/lib/cli.js +84 -80
  75. package/front_end/third_party/puppeteer-replay/package/lib/cli.js.map +1 -1
  76. package/front_end/third_party/puppeteer-replay/package/lib/extension-test.js +79 -83
  77. package/front_end/third_party/puppeteer-replay/package/lib/extension-test.js.map +1 -1
  78. package/front_end/third_party/puppeteer-replay/package/lib/main.d.ts +43 -171
  79. package/front_end/third_party/puppeteer-replay/package/lib/main.js +51 -206
  80. package/front_end/third_party/puppeteer-replay/package/lib/main.js.map +1 -1
  81. package/front_end/third_party/puppeteer-replay/package/package.json +37 -67
  82. package/front_end/ui/legacy/Dialog.ts +1 -0
  83. package/front_end/ui/legacy/UIUtils.ts +4 -0
  84. package/front_end/ui/visual_logging/KnownContextValues.ts +3 -0
  85. package/mcp/mcp.ts +1 -6
  86. package/package.json +8 -10
  87. package/front_end/models/ai_assistance/agents/BreakpointDebuggerAgent.ts +0 -1015
  88. package/front_end/models/ai_assistance/agents/BreakpointDebuggerAgentOverlay.ts +0 -87
  89. package/front_end/third_party/puppeteer-replay/package/lib/cjs/main.cjs +0 -2099
  90. package/front_end/third_party/puppeteer-replay/package/lib/cjs/main.cjs.map +0 -1
  91. package/front_end/third_party/puppeteer-replay/package/lib/cjs/main.d.cts +0 -686
  92. package/front_end/third_party/puppeteer-replay/package/lib/cjs/main.d.ts +0 -35
  93. package/mcp/HostBindings.ts +0 -319
@@ -2534,7 +2534,10 @@ export class NetworkLogView extends Common.ObjectWrapper.eventMixin<EventTypes,
2534
2534
  // value tells curl to not set the header at all. To post an empty
2535
2535
  // header, you have to terminate it with a semicolon.
2536
2536
  command.push('-H ' + escapeString(name + ';'));
2537
- } else if (name.toLowerCase() === 'cookie') {
2537
+ } else if (name.toLowerCase() === 'cookie' && value.includes('=')) {
2538
+ // If value contains no '=', curl treats it as a filename to read
2539
+ // cookies from, which would be a security risk. Fall back to -H in
2540
+ // that case.
2538
2541
  command.push('-b ' + escapeString(value));
2539
2542
  } else {
2540
2543
  command.push('-H ' + escapeString(name + ': ' + value));
@@ -106,8 +106,8 @@ interface ViewInput {
106
106
  toReveal?: {section: NetworkForward.UIRequestLocation.UIHeaderSection, header?: string};
107
107
  }
108
108
  type View = (input: ViewInput, output: object, target: HTMLElement) => void;
109
- export const DEFAULT_VIEW: View = (input, output, target) => {
110
- const requestHeadersText = input.request.requestHeadersText();
109
+
110
+ export function renderGeneralRows(input: ViewInput): Lit.LitTemplate {
111
111
  const statusClasses = ['status'];
112
112
  if (input.request.statusCode < 300 || input.request.statusCode === 304) {
113
113
  statusClasses.push('green-circle');
@@ -137,28 +137,42 @@ export const DEFAULT_VIEW: View = (input, output, target) => {
137
137
  }
138
138
 
139
139
  const statusText = [input.request.statusCode, input.request.getInferredStatusText(), comment].join(' ');
140
+
141
+ // clang-format off
142
+ return html`<div jslog=${VisualLogging.section('general')}>
143
+ ${renderGeneralRow(input, i18nString(UIStrings.requestUrl), input.request.url(), 'request-url')}
144
+ ${input.request.statusCode ? renderGeneralRow(input, i18nString(UIStrings.requestMethod), input.request.requestMethod, 'request-method') :
145
+ Lit.nothing}
146
+ ${input.request.statusCode ? renderGeneralRow(input, i18nString(UIStrings.statusCode), statusText, 'status-code', statusClasses) :
147
+ Lit.nothing}
148
+ ${input.request.remoteAddress()? renderGeneralRow(input, i18nString(UIStrings.remoteAddress), input.request.remoteAddress(), 'remote-address') :
149
+ Lit.nothing}
150
+ ${input.request.referrerPolicy()? renderGeneralRow(input, i18nString(UIStrings.referrerPolicy), String(input.request.referrerPolicy()), 'referrer-policy') :
151
+ Lit.nothing}
152
+ </div>`;
153
+ // clang-format on
154
+ }
155
+
156
+ export function renderGeneralSection(input: ViewInput, forceOpen: boolean): Lit.LitTemplate {
157
+ // Rendered in a walkthrough widget where we only want rows without the ability to collapse the section.
158
+ return renderCategory({
159
+ name: 'general',
160
+ title: i18nString(UIStrings.general),
161
+ forceOpen,
162
+ loggingContext: 'general',
163
+ contents: renderGeneralRows(input),
164
+ });
165
+ }
166
+
167
+ export const DEFAULT_VIEW: View = (input, _output, target) => {
168
+ const requestHeadersText = input.request.requestHeadersText();
169
+
140
170
  // clang-format off
141
171
  render(
142
172
  html`
143
173
  <style>${NetworkComponents.RequestHeaderSection.requestHeadersViewStyles}</style>
144
174
  <style>${Input.checkboxStyles}</style>
145
- ${renderCategory({
146
- name: 'general',
147
- title: i18nString(UIStrings.general),
148
- forceOpen: input.toReveal?.section === NetworkForward.UIRequestLocation.UIHeaderSection.GENERAL,
149
- loggingContext: 'general',
150
- contents: html`<div jslog=${VisualLogging.section('general')}>
151
- ${renderGeneralRow(input, i18nString(UIStrings.requestUrl), input.request.url(), 'request-url')}
152
- ${input.request.statusCode? renderGeneralRow(input, i18nString(UIStrings.requestMethod),
153
- input.request.requestMethod, 'request-method') : Lit.nothing}
154
- ${input.request.statusCode? renderGeneralRow(input, i18nString(UIStrings.statusCode),
155
- statusText, 'status-code', statusClasses) : Lit.nothing}
156
- ${input.request.remoteAddress()? renderGeneralRow(input, i18nString(UIStrings.remoteAddress),
157
- input.request.remoteAddress(), 'remote-address') : Lit.nothing}
158
- ${input.request.referrerPolicy()? renderGeneralRow(input, i18nString(UIStrings.referrerPolicy),
159
- String(input.request.referrerPolicy()), 'referrer-policy') : Lit.nothing}
160
- </div>`
161
- })}
175
+ ${renderGeneralSection(input, input.toReveal?.section === NetworkForward.UIRequestLocation.UIHeaderSection.GENERAL)}
162
176
  ${!input.request?.earlyHintsHeaders || input.request.earlyHintsHeaders.length === 0
163
177
  ? Lit.nothing
164
178
  : renderCategory({
@@ -221,6 +235,22 @@ export const DEFAULT_VIEW: View = (input, output, target) => {
221
235
  target, {container: {attributes: {jslog: `${VisualLogging.pane('headers').track({resize: true})}`}}});
222
236
  };
223
237
 
238
+ /**
239
+ * View used by the AI Assistance walkthrough's NetworkRequestGeneralHeaders widget
240
+ * to display only the General section of the network headers.
241
+ */
242
+ export const GENERAL_HEADERS_ONLY_VIEW: View = (input, _output, target) => {
243
+ // clang-format off
244
+ render(
245
+ html`
246
+ <style>${NetworkComponents.RequestHeaderSection.requestHeadersViewStyles}</style>
247
+ <style>${Input.checkboxStyles}</style>
248
+ ${renderGeneralRows(input)}
249
+ `,
250
+ target, {container: {attributes: {jslog: `${VisualLogging.pane('headers').track({resize: true})}`}}});
251
+ // clang-format on
252
+ };
253
+
224
254
  export class RequestHeadersView extends UI.Widget.Widget {
225
255
  #request?: SDK.NetworkRequest.NetworkRequest;
226
256
  #showResponseHeadersText = false;
@@ -243,6 +273,12 @@ export class RequestHeadersView extends UI.Widget.Widget {
243
273
  this.#view = view;
244
274
  }
245
275
 
276
+ static createGeneralHeadersView(request: SDK.NetworkRequest.NetworkRequest): RequestHeadersView {
277
+ const view = new RequestHeadersView(undefined, GENERAL_HEADERS_ONLY_VIEW);
278
+ view.request = request;
279
+ return view;
280
+ }
281
+
246
282
  #addEventListeners(): void {
247
283
  this.#request?.addEventListener(SDK.NetworkRequest.Events.REMOTE_ADDRESS_CHANGED, this.#refreshHeadersView, this);
248
284
  this.#request?.addEventListener(SDK.NetworkRequest.Events.FINISHED_LOADING, this.#refreshHeadersView, this);
@@ -72,6 +72,11 @@ const i18nString = i18n.i18n.getLocalizedString.bind(undefined, str_);
72
72
 
73
73
  const REPLAY_EXTENSION_PREFIX = 'extension';
74
74
 
75
+ function isPlayRecordingSpeed(string: string): string is PlayRecordingSpeed {
76
+ return string === PlayRecordingSpeed.NORMAL || string === PlayRecordingSpeed.SLOW ||
77
+ string === PlayRecordingSpeed.VERY_SLOW || string === PlayRecordingSpeed.EXTREMELY_SLOW;
78
+ }
79
+
75
80
  interface Item {
76
81
  value: string;
77
82
  buttonIconName: string;
@@ -274,9 +279,9 @@ export class ReplaySection extends UI.Widget.Widget {
274
279
  if (this.#replayExtensions.length) {
275
280
  groups.push({
276
281
  name: i18nString(UIStrings.extensionGroup),
277
- items: this.#replayExtensions.map((extension, idx) => {
282
+ items: this.#replayExtensions.map(extension => {
278
283
  return {
279
- value: (REPLAY_EXTENSION_PREFIX + idx),
284
+ value: REPLAY_EXTENSION_PREFIX + extension.getOrigin(),
280
285
  buttonIconName: 'play',
281
286
  buttonLabel: () => extension.getName() as Platform.UIString.LocalizedString,
282
287
  label: () => extension.getName() as Platform.UIString.LocalizedString,
@@ -301,28 +306,35 @@ export class ReplaySection extends UI.Widget.Widget {
301
306
 
302
307
  #onStartReplay(): void {
303
308
  const value = this.#settings?.replayExtension || this.#settings?.speed || '';
304
- if (value?.startsWith(REPLAY_EXTENSION_PREFIX)) {
305
- const extensionIdx = Number(
306
- value.substring(REPLAY_EXTENSION_PREFIX.length),
307
- );
308
- const extension = this.#replayExtensions[extensionIdx];
309
- if (this.#settings) {
310
- this.#settings.replayExtension = REPLAY_EXTENSION_PREFIX + extensionIdx;
311
- }
312
- if (this.onStartReplay) {
313
- this.onStartReplay(PlayRecordingSpeed.NORMAL, extension);
309
+ if (value.startsWith(REPLAY_EXTENSION_PREFIX)) {
310
+ const origin = value.substring(REPLAY_EXTENSION_PREFIX.length);
311
+ const extension = this.#replayExtensions.find(ext => ext.getOrigin() === origin);
312
+ if (extension) {
313
+ if (this.#settings) {
314
+ this.#settings.replayExtension = REPLAY_EXTENSION_PREFIX + extension.getOrigin();
315
+ }
316
+ if (this.onStartReplay) {
317
+ this.onStartReplay(PlayRecordingSpeed.NORMAL, extension);
318
+ }
319
+ this.performUpdate();
320
+ return;
314
321
  }
315
- } else if (this.onStartReplay) {
322
+ }
323
+ if (this.onStartReplay) {
316
324
  this.onStartReplay(this.#settings ? this.#settings.speed : PlayRecordingSpeed.NORMAL);
317
325
  }
318
326
  this.performUpdate();
319
327
  }
320
328
 
321
329
  #onItemSelected(item: string): void {
322
- const speed = item as PlayRecordingSpeed;
323
- if (this.#settings && speed) {
324
- this.#settings.speed = speed;
330
+ if (!this.#settings) {
331
+ return;
332
+ }
333
+ if (isPlayRecordingSpeed(item)) {
334
+ this.#settings.speed = item;
325
335
  this.#settings.replayExtension = '';
336
+ } else {
337
+ this.#settings.replayExtension = item;
326
338
  }
327
339
  this.performUpdate();
328
340
  }
@@ -0,0 +1,47 @@
1
+ Title: LighthouseConverter should stringify a flow
2
+ Content:
3
+ import fs from 'fs';
4
+ import { Locator, launch } from 'puppeteer'; // v25.0.0 or later
5
+
6
+ const browser = await launch();
7
+ const page = await browser.newPage();
8
+ const timeout = 5000;
9
+ page.setDefaultTimeout(timeout);
10
+
11
+ const lhApi = await import('lighthouse'); // v10.0.0 or later
12
+ const flags = {
13
+ screenEmulation: {
14
+ disabled: true
15
+ }
16
+ }
17
+ const config = lhApi.desktopConfig;
18
+ const lhFlow = await lhApi.startFlow(page, {name: 'test', config, flags});
19
+ await lhFlow.startNavigation();
20
+ {
21
+ const targetPage = page;
22
+ await targetPage.goto('https://example.com');
23
+ }
24
+ await lhFlow.endNavigation();
25
+ await lhFlow.startTimespan();
26
+ {
27
+ const targetPage = page;
28
+ await Locator.race([
29
+ targetPage.locator('.cls')
30
+ ])
31
+ .setTimeout(timeout)
32
+ .scroll({ scrollTop: undefined, scrollLeft: undefined});
33
+ }
34
+ await lhFlow.endTimespan();
35
+ const lhFlowReport = await lhFlow.generateReport();
36
+ fs.writeFileSync(import.meta.dirname + '/flow.report.html', lhFlowReport)
37
+
38
+ await browser.close();
39
+ === end content
40
+
41
+ Title: LighthouseConverter should stringify a step
42
+ Content:
43
+ {
44
+ const targetPage = page;
45
+ await targetPage.evaluate((x, y) => { window.scroll(x, y); }, undefined, undefined)
46
+ }
47
+ === end content
@@ -0,0 +1,49 @@
1
+ Title: PuppeteerConverter should stringify a flow
2
+ Content:
3
+ import { Locator, launch } from 'puppeteer'; // v25.0.0 or later
4
+
5
+ const browser = await launch();
6
+ const page = await browser.newPage();
7
+ const timeout = 5000;
8
+ page.setDefaultTimeout(timeout);
9
+
10
+ {
11
+ const targetPage = page;
12
+ await Locator.race([
13
+ targetPage.locator('.cls')
14
+ ])
15
+ .setTimeout(timeout)
16
+ .scroll({ scrollTop: undefined, scrollLeft: undefined});
17
+ }
18
+
19
+ await browser.close();
20
+ === end content
21
+
22
+ Title: PuppeteerConverter should stringify a step
23
+ Content:
24
+ {
25
+ const targetPage = page;
26
+ await targetPage.evaluate((x, y) => { window.scroll(x, y); }, undefined, undefined)
27
+ }
28
+ === end content
29
+
30
+ Title: PuppeteerConverter should stringify a flow for Firefox
31
+ Content:
32
+ import { Locator, launch } from 'puppeteer'; // v25.0.0 or later
33
+
34
+ const browser = await launch({browser: 'firefox'});
35
+ const page = await browser.newPage();
36
+ const timeout = 5000;
37
+ page.setDefaultTimeout(timeout);
38
+
39
+ {
40
+ const targetPage = page;
41
+ await Locator.race([
42
+ targetPage.locator('.cls')
43
+ ])
44
+ .setTimeout(timeout)
45
+ .scroll({ scrollTop: undefined, scrollLeft: undefined});
46
+ }
47
+
48
+ await browser.close();
49
+ === end content
@@ -0,0 +1,33 @@
1
+ Title: PuppeteerReplayConverter should stringify a flow
2
+ Content:
3
+ import url from 'url';
4
+ import { createRunner } from '@puppeteer/replay';
5
+
6
+ export async function run(extension) {
7
+ const runner = await createRunner(extension);
8
+
9
+ await runner.runBeforeAllSteps();
10
+
11
+ await runner.runStep({
12
+ type: 'scroll',
13
+ selectors: [
14
+ [
15
+ '.cls'
16
+ ]
17
+ ]
18
+ });
19
+
20
+ await runner.runAfterAllSteps();
21
+ }
22
+
23
+ if (process && import.meta.url === url.pathToFileURL(process.argv[1]).href) {
24
+ run()
25
+ }
26
+ === end content
27
+
28
+ Title: PuppeteerReplayConverter should stringify a step
29
+ Content:
30
+ await runner.runStep({
31
+ type: 'scroll'
32
+ });
33
+ === end content
@@ -636,7 +636,7 @@ const GREENDEV_VIEW: View = (input, _output, target) => {
636
636
  <span>${i18nString(UIStrings.greenDevUnstable)}</span>
637
637
  </div>
638
638
  <div class="settings-experiments-block">
639
- ${renderPrototypeCheckboxes(input.settings, ['aiAnnotations', 'beyondStylingGemini', 'beyondStylingAntigravity', 'breakpointDebuggerAgent', 'emulationCapabilities'])}
639
+ ${renderPrototypeCheckboxes(input.settings, ['aiAnnotations', 'beyondStylingGemini', 'beyondStylingAntigravity', 'emulationCapabilities'])}
640
640
  </div>
641
641
  </devtools-card>
642
642
  </div>
@@ -648,7 +648,6 @@ const GREENDEV_PROTOTYPE_NAMES: Record<keyof GreenDev.GreenDevSettings, string>
648
648
  aiAnnotations: 'AI auto-annotations',
649
649
  beyondStylingGemini: 'Beyond Styling (Gemini CLI)',
650
650
  beyondStylingAntigravity: 'Beyond Styling (Antigravity CLI)',
651
- breakpointDebuggerAgent: 'Breakpoint Debugger Agent',
652
651
  emulationCapabilities: 'Emulation Capabilities',
653
652
  };
654
653
 
@@ -300,7 +300,7 @@ export class BreakpointsSidebarController implements UI.ContextFlavorListener.Co
300
300
  }
301
301
 
302
302
  const locationsGroupedById = this.#groupBreakpointLocationsById(breakpointLocations);
303
- const locationIdsByLineId = this.#getLocationIdsByLineId(breakpointLocations);
303
+ const locationIdsByLineId = this.#getLocationIdsByLineId(locationsGroupedById);
304
304
 
305
305
  const [content, selectedUILocation] = await Promise.all([
306
306
  this.#getContent(locationsGroupedById),
@@ -312,9 +312,9 @@ export class BreakpointsSidebarController implements UI.ContextFlavorListener.Co
312
312
  for (let idx = 0; idx < locationsGroupedById.length; idx++) {
313
313
  const locations = locationsGroupedById[idx];
314
314
  const fstLocation = locations[0];
315
- const sourceURL = fstLocation.uiLocation.uiSourceCode.url();
316
- const scriptId = fstLocation.uiLocation.uiSourceCode.canonicalScriptId();
317
- const uiLocation = fstLocation.uiLocation;
315
+ const uiLocation = fstLocation.breakpoint.getClosestResolvedLocation() || fstLocation.uiLocation;
316
+ const sourceURL = uiLocation.uiSourceCode.url();
317
+ const scriptId = uiLocation.uiSourceCode.canonicalScriptId();
318
318
 
319
319
  const isHit = selectedUILocation !== null &&
320
320
  locations.some(location => location.uiLocation.id() === selectedUILocation.id());
@@ -334,8 +334,8 @@ export class BreakpointsSidebarController implements UI.ContextFlavorListener.Co
334
334
  }
335
335
  const expanded = !this.#collapsedFiles.has(sourceURL);
336
336
 
337
- const status: BreakpointStatus = this.#getBreakpointState(locations);
338
- const {type, hoverText} = this.#getBreakpointTypeAndDetails(locations);
337
+ const status: BreakpointStatus = this.#getBreakpointState(fstLocation.breakpoint);
338
+ const {type, hoverText} = this.#getBreakpointTypeAndDetails(fstLocation.breakpoint);
339
339
  const item = {
340
340
  id: fstLocation.breakpoint.breakpointStorageId(),
341
341
  location: locationText,
@@ -403,15 +403,13 @@ export class BreakpointsSidebarController implements UI.ContextFlavorListener.Co
403
403
  this.#collapsedFilesSettings.set(Array.from(this.#collapsedFiles.values()));
404
404
  }
405
405
 
406
- #getBreakpointTypeAndDetails(locations: Breakpoints.BreakpointManager.BreakpointLocation[]):
406
+ #getBreakpointTypeAndDetails(breakpoint: Breakpoints.BreakpointManager.Breakpoint):
407
407
  {type: SDK.DebuggerModel.BreakpointType, hoverText?: string} {
408
- const breakpointWithCondition = locations.find(location => Boolean(location.breakpoint.condition()));
409
- const breakpoint = breakpointWithCondition?.breakpoint;
410
- if (!breakpoint?.condition()) {
408
+ const condition = breakpoint.condition();
409
+ if (!condition) {
411
410
  return {type: SDK.DebuggerModel.BreakpointType.REGULAR_BREAKPOINT};
412
411
  }
413
412
 
414
- const condition = breakpoint.condition();
415
413
  if (breakpoint.isLogpoint()) {
416
414
  return {type: SDK.DebuggerModel.BreakpointType.LOGPOINT, hoverText: condition};
417
415
  }
@@ -456,49 +454,32 @@ export class BreakpointsSidebarController implements UI.ContextFlavorListener.Co
456
454
 
457
455
  #groupBreakpointLocationsById(breakpointLocations: Breakpoints.BreakpointManager.BreakpointLocation[]):
458
456
  Breakpoints.BreakpointManager.BreakpointLocation[][] {
459
- const map = new Platform.MapUtilities.Multimap<string, Breakpoints.BreakpointManager.BreakpointLocation>();
460
- for (const breakpointLocation of breakpointLocations) {
461
- const uiLocation = breakpointLocation.uiLocation;
462
- map.set(uiLocation.id(), breakpointLocation);
463
- }
464
- const arr: Breakpoints.BreakpointManager.BreakpointLocation[][] = [];
465
- for (const id of map.keysArray()) {
466
- const locations = Array.from(map.get(id));
467
- if (locations.length) {
468
- arr.push(locations);
469
- }
470
- }
471
- return arr;
457
+ const map = Map.groupBy(breakpointLocations, loc => loc.breakpoint.breakpointStorageId());
458
+ return Array.from(map.values());
472
459
  }
473
460
 
474
- #getLocationIdsByLineId(breakpointLocations: Breakpoints.BreakpointManager.BreakpointLocation[]):
461
+ #getLocationIdsByLineId(locationsGroupedById: Breakpoints.BreakpointManager.BreakpointLocation[][]):
475
462
  Platform.MapUtilities.Multimap<string, string> {
476
463
  const result = new Platform.MapUtilities.Multimap<string, string>();
477
464
 
478
- for (const breakpointLocation of breakpointLocations) {
479
- const uiLocation = breakpointLocation.uiLocation;
480
- result.set(uiLocation.lineId(), uiLocation.id());
465
+ for (const locations of locationsGroupedById) {
466
+ const breakpoint = locations[0].breakpoint;
467
+ const uiLocation = breakpoint.getClosestResolvedLocation() || locations[0].uiLocation;
468
+ result.set(uiLocation.lineId(), breakpoint.breakpointStorageId());
481
469
  }
482
-
483
470
  return result;
484
471
  }
485
472
 
486
- #getBreakpointState(locations: Breakpoints.BreakpointManager.BreakpointLocation[]): BreakpointStatus {
487
- const hasEnabled = locations.some(location => location.breakpoint.enabled());
488
- const hasDisabled = locations.some(location => !location.breakpoint.enabled());
489
- let status: BreakpointStatus;
490
- if (hasEnabled) {
491
- status = hasDisabled ? BreakpointStatus.INDETERMINATE : BreakpointStatus.ENABLED;
492
- } else {
493
- status = BreakpointStatus.DISABLED;
494
- }
495
- return status;
473
+ #getBreakpointState(breakpoint: Breakpoints.BreakpointManager.Breakpoint): BreakpointStatus {
474
+ return breakpoint.enabled() ? BreakpointStatus.ENABLED : BreakpointStatus.DISABLED;
496
475
  }
497
476
 
498
- #getContent(locations: Breakpoints.BreakpointManager.BreakpointLocation[][]):
477
+ #getContent(locationsGroupedById: Breakpoints.BreakpointManager.BreakpointLocation[][]):
499
478
  Promise<TextUtils.ContentData.ContentData[]> {
500
- return Promise.all(locations.map(async ([{uiLocation: {uiSourceCode}}]) => {
501
- const contentData = await uiSourceCode.requestContentData({cachedWasmOnly: true});
479
+ return Promise.all(locationsGroupedById.map(async locations => {
480
+ const fstLocation = locations[0];
481
+ const uiLocation = fstLocation.breakpoint.getClosestResolvedLocation() || fstLocation.uiLocation;
482
+ const contentData = await uiLocation.uiSourceCode.requestContentData({cachedWasmOnly: true});
502
483
  return TextUtils.ContentData.ContentData.contentDataOrEmpty(contentData);
503
484
  }));
504
485
  }
@@ -1179,14 +1179,21 @@ export class DebuggerPlugin extends Plugin {
1179
1179
  }
1180
1180
  const {editor} = this;
1181
1181
  const breakpointLocations = this.breakpointManager.breakpointLocationsForUISourceCode(this.uiSourceCode);
1182
- return breakpointLocations.map(({uiLocation, breakpoint}) => {
1182
+
1183
+ // Group by breakpoint to de-duplicate
1184
+ const uniqueBreakpoints = Map.groupBy(breakpointLocations, loc => loc.breakpoint);
1185
+
1186
+ const result = [];
1187
+ for (const [breakpoint, locations] of uniqueBreakpoints) {
1188
+ const closestUILoc = breakpoint.getClosestResolvedLocation() || locations[0].uiLocation;
1183
1189
  const editorLocation =
1184
- this.transformer.uiLocationToEditorLocation(uiLocation.lineNumber, uiLocation.columnNumber);
1185
- return {
1190
+ this.transformer.uiLocationToEditorLocation(closestUILoc.lineNumber, closestUILoc.columnNumber);
1191
+ result.push({
1186
1192
  position: editor.toOffset(editorLocation),
1187
1193
  breakpoint,
1188
- };
1189
- });
1194
+ });
1195
+ }
1196
+ return result;
1190
1197
  }
1191
1198
 
1192
1199
  private lineBreakpoints(line: CodeMirror.Line): readonly Breakpoints.BreakpointManager.Breakpoint[] {
@@ -115,14 +115,28 @@ export class ContextMenuProvider implements
115
115
  const networkPersistenceManager = Persistence.NetworkPersistenceManager.NetworkPersistenceManager.instance();
116
116
 
117
117
  const binding = uiSourceCode && Persistence.Persistence.PersistenceImpl.instance().binding(uiSourceCode);
118
- const fileURL = binding ? binding.fileSystem.contentURL() : contentProvider.contentURL();
118
+ // If contentProvider is already a FileSystem UISourceCode, there's a small chance that uiSourceCodeForURL
119
+ // might return a Network UISourceCode instead (e.g. if they share the same URL but aren't currently bound
120
+ // and the Network project represents the URL first in the lookup list).
121
+ // In this case, the binding will be null. To ensure "Open in containing folder" is still appended when
122
+ // right-clicking the FileSystem file in the Workspace tree, we fall back to contentProvider.
123
+ const fileSystemUISourceCode = binding ?
124
+ binding.fileSystem :
125
+ (contentProvider instanceof Workspace.UISourceCode.UISourceCode &&
126
+ contentProvider.project().type() === Workspace.Workspace.projectTypes.FileSystem ?
127
+ contentProvider :
128
+ uiSourceCode);
119
129
 
120
- if (Common.ParsedURL.schemeIs(fileURL, 'file:')) {
121
- const path = Common.ParsedURL.ParsedURL.urlToRawPathString(fileURL, Host.Platform.isWin());
122
- contextMenu.revealSection().appendItem(
123
- i18nString(UIStrings.openInContainingFolder),
124
- () => Host.InspectorFrontendHost.InspectorFrontendHostInstance.showItemInFolder(path),
125
- {jslogContext: 'open-in-containing-folder'});
130
+ if (fileSystemUISourceCode &&
131
+ fileSystemUISourceCode.project().type() === Workspace.Workspace.projectTypes.FileSystem) {
132
+ const fileURL = fileSystemUISourceCode.contentURL();
133
+ if (Common.ParsedURL.schemeIs(fileURL, 'file:')) {
134
+ const path = Common.ParsedURL.ParsedURL.urlToRawPathString(fileURL, Host.Platform.isWin());
135
+ contextMenu.revealSection().appendItem(
136
+ i18nString(UIStrings.openInContainingFolder),
137
+ () => Host.InspectorFrontendHost.InspectorFrontendHostInstance.showItemInFolder(path),
138
+ {jslogContext: 'open-in-containing-folder'});
139
+ }
126
140
  }
127
141
 
128
142
  if (contentProvider instanceof Workspace.UISourceCode.UISourceCode &&
@@ -93,6 +93,38 @@ export class TimelineDetailsPane extends
93
93
  #onTraceBoundsChangeBound = this.#onTraceBoundsChange.bind(this);
94
94
  #entityMapper: Trace.EntityMapper.EntityMapper|null = null;
95
95
 
96
+ static makeEventWidget(
97
+ event: Trace.Types.Events.Event,
98
+ parsedTrace: Trace.TraceModel.ParsedTrace,
99
+ ): TimelineDetailsPane {
100
+ // Provide a mock delegate to satisfy the constructor requirements.
101
+ // These delegate interactions are not relevant for an AI assistant widget.
102
+ const mockDelegate = {
103
+ select: () => {},
104
+ zoomEvent: () => {},
105
+ element: document.createElement('div'),
106
+ set3PCheckboxDisabled: () => {},
107
+ selectEntryAtTime: () => {},
108
+ highlightEvent: () => {},
109
+ };
110
+ const pane = new TimelineDetailsPane(mockDelegate);
111
+ pane.hideHeader();
112
+ const entityMapper = new Trace.EntityMapper.EntityMapper(parsedTrace);
113
+ void pane
114
+ .setModel({
115
+ parsedTrace,
116
+ selectedEvents: [event],
117
+ eventToRelatedInsightsMap: null,
118
+ entityMapper,
119
+ })
120
+ .then(() => {
121
+ void pane.setSelection({
122
+ event,
123
+ });
124
+ });
125
+ return pane;
126
+ }
127
+
96
128
  constructor(delegate: TimelineModeViewDelegate) {
97
129
  super();
98
130
  this.registerRequiredCSS(detailsViewStyles);
@@ -343,6 +375,10 @@ export class TimelineDetailsPane extends
343
375
  return this.tabbedPane.headerElement();
344
376
  }
345
377
 
378
+ hideHeader(): void {
379
+ this.tabbedPane.headerElement().classList.add('hidden');
380
+ }
381
+
346
382
  setPreferredTab(tabId: string): void {
347
383
  this.preferredTabId = tabId;
348
384
  }
@@ -1,7 +1,7 @@
1
1
  Name: Dependencies sourced from the upstream `chromium` repository
2
2
  URL: Internal
3
3
  Version: N/A
4
- Revision: 268971579b74f0369f828111e6c8f5bafbacd5ee
4
+ Revision: c76b4a416b8d83c855cffa79e49ac6b5709b42ec
5
5
  Update Mechanism: Manual (https://crbug.com/428069060)
6
6
  License: BSD-3-Clause
7
7
  License File: LICENSE
@@ -462,8 +462,8 @@ f=x});do var h=this._binding.writeSync(a,e,o,r,this._buffer,this._offset,t);whil
462
462
  r=[];for(let[t,o]of a)i.set(t,e.getSummary(o)),r.push(...o);return i.set(e.summary,e.getSummary(r)),i}static estimateValueByOrigin(a,i){let r=e.estimateIfConnectionWasReused(a),t=e.groupByOrigin(a),o=new Map;for(let[n,d]of t.entries()){let l=[];for(let c of d){let f=c.timing;if(!f)continue;let h=i({request:c,timing:f,connectionReused:r.get(c.requestId)});typeof h<"u"&&(l=l.concat(h))}l.length&&o.set(n,l)}return o}static estimateRTTViaConnectionTiming(a){let{timing:i,connectionReused:r,request:t}=a;if(r)return;let{connectStart:o,sslStart:n,sslEnd:d,connectEnd:l}=i;if(l>=0&&o>=0&&t.protocol.startsWith("h3"))return l-o;if(n>=0&&d>=0&&n!==o)return[l-n,n-o];if(o>=0&&l>=0)return l-o}static estimateRTTViaDownloadTiming(a){let{timing:i,connectionReused:r,request:t}=a;if(r||t.transferSize<=XD||!Number.isFinite(i.receiveHeadersEnd)||i.receiveHeadersEnd<0)return;let n=t.networkEndTime-t.networkRequestTime-i.receiveHeadersEnd,d=Math.log2(t.transferSize/XD);if(!(d>5))return n/d}static estimateRTTViaSendStartTiming(a){
463
463
  let{timing:i,connectionReused:r,request:t}=a;if(r||!Number.isFinite(i.sendStart)||i.sendStart<0)return;let o=1;return t.protocol.startsWith("h3")||(o+=1),t.parsedURL.scheme==="https"&&(o+=1),i.sendStart/o}static estimateRTTViaHeadersEndTiming(a){let{timing:i,connectionReused:r,request:t}=a;if(!Number.isFinite(i.receiveHeadersEnd)||i.receiveHeadersEnd<0||!t.resourceType)return;let o=Fee[t.resourceType]||Nee,n=i.receiveHeadersEnd*o,d=1;return r||(d+=1,t.protocol.startsWith("h3")||(d+=1),t.parsedURL.scheme==="https"&&(d+=1)),Math.max((i.receiveHeadersEnd-n)/d,3)}static estimateResponseTimeByOrigin(a,i){return e.estimateValueByOrigin(a,({request:r,timing:t})=>{if(r.serverResponseTime!==void 0)return r.serverResponseTime;if(!Number.isFinite(t.receiveHeadersEnd)||t.receiveHeadersEnd<0||!Number.isFinite(t.sendEnd)||t.sendEnd<0)return;let o=t.receiveHeadersEnd-t.sendEnd,n=r.parsedURL.securityOrigin,d=i.get(n)||i.get(e.summary)||0;return Math.max(o-d,0)})}static canTrustConnectionInformation(a){
464
464
  let i=new Map;for(let r of a){let t=i.get(r.connectionId)||!r.connectionReused;i.set(r.connectionId,t)}return i.size<=1?!1:Array.from(i.values()).every(r=>r)}static estimateIfConnectionWasReused(a,i){let{forceCoarseEstimates:r=!1}=i||{};if(!r&&e.canTrustConnectionInformation(a))return new Map(a.map(n=>[n.requestId,!!n.connectionReused]));let t=new Map,o=e.groupByOrigin(a);for(let n of o.values()){let d=n.map(c=>c.networkEndTime).reduce((c,f)=>Math.min(c,f),1/0);for(let c of n)t.set(c.requestId,c.networkRequestTime>=d||c.protocol==="h2");let l=n.reduce((c,f)=>c.networkRequestTime>f.networkRequestTime?f:c);t.set(l.requestId,!1)}return t}static estimateRTTByOrigin(a,i){let{forceCoarseEstimates:r=!1,coarseEstimateMultiplier:t=.3,useDownloadEstimates:o=!0,useSendStartEstimates:n=!0,useHeadersEndEstimates:d=!0}=i||{},l=e.estimateIfConnectionWasReused(a),c=e.groupByOrigin(a),f=new Map;for(let[h,m]of c.entries()){let g=function(x,y=1){for(let E of m){let C=E.timing;if(!C||!E.transferSize)continue;
465
- let k=x({request:E,timing:C,connectionReused:l.get(E.requestId)});k!==void 0&&(Array.isArray(k)?u.push(...k.map(T=>T*y)):u.push(k*y))}};s(g,"collectEstimates");let u=[];r||g(this.estimateRTTViaConnectionTiming),u.length||(o&&g(this.estimateRTTViaDownloadTiming,t),n&&g(this.estimateRTTViaSendStartTiming,t),d&&g(this.estimateRTTViaHeadersEndTiming,t)),u.length&&f.set(h,u)}if(!f.size)throw new J("No timing information available");return e.summarize(f)}static estimateServerResponseTimeByOrigin(a,i){let r=i?.rttByOrigin;if(!r){r=new Map;let o=e.estimateRTTByOrigin(a,i);for(let[n,d]of o.entries())r.set(n,d.min)}let t=e.estimateResponseTimeByOrigin(a,r);return e.summarize(t)}static estimateThroughput(a){let i=0,r=a.reduce((d,l)=>(l.parsedURL?.scheme==="data"||l.failed||!l.finished||l.statusCode>300||!l.transferSize||(i+=l.transferSize,d.push({time:l.responseHeadersEndTime/1e3,isStart:!0}),d.push({time:l.networkEndTime/1e3,isStart:!1})),d),[]).sort((d,l)=>d.time-l.time);if(!r.length)return null;
466
- let t=0,o=0,n=0;return r.forEach(d=>{d.isStart?(t===0&&(o=d.time),t++):(t--,t===0&&(n+=d.time-o))}),i*8/n}static computeRTTAndServerResponseTime(a){let i=new Map;for(let[d,l]of e.estimateRTTByOrigin(a).entries())i.set(d,l.min);let r=Math.min(...Array.from(i.values())),t=e.estimateServerResponseTimeByOrigin(a,{rttByOrigin:i}),o=new Map,n=new Map;for(let[d,l]of t.entries()){let c=i.get(d)||r;o.set(d,c-r),n.set(d,l.median)}return{rtt:r,additionalRttByOrigin:o,serverResponseTimeByOrigin:n}}static analyze(a){let i=e.estimateThroughput(a);return i===null?null:{throughput:i,...e.computeRTTAndServerResponseTime(a)}}static findResourceForUrl(a,i){return a.find(r=>i.startsWith(r.url)&&Vm.equalWithExcludedFragments(r.url,i))}static findLastDocumentForUrl(a,i){let r=a.filter(t=>t.resourceType==="Document"&&!t.failed&&i.startsWith(t.url)&&Vm.equalWithExcludedFragments(t.url,i));return r[r.length-1]}static resolveRedirects(a){for(;a.redirectDestination;)a=a.redirectDestination;return a}}});var ca={};S(ca,{LanternError:()=>J,NetworkAnalyzer:()=>Bt});var dr=_(()=>{p();Q2();KD()});var aa,qm=_(()=>{p();dr();aa=class e{static{s(this,"BaseNode")}static types={NETWORK:"network",CPU:"cpu"};_id;_isMainDocument;dependents;dependencies;constructor(a){this._id=a,this._isMainDocument=!1,this.dependents=[],this.dependencies=[]}get id(){return this._id}get type(){throw new J("Unimplemented")}get startTime(){throw new J("Unimplemented")}get endTime(){throw new J("Unimplemented")}setIsMainDocument(a){this._isMainDocument=a}isMainDocument(){return this._isMainDocument}getDependents(){return this.dependents.slice()}getNumberOfDependents(){return this.dependents.length}getDependencies(){return this.dependencies.slice()}getNumberOfDependencies(){return this.dependencies.length}getRootNode(){let a=this;for(;a.dependencies.length;)a=a.dependencies[0];return a}addDependent(a){a.addDependency(this)}addDependency(a){if(a===this)throw new J("Cannot add dependency on itself");this.dependencies.includes(a)||(a.dependents.push(this),this.dependencies.push(a))}removeDependent(a){a.removeDependency(
465
+ let k=x({request:E,timing:C,connectionReused:l.get(E.requestId)});k!==void 0&&(Array.isArray(k)?u.push(...k.map(T=>T*y)):u.push(k*y))}};s(g,"collectEstimates");let u=[];r||g(this.estimateRTTViaConnectionTiming),u.length||(o&&g(this.estimateRTTViaDownloadTiming,t),n&&g(this.estimateRTTViaSendStartTiming,t),d&&g(this.estimateRTTViaHeadersEndTiming,t)),u.length&&f.set(h,u)};return e.summarize(f)}static estimateServerResponseTimeByOrigin(a,i){let r=i?.rttByOrigin;if(!r){r=new Map;let o=e.estimateRTTByOrigin(a,i);for(let[n,d]of o.entries())r.set(n,d.min)}let t=e.estimateResponseTimeByOrigin(a,r);return e.summarize(t)}static estimateThroughput(a){let i=0,r=a.reduce((d,l)=>(l.parsedURL?.scheme==="data"||l.failed||!l.finished||l.statusCode>300||!l.transferSize||(i+=l.transferSize,d.push({time:l.responseHeadersEndTime/1e3,isStart:!0}),d.push({time:l.networkEndTime/1e3,isStart:!1})),d),[]).sort((d,l)=>d.time-l.time);if(!r.length)return null;
466
+ let t=0,o=0,n=0;return r.forEach(d=>{d.isStart?(t===0&&(o=d.time),t++):(t--,t===0&&(n+=d.time-o))}),i*8/n}static computeRTTAndServerResponseTime(a){let i=new Map;for(let[d,l]of e.estimateRTTByOrigin(a).entries())i.set(d,l.min);let r=i.size?Math.min(...Array.from(i.values())):0,t=e.estimateServerResponseTimeByOrigin(a,{rttByOrigin:i}),o=new Map,n=new Map;for(let[d,l]of t.entries()){let c=i.get(d)||r;o.set(d,c-r),n.set(d,l.median)}return{rtt:r,additionalRttByOrigin:o,serverResponseTimeByOrigin:n}}static analyze(a){let i=e.estimateThroughput(a);return i===null?null:{throughput:i,...e.computeRTTAndServerResponseTime(a)}}static findResourceForUrl(a,i){return a.find(r=>i.startsWith(r.url)&&Vm.equalWithExcludedFragments(r.url,i))}static findLastDocumentForUrl(a,i){let r=a.filter(t=>t.resourceType==="Document"&&!t.failed&&i.startsWith(t.url)&&Vm.equalWithExcludedFragments(t.url,i));return r[r.length-1]}static resolveRedirects(a){for(;a.redirectDestination;)a=a.redirectDestination;return a}}});var ca={};S(ca,{LanternError:()=>J,NetworkAnalyzer:()=>Bt});var dr=_(()=>{p();Q2();KD()});var aa,qm=_(()=>{p();dr();aa=class e{static{s(this,"BaseNode")}static types={NETWORK:"network",CPU:"cpu"};_id;_isMainDocument;dependents;dependencies;constructor(a){this._id=a,this._isMainDocument=!1,this.dependents=[],this.dependencies=[]}get id(){return this._id}get type(){throw new J("Unimplemented")}get startTime(){throw new J("Unimplemented")}get endTime(){throw new J("Unimplemented")}setIsMainDocument(a){this._isMainDocument=a}isMainDocument(){return this._isMainDocument}getDependents(){return this.dependents.slice()}getNumberOfDependents(){return this.dependents.length}getDependencies(){return this.dependencies.slice()}getNumberOfDependencies(){return this.dependencies.length}getRootNode(){let a=this;for(;a.dependencies.length;)a=a.dependencies[0];return a}addDependent(a){a.addDependency(this)}addDependency(a){if(a===this)throw new J("Cannot add dependency on itself");this.dependencies.includes(a)||(a.dependents.push(this),this.dependencies.push(a))}removeDependent(a){a.removeDependency(
467
467
  this)}removeDependency(a){if(!this.dependencies.includes(a))return;let i=a.dependents.indexOf(this);a.dependents.splice(i,1),this.dependencies.splice(this.dependencies.indexOf(a),1)}removeAllDependencies(){for(let a of this.dependencies.slice())this.removeDependency(a)}isDependentOn(a){let i=!1;return this.traverse(r=>{i||(i=r===a)},r=>i?[]:r.getDependencies()),i}cloneWithoutRelationships(){let a=new e(this.id);return a.setIsMainDocument(this._isMainDocument),a}cloneWithRelationships(a){let i=this.getRootNode(),r=new Map;i.traverse(o=>{if(!r.has(o.id)){if(a===void 0){r.set(o.id,o.cloneWithoutRelationships());return}a(o)&&o.traverse(n=>r.set(n.id,n.cloneWithoutRelationships()),n=>n.dependencies.filter(d=>!r.has(d.id)))}}),i.traverse(o=>{let n=r.get(o.id);if(n)for(let d of o.dependencies){let l=r.get(d.id);if(!l)throw new J("Dependency somehow not cloned");n.addDependency(l)}});let t=r.get(this.id);if(!t)throw new J("Cloned graph missing node");return t}traverse(a,i){for(let{node:r,traversalPath:t}of this.
468
468
  traverseGenerator(i))a(r,t)}*traverseGenerator(a){a||(a=s(t=>t.getDependents(),"getNextNodes"));let i=[[this]],r=new Set([this.id]);for(;i.length;){let t=i.shift(),o=t[0];yield{node:o,traversalPath:t};for(let n of a(o))r.has(n.id)||(r.add(n.id),i.push([n,...t]))}}static findCycle(a,i="both"){if(i==="both")return e.findCycle(a,"dependents")||e.findCycle(a,"dependencies");let r=new Set,t=[],o=[a],n=new Map([[a,0]]);for(;o.length;){let d=o.pop();if(t.includes(d))return t;if(r.has(d))continue;for(;t.length>n.get(d);)t.pop();r.add(d),t.push(d);let l=i==="dependents"?d.dependents:d.dependencies;for(let c of l)o.includes(c)||(o.push(c),n.set(c,t.length))}return null}canDependOn(a){return a.startTime<=this.startTime}}});var xc,eb=_(()=>{p();qm();xc=class e extends aa{static{s(this,"CPUNode")}_event;_childEvents;correctedEndTs;constructor(a,i=[],r){let t=`${a.tid}.${a.ts}`;super(t),this._event=a,this._childEvents=i,this.correctedEndTs=r}get type(){return aa.types.CPU}get startTime(){return this._event.ts}get endTime(){return this.correctedEndTs?this.correctedEndTs:this._event.ts+this._event.dur}get duration(){return this.endTime-this.startTime}get event(){return this._event}get childEvents(){return this._childEvents}didPerformLayout(){return this._childEvents.some(a=>a.name==="Layout")}getEvaluateScriptURLs(){let a=new Set;for(let i of this._childEvents)i.name==="EvaluateScript"&&i.args.data?.url&&a.add(i.args.data.url);return a}cloneWithoutRelationships(){return new e(this._event,this._childEvents,this.correctedEndTs)}}});function YD(e){let a=e.includes(":")?e.slice(0,e.indexOf(":")):e;return jee.includes(a)}var jee,zs,ab=_(()=>{p();qm();jee=["blob","data","intent","file","filesystem","chrome-extension"];s(YD,"isNonNetworkProtocol");zs=class e extends aa{static{s(this,"NetworkNode")}_request;constructor(a){super(a.requestId),this._request=a}get type(){return aa.types.NETWORK}get startTime(){return this._request.rendererStartTime*1e3}get endTime(){return this._request.networkEndTime*1e3}get rawRequest(){return this._request.rawRequest}get request(){return this._request}get initiatorType(){return this._request.initiator.type}get fromDiskCache(){return!!this._request.fromDiskCache}get isNonNetworkProtocol(){return YD(this.request.protocol)||YD(this.request.parsedURL.scheme)}get isConnectionless(){return this.fromDiskCache||this.isNonNetworkProtocol}hasRenderBlockingPriority(){let a=this._request.priority,i=this._request.resourceType==="Script",r=this._request.resourceType==="Document";return a==="VeryHigh"||
469
469
  a==="High"&&i||a==="High"&&r}cloneWithoutRelationships(){let a=new e(this._request);return a.setIsMainDocument(this._isMainDocument),a}}});var Gee,Bee,Hee,Uee,Wee,Vee,ib,$D=_(()=>{p();dr();eb();ab();Gee="RunTask",Bee="ThreadControllerImpl::RunTask",Hee="ThreadControllerImpl::DoWork",Uee="TaskQueueManager::ProcessTaskFromWorkQueue",Wee=10,Vee=/^video/,ib=class e{static{s(this,"PageDependencyGraph")}static getNetworkInitiators(a){if(!a.initiator)return[];if(a.initiator.url)return[a.initiator.url];if(a.initiator.type==="script"){let i=new Set,r=a.initiator.stack;for(;r;){let t=r.callFrames||[];for(let o of t)o.url&&i.add(o.url);r=r.parent}return Array.from(i)}return[]}static getNetworkNodeOutput(a){let i=[],r=new Map,t=new Map,o=new Map;return a.forEach(n=>{if(Vee.test(n.mimeType)||n.fromWorker)return;for(;r.has(n.requestId);)n.requestId+=":duplicate";let d=new zs(n);i.push(d);let l=t.get(n.url)||[];if(l.push(d),r.set(n.requestId,d),t.set(n.url,l),n.frameId&&n.resourceType==="Document"&&n.documentURL===n.url){let c=o.has(n.frameId)?null:d;o.set(n.frameId,c)}}),{nodes:i,idToNodeMap:r,urlToNodeMap:t,frameIdToNodeMap:o}}static isScheduleableTask(a){
@@ -1,10 +1,10 @@
1
1
  Name: @puppeteer/replay
2
2
  Short Name: @puppeteer/replay
3
3
  URL: https://github.com/puppeteer/replay
4
- Version: 3.1.3
4
+ Version: 4.0.2
5
5
  License: Apache-2.0
6
6
  License File: package/LICENSE
7
- Revision: 8be2fd240bbe6da6fbf031164b24f5057350f175
7
+ Revision: 23ab6bc760bc6982d0dcbf3f832a2a7d54571f72
8
8
  Update Mechanism: Manual
9
9
  Security Critical: no
10
10
  Shipped: yes