@paulirish/trace_engine 0.0.43 → 0.0.44
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.tmp/tsbuildinfo/tsconfig.tsbuildinfo +1 -1
- package/locales/en-US.json +5 -2
- package/locales/en-XL.json +5 -2
- package/models/trace/ModelImpl.d.ts +0 -1
- package/models/trace/ModelImpl.js +0 -3
- package/models/trace/ModelImpl.js.map +1 -1
- package/models/trace/extras/ThirdParties.d.ts +2 -1
- package/models/trace/extras/ThirdParties.js +26 -7
- package/models/trace/extras/ThirdParties.js.map +1 -1
- package/models/trace/handlers/InitiatorsHandler.js +0 -46
- package/models/trace/handlers/InitiatorsHandler.js.map +1 -1
- package/models/trace/helpers/Timing.d.ts +0 -1
- package/models/trace/helpers/Timing.js +0 -7
- package/models/trace/helpers/Timing.js.map +1 -1
- package/models/trace/helpers/Trace.d.ts +0 -1
- package/models/trace/helpers/Trace.js +0 -3
- package/models/trace/helpers/Trace.js.map +1 -1
- package/models/trace/insights/CLSCulprits.js +1 -1
- package/models/trace/insights/DOMSize.js +1 -1
- package/models/trace/insights/DocumentLatency.js +1 -1
- package/models/trace/insights/FontDisplay.js +1 -1
- package/models/trace/insights/ForcedReflow.js +1 -1
- package/models/trace/insights/ImageDelivery.d.ts +1 -0
- package/models/trace/insights/ImageDelivery.js +9 -2
- package/models/trace/insights/ImageDelivery.js.map +1 -1
- package/models/trace/insights/InteractionToNextPaint.js +1 -1
- package/models/trace/insights/LCPDiscovery.d.ts +4 -0
- package/models/trace/insights/LCPDiscovery.js +11 -2
- package/models/trace/insights/LCPDiscovery.js.map +1 -1
- package/models/trace/insights/LCPPhases.js +1 -1
- package/models/trace/insights/LongCriticalNetworkTree.js +1 -1
- package/models/trace/insights/RenderBlocking.js +1 -1
- package/models/trace/insights/SlowCSSSelector.js +1 -1
- package/models/trace/insights/ThirdParties.d.ts +4 -2
- package/models/trace/insights/ThirdParties.js +5 -3
- package/models/trace/insights/ThirdParties.js.map +1 -1
- package/models/trace/insights/Viewport.js +1 -1
- package/models/trace/insights/types.d.ts +3 -3
- package/models/trace/lantern/graph/BaseNode.js +1 -0
- package/models/trace/lantern/graph/BaseNode.js.map +1 -1
- package/models/trace/lantern/graph/PageDependencyGraph.js +1 -0
- package/models/trace/lantern/graph/PageDependencyGraph.js.map +1 -1
- package/models/trace/lantern/simulation/Simulator.js +1 -0
- package/models/trace/lantern/simulation/Simulator.js.map +1 -1
- package/models/trace/lantern/simulation/TCPConnection.d.ts +0 -1
- package/models/trace/lantern/simulation/TCPConnection.js +0 -3
- package/models/trace/lantern/simulation/TCPConnection.js.map +1 -1
- package/models/trace/types/Extensions.d.ts +0 -1
- package/models/trace/types/Extensions.js +0 -3
- package/models/trace/types/Extensions.js.map +1 -1
- package/models/trace/types/TraceEvents.d.ts +0 -9
- package/models/trace/types/TraceEvents.js +0 -3
- package/models/trace/types/TraceEvents.js.map +1 -1
- package/package.json +1 -1
|
@@ -23,24 +23,14 @@ const eventToInitiatorMap = new Map();
|
|
|
23
23
|
// For a given event, tell me what events it initiated. An event can initiate
|
|
24
24
|
// multiple events, hence why the value for this map is an array.
|
|
25
25
|
const initiatorToEventsMap = new Map();
|
|
26
|
-
// Note: we are keeping the parsing of the following async JS schedulers
|
|
27
|
-
// for backwards compatibility only. They are targeted to be removed
|
|
28
|
-
// completely by M134. See more details at crbug.com/383974422
|
|
29
|
-
// TODO(andoli): remove manual parsing of async JS schedulers.
|
|
30
|
-
const requestAnimationFrameEventsById = new Map();
|
|
31
|
-
const timerInstallEventsById = new Map();
|
|
32
|
-
const requestIdleCallbackEventsById = new Map();
|
|
33
26
|
const webSocketCreateEventsById = new Map();
|
|
34
27
|
const schedulePostTaskCallbackEventsById = new Map();
|
|
35
28
|
export function reset() {
|
|
36
29
|
lastScheduleStyleRecalcByFrame.clear();
|
|
37
30
|
lastInvalidationEventForFrame.clear();
|
|
38
31
|
lastUpdateLayoutTreeByFrame.clear();
|
|
39
|
-
timerInstallEventsById.clear();
|
|
40
32
|
eventToInitiatorMap.clear();
|
|
41
33
|
initiatorToEventsMap.clear();
|
|
42
|
-
requestAnimationFrameEventsById.clear();
|
|
43
|
-
requestIdleCallbackEventsById.clear();
|
|
44
34
|
webSocketCreateEventsById.clear();
|
|
45
35
|
schedulePostTaskCallbackEventsById.clear();
|
|
46
36
|
}
|
|
@@ -118,42 +108,6 @@ export function handleEvent(event) {
|
|
|
118
108
|
// Now clear the last invalidation for the frame: the last invalidation has been linked to a Layout event, so it cannot be the initiator for any future layouts.
|
|
119
109
|
lastInvalidationEventForFrame.delete(event.args.beginData.frame);
|
|
120
110
|
}
|
|
121
|
-
else if (Types.Events.isRequestAnimationFrame(event)) {
|
|
122
|
-
requestAnimationFrameEventsById.set(event.args.data.id, event);
|
|
123
|
-
}
|
|
124
|
-
else if (Types.Events.isFireAnimationFrame(event)) {
|
|
125
|
-
// If we get a fire event, that means we should have had the
|
|
126
|
-
// RequestAnimationFrame event by now. If so, we can set that as the
|
|
127
|
-
// initiator for the fire event.
|
|
128
|
-
const matchingRequestEvent = requestAnimationFrameEventsById.get(event.args.data.id);
|
|
129
|
-
if (matchingRequestEvent) {
|
|
130
|
-
storeInitiator({
|
|
131
|
-
event,
|
|
132
|
-
initiator: matchingRequestEvent,
|
|
133
|
-
});
|
|
134
|
-
}
|
|
135
|
-
}
|
|
136
|
-
else if (Types.Events.isTimerInstall(event)) {
|
|
137
|
-
timerInstallEventsById.set(event.args.data.timerId, event);
|
|
138
|
-
}
|
|
139
|
-
else if (Types.Events.isTimerFire(event)) {
|
|
140
|
-
const matchingInstall = timerInstallEventsById.get(event.args.data.timerId);
|
|
141
|
-
if (matchingInstall) {
|
|
142
|
-
storeInitiator({ event, initiator: matchingInstall });
|
|
143
|
-
}
|
|
144
|
-
}
|
|
145
|
-
else if (Types.Events.isRequestIdleCallback(event)) {
|
|
146
|
-
requestIdleCallbackEventsById.set(event.args.data.id, event);
|
|
147
|
-
}
|
|
148
|
-
else if (Types.Events.isFireIdleCallback(event)) {
|
|
149
|
-
const matchingRequestEvent = requestIdleCallbackEventsById.get(event.args.data.id);
|
|
150
|
-
if (matchingRequestEvent) {
|
|
151
|
-
storeInitiator({
|
|
152
|
-
event,
|
|
153
|
-
initiator: matchingRequestEvent,
|
|
154
|
-
});
|
|
155
|
-
}
|
|
156
|
-
}
|
|
157
111
|
else if (Types.Events.isWebSocketCreate(event)) {
|
|
158
112
|
webSocketCreateEventsById.set(event.args.data.identifier, event);
|
|
159
113
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"InitiatorsHandler.js","sourceRoot":"","sources":["../../../../../../../front_end/models/trace/handlers/InitiatorsHandler.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright 2023 The Chromium Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\n\nimport * as Helpers from '../helpers/helpers.js';\nimport * as Types from '../types/types.js';\n\nimport {data as AsyncJSCallsHandlerData} from './AsyncJSCallsHandler.js';\nimport {data as flowsHandlerData} from './FlowsHandler.js';\n\nconst lastScheduleStyleRecalcByFrame = new Map<string, Types.Events.ScheduleStyleRecalculation>();\n\n// This tracks the last event that is considered to have invalidated the layout\n// for a given frame.\n// Note that although there is an InvalidateLayout event, there are also other\n// events (ScheduleStyleRecalculation) that could be the reason a layout was\n// invalidated.\nconst lastInvalidationEventForFrame = new Map<string, Types.Events.Event>();\n\n// Important: although the event is called UpdateLayoutTree, in the UI we\n// present these to the user as \"Recalculate Style\". So don't get confused!\n// These are the same - just UpdateLayoutTree is what the event from Chromium\n// is called.\nconst lastUpdateLayoutTreeByFrame = new Map<string, Types.Events.UpdateLayoutTree>();\n\n// These two maps store the same data but in different directions.\n// For a given event, tell me what its initiator was. An event can only have one initiator.\nconst eventToInitiatorMap = new Map<Types.Events.Event, Types.Events.Event>();\n// For a given event, tell me what events it initiated. An event can initiate\n// multiple events, hence why the value for this map is an array.\nconst initiatorToEventsMap = new Map<Types.Events.Event, Types.Events.Event[]>();\n\n// Note: we are keeping the parsing of the following async JS schedulers\n// for backwards compatibility only. They are targeted to be removed\n// completely by M134. See more details at crbug.com/383974422\n// TODO(andoli): remove manual parsing of async JS schedulers.\nconst requestAnimationFrameEventsById: Map<number, Types.Events.RequestAnimationFrame> = new Map();\nconst timerInstallEventsById: Map<number, Types.Events.TimerInstall> = new Map();\nconst requestIdleCallbackEventsById: Map<number, Types.Events.RequestIdleCallback> = new Map();\n\nconst webSocketCreateEventsById: Map<number, Types.Events.WebSocketCreate> = new Map();\nconst schedulePostTaskCallbackEventsById: Map<number, Types.Events.SchedulePostTaskCallback> = new Map();\n\nexport function reset(): void {\n lastScheduleStyleRecalcByFrame.clear();\n lastInvalidationEventForFrame.clear();\n lastUpdateLayoutTreeByFrame.clear();\n timerInstallEventsById.clear();\n eventToInitiatorMap.clear();\n initiatorToEventsMap.clear();\n requestAnimationFrameEventsById.clear();\n requestIdleCallbackEventsById.clear();\n webSocketCreateEventsById.clear();\n schedulePostTaskCallbackEventsById.clear();\n}\n\nfunction storeInitiator(data: {initiator: Types.Events.Event, event: Types.Events.Event}): void {\n eventToInitiatorMap.set(data.event, data.initiator);\n const eventsForInitiator = initiatorToEventsMap.get(data.initiator) || [];\n eventsForInitiator.push(data.event);\n initiatorToEventsMap.set(data.initiator, eventsForInitiator);\n}\n\n/**\n * IMPORTANT: Before adding support for new initiator relationships in\n * trace events consider using Perfetto's flow API on the events in\n * question, so that they get automatically computed.\n * @see {@link flowsHandlerData}\n *\n * The events manually computed here were added before we had support\n * for flow events. As such they should be migrated to use the flow\n * API so that no manual parsing is needed.\n */\nexport function handleEvent(event: Types.Events.Event): void {\n if (Types.Events.isScheduleStyleRecalculation(event)) {\n lastScheduleStyleRecalcByFrame.set(event.args.data.frame, event);\n } else if (Types.Events.isUpdateLayoutTree(event)) {\n // IMPORTANT: although the trace event is called UpdateLayoutTree, this\n // represents a Styles Recalculation. This event in the timeline is shown to\n // the user as \"Recalculate Styles.\"\n if (event.args.beginData) {\n // Store the last UpdateLayout event: we use this when we see an\n // InvalidateLayout and try to figure out its initiator.\n lastUpdateLayoutTreeByFrame.set(event.args.beginData.frame, event);\n\n // If this frame has seen a ScheduleStyleRecalc event, then that event is\n // considered to be the initiator of this StylesRecalc.\n const scheduledStyleForFrame = lastScheduleStyleRecalcByFrame.get(event.args.beginData.frame);\n if (scheduledStyleForFrame) {\n storeInitiator({\n event,\n initiator: scheduledStyleForFrame,\n });\n }\n }\n } else if (Types.Events.isInvalidateLayout(event)) {\n // By default, the InvalidateLayout event is what triggered the layout invalidation for this frame.\n let invalidationInitiator: Types.Events.Event = event;\n\n // However, if we have not had any prior invalidations for this frame, we\n // want to consider StyleRecalculation events as they might be the actual\n // cause of this layout invalidation.\n if (!lastInvalidationEventForFrame.has(event.args.data.frame)) {\n // 1. If we have not had an invalidation event for this frame\n // 2. AND we have had an UpdateLayoutTree for this frame\n // 3. AND the UpdateLayoutTree event ended AFTER the InvalidateLayout startTime\n // 4. AND we have an initiator for the UpdateLayoutTree event\n // 5. Then we set the last invalidation event for this frame to be the UpdateLayoutTree's initiator.\n const lastUpdateLayoutTreeForFrame = lastUpdateLayoutTreeByFrame.get(event.args.data.frame);\n if (lastUpdateLayoutTreeForFrame) {\n const {endTime} = Helpers.Timing.eventTimingsMicroSeconds(lastUpdateLayoutTreeForFrame);\n const initiatorOfUpdateLayout = eventToInitiatorMap.get(lastUpdateLayoutTreeForFrame);\n\n if (initiatorOfUpdateLayout && endTime && endTime > event.ts) {\n invalidationInitiator = initiatorOfUpdateLayout;\n }\n }\n }\n lastInvalidationEventForFrame.set(event.args.data.frame, invalidationInitiator);\n } else if (Types.Events.isLayout(event)) {\n // The initiator of a Layout event is the last Invalidation event.\n const lastInvalidation = lastInvalidationEventForFrame.get(event.args.beginData.frame);\n if (lastInvalidation) {\n storeInitiator({\n event,\n initiator: lastInvalidation,\n });\n }\n // Now clear the last invalidation for the frame: the last invalidation has been linked to a Layout event, so it cannot be the initiator for any future layouts.\n lastInvalidationEventForFrame.delete(event.args.beginData.frame);\n } else if (Types.Events.isRequestAnimationFrame(event)) {\n requestAnimationFrameEventsById.set(event.args.data.id, event);\n } else if (Types.Events.isFireAnimationFrame(event)) {\n // If we get a fire event, that means we should have had the\n // RequestAnimationFrame event by now. If so, we can set that as the\n // initiator for the fire event.\n const matchingRequestEvent = requestAnimationFrameEventsById.get(event.args.data.id);\n if (matchingRequestEvent) {\n storeInitiator({\n event,\n initiator: matchingRequestEvent,\n });\n }\n } else if (Types.Events.isTimerInstall(event)) {\n timerInstallEventsById.set(event.args.data.timerId, event);\n } else if (Types.Events.isTimerFire(event)) {\n const matchingInstall = timerInstallEventsById.get(event.args.data.timerId);\n if (matchingInstall) {\n storeInitiator({event, initiator: matchingInstall});\n }\n } else if (Types.Events.isRequestIdleCallback(event)) {\n requestIdleCallbackEventsById.set(event.args.data.id, event);\n } else if (Types.Events.isFireIdleCallback(event)) {\n const matchingRequestEvent = requestIdleCallbackEventsById.get(event.args.data.id);\n if (matchingRequestEvent) {\n storeInitiator({\n event,\n initiator: matchingRequestEvent,\n });\n }\n } else if (Types.Events.isWebSocketCreate(event)) {\n webSocketCreateEventsById.set(event.args.data.identifier, event);\n } else if (Types.Events.isWebSocketInfo(event) || Types.Events.isWebSocketTransfer(event)) {\n const matchingCreateEvent = webSocketCreateEventsById.get(event.args.data.identifier);\n if (matchingCreateEvent) {\n storeInitiator({\n event,\n initiator: matchingCreateEvent,\n });\n }\n } else if (Types.Events.isSchedulePostTaskCallback(event)) {\n schedulePostTaskCallbackEventsById.set(event.args.data.taskId, event);\n } else if (Types.Events.isRunPostTaskCallback(event) || Types.Events.isAbortPostTaskCallback(event)) {\n const matchingSchedule = schedulePostTaskCallbackEventsById.get(event.args.data.taskId);\n if (matchingSchedule) {\n storeInitiator({event, initiator: matchingSchedule});\n }\n }\n}\n\nfunction createRelationshipsFromFlows(): void {\n const flows = flowsHandlerData().flows;\n for (let i = 0; i < flows.length; i++) {\n const flow = flows[i];\n for (let j = 0; j < flow.length - 1; j++) {\n storeInitiator({event: flow[j + 1], initiator: flow[j]});\n }\n }\n}\n\nfunction createRelationshipsFromAsyncJSCalls(): void {\n const asyncCallEntries = AsyncJSCallsHandlerData().schedulerToRunEntryPoints.entries();\n for (const [asyncCaller, asyncCallees] of asyncCallEntries) {\n for (const asyncCallee of asyncCallees) {\n storeInitiator({event: asyncCallee, initiator: asyncCaller});\n }\n }\n}\n\nexport async function finalize(): Promise<void> {\n createRelationshipsFromFlows();\n createRelationshipsFromAsyncJSCalls();\n}\n\nexport interface InitiatorsData {\n eventToInitiator: Map<Types.Events.Event, Types.Events.Event>;\n initiatorToEvents: Map<Types.Events.Event, Types.Events.Event[]>;\n}\n\nexport function data(): InitiatorsData {\n return {\n eventToInitiator: eventToInitiatorMap,\n initiatorToEvents: initiatorToEventsMap,\n };\n}\n\nexport function deps(): ['Flows', 'AsyncJSCalls'] {\n return ['Flows', 'AsyncJSCalls'];\n}\n"]}
|
|
1
|
+
{"version":3,"file":"InitiatorsHandler.js","sourceRoot":"","sources":["../../../../../../../front_end/models/trace/handlers/InitiatorsHandler.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright 2023 The Chromium Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\n\nimport * as Helpers from '../helpers/helpers.js';\nimport * as Types from '../types/types.js';\n\nimport {data as AsyncJSCallsHandlerData} from './AsyncJSCallsHandler.js';\nimport {data as flowsHandlerData} from './FlowsHandler.js';\n\nconst lastScheduleStyleRecalcByFrame = new Map<string, Types.Events.ScheduleStyleRecalculation>();\n\n// This tracks the last event that is considered to have invalidated the layout\n// for a given frame.\n// Note that although there is an InvalidateLayout event, there are also other\n// events (ScheduleStyleRecalculation) that could be the reason a layout was\n// invalidated.\nconst lastInvalidationEventForFrame = new Map<string, Types.Events.Event>();\n\n// Important: although the event is called UpdateLayoutTree, in the UI we\n// present these to the user as \"Recalculate Style\". So don't get confused!\n// These are the same - just UpdateLayoutTree is what the event from Chromium\n// is called.\nconst lastUpdateLayoutTreeByFrame = new Map<string, Types.Events.UpdateLayoutTree>();\n\n// These two maps store the same data but in different directions.\n// For a given event, tell me what its initiator was. An event can only have one initiator.\nconst eventToInitiatorMap = new Map<Types.Events.Event, Types.Events.Event>();\n// For a given event, tell me what events it initiated. An event can initiate\n// multiple events, hence why the value for this map is an array.\nconst initiatorToEventsMap = new Map<Types.Events.Event, Types.Events.Event[]>();\n\nconst webSocketCreateEventsById: Map<number, Types.Events.WebSocketCreate> = new Map();\nconst schedulePostTaskCallbackEventsById: Map<number, Types.Events.SchedulePostTaskCallback> = new Map();\n\nexport function reset(): void {\n lastScheduleStyleRecalcByFrame.clear();\n lastInvalidationEventForFrame.clear();\n lastUpdateLayoutTreeByFrame.clear();\n eventToInitiatorMap.clear();\n initiatorToEventsMap.clear();\n webSocketCreateEventsById.clear();\n schedulePostTaskCallbackEventsById.clear();\n}\n\nfunction storeInitiator(data: {initiator: Types.Events.Event, event: Types.Events.Event}): void {\n eventToInitiatorMap.set(data.event, data.initiator);\n const eventsForInitiator = initiatorToEventsMap.get(data.initiator) || [];\n eventsForInitiator.push(data.event);\n initiatorToEventsMap.set(data.initiator, eventsForInitiator);\n}\n\n/**\n * IMPORTANT: Before adding support for new initiator relationships in\n * trace events consider using Perfetto's flow API on the events in\n * question, so that they get automatically computed.\n * @see {@link flowsHandlerData}\n *\n * The events manually computed here were added before we had support\n * for flow events. As such they should be migrated to use the flow\n * API so that no manual parsing is needed.\n */\nexport function handleEvent(event: Types.Events.Event): void {\n if (Types.Events.isScheduleStyleRecalculation(event)) {\n lastScheduleStyleRecalcByFrame.set(event.args.data.frame, event);\n } else if (Types.Events.isUpdateLayoutTree(event)) {\n // IMPORTANT: although the trace event is called UpdateLayoutTree, this\n // represents a Styles Recalculation. This event in the timeline is shown to\n // the user as \"Recalculate Styles.\"\n if (event.args.beginData) {\n // Store the last UpdateLayout event: we use this when we see an\n // InvalidateLayout and try to figure out its initiator.\n lastUpdateLayoutTreeByFrame.set(event.args.beginData.frame, event);\n\n // If this frame has seen a ScheduleStyleRecalc event, then that event is\n // considered to be the initiator of this StylesRecalc.\n const scheduledStyleForFrame = lastScheduleStyleRecalcByFrame.get(event.args.beginData.frame);\n if (scheduledStyleForFrame) {\n storeInitiator({\n event,\n initiator: scheduledStyleForFrame,\n });\n }\n }\n } else if (Types.Events.isInvalidateLayout(event)) {\n // By default, the InvalidateLayout event is what triggered the layout invalidation for this frame.\n let invalidationInitiator: Types.Events.Event = event;\n\n // However, if we have not had any prior invalidations for this frame, we\n // want to consider StyleRecalculation events as they might be the actual\n // cause of this layout invalidation.\n if (!lastInvalidationEventForFrame.has(event.args.data.frame)) {\n // 1. If we have not had an invalidation event for this frame\n // 2. AND we have had an UpdateLayoutTree for this frame\n // 3. AND the UpdateLayoutTree event ended AFTER the InvalidateLayout startTime\n // 4. AND we have an initiator for the UpdateLayoutTree event\n // 5. Then we set the last invalidation event for this frame to be the UpdateLayoutTree's initiator.\n const lastUpdateLayoutTreeForFrame = lastUpdateLayoutTreeByFrame.get(event.args.data.frame);\n if (lastUpdateLayoutTreeForFrame) {\n const {endTime} = Helpers.Timing.eventTimingsMicroSeconds(lastUpdateLayoutTreeForFrame);\n const initiatorOfUpdateLayout = eventToInitiatorMap.get(lastUpdateLayoutTreeForFrame);\n\n if (initiatorOfUpdateLayout && endTime && endTime > event.ts) {\n invalidationInitiator = initiatorOfUpdateLayout;\n }\n }\n }\n lastInvalidationEventForFrame.set(event.args.data.frame, invalidationInitiator);\n } else if (Types.Events.isLayout(event)) {\n // The initiator of a Layout event is the last Invalidation event.\n const lastInvalidation = lastInvalidationEventForFrame.get(event.args.beginData.frame);\n if (lastInvalidation) {\n storeInitiator({\n event,\n initiator: lastInvalidation,\n });\n }\n // Now clear the last invalidation for the frame: the last invalidation has been linked to a Layout event, so it cannot be the initiator for any future layouts.\n lastInvalidationEventForFrame.delete(event.args.beginData.frame);\n } else if (Types.Events.isWebSocketCreate(event)) {\n webSocketCreateEventsById.set(event.args.data.identifier, event);\n } else if (Types.Events.isWebSocketInfo(event) || Types.Events.isWebSocketTransfer(event)) {\n const matchingCreateEvent = webSocketCreateEventsById.get(event.args.data.identifier);\n if (matchingCreateEvent) {\n storeInitiator({\n event,\n initiator: matchingCreateEvent,\n });\n }\n } else if (Types.Events.isSchedulePostTaskCallback(event)) {\n schedulePostTaskCallbackEventsById.set(event.args.data.taskId, event);\n } else if (Types.Events.isRunPostTaskCallback(event) || Types.Events.isAbortPostTaskCallback(event)) {\n const matchingSchedule = schedulePostTaskCallbackEventsById.get(event.args.data.taskId);\n if (matchingSchedule) {\n storeInitiator({event, initiator: matchingSchedule});\n }\n }\n}\n\nfunction createRelationshipsFromFlows(): void {\n const flows = flowsHandlerData().flows;\n for (let i = 0; i < flows.length; i++) {\n const flow = flows[i];\n for (let j = 0; j < flow.length - 1; j++) {\n storeInitiator({event: flow[j + 1], initiator: flow[j]});\n }\n }\n}\n\nfunction createRelationshipsFromAsyncJSCalls(): void {\n const asyncCallEntries = AsyncJSCallsHandlerData().schedulerToRunEntryPoints.entries();\n for (const [asyncCaller, asyncCallees] of asyncCallEntries) {\n for (const asyncCallee of asyncCallees) {\n storeInitiator({event: asyncCallee, initiator: asyncCaller});\n }\n }\n}\n\nexport async function finalize(): Promise<void> {\n createRelationshipsFromFlows();\n createRelationshipsFromAsyncJSCalls();\n}\n\nexport interface InitiatorsData {\n eventToInitiator: Map<Types.Events.Event, Types.Events.Event>;\n initiatorToEvents: Map<Types.Events.Event, Types.Events.Event[]>;\n}\n\nexport function data(): InitiatorsData {\n return {\n eventToInitiator: eventToInitiatorMap,\n initiatorToEvents: initiatorToEventsMap,\n };\n}\n\nexport function deps(): ['Flows', 'AsyncJSCalls'] {\n return ['Flows', 'AsyncJSCalls'];\n}\n"]}
|
|
@@ -14,7 +14,6 @@ export interface EventTimingsData<ValueType extends Types.Timing.Micro | Types.T
|
|
|
14
14
|
export declare function eventTimingsMicroSeconds(event: Types.Events.Event): EventTimingsData<Types.Timing.Micro>;
|
|
15
15
|
export declare function eventTimingsMilliSeconds(event: Types.Events.Event): EventTimingsData<Types.Timing.Milli>;
|
|
16
16
|
export declare function traceWindowMilliSeconds(bounds: Types.Timing.TraceWindowMicro): Types.Timing.TraceWindowMilli;
|
|
17
|
-
export declare function traceWindowMillisecondsToMicroSeconds(bounds: Types.Timing.TraceWindowMilli): Types.Timing.TraceWindowMicro;
|
|
18
17
|
export declare function traceWindowMicroSecondsToMilliSeconds(bounds: Types.Timing.TraceWindowMicro): Types.Timing.TraceWindowMilli;
|
|
19
18
|
export declare function traceWindowFromMilliSeconds(min: Types.Timing.Milli, max: Types.Timing.Milli): Types.Timing.TraceWindowMicro;
|
|
20
19
|
export declare function traceWindowFromMicroSeconds(min: Types.Timing.Micro, max: Types.Timing.Micro): Types.Timing.TraceWindowMicro;
|
|
@@ -65,13 +65,6 @@ export function traceWindowMilliSeconds(bounds) {
|
|
|
65
65
|
range: microToMilli(bounds.range),
|
|
66
66
|
};
|
|
67
67
|
}
|
|
68
|
-
export function traceWindowMillisecondsToMicroSeconds(bounds) {
|
|
69
|
-
return {
|
|
70
|
-
min: milliToMicro(bounds.min),
|
|
71
|
-
max: milliToMicro(bounds.max),
|
|
72
|
-
range: milliToMicro(bounds.range),
|
|
73
|
-
};
|
|
74
|
-
}
|
|
75
68
|
export function traceWindowMicroSecondsToMilliSeconds(bounds) {
|
|
76
69
|
return {
|
|
77
70
|
min: microToMilli(bounds.min),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Timing.js","sourceRoot":"","sources":["../../../../../../../front_end/models/trace/helpers/Timing.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright 2022 The Chromium Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\n\nimport * as Types from '../types/types.js';\n\nimport {getNavigationForTraceEvent} from './Trace.js';\n\nexport const milliToMicro = (value: Types.Timing.Milli): Types.Timing.Micro => Types.Timing.Micro(value * 1000);\n\nexport const secondsToMilli = (value: Types.Timing.Seconds): Types.Timing.Milli => Types.Timing.Milli(value * 1000);\n\nexport const secondsToMicro = (value: Types.Timing.Seconds): Types.Timing.Micro => milliToMicro(secondsToMilli(value));\n\nexport const microToMilli = (value: Types.Timing.Micro): Types.Timing.Milli => Types.Timing.Milli(value / 1000);\n\nexport const microToSeconds = (value: Types.Timing.Micro): Types.Timing.Seconds =>\n Types.Timing.Seconds(value / 1000 / 1000);\n\nexport function timeStampForEventAdjustedByClosestNavigation(\n event: Types.Events.Event,\n traceBounds: Types.Timing.TraceWindowMicro,\n navigationsByNavigationId: Map<string, Types.Events.NavigationStart>,\n navigationsByFrameId: Map<string, Types.Events.NavigationStart[]>,\n ): Types.Timing.Micro {\n let eventTimeStamp = event.ts - traceBounds.min;\n if (event.args?.data?.navigationId) {\n const navigationForEvent = navigationsByNavigationId.get(event.args.data.navigationId);\n if (navigationForEvent) {\n eventTimeStamp = event.ts - navigationForEvent.ts;\n }\n } else if (event.args?.data?.frame) {\n const navigationForEvent = getNavigationForTraceEvent(event, event.args.data.frame, navigationsByFrameId);\n if (navigationForEvent) {\n eventTimeStamp = event.ts - navigationForEvent.ts;\n }\n }\n return Types.Timing.Micro(eventTimeStamp);\n}\n\n// Expands the trace window by a provided percentage or, if it the expanded window is smaller than 1 millisecond, expands it to 1 millisecond.\n// If the expanded window is outside of the max trace window, cut the overflowing bound to the max trace window bound.\nexport function expandWindowByPercentOrToOneMillisecond(\n annotationWindow: Types.Timing.TraceWindowMicro, maxTraceWindow: Types.Timing.TraceWindowMicro,\n percentage: number): Types.Timing.TraceWindowMicro {\n // Expand min and max of the window by half of the provided percentage. That way, in total, the window will be expanded by the provided percentage.\n let newMin = annotationWindow.min - annotationWindow.range * (percentage / 100) / 2;\n let newMax = annotationWindow.max + annotationWindow.range * (percentage / 100) / 2;\n\n if (newMax - newMin < 1_000) {\n const rangeMiddle = (annotationWindow.min + annotationWindow.max) / 2;\n newMin = rangeMiddle - 500;\n newMax = rangeMiddle + 500;\n }\n\n newMin = Math.max(newMin, maxTraceWindow.min);\n newMax = Math.min(newMax, maxTraceWindow.max);\n\n const expandedWindow: Types.Timing.TraceWindowMicro = {\n min: Types.Timing.Micro(newMin),\n max: Types.Timing.Micro(newMax),\n range: Types.Timing.Micro(newMax - newMin),\n };\n\n return expandedWindow;\n}\n\nexport interface EventTimingsData<ValueType extends Types.Timing.Micro|Types.Timing.Milli|Types.Timing.Seconds, > {\n startTime: ValueType;\n endTime: ValueType;\n duration: ValueType;\n}\n\nexport function eventTimingsMicroSeconds(event: Types.Events.Event): EventTimingsData<Types.Timing.Micro> {\n return {\n startTime: event.ts as Types.Timing.Micro,\n endTime: (event.ts + (event.dur ?? 0)) as Types.Timing.Micro,\n duration: (event.dur || 0) as Types.Timing.Micro,\n };\n}\nexport function eventTimingsMilliSeconds(event: Types.Events.Event): EventTimingsData<Types.Timing.Milli> {\n return {\n startTime: (event.ts / 1000) as Types.Timing.Milli,\n endTime: (event.ts + (event.dur ?? 0)) / 1000 as Types.Timing.Milli,\n duration: (event.dur || 0) / 1000 as Types.Timing.Milli,\n };\n}\n\nexport function traceWindowMilliSeconds(bounds: Types.Timing.TraceWindowMicro): Types.Timing.TraceWindowMilli {\n return {\n min: microToMilli(bounds.min),\n max: microToMilli(bounds.max),\n range: microToMilli(bounds.range),\n };\n}\n\nexport function traceWindowMillisecondsToMicroSeconds(bounds: Types.Timing.TraceWindowMilli):\n Types.Timing.TraceWindowMicro {\n return {\n min: milliToMicro(bounds.min),\n max: milliToMicro(bounds.max),\n range: milliToMicro(bounds.range),\n };\n}\nexport function traceWindowMicroSecondsToMilliSeconds(bounds: Types.Timing.TraceWindowMicro):\n Types.Timing.TraceWindowMilli {\n return {\n min: microToMilli(bounds.min),\n max: microToMilli(bounds.max),\n range: microToMilli(bounds.range),\n };\n}\n\nexport function traceWindowFromMilliSeconds(\n min: Types.Timing.Milli, max: Types.Timing.Milli): Types.Timing.TraceWindowMicro {\n const traceWindow: Types.Timing.TraceWindowMicro = {\n min: milliToMicro(min),\n max: milliToMicro(max),\n range: Types.Timing.Micro(milliToMicro(max) - milliToMicro(min)),\n };\n return traceWindow;\n}\n\nexport function traceWindowFromMicroSeconds(\n min: Types.Timing.Micro, max: Types.Timing.Micro): Types.Timing.TraceWindowMicro {\n const traceWindow: Types.Timing.TraceWindowMicro = {\n min,\n max,\n range: Types.Timing.Micro(max - min),\n };\n return traceWindow;\n}\n\nexport function traceWindowFromEvent(event: Types.Events.Event): Types.Timing.TraceWindowMicro {\n return {\n min: event.ts,\n max: Types.Timing.Micro(event.ts + (event.dur ?? 0)),\n range: event.dur ?? Types.Timing.Micro(0),\n };\n}\n\nexport interface BoundsIncludeTimeRange {\n timeRange: Types.Timing.TraceWindowMicro;\n bounds: Types.Timing.TraceWindowMicro;\n}\n\n/**\n * Checks to see if the timeRange is within the bounds. By \"within\" we mean\n * \"has any overlap\":\n * |------------------------|\n * == no overlap (entirely before)\n * ========= overlap\n * ========= overlap\n * ========= overlap\n * ==== no overlap (entirely after)\n * ============================== overlap (time range is larger than bounds)\n * |------------------------|\n */\nexport function boundsIncludeTimeRange(data: BoundsIncludeTimeRange): boolean {\n const {min: visibleMin, max: visibleMax} = data.bounds;\n const {min: rangeMin, max: rangeMax} = data.timeRange;\n\n return visibleMin <= rangeMax && visibleMax >= rangeMin;\n}\n\n/** Checks to see if the event is within or overlaps the bounds */\nexport function eventIsInBounds(event: Types.Events.Event, bounds: Types.Timing.TraceWindowMicro): boolean {\n const startTime = event.ts;\n return startTime <= bounds.max && bounds.min <= (startTime + (event.dur ?? 0));\n}\n\nexport function timestampIsInBounds(bounds: Types.Timing.TraceWindowMicro, timestamp: Types.Timing.Micro): boolean {\n return timestamp >= bounds.min && timestamp <= bounds.max;\n}\n\nexport interface WindowFitsInsideBounds {\n window: Types.Timing.TraceWindowMicro;\n bounds: Types.Timing.TraceWindowMicro;\n}\n\n/**\n * Returns true if the window fits entirely within the bounds.\n * Note that if the window is equivalent to the bounds, that is considered to fit\n */\nexport function windowFitsInsideBounds(data: WindowFitsInsideBounds): boolean {\n return data.window.min >= data.bounds.min && data.window.max <= data.bounds.max;\n}\n\nexport function windowsEqual(w1: Types.Timing.TraceWindowMicro, w2: Types.Timing.TraceWindowMicro): boolean {\n return w1.min === w2.min && w1.max === w2.max;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"Timing.js","sourceRoot":"","sources":["../../../../../../../front_end/models/trace/helpers/Timing.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright 2022 The Chromium Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\n\nimport * as Types from '../types/types.js';\n\nimport {getNavigationForTraceEvent} from './Trace.js';\n\nexport const milliToMicro = (value: Types.Timing.Milli): Types.Timing.Micro => Types.Timing.Micro(value * 1000);\n\nexport const secondsToMilli = (value: Types.Timing.Seconds): Types.Timing.Milli => Types.Timing.Milli(value * 1000);\n\nexport const secondsToMicro = (value: Types.Timing.Seconds): Types.Timing.Micro => milliToMicro(secondsToMilli(value));\n\nexport const microToMilli = (value: Types.Timing.Micro): Types.Timing.Milli => Types.Timing.Milli(value / 1000);\n\nexport const microToSeconds = (value: Types.Timing.Micro): Types.Timing.Seconds =>\n Types.Timing.Seconds(value / 1000 / 1000);\n\nexport function timeStampForEventAdjustedByClosestNavigation(\n event: Types.Events.Event,\n traceBounds: Types.Timing.TraceWindowMicro,\n navigationsByNavigationId: Map<string, Types.Events.NavigationStart>,\n navigationsByFrameId: Map<string, Types.Events.NavigationStart[]>,\n ): Types.Timing.Micro {\n let eventTimeStamp = event.ts - traceBounds.min;\n if (event.args?.data?.navigationId) {\n const navigationForEvent = navigationsByNavigationId.get(event.args.data.navigationId);\n if (navigationForEvent) {\n eventTimeStamp = event.ts - navigationForEvent.ts;\n }\n } else if (event.args?.data?.frame) {\n const navigationForEvent = getNavigationForTraceEvent(event, event.args.data.frame, navigationsByFrameId);\n if (navigationForEvent) {\n eventTimeStamp = event.ts - navigationForEvent.ts;\n }\n }\n return Types.Timing.Micro(eventTimeStamp);\n}\n\n// Expands the trace window by a provided percentage or, if it the expanded window is smaller than 1 millisecond, expands it to 1 millisecond.\n// If the expanded window is outside of the max trace window, cut the overflowing bound to the max trace window bound.\nexport function expandWindowByPercentOrToOneMillisecond(\n annotationWindow: Types.Timing.TraceWindowMicro, maxTraceWindow: Types.Timing.TraceWindowMicro,\n percentage: number): Types.Timing.TraceWindowMicro {\n // Expand min and max of the window by half of the provided percentage. That way, in total, the window will be expanded by the provided percentage.\n let newMin = annotationWindow.min - annotationWindow.range * (percentage / 100) / 2;\n let newMax = annotationWindow.max + annotationWindow.range * (percentage / 100) / 2;\n\n if (newMax - newMin < 1_000) {\n const rangeMiddle = (annotationWindow.min + annotationWindow.max) / 2;\n newMin = rangeMiddle - 500;\n newMax = rangeMiddle + 500;\n }\n\n newMin = Math.max(newMin, maxTraceWindow.min);\n newMax = Math.min(newMax, maxTraceWindow.max);\n\n const expandedWindow: Types.Timing.TraceWindowMicro = {\n min: Types.Timing.Micro(newMin),\n max: Types.Timing.Micro(newMax),\n range: Types.Timing.Micro(newMax - newMin),\n };\n\n return expandedWindow;\n}\n\nexport interface EventTimingsData<ValueType extends Types.Timing.Micro|Types.Timing.Milli|Types.Timing.Seconds, > {\n startTime: ValueType;\n endTime: ValueType;\n duration: ValueType;\n}\n\nexport function eventTimingsMicroSeconds(event: Types.Events.Event): EventTimingsData<Types.Timing.Micro> {\n return {\n startTime: event.ts as Types.Timing.Micro,\n endTime: (event.ts + (event.dur ?? 0)) as Types.Timing.Micro,\n duration: (event.dur || 0) as Types.Timing.Micro,\n };\n}\nexport function eventTimingsMilliSeconds(event: Types.Events.Event): EventTimingsData<Types.Timing.Milli> {\n return {\n startTime: (event.ts / 1000) as Types.Timing.Milli,\n endTime: (event.ts + (event.dur ?? 0)) / 1000 as Types.Timing.Milli,\n duration: (event.dur || 0) / 1000 as Types.Timing.Milli,\n };\n}\n\nexport function traceWindowMilliSeconds(bounds: Types.Timing.TraceWindowMicro): Types.Timing.TraceWindowMilli {\n return {\n min: microToMilli(bounds.min),\n max: microToMilli(bounds.max),\n range: microToMilli(bounds.range),\n };\n}\n\nexport function traceWindowMicroSecondsToMilliSeconds(bounds: Types.Timing.TraceWindowMicro):\n Types.Timing.TraceWindowMilli {\n return {\n min: microToMilli(bounds.min),\n max: microToMilli(bounds.max),\n range: microToMilli(bounds.range),\n };\n}\n\nexport function traceWindowFromMilliSeconds(\n min: Types.Timing.Milli, max: Types.Timing.Milli): Types.Timing.TraceWindowMicro {\n const traceWindow: Types.Timing.TraceWindowMicro = {\n min: milliToMicro(min),\n max: milliToMicro(max),\n range: Types.Timing.Micro(milliToMicro(max) - milliToMicro(min)),\n };\n return traceWindow;\n}\n\nexport function traceWindowFromMicroSeconds(\n min: Types.Timing.Micro, max: Types.Timing.Micro): Types.Timing.TraceWindowMicro {\n const traceWindow: Types.Timing.TraceWindowMicro = {\n min,\n max,\n range: Types.Timing.Micro(max - min),\n };\n return traceWindow;\n}\n\nexport function traceWindowFromEvent(event: Types.Events.Event): Types.Timing.TraceWindowMicro {\n return {\n min: event.ts,\n max: Types.Timing.Micro(event.ts + (event.dur ?? 0)),\n range: event.dur ?? Types.Timing.Micro(0),\n };\n}\n\nexport interface BoundsIncludeTimeRange {\n timeRange: Types.Timing.TraceWindowMicro;\n bounds: Types.Timing.TraceWindowMicro;\n}\n\n/**\n * Checks to see if the timeRange is within the bounds. By \"within\" we mean\n * \"has any overlap\":\n * |------------------------|\n * == no overlap (entirely before)\n * ========= overlap\n * ========= overlap\n * ========= overlap\n * ==== no overlap (entirely after)\n * ============================== overlap (time range is larger than bounds)\n * |------------------------|\n */\nexport function boundsIncludeTimeRange(data: BoundsIncludeTimeRange): boolean {\n const {min: visibleMin, max: visibleMax} = data.bounds;\n const {min: rangeMin, max: rangeMax} = data.timeRange;\n\n return visibleMin <= rangeMax && visibleMax >= rangeMin;\n}\n\n/** Checks to see if the event is within or overlaps the bounds */\nexport function eventIsInBounds(event: Types.Events.Event, bounds: Types.Timing.TraceWindowMicro): boolean {\n const startTime = event.ts;\n return startTime <= bounds.max && bounds.min <= (startTime + (event.dur ?? 0));\n}\n\nexport function timestampIsInBounds(bounds: Types.Timing.TraceWindowMicro, timestamp: Types.Timing.Micro): boolean {\n return timestamp >= bounds.min && timestamp <= bounds.max;\n}\n\nexport interface WindowFitsInsideBounds {\n window: Types.Timing.TraceWindowMicro;\n bounds: Types.Timing.TraceWindowMicro;\n}\n\n/**\n * Returns true if the window fits entirely within the bounds.\n * Note that if the window is equivalent to the bounds, that is considered to fit\n */\nexport function windowFitsInsideBounds(data: WindowFitsInsideBounds): boolean {\n return data.window.min >= data.bounds.min && data.window.max <= data.bounds.max;\n}\n\nexport function windowsEqual(w1: Types.Timing.TraceWindowMicro, w2: Types.Timing.TraceWindowMicro): boolean {\n return w1.min === w2.min && w1.max === w2.max;\n}\n"]}
|
|
@@ -142,7 +142,6 @@ export interface ForEachEventConfig {
|
|
|
142
142
|
*/
|
|
143
143
|
export declare function forEachEvent(events: Types.Events.Event[], config: ForEachEventConfig): void;
|
|
144
144
|
export declare function eventHasCategory(event: Types.Events.Event, category: string): boolean;
|
|
145
|
-
export declare function nodeIdForInvalidationEvent(event: Types.Events.InvalidationTrackingEvent): Protocol.DOM.BackendNodeId | null;
|
|
146
145
|
/**
|
|
147
146
|
* This compares Types.Events.CallFrame with Protocol.Runtime.CallFrame and checks for equality.
|
|
148
147
|
*/
|
|
@@ -557,9 +557,6 @@ export function eventHasCategory(event, category) {
|
|
|
557
557
|
}
|
|
558
558
|
return parsedCategoriesForEvent.has(category);
|
|
559
559
|
}
|
|
560
|
-
export function nodeIdForInvalidationEvent(event) {
|
|
561
|
-
return event.args.data.nodeId ?? null;
|
|
562
|
-
}
|
|
563
560
|
/**
|
|
564
561
|
* This compares Types.Events.CallFrame with Protocol.Runtime.CallFrame and checks for equality.
|
|
565
562
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Trace.js","sourceRoot":"","sources":["../../../../../../../front_end/models/trace/helpers/Trace.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright 2022 The Chromium Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\n\nimport * as Platform from '../../../core/platform/platform.js';\nimport type * as Protocol from '../../../generated/protocol.js';\nimport type * as CPUProfile from '../../cpu_profile/cpu_profile.js';\nimport * as Types from '../types/types.js';\n\nimport {SyntheticEventsManager} from './SyntheticEvents.js';\nimport {eventTimingsMicroSeconds} from './Timing.js';\n\ninterface MatchingPairableAsyncEvents {\n begin: Types.Events.PairableAsyncBegin|null;\n end: Types.Events.PairableAsyncEnd|null;\n instant?: Types.Events.PairableAsyncInstant[];\n}\n\n/**\n * Extracts the raw stack trace in known trace events. Most likely than\n * not you want to use `getZeroIndexedStackTraceForEvent`, which returns\n * the stack with zero based numbering. Since some trace events are\n * one based this function can yield unexpected results when used\n * indiscriminately.\n *\n * Note: this only returns the stack trace contained in the payload of\n * an event, which only contains the synchronous portion of the call\n * stack. If you want to obtain the whole stack trace you might need to\n * use the @see Trace.Extras.StackTraceForEvent util.\n */\nexport function stackTraceInEvent(event: Types.Events.Event): Types.Events.CallFrame[]|null {\n if (event.args?.data?.stackTrace) {\n return event.args.data.stackTrace;\n }\n if (event.args?.stackTrace) {\n return event.args.stackTrace;\n }\n if (Types.Events.isUpdateLayoutTree(event)) {\n return event.args.beginData?.stackTrace || null;\n }\n if (Types.Extensions.isSyntheticExtensionEntry(event)) {\n return stackTraceInEvent(event.rawSourceEvent);\n }\n if (Types.Events.isSyntheticUserTiming(event)) {\n return stackTraceInEvent(event.rawSourceEvent);\n }\n if (Types.Events.isFunctionCall(event)) {\n const data = event.args.data;\n if (!data) {\n return null;\n }\n const {columnNumber, lineNumber, url, scriptId, functionName} = data;\n if (lineNumber === undefined || functionName === undefined || columnNumber === undefined ||\n scriptId === undefined || url === undefined) {\n return null;\n }\n return [{columnNumber, lineNumber, url, scriptId, functionName}];\n }\n if (Types.Events.isProfileCall(event)) {\n // Of type Protocol.Runtime.CallFrame, handle accordingly.\n const callFrame = event.callFrame;\n if (!callFrame) {\n return null;\n }\n const {columnNumber, lineNumber, url, scriptId, functionName} = callFrame;\n if (lineNumber === undefined || functionName === undefined || columnNumber === undefined ||\n scriptId === undefined || url === undefined) {\n return null;\n }\n return [{columnNumber, lineNumber, url, scriptId, functionName}];\n }\n return null;\n}\n\nexport function extractOriginFromTrace(firstNavigationURL: string): string|null {\n const url = new URL(firstNavigationURL);\n if (url) {\n // We do this to save some space in the toolbar - seeing the `www` is less\n // useful than seeing `foo.com` if it's truncated at narrow widths\n if (url.host.startsWith('www.')) {\n return url.host.slice(4);\n }\n return url.host;\n }\n return null;\n}\n\nexport type EventsInThread<T extends Types.Events.Event> = Map<Types.Events.ThreadID, T[]>;\n// Each thread contains events. Events indicate the thread and process IDs, which are\n// used to store the event in the correct process thread entry below.\nexport function addEventToProcessThread<T extends Types.Events.Event>(\n event: T,\n eventsInProcessThread: Map<Types.Events.ProcessID, EventsInThread<T>>,\n ): void {\n const {tid, pid} = event;\n let eventsInThread = eventsInProcessThread.get(pid);\n if (!eventsInThread) {\n eventsInThread = new Map<Types.Events.ThreadID, T[]>();\n }\n\n let events = eventsInThread.get(tid);\n if (!events) {\n events = [];\n }\n\n events.push(event);\n eventsInThread.set(event.tid, events);\n eventsInProcessThread.set(event.pid, eventsInThread);\n}\n\nexport interface TimeSpan {\n ts: Types.Timing.Micro;\n dur?: Types.Timing.Micro;\n}\nexport function eventTimeComparator(a: TimeSpan, b: TimeSpan): -1|0|1 {\n const aBeginTime = a.ts;\n const bBeginTime = b.ts;\n if (aBeginTime < bBeginTime) {\n return -1;\n }\n if (aBeginTime > bBeginTime) {\n return 1;\n }\n const aDuration = a.dur ?? 0;\n const bDuration = b.dur ?? 0;\n const aEndTime = aBeginTime + aDuration;\n const bEndTime = bBeginTime + bDuration;\n if (aEndTime > bEndTime) {\n return -1;\n }\n if (aEndTime < bEndTime) {\n return 1;\n }\n return 0;\n}\n/**\n * Sorts all the events in place, in order, by their start time. If they have\n * the same start time, orders them by longest first.\n */\nexport function sortTraceEventsInPlace(events: {ts: Types.Timing.Micro, dur?: Types.Timing.Micro}[]): void {\n events.sort(eventTimeComparator);\n}\n\n/**\n * Returns an array of ordered events that results after merging the two\n * ordered input arrays.\n */\nexport function mergeEventsInOrder<T1 extends Types.Events.Event, T2 extends Types.Events.Event>(\n eventsArray1: readonly T1[], eventsArray2: readonly T2[]): (T1|T2)[] {\n const result = [];\n let i = 0;\n let j = 0;\n while (i < eventsArray1.length && j < eventsArray2.length) {\n const event1 = eventsArray1[i];\n const event2 = eventsArray2[j];\n const compareValue = eventTimeComparator(event1, event2);\n if (compareValue <= 0) {\n result.push(event1);\n i++;\n }\n if (compareValue === 1) {\n result.push(event2);\n j++;\n }\n }\n while (i < eventsArray1.length) {\n result.push(eventsArray1[i++]);\n }\n while (j < eventsArray2.length) {\n result.push(eventsArray2[j++]);\n }\n return result;\n}\n\nexport function getNavigationForTraceEvent(\n event: Types.Events.Event,\n eventFrameId: string,\n navigationsByFrameId: Map<string, Types.Events.NavigationStart[]>,\n ): Types.Events.NavigationStart|null {\n const navigations = navigationsByFrameId.get(eventFrameId);\n if (!navigations || eventFrameId === '') {\n // This event's navigation has been filtered out by the meta handler as a noise event\n // or contains an empty frameId.\n return null;\n }\n\n const eventNavigationIndex =\n Platform.ArrayUtilities.nearestIndexFromEnd(navigations, navigation => navigation.ts <= event.ts);\n\n if (eventNavigationIndex === null) {\n // This event's navigation has been filtered out by the meta handler as a noise event.\n return null;\n }\n return navigations[eventNavigationIndex];\n}\n\nexport function extractId(event: Types.Events.PairableAsync|\n Types.Events.SyntheticEventPair<Types.Events.PairableAsync>): string|undefined {\n return event.id ?? event.id2?.global ?? event.id2?.local;\n}\n\nexport function activeURLForFrameAtTime(\n frameId: string, time: Types.Timing.Micro,\n rendererProcessesByFrame:\n Map<string,\n Map<Types.Events.ProcessID, {frame: Types.Events.TraceFrame, window: Types.Timing.TraceWindowMicro}[]>>):\n string|null {\n const processData = rendererProcessesByFrame.get(frameId);\n if (!processData) {\n return null;\n }\n for (const processes of processData.values()) {\n for (const processInfo of processes) {\n if (processInfo.window.min > time || processInfo.window.max < time) {\n continue;\n }\n return processInfo.frame.url;\n }\n }\n return null;\n}\n\n/**\n * @param node the node attached to the profile call. Here a node represents a function in the call tree.\n * @param profileId the profile ID that the sample came from that backs this call.\n * @param sampleIndex the index of the sample in the given profile that this call was created from\n * @param ts the timestamp of the profile call\n * @param pid the process ID of the profile call\n * @param tid the thread ID of the profile call\n *\n * See `panels/timeline/docs/profile_calls.md` for more context on how these events are created.\n */\nexport function makeProfileCall(\n node: CPUProfile.ProfileTreeModel.ProfileNode, profileId: Types.Events.ProfileID, sampleIndex: number,\n ts: Types.Timing.Micro, pid: Types.Events.ProcessID,\n tid: Types.Events.ThreadID): Types.Events.SyntheticProfileCall {\n return {\n cat: '',\n name: 'ProfileCall',\n nodeId: node.id,\n args: {},\n ph: Types.Events.Phase.COMPLETE,\n pid,\n tid,\n ts,\n dur: Types.Timing.Micro(0),\n callFrame: node.callFrame,\n sampleIndex,\n profileId,\n };\n}\n\n/**\n * Matches beginning events with PairableAsyncEnd and PairableAsyncInstant (ASYNC_NESTABLE_INSTANT)\n * if provided, though currently only coming from Animations. Traces may contain multiple instant events so we need to\n * account for that.\n *\n * @returns {Map<string, MatchingPairableAsyncEvents>} Map of the animation's ID to it's matching events.\n */\nexport function matchEvents(unpairedEvents: Types.Events.PairableAsync[]): Map<string, MatchingPairableAsyncEvents> {\n // map to store begin and end of the event\n const matchedPairs: Map<string, MatchingPairableAsyncEvents> = new Map();\n\n // looking for start and end\n for (const event of unpairedEvents) {\n const syntheticId = getSyntheticId(event);\n if (syntheticId === undefined) {\n continue;\n }\n // Create a synthetic id to prevent collisions across categories.\n // Console timings can be dispatched with the same id, so use the\n // event name as well to generate unique ids.\n const otherEventsWithID = Platform.MapUtilities.getWithDefault(matchedPairs, syntheticId, () => {\n return {begin: null, end: null, instant: []};\n });\n\n const isStartEvent = event.ph === Types.Events.Phase.ASYNC_NESTABLE_START;\n const isEndEvent = event.ph === Types.Events.Phase.ASYNC_NESTABLE_END;\n const isInstantEvent = event.ph === Types.Events.Phase.ASYNC_NESTABLE_INSTANT;\n\n if (isStartEvent) {\n otherEventsWithID.begin = event as Types.Events.PairableAsyncBegin;\n } else if (isEndEvent) {\n otherEventsWithID.end = event as Types.Events.PairableAsyncEnd;\n } else if (isInstantEvent) {\n if (!otherEventsWithID.instant) {\n otherEventsWithID.instant = [];\n }\n otherEventsWithID.instant.push(event as Types.Events.PairableAsyncInstant);\n }\n }\n return matchedPairs;\n}\n\nfunction getSyntheticId(event: Types.Events.PairableAsync): string|undefined {\n const id = extractId(event);\n return id && `${event.cat}:${id}:${event.name}`;\n}\n\nexport function createSortedSyntheticEvents<T extends Types.Events.PairableAsync>(\n matchedPairs: Map<string, {\n begin: Types.Events.PairableAsyncBegin | null,\n end: Types.Events.PairableAsyncEnd | null,\n instant?: Types.Events.PairableAsyncInstant[],\n }>,\n syntheticEventCallback?: (syntheticEvent: Types.Events.SyntheticEventPair<T>) => void,\n ): Types.Events.SyntheticEventPair<T>[] {\n const syntheticEvents: Types.Events.SyntheticEventPair<T>[] = [];\n for (const [id, eventsTriplet] of matchedPairs.entries()) {\n const beginEvent = eventsTriplet.begin;\n const endEvent = eventsTriplet.end;\n const instantEvents = eventsTriplet.instant;\n if (!beginEvent || !(endEvent || instantEvents)) {\n // This should never happen, the backend only creates the events once it\n // has them both (beginEvent & endEvent/instantEvents), so we should never get into this state.\n // If we do, something is very wrong, so let's just drop that problematic event.\n continue;\n }\n const triplet = {beginEvent, endEvent, instantEvents};\n /**\n * When trying to pair events with instant events present, there are times when these\n * ASYNC_NESTABLE_INSTANT ('n') don't have a corresponding ASYNC_NESTABLE_END ('e') event.\n * In these cases, pair without needing the endEvent.\n */\n function eventsArePairable(data: {\n beginEvent: Types.Events.PairableAsyncBegin,\n endEvent: Types.Events.PairableAsyncEnd|null,\n instantEvents?: Types.Events.PairableAsyncInstant[],\n }): data is Types.Events.SyntheticEventPair<T>['args']['data'] {\n const instantEventsMatch = data.instantEvents ? data.instantEvents.some(e => id === getSyntheticId(e)) : false;\n const endEventMatch = data.endEvent ? id === getSyntheticId(data.endEvent) : false;\n return Boolean(id) && (instantEventsMatch || endEventMatch);\n }\n if (!eventsArePairable(triplet)) {\n continue;\n }\n const targetEvent = endEvent || beginEvent;\n\n const event = SyntheticEventsManager.registerSyntheticEvent<Types.Events.SyntheticEventPair<T>>({\n rawSourceEvent: triplet.beginEvent,\n cat: targetEvent.cat,\n ph: targetEvent.ph,\n pid: targetEvent.pid,\n tid: targetEvent.tid,\n id,\n // Both events have the same name, so it doesn't matter which we pick to\n // use as the description\n name: beginEvent.name,\n dur: Types.Timing.Micro(targetEvent.ts - beginEvent.ts),\n ts: beginEvent.ts,\n args: {\n data: triplet,\n },\n });\n\n if (event.dur < 0) {\n // We have seen in the backend that sometimes animation events get\n // generated with multiple begin entries, or multiple end entries, and this\n // can cause invalid data on the performance panel, so we drop them.\n // crbug.com/1472375\n continue;\n }\n syntheticEventCallback?.(event);\n syntheticEvents.push(event);\n }\n return syntheticEvents.sort((a, b) => a.ts - b.ts);\n}\n\nexport function createMatchedSortedSyntheticEvents<T extends Types.Events.PairableAsync>(\n unpairedAsyncEvents: T[], syntheticEventCallback?: (syntheticEvent: Types.Events.SyntheticEventPair<T>) => void):\n Types.Events.SyntheticEventPair<T>[] {\n const matchedPairs = matchEvents(unpairedAsyncEvents);\n const syntheticEvents = createSortedSyntheticEvents<T>(matchedPairs, syntheticEventCallback);\n return syntheticEvents;\n}\n\n/**\n * Different trace events return line/column numbers that are 1 or 0 indexed.\n * This function knows which events return 1 indexed numbers and normalizes\n * them. The UI expects 0 indexed line numbers, so that is what we return.\n */\nexport function getZeroIndexedLineAndColumnForEvent(event: Types.Events.Event): {\n lineNumber?: number,\n columnNumber?: number,\n} {\n // Some events emit line numbers that are 1 indexed, but the UI layer expects\n // numbers to be 0 indexed. So here, if the event matches a known 1-indexed\n // number event, we subtract one from the line and column numbers.\n // Otherwise, if the event has args.data.lineNumber/colNumber, we return it\n // as is.\n const numbers = getRawLineAndColumnNumbersForEvent(event);\n const {lineNumber, columnNumber} = numbers;\n\n switch (event.name) {\n // All these events have line/column numbers which are 1 indexed; so we\n // subtract to make them 0 indexed.\n case Types.Events.Name.FUNCTION_CALL:\n case Types.Events.Name.EVALUATE_SCRIPT:\n case Types.Events.Name.COMPILE:\n case Types.Events.Name.CACHE_SCRIPT: {\n return {\n lineNumber: typeof lineNumber === 'number' ? lineNumber - 1 : undefined,\n columnNumber: typeof columnNumber === 'number' ? columnNumber - 1 : undefined,\n };\n }\n default: {\n return numbers;\n }\n }\n}\n\n/**\n * Different trace events contain stack traces with line/column numbers\n * that are 1 or 0 indexed.\n * This function knows which events return 1 indexed numbers and normalizes\n * them. The UI expects 0 indexed line numbers, so that is what we return.\n *\n * Note: this only returns the stack trace contained in the payload of\n * an event, which only contains the synchronous portion of the call\n * stack. If you want to obtain the whole stack trace you might need to\n * use the @see Trace.Extras.StackTraceForEvent util.\n */\nexport function getZeroIndexedStackTraceForEvent(event: Types.Events.Event): Types.Events.CallFrame[]|null {\n const stack = stackTraceInEvent(event);\n if (!stack) {\n return null;\n }\n return stack.map(callFrame => {\n switch (event.name) {\n case Types.Events.Name.SCHEDULE_STYLE_RECALCULATION:\n case Types.Events.Name.INVALIDATE_LAYOUT:\n case Types.Events.Name.FUNCTION_CALL:\n case Types.Events.Name.UPDATE_LAYOUT_TREE: {\n return makeZeroBasedCallFrame(callFrame);\n }\n default: {\n if (Types.Events.isUserTiming(event) || Types.Extensions.isSyntheticExtensionEntry(event)) {\n return makeZeroBasedCallFrame(callFrame);\n }\n }\n }\n return callFrame;\n });\n}\n\n/**\n * Given a 1-based call frame creates a 0-based one.\n */\nexport function makeZeroBasedCallFrame(callFrame: Types.Events.CallFrame): Types.Events.CallFrame {\n const normalizedCallFrame = {...callFrame};\n\n normalizedCallFrame.lineNumber = callFrame.lineNumber && callFrame.lineNumber - 1;\n normalizedCallFrame.columnNumber = callFrame.columnNumber && callFrame.columnNumber - 1;\n return normalizedCallFrame;\n}\n\n/**\n * NOTE: you probably do not want this function! (Which is why it is not exported).\n *\n * Some trace events have 0 indexed line/column numbers, and others have 1\n * indexed. This function does NOT normalize them, but\n * `getZeroIndexedLineAndColumnNumbersForEvent` does. It is best to use that!\n *\n * @see {@link getZeroIndexedLineAndColumnForEvent}\n **/\nfunction getRawLineAndColumnNumbersForEvent(event: Types.Events.Event): {\n lineNumber?: number,\n columnNumber?: number,\n} {\n if (!event.args?.data) {\n return {\n lineNumber: undefined,\n columnNumber: undefined,\n };\n }\n let lineNumber: number|undefined = undefined;\n let columnNumber: number|undefined = undefined;\n if ('lineNumber' in event.args.data && typeof event.args.data.lineNumber === 'number') {\n lineNumber = event.args.data.lineNumber;\n }\n if ('columnNumber' in event.args.data && typeof event.args.data.columnNumber === 'number') {\n columnNumber = event.args.data.columnNumber;\n }\n\n return {lineNumber, columnNumber};\n}\n\nexport function frameIDForEvent(event: Types.Events.Event): string|null {\n // There are a few events (for example UpdateLayoutTree, ParseHTML) that have\n // the frame stored in args.beginData\n // Rather than list them all we just check for the presence of the field, so\n // we are robust against future trace events also doing this.\n // This check seems very robust, but it also helps satisfy TypeScript and\n // prevents us against unexpected data.\n if (event.args && 'beginData' in event.args && typeof event.args.beginData === 'object' &&\n event.args.beginData !== null && 'frame' in event.args.beginData &&\n typeof event.args.beginData.frame === 'string') {\n return event.args.beginData.frame;\n }\n // Otherwise, we expect frame to be in args.data\n if (event.args?.data?.frame) {\n return event.args.data.frame;\n }\n\n // No known frame for this event.\n return null;\n}\n\nconst DevToolsTimelineEventCategory = 'disabled-by-default-devtools.timeline';\nexport function isTopLevelEvent(event: Types.Events.Event): boolean {\n if (event.name === 'JSRoot' && event.cat === 'toplevel') {\n // This is used in TimelineJSProfile to insert a fake event prior to the\n // CPU Profile in order to ensure the trace isn't truncated. So if we see\n // this, we want to treat it as a top level event.\n // TODO(crbug.com/341234884): do we need this?\n return true;\n }\n return event.cat.includes(DevToolsTimelineEventCategory) && event.name === Types.Events.Name.RUN_TASK;\n}\n\nfunction topLevelEventIndexEndingAfter(events: Types.Events.Event[], time: Types.Timing.Micro): number {\n let index = Platform.ArrayUtilities.upperBound(events, time, (time, event) => time - event.ts) - 1;\n while (index > 0 && !isTopLevelEvent(events[index])) {\n index--;\n }\n return Math.max(index, 0);\n}\nexport function findUpdateLayoutTreeEvents(\n events: Types.Events.Event[], startTime: Types.Timing.Micro,\n endTime?: Types.Timing.Micro): Types.Events.UpdateLayoutTree[] {\n const foundEvents: Types.Events.UpdateLayoutTree[] = [];\n const startEventIndex = topLevelEventIndexEndingAfter(events, startTime);\n for (let i = startEventIndex; i < events.length; i++) {\n const event = events[i];\n if (!Types.Events.isUpdateLayoutTree(event)) {\n continue;\n }\n if (event.ts >= (endTime || Infinity)) {\n continue;\n }\n foundEvents.push(event);\n }\n return foundEvents;\n}\n\nexport function findNextEventAfterTimestamp<T extends Types.Events.Event>(candidates: T[], ts: Types.Timing.Micro): T|\n null {\n const index = Platform.ArrayUtilities.nearestIndexFromBeginning(candidates, candidate => ts < candidate.ts);\n return index === null ? null : candidates[index];\n}\n\nexport function findPreviousEventBeforeTimestamp<T extends Types.Events.Event>(\n candidates: T[], ts: Types.Timing.Micro): T|null {\n const index = Platform.ArrayUtilities.nearestIndexFromEnd(candidates, candidate => candidate.ts < ts);\n return index === null ? null : candidates[index];\n}\n\nexport interface ForEachEventConfig {\n onStartEvent: (event: Types.Events.Event) => void;\n onEndEvent: (event: Types.Events.Event) => void;\n onInstantEvent?: (event: Types.Events.Event) => void;\n eventFilter?: (event: Types.Events.Event) => boolean;\n startTime?: Types.Timing.Micro;\n endTime?: Types.Timing.Micro;\n /* If async events should be skipped. Defaults to true */\n ignoreAsyncEvents?: boolean;\n}\n\n/**\n * Iterates events in a tree hierarchically, from top to bottom,\n * calling back on every event's start and end in the order\n * dictated by the corresponding timestamp.\n *\n * Events are assumed to be in ascendent order by timestamp.\n *\n * Events with 0 duration are treated as instant events. These do not have a\n * begin and end, but will be passed to the config.onInstantEvent callback as\n * they are discovered. Do not provide this callback if you are not interested\n * in them.\n *\n * For example, given this tree, the following callbacks\n * are expected to be made in the following order\n * |---------------A---------------|\n * |------B------||-------D------|\n * |---C---|\n *\n * 1. Start A\n * 3. Start B\n * 4. Start C\n * 5. End C\n * 6. End B\n * 7. Start D\n * 8. End D\n * 9. End A\n *\n * By default, async events are skipped. This behaviour can be\n * overridden making use of the config.ignoreAsyncEvents parameter.\n */\nexport function forEachEvent(\n events: Types.Events.Event[],\n config: ForEachEventConfig,\n ): void {\n const globalStartTime = config.startTime ?? Types.Timing.Micro(0);\n const globalEndTime = config.endTime || Types.Timing.Micro(Infinity);\n const ignoreAsyncEvents = config.ignoreAsyncEvents === false ? false : true;\n\n const stack: Types.Events.Event[] = [];\n const startEventIndex = topLevelEventIndexEndingAfter(events, globalStartTime);\n for (let i = startEventIndex; i < events.length; i++) {\n const currentEvent = events[i];\n const currentEventTimings = eventTimingsMicroSeconds(currentEvent);\n if (currentEventTimings.endTime < globalStartTime) {\n continue;\n }\n if (currentEventTimings.startTime > globalEndTime) {\n break;\n }\n\n const isIgnoredAsyncEvent = ignoreAsyncEvents && Types.Events.isPhaseAsync(currentEvent.ph);\n if (isIgnoredAsyncEvent || Types.Events.isFlowPhase(currentEvent.ph)) {\n continue;\n }\n\n // If we have now reached an event that is after a bunch of events, we need\n // to call the onEndEvent callback for those events before moving on.\n let lastEventOnStack = stack.at(-1);\n let lastEventEndTime = lastEventOnStack ? eventTimingsMicroSeconds(lastEventOnStack).endTime : null;\n while (lastEventOnStack && lastEventEndTime && lastEventEndTime <= currentEventTimings.startTime) {\n stack.pop();\n config.onEndEvent(lastEventOnStack);\n lastEventOnStack = stack.at(-1);\n lastEventEndTime = lastEventOnStack ? eventTimingsMicroSeconds(lastEventOnStack).endTime : null;\n }\n\n // Now we have dealt with all events prior to this one, see if we need to care about this one.\n if (config.eventFilter && !config.eventFilter(currentEvent)) {\n // The user has chosen to filter this event out, so continue on and do nothing\n continue;\n }\n\n if (currentEventTimings.duration) {\n config.onStartEvent(currentEvent);\n stack.push(currentEvent);\n } else if (config.onInstantEvent) {\n // An event with 0 duration is an instant event.\n config.onInstantEvent(currentEvent);\n }\n }\n\n // Now we have finished looping over all events; any events remaining on the\n // stack need to have their onEndEvent called.\n while (stack.length) {\n const last = stack.pop();\n if (last) {\n config.onEndEvent(last);\n }\n }\n}\n\n// Parsed categories are cached to prevent calling cat.split()\n// multiple times on the same categories string.\nconst parsedCategories = new Map<string, Set<string>>();\nexport function eventHasCategory(event: Types.Events.Event, category: string): boolean {\n let parsedCategoriesForEvent = parsedCategories.get(event.cat);\n if (!parsedCategoriesForEvent) {\n parsedCategoriesForEvent = new Set(event.cat.split(',') || []);\n }\n return parsedCategoriesForEvent.has(category);\n}\n\nexport function nodeIdForInvalidationEvent(event: Types.Events.InvalidationTrackingEvent): Protocol.DOM.BackendNodeId|\n null {\n return event.args.data.nodeId ?? null;\n}\n\n/**\n * This compares Types.Events.CallFrame with Protocol.Runtime.CallFrame and checks for equality.\n */\nexport function isMatchingCallFrame(\n eventFrame: Types.Events.CallFrame, nodeFrame: Protocol.Runtime.CallFrame): boolean {\n return eventFrame.columnNumber === nodeFrame.columnNumber && eventFrame.lineNumber === nodeFrame.lineNumber &&\n String(eventFrame.scriptId) === nodeFrame.scriptId && eventFrame.url === nodeFrame.url &&\n eventFrame.functionName === nodeFrame.functionName;\n}\n\nexport function eventContainsTimestamp(event: Types.Events.Event, ts: Types.Timing.Micro): boolean {\n return event.ts <= ts && event.ts + (event.dur || 0) >= ts;\n}\n\nexport function extractSampleTraceId(event: Types.Events.Event): number|null {\n if (Types.Events.isConsoleRunTask(event) || Types.Events.isConsoleTimeStamp(event)) {\n return event.args?.data?.sampleTraceId || null;\n }\n return null;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"Trace.js","sourceRoot":"","sources":["../../../../../../../front_end/models/trace/helpers/Trace.ts"],"names":[],"mappings":"AAAA,4DAA4D;AAC5D,yEAAyE;AACzE,6BAA6B;AAE7B,OAAO,KAAK,QAAQ,MAAM,oCAAoC,CAAC;AAG/D,OAAO,KAAK,KAAK,MAAM,mBAAmB,CAAC;AAE3C,OAAO,EAAC,sBAAsB,EAAC,MAAM,sBAAsB,CAAC;AAC5D,OAAO,EAAC,wBAAwB,EAAC,MAAM,aAAa,CAAC;AAQrD;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,iBAAiB,CAAC,KAAyB;IACzD,IAAI,KAAK,CAAC,IAAI,EAAE,IAAI,EAAE,UAAU,EAAE,CAAC;QACjC,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC;IACpC,CAAC;IACD,IAAI,KAAK,CAAC,IAAI,EAAE,UAAU,EAAE,CAAC;QAC3B,OAAO,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC;IAC/B,CAAC;IACD,IAAI,KAAK,CAAC,MAAM,CAAC,kBAAkB,CAAC,KAAK,CAAC,EAAE,CAAC;QAC3C,OAAO,KAAK,CAAC,IAAI,CAAC,SAAS,EAAE,UAAU,IAAI,IAAI,CAAC;IAClD,CAAC;IACD,IAAI,KAAK,CAAC,UAAU,CAAC,yBAAyB,CAAC,KAAK,CAAC,EAAE,CAAC;QACtD,OAAO,iBAAiB,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC;IACjD,CAAC;IACD,IAAI,KAAK,CAAC,MAAM,CAAC,qBAAqB,CAAC,KAAK,CAAC,EAAE,CAAC;QAC9C,OAAO,iBAAiB,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC;IACjD,CAAC;IACD,IAAI,KAAK,CAAC,MAAM,CAAC,cAAc,CAAC,KAAK,CAAC,EAAE,CAAC;QACvC,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC;QAC7B,IAAI,CAAC,IAAI,EAAE,CAAC;YACV,OAAO,IAAI,CAAC;QACd,CAAC;QACD,MAAM,EAAC,YAAY,EAAE,UAAU,EAAE,GAAG,EAAE,QAAQ,EAAE,YAAY,EAAC,GAAG,IAAI,CAAC;QACrE,IAAI,UAAU,KAAK,SAAS,IAAI,YAAY,KAAK,SAAS,IAAI,YAAY,KAAK,SAAS;YACpF,QAAQ,KAAK,SAAS,IAAI,GAAG,KAAK,SAAS,EAAE,CAAC;YAChD,OAAO,IAAI,CAAC;QACd,CAAC;QACD,OAAO,CAAC,EAAC,YAAY,EAAE,UAAU,EAAE,GAAG,EAAE,QAAQ,EAAE,YAAY,EAAC,CAAC,CAAC;IACnE,CAAC;IACD,IAAI,KAAK,CAAC,MAAM,CAAC,aAAa,CAAC,KAAK,CAAC,EAAE,CAAC;QACtC,0DAA0D;QAC1D,MAAM,SAAS,GAAG,KAAK,CAAC,SAAS,CAAC;QAClC,IAAI,CAAC,SAAS,EAAE,CAAC;YACf,OAAO,IAAI,CAAC;QACd,CAAC;QACD,MAAM,EAAC,YAAY,EAAE,UAAU,EAAE,GAAG,EAAE,QAAQ,EAAE,YAAY,EAAC,GAAG,SAAS,CAAC;QAC1E,IAAI,UAAU,KAAK,SAAS,IAAI,YAAY,KAAK,SAAS,IAAI,YAAY,KAAK,SAAS;YACpF,QAAQ,KAAK,SAAS,IAAI,GAAG,KAAK,SAAS,EAAE,CAAC;YAChD,OAAO,IAAI,CAAC;QACd,CAAC;QACD,OAAO,CAAC,EAAC,YAAY,EAAE,UAAU,EAAE,GAAG,EAAE,QAAQ,EAAE,YAAY,EAAC,CAAC,CAAC;IACnE,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,MAAM,UAAU,sBAAsB,CAAC,kBAA0B;IAC/D,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,kBAAkB,CAAC,CAAC;IACxC,IAAI,GAAG,EAAE,CAAC;QACR,0EAA0E;QAC1E,kEAAkE;QAClE,IAAI,GAAG,CAAC,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;YAChC,OAAO,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QAC3B,CAAC;QACD,OAAO,GAAG,CAAC,IAAI,CAAC;IAClB,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAGD,qFAAqF;AACrF,qEAAqE;AACrE,MAAM,UAAU,uBAAuB,CACnC,KAAQ,EACR,qBAAqE;IAEvE,MAAM,EAAC,GAAG,EAAE,GAAG,EAAC,GAAG,KAAK,CAAC;IACzB,IAAI,cAAc,GAAG,qBAAqB,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IACpD,IAAI,CAAC,cAAc,EAAE,CAAC;QACpB,cAAc,GAAG,IAAI,GAAG,EAA8B,CAAC;IACzD,CAAC;IAED,IAAI,MAAM,GAAG,cAAc,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IACrC,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,MAAM,GAAG,EAAE,CAAC;IACd,CAAC;IAED,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACnB,cAAc,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;IACtC,qBAAqB,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,EAAE,cAAc,CAAC,CAAC;AACvD,CAAC;AAMD,MAAM,UAAU,mBAAmB,CAAC,CAAW,EAAE,CAAW;IAC1D,MAAM,UAAU,GAAG,CAAC,CAAC,EAAE,CAAC;IACxB,MAAM,UAAU,GAAG,CAAC,CAAC,EAAE,CAAC;IACxB,IAAI,UAAU,GAAG,UAAU,EAAE,CAAC;QAC5B,OAAO,CAAC,CAAC,CAAC;IACZ,CAAC;IACD,IAAI,UAAU,GAAG,UAAU,EAAE,CAAC;QAC5B,OAAO,CAAC,CAAC;IACX,CAAC;IACD,MAAM,SAAS,GAAG,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;IAC7B,MAAM,SAAS,GAAG,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;IAC7B,MAAM,QAAQ,GAAG,UAAU,GAAG,SAAS,CAAC;IACxC,MAAM,QAAQ,GAAG,UAAU,GAAG,SAAS,CAAC;IACxC,IAAI,QAAQ,GAAG,QAAQ,EAAE,CAAC;QACxB,OAAO,CAAC,CAAC,CAAC;IACZ,CAAC;IACD,IAAI,QAAQ,GAAG,QAAQ,EAAE,CAAC;QACxB,OAAO,CAAC,CAAC;IACX,CAAC;IACD,OAAO,CAAC,CAAC;AACX,CAAC;AACD;;;GAGG;AACH,MAAM,UAAU,sBAAsB,CAAC,MAA4D;IACjG,MAAM,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC;AACnC,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,kBAAkB,CAC9B,YAA2B,EAAE,YAA2B;IAC1D,MAAM,MAAM,GAAG,EAAE,CAAC;IAClB,IAAI,CAAC,GAAG,CAAC,CAAC;IACV,IAAI,CAAC,GAAG,CAAC,CAAC;IACV,OAAO,CAAC,GAAG,YAAY,CAAC,MAAM,IAAI,CAAC,GAAG,YAAY,CAAC,MAAM,EAAE,CAAC;QAC1D,MAAM,MAAM,GAAG,YAAY,CAAC,CAAC,CAAC,CAAC;QAC/B,MAAM,MAAM,GAAG,YAAY,CAAC,CAAC,CAAC,CAAC;QAC/B,MAAM,YAAY,GAAG,mBAAmB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QACzD,IAAI,YAAY,IAAI,CAAC,EAAE,CAAC;YACtB,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;YACpB,CAAC,EAAE,CAAC;QACN,CAAC;QACD,IAAI,YAAY,KAAK,CAAC,EAAE,CAAC;YACvB,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;YACpB,CAAC,EAAE,CAAC;QACN,CAAC;IACH,CAAC;IACD,OAAO,CAAC,GAAG,YAAY,CAAC,MAAM,EAAE,CAAC;QAC/B,MAAM,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IACjC,CAAC;IACD,OAAO,CAAC,GAAG,YAAY,CAAC,MAAM,EAAE,CAAC;QAC/B,MAAM,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IACjC,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,MAAM,UAAU,0BAA0B,CACtC,KAAyB,EACzB,YAAoB,EACpB,oBAAiE;IAEnE,MAAM,WAAW,GAAG,oBAAoB,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;IAC3D,IAAI,CAAC,WAAW,IAAI,YAAY,KAAK,EAAE,EAAE,CAAC;QACxC,qFAAqF;QACrF,gCAAgC;QAChC,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,oBAAoB,GACtB,QAAQ,CAAC,cAAc,CAAC,mBAAmB,CAAC,WAAW,EAAE,UAAU,CAAC,EAAE,CAAC,UAAU,CAAC,EAAE,IAAI,KAAK,CAAC,EAAE,CAAC,CAAC;IAEtG,IAAI,oBAAoB,KAAK,IAAI,EAAE,CAAC;QAClC,sFAAsF;QACtF,OAAO,IAAI,CAAC;IACd,CAAC;IACD,OAAO,WAAW,CAAC,oBAAoB,CAAC,CAAC;AAC3C,CAAC;AAED,MAAM,UAAU,SAAS,CAAC,KAC2D;IACnF,OAAO,KAAK,CAAC,EAAE,IAAI,KAAK,CAAC,GAAG,EAAE,MAAM,IAAI,KAAK,CAAC,GAAG,EAAE,KAAK,CAAC;AAC3D,CAAC;AAED,MAAM,UAAU,uBAAuB,CACnC,OAAe,EAAE,IAAwB,EACzC,wBAE+G;IAEjH,MAAM,WAAW,GAAG,wBAAwB,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;IAC1D,IAAI,CAAC,WAAW,EAAE,CAAC;QACjB,OAAO,IAAI,CAAC;IACd,CAAC;IACD,KAAK,MAAM,SAAS,IAAI,WAAW,CAAC,MAAM,EAAE,EAAE,CAAC;QAC7C,KAAK,MAAM,WAAW,IAAI,SAAS,EAAE,CAAC;YACpC,IAAI,WAAW,CAAC,MAAM,CAAC,GAAG,GAAG,IAAI,IAAI,WAAW,CAAC,MAAM,CAAC,GAAG,GAAG,IAAI,EAAE,CAAC;gBACnE,SAAS;YACX,CAAC;YACD,OAAO,WAAW,CAAC,KAAK,CAAC,GAAG,CAAC;QAC/B,CAAC;IACH,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,UAAU,eAAe,CAC3B,IAA6C,EAAE,SAAiC,EAAE,WAAmB,EACrG,EAAsB,EAAE,GAA2B,EACnD,GAA0B;IAC5B,OAAO;QACL,GAAG,EAAE,EAAE;QACP,IAAI,EAAE,aAAa;QACnB,MAAM,EAAE,IAAI,CAAC,EAAE;QACf,IAAI,EAAE,EAAE;QACR,EAAE,uCAA6B;QAC/B,GAAG;QACH,GAAG;QACH,EAAE;QACF,GAAG,EAAE,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;QAC1B,SAAS,EAAE,IAAI,CAAC,SAAS;QACzB,WAAW;QACX,SAAS;KACV,CAAC;AACJ,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,WAAW,CAAC,cAA4C;IACtE,0CAA0C;IAC1C,MAAM,YAAY,GAA6C,IAAI,GAAG,EAAE,CAAC;IAEzE,4BAA4B;IAC5B,KAAK,MAAM,KAAK,IAAI,cAAc,EAAE,CAAC;QACnC,MAAM,WAAW,GAAG,cAAc,CAAC,KAAK,CAAC,CAAC;QAC1C,IAAI,WAAW,KAAK,SAAS,EAAE,CAAC;YAC9B,SAAS;QACX,CAAC;QACD,iEAAiE;QACjE,iEAAiE;QACjE,6CAA6C;QAC7C,MAAM,iBAAiB,GAAG,QAAQ,CAAC,YAAY,CAAC,cAAc,CAAC,YAAY,EAAE,WAAW,EAAE,GAAG,EAAE;YAC7F,OAAO,EAAC,KAAK,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,EAAC,CAAC;QAC/C,CAAC,CAAC,CAAC;QAEH,MAAM,YAAY,GAAG,KAAK,CAAC,EAAE,sDAA4C,CAAC;QAC1E,MAAM,UAAU,GAAG,KAAK,CAAC,EAAE,oDAA0C,CAAC;QACtE,MAAM,cAAc,GAAG,KAAK,CAAC,EAAE,wDAA8C,CAAC;QAE9E,IAAI,YAAY,EAAE,CAAC;YACjB,iBAAiB,CAAC,KAAK,GAAG,KAAwC,CAAC;QACrE,CAAC;aAAM,IAAI,UAAU,EAAE,CAAC;YACtB,iBAAiB,CAAC,GAAG,GAAG,KAAsC,CAAC;QACjE,CAAC;aAAM,IAAI,cAAc,EAAE,CAAC;YAC1B,IAAI,CAAC,iBAAiB,CAAC,OAAO,EAAE,CAAC;gBAC/B,iBAAiB,CAAC,OAAO,GAAG,EAAE,CAAC;YACjC,CAAC;YACD,iBAAiB,CAAC,OAAO,CAAC,IAAI,CAAC,KAA0C,CAAC,CAAC;QAC7E,CAAC;IACH,CAAC;IACD,OAAO,YAAY,CAAC;AACtB,CAAC;AAED,SAAS,cAAc,CAAC,KAAiC;IACvD,MAAM,EAAE,GAAG,SAAS,CAAC,KAAK,CAAC,CAAC;IAC5B,OAAO,EAAE,IAAI,GAAG,KAAK,CAAC,GAAG,IAAI,EAAE,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC;AAClD,CAAC;AAED,MAAM,UAAU,2BAA2B,CACvC,YAIE,EACF,sBAAqF;IAEvF,MAAM,eAAe,GAAyC,EAAE,CAAC;IACjE,KAAK,MAAM,CAAC,EAAE,EAAE,aAAa,CAAC,IAAI,YAAY,CAAC,OAAO,EAAE,EAAE,CAAC;QACzD,MAAM,UAAU,GAAG,aAAa,CAAC,KAAK,CAAC;QACvC,MAAM,QAAQ,GAAG,aAAa,CAAC,GAAG,CAAC;QACnC,MAAM,aAAa,GAAG,aAAa,CAAC,OAAO,CAAC;QAC5C,IAAI,CAAC,UAAU,IAAI,CAAC,CAAC,QAAQ,IAAI,aAAa,CAAC,EAAE,CAAC;YAChD,wEAAwE;YACxE,+FAA+F;YAC/F,gFAAgF;YAChF,SAAS;QACX,CAAC;QACD,MAAM,OAAO,GAAG,EAAC,UAAU,EAAE,QAAQ,EAAE,aAAa,EAAC,CAAC;QACtD;;;;WAIG;QACH,SAAS,iBAAiB,CAAC,IAI1B;YACC,MAAM,kBAAkB,GAAG,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,KAAK,cAAc,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;YAC/G,MAAM,aAAa,GAAG,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,KAAK,cAAc,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;YACnF,OAAO,OAAO,CAAC,EAAE,CAAC,IAAI,CAAC,kBAAkB,IAAI,aAAa,CAAC,CAAC;QAC9D,CAAC;QACD,IAAI,CAAC,iBAAiB,CAAC,OAAO,CAAC,EAAE,CAAC;YAChC,SAAS;QACX,CAAC;QACD,MAAM,WAAW,GAAG,QAAQ,IAAI,UAAU,CAAC;QAE3C,MAAM,KAAK,GAAG,sBAAsB,CAAC,sBAAsB,CAAqC;YAC9F,cAAc,EAAE,OAAO,CAAC,UAAU;YAClC,GAAG,EAAE,WAAW,CAAC,GAAG;YACpB,EAAE,EAAE,WAAW,CAAC,EAAE;YAClB,GAAG,EAAE,WAAW,CAAC,GAAG;YACpB,GAAG,EAAE,WAAW,CAAC,GAAG;YACpB,EAAE;YACF,wEAAwE;YACxE,yBAAyB;YACzB,IAAI,EAAE,UAAU,CAAC,IAAI;YACrB,GAAG,EAAE,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,WAAW,CAAC,EAAE,GAAG,UAAU,CAAC,EAAE,CAAC;YACvD,EAAE,EAAE,UAAU,CAAC,EAAE;YACjB,IAAI,EAAE;gBACJ,IAAI,EAAE,OAAO;aACd;SACF,CAAC,CAAC;QAEH,IAAI,KAAK,CAAC,GAAG,GAAG,CAAC,EAAE,CAAC;YAClB,kEAAkE;YAClE,2EAA2E;YAC3E,oEAAoE;YACpE,oBAAoB;YACpB,SAAS;QACX,CAAC;QACD,sBAAsB,EAAE,CAAC,KAAK,CAAC,CAAC;QAChC,eAAe,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAC9B,CAAC;IACD,OAAO,eAAe,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC;AACrD,CAAC;AAED,MAAM,UAAU,kCAAkC,CAC9C,mBAAwB,EAAE,sBAAqF;IAEjH,MAAM,YAAY,GAAG,WAAW,CAAC,mBAAmB,CAAC,CAAC;IACtD,MAAM,eAAe,GAAG,2BAA2B,CAAI,YAAY,EAAE,sBAAsB,CAAC,CAAC;IAC7F,OAAO,eAAe,CAAC;AACzB,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,mCAAmC,CAAC,KAAyB;IAI3E,6EAA6E;IAC7E,2EAA2E;IAC3E,kEAAkE;IAClE,2EAA2E;IAC3E,SAAS;IACT,MAAM,OAAO,GAAG,kCAAkC,CAAC,KAAK,CAAC,CAAC;IAC1D,MAAM,EAAC,UAAU,EAAE,YAAY,EAAC,GAAG,OAAO,CAAC;IAE3C,QAAQ,KAAK,CAAC,IAAI,EAAE,CAAC;QACnB,uEAAuE;QACvE,mCAAmC;QACnC,0DAAqC;QACrC,8DAAuC;QACvC,kDAA+B;QAC/B,2DAAmC,CAAC,CAAC,CAAC;YACpC,OAAO;gBACL,UAAU,EAAE,OAAO,UAAU,KAAK,QAAQ,CAAC,CAAC,CAAC,UAAU,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS;gBACvE,YAAY,EAAE,OAAO,YAAY,KAAK,QAAQ,CAAC,CAAC,CAAC,YAAY,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS;aAC9E,CAAC;QACJ,CAAC;QACD,OAAO,CAAC,CAAC,CAAC;YACR,OAAO,OAAO,CAAC;QACjB,CAAC;IACH,CAAC;AACH,CAAC;AAED;;;;;;;;;;GAUG;AACH,MAAM,UAAU,gCAAgC,CAAC,KAAyB;IACxE,MAAM,KAAK,GAAG,iBAAiB,CAAC,KAAK,CAAC,CAAC;IACvC,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,OAAO,IAAI,CAAC;IACd,CAAC;IACD,OAAO,KAAK,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE;QAC3B,QAAQ,KAAK,CAAC,IAAI,EAAE,CAAC;YACnB,uFAAoD;YACpD,kEAAyC;YACzC,0DAAqC;YACrC,kEAAyC,CAAC,CAAC,CAAC;gBAC1C,OAAO,sBAAsB,CAAC,SAAS,CAAC,CAAC;YAC3C,CAAC;YACD,OAAO,CAAC,CAAC,CAAC;gBACR,IAAI,KAAK,CAAC,MAAM,CAAC,YAAY,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,UAAU,CAAC,yBAAyB,CAAC,KAAK,CAAC,EAAE,CAAC;oBAC1F,OAAO,sBAAsB,CAAC,SAAS,CAAC,CAAC;gBAC3C,CAAC;YACH,CAAC;QACH,CAAC;QACD,OAAO,SAAS,CAAC;IACnB,CAAC,CAAC,CAAC;AACL,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,sBAAsB,CAAC,SAAiC;IACtE,MAAM,mBAAmB,GAAG,EAAC,GAAG,SAAS,EAAC,CAAC;IAE3C,mBAAmB,CAAC,UAAU,GAAG,SAAS,CAAC,UAAU,IAAI,SAAS,CAAC,UAAU,GAAG,CAAC,CAAC;IAClF,mBAAmB,CAAC,YAAY,GAAG,SAAS,CAAC,YAAY,IAAI,SAAS,CAAC,YAAY,GAAG,CAAC,CAAC;IACxF,OAAO,mBAAmB,CAAC;AAC7B,CAAC;AAED;;;;;;;;IAQI;AACJ,SAAS,kCAAkC,CAAC,KAAyB;IAInE,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC;QACtB,OAAO;YACL,UAAU,EAAE,SAAS;YACrB,YAAY,EAAE,SAAS;SACxB,CAAC;IACJ,CAAC;IACD,IAAI,UAAU,GAAqB,SAAS,CAAC;IAC7C,IAAI,YAAY,GAAqB,SAAS,CAAC;IAC/C,IAAI,YAAY,IAAI,KAAK,CAAC,IAAI,CAAC,IAAI,IAAI,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,KAAK,QAAQ,EAAE,CAAC;QACtF,UAAU,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC;IAC1C,CAAC;IACD,IAAI,cAAc,IAAI,KAAK,CAAC,IAAI,CAAC,IAAI,IAAI,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,YAAY,KAAK,QAAQ,EAAE,CAAC;QAC1F,YAAY,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC;IAC9C,CAAC;IAED,OAAO,EAAC,UAAU,EAAE,YAAY,EAAC,CAAC;AACpC,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,KAAyB;IACvD,6EAA6E;IAC7E,qCAAqC;IACrC,4EAA4E;IAC5E,6DAA6D;IAC7D,yEAAyE;IACzE,uCAAuC;IACvC,IAAI,KAAK,CAAC,IAAI,IAAI,WAAW,IAAI,KAAK,CAAC,IAAI,IAAI,OAAO,KAAK,CAAC,IAAI,CAAC,SAAS,KAAK,QAAQ;QACnF,KAAK,CAAC,IAAI,CAAC,SAAS,KAAK,IAAI,IAAI,OAAO,IAAI,KAAK,CAAC,IAAI,CAAC,SAAS;QAChE,OAAO,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,KAAK,QAAQ,EAAE,CAAC;QACnD,OAAO,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC;IACpC,CAAC;IACD,gDAAgD;IAChD,IAAI,KAAK,CAAC,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC;QAC5B,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC;IAC/B,CAAC;IAED,iCAAiC;IACjC,OAAO,IAAI,CAAC;AACd,CAAC;AAED,MAAM,6BAA6B,GAAG,uCAAuC,CAAC;AAC9E,MAAM,UAAU,eAAe,CAAC,KAAyB;IACvD,IAAI,KAAK,CAAC,IAAI,KAAK,QAAQ,IAAI,KAAK,CAAC,GAAG,KAAK,UAAU,EAAE,CAAC;QACxD,wEAAwE;QACxE,yEAAyE;QACzE,kDAAkD;QAClD,8CAA8C;QAC9C,OAAO,IAAI,CAAC;IACd,CAAC;IACD,OAAO,KAAK,CAAC,GAAG,CAAC,QAAQ,CAAC,6BAA6B,CAAC,IAAI,KAAK,CAAC,IAAI,+CAA+B,CAAC;AACxG,CAAC;AAED,SAAS,6BAA6B,CAAC,MAA4B,EAAE,IAAwB;IAC3F,IAAI,KAAK,GAAG,QAAQ,CAAC,cAAc,CAAC,UAAU,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC,IAAI,GAAG,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC;IACnG,OAAO,KAAK,GAAG,CAAC,IAAI,CAAC,eAAe,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC;QACpD,KAAK,EAAE,CAAC;IACV,CAAC;IACD,OAAO,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;AAC5B,CAAC;AACD,MAAM,UAAU,0BAA0B,CACtC,MAA4B,EAAE,SAA6B,EAC3D,OAA4B;IAC9B,MAAM,WAAW,GAAoC,EAAE,CAAC;IACxD,MAAM,eAAe,GAAG,6BAA6B,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;IACzE,KAAK,IAAI,CAAC,GAAG,eAAe,EAAE,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACrD,MAAM,KAAK,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC;QACxB,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,kBAAkB,CAAC,KAAK,CAAC,EAAE,CAAC;YAC5C,SAAS;QACX,CAAC;QACD,IAAI,KAAK,CAAC,EAAE,IAAI,CAAC,OAAO,IAAI,QAAQ,CAAC,EAAE,CAAC;YACtC,SAAS;QACX,CAAC;QACD,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAC1B,CAAC;IACD,OAAO,WAAW,CAAC;AACrB,CAAC;AAED,MAAM,UAAU,2BAA2B,CAA+B,UAAe,EAAE,EAAsB;IAE/G,MAAM,KAAK,GAAG,QAAQ,CAAC,cAAc,CAAC,yBAAyB,CAAC,UAAU,EAAE,SAAS,CAAC,EAAE,CAAC,EAAE,GAAG,SAAS,CAAC,EAAE,CAAC,CAAC;IAC5G,OAAO,KAAK,KAAK,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;AACnD,CAAC;AAED,MAAM,UAAU,gCAAgC,CAC5C,UAAe,EAAE,EAAsB;IACzC,MAAM,KAAK,GAAG,QAAQ,CAAC,cAAc,CAAC,mBAAmB,CAAC,UAAU,EAAE,SAAS,CAAC,EAAE,CAAC,SAAS,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC;IACtG,OAAO,KAAK,KAAK,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;AACnD,CAAC;AAaD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,MAAM,UAAU,YAAY,CACxB,MAA4B,EAC5B,MAA0B;IAE5B,MAAM,eAAe,GAAG,MAAM,CAAC,SAAS,IAAI,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IAClE,MAAM,aAAa,GAAG,MAAM,CAAC,OAAO,IAAI,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;IACrE,MAAM,iBAAiB,GAAG,MAAM,CAAC,iBAAiB,KAAK,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC;IAE5E,MAAM,KAAK,GAAyB,EAAE,CAAC;IACvC,MAAM,eAAe,GAAG,6BAA6B,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;IAC/E,KAAK,IAAI,CAAC,GAAG,eAAe,EAAE,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACrD,MAAM,YAAY,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC;QAC/B,MAAM,mBAAmB,GAAG,wBAAwB,CAAC,YAAY,CAAC,CAAC;QACnE,IAAI,mBAAmB,CAAC,OAAO,GAAG,eAAe,EAAE,CAAC;YAClD,SAAS;QACX,CAAC;QACD,IAAI,mBAAmB,CAAC,SAAS,GAAG,aAAa,EAAE,CAAC;YAClD,MAAM;QACR,CAAC;QAED,MAAM,mBAAmB,GAAG,iBAAiB,IAAI,KAAK,CAAC,MAAM,CAAC,YAAY,CAAC,YAAY,CAAC,EAAE,CAAC,CAAC;QAC5F,IAAI,mBAAmB,IAAI,KAAK,CAAC,MAAM,CAAC,WAAW,CAAC,YAAY,CAAC,EAAE,CAAC,EAAE,CAAC;YACrE,SAAS;QACX,CAAC;QAED,2EAA2E;QAC3E,qEAAqE;QACrE,IAAI,gBAAgB,GAAG,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;QACpC,IAAI,gBAAgB,GAAG,gBAAgB,CAAC,CAAC,CAAC,wBAAwB,CAAC,gBAAgB,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC;QACpG,OAAO,gBAAgB,IAAI,gBAAgB,IAAI,gBAAgB,IAAI,mBAAmB,CAAC,SAAS,EAAE,CAAC;YACjG,KAAK,CAAC,GAAG,EAAE,CAAC;YACZ,MAAM,CAAC,UAAU,CAAC,gBAAgB,CAAC,CAAC;YACpC,gBAAgB,GAAG,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;YAChC,gBAAgB,GAAG,gBAAgB,CAAC,CAAC,CAAC,wBAAwB,CAAC,gBAAgB,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC;QAClG,CAAC;QAED,8FAA8F;QAC9F,IAAI,MAAM,CAAC,WAAW,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC,YAAY,CAAC,EAAE,CAAC;YAC5D,8EAA8E;YAC9E,SAAS;QACX,CAAC;QAED,IAAI,mBAAmB,CAAC,QAAQ,EAAE,CAAC;YACjC,MAAM,CAAC,YAAY,CAAC,YAAY,CAAC,CAAC;YAClC,KAAK,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;QAC3B,CAAC;aAAM,IAAI,MAAM,CAAC,cAAc,EAAE,CAAC;YACjC,gDAAgD;YAChD,MAAM,CAAC,cAAc,CAAC,YAAY,CAAC,CAAC;QACtC,CAAC;IACH,CAAC;IAED,4EAA4E;IAC5E,8CAA8C;IAC9C,OAAO,KAAK,CAAC,MAAM,EAAE,CAAC;QACpB,MAAM,IAAI,GAAG,KAAK,CAAC,GAAG,EAAE,CAAC;QACzB,IAAI,IAAI,EAAE,CAAC;YACT,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;QAC1B,CAAC;IACH,CAAC;AACH,CAAC;AAED,8DAA8D;AAC9D,gDAAgD;AAChD,MAAM,gBAAgB,GAAG,IAAI,GAAG,EAAuB,CAAC;AACxD,MAAM,UAAU,gBAAgB,CAAC,KAAyB,EAAE,QAAgB;IAC1E,IAAI,wBAAwB,GAAG,gBAAgB,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAC/D,IAAI,CAAC,wBAAwB,EAAE,CAAC;QAC9B,wBAAwB,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC;IACjE,CAAC;IACD,OAAO,wBAAwB,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;AAChD,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,mBAAmB,CAC/B,UAAkC,EAAE,SAAqC;IAC3E,OAAO,UAAU,CAAC,YAAY,KAAK,SAAS,CAAC,YAAY,IAAI,UAAU,CAAC,UAAU,KAAK,SAAS,CAAC,UAAU;QACvG,MAAM,CAAC,UAAU,CAAC,QAAQ,CAAC,KAAK,SAAS,CAAC,QAAQ,IAAI,UAAU,CAAC,GAAG,KAAK,SAAS,CAAC,GAAG;QACtF,UAAU,CAAC,YAAY,KAAK,SAAS,CAAC,YAAY,CAAC;AACzD,CAAC;AAED,MAAM,UAAU,sBAAsB,CAAC,KAAyB,EAAE,EAAsB;IACtF,OAAO,KAAK,CAAC,EAAE,IAAI,EAAE,IAAI,KAAK,CAAC,EAAE,GAAG,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC,CAAC,IAAI,EAAE,CAAC;AAC7D,CAAC;AAED,MAAM,UAAU,oBAAoB,CAAC,KAAyB;IAC5D,IAAI,KAAK,CAAC,MAAM,CAAC,gBAAgB,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,kBAAkB,CAAC,KAAK,CAAC,EAAE,CAAC;QACnF,OAAO,KAAK,CAAC,IAAI,EAAE,IAAI,EAAE,aAAa,IAAI,IAAI,CAAC;IACjD,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC","sourcesContent":["// Copyright 2022 The Chromium Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\n\nimport * as Platform from '../../../core/platform/platform.js';\nimport type * as Protocol from '../../../generated/protocol.js';\nimport type * as CPUProfile from '../../cpu_profile/cpu_profile.js';\nimport * as Types from '../types/types.js';\n\nimport {SyntheticEventsManager} from './SyntheticEvents.js';\nimport {eventTimingsMicroSeconds} from './Timing.js';\n\ninterface MatchingPairableAsyncEvents {\n begin: Types.Events.PairableAsyncBegin|null;\n end: Types.Events.PairableAsyncEnd|null;\n instant?: Types.Events.PairableAsyncInstant[];\n}\n\n/**\n * Extracts the raw stack trace in known trace events. Most likely than\n * not you want to use `getZeroIndexedStackTraceForEvent`, which returns\n * the stack with zero based numbering. Since some trace events are\n * one based this function can yield unexpected results when used\n * indiscriminately.\n *\n * Note: this only returns the stack trace contained in the payload of\n * an event, which only contains the synchronous portion of the call\n * stack. If you want to obtain the whole stack trace you might need to\n * use the @see Trace.Extras.StackTraceForEvent util.\n */\nexport function stackTraceInEvent(event: Types.Events.Event): Types.Events.CallFrame[]|null {\n if (event.args?.data?.stackTrace) {\n return event.args.data.stackTrace;\n }\n if (event.args?.stackTrace) {\n return event.args.stackTrace;\n }\n if (Types.Events.isUpdateLayoutTree(event)) {\n return event.args.beginData?.stackTrace || null;\n }\n if (Types.Extensions.isSyntheticExtensionEntry(event)) {\n return stackTraceInEvent(event.rawSourceEvent);\n }\n if (Types.Events.isSyntheticUserTiming(event)) {\n return stackTraceInEvent(event.rawSourceEvent);\n }\n if (Types.Events.isFunctionCall(event)) {\n const data = event.args.data;\n if (!data) {\n return null;\n }\n const {columnNumber, lineNumber, url, scriptId, functionName} = data;\n if (lineNumber === undefined || functionName === undefined || columnNumber === undefined ||\n scriptId === undefined || url === undefined) {\n return null;\n }\n return [{columnNumber, lineNumber, url, scriptId, functionName}];\n }\n if (Types.Events.isProfileCall(event)) {\n // Of type Protocol.Runtime.CallFrame, handle accordingly.\n const callFrame = event.callFrame;\n if (!callFrame) {\n return null;\n }\n const {columnNumber, lineNumber, url, scriptId, functionName} = callFrame;\n if (lineNumber === undefined || functionName === undefined || columnNumber === undefined ||\n scriptId === undefined || url === undefined) {\n return null;\n }\n return [{columnNumber, lineNumber, url, scriptId, functionName}];\n }\n return null;\n}\n\nexport function extractOriginFromTrace(firstNavigationURL: string): string|null {\n const url = new URL(firstNavigationURL);\n if (url) {\n // We do this to save some space in the toolbar - seeing the `www` is less\n // useful than seeing `foo.com` if it's truncated at narrow widths\n if (url.host.startsWith('www.')) {\n return url.host.slice(4);\n }\n return url.host;\n }\n return null;\n}\n\nexport type EventsInThread<T extends Types.Events.Event> = Map<Types.Events.ThreadID, T[]>;\n// Each thread contains events. Events indicate the thread and process IDs, which are\n// used to store the event in the correct process thread entry below.\nexport function addEventToProcessThread<T extends Types.Events.Event>(\n event: T,\n eventsInProcessThread: Map<Types.Events.ProcessID, EventsInThread<T>>,\n ): void {\n const {tid, pid} = event;\n let eventsInThread = eventsInProcessThread.get(pid);\n if (!eventsInThread) {\n eventsInThread = new Map<Types.Events.ThreadID, T[]>();\n }\n\n let events = eventsInThread.get(tid);\n if (!events) {\n events = [];\n }\n\n events.push(event);\n eventsInThread.set(event.tid, events);\n eventsInProcessThread.set(event.pid, eventsInThread);\n}\n\nexport interface TimeSpan {\n ts: Types.Timing.Micro;\n dur?: Types.Timing.Micro;\n}\nexport function eventTimeComparator(a: TimeSpan, b: TimeSpan): -1|0|1 {\n const aBeginTime = a.ts;\n const bBeginTime = b.ts;\n if (aBeginTime < bBeginTime) {\n return -1;\n }\n if (aBeginTime > bBeginTime) {\n return 1;\n }\n const aDuration = a.dur ?? 0;\n const bDuration = b.dur ?? 0;\n const aEndTime = aBeginTime + aDuration;\n const bEndTime = bBeginTime + bDuration;\n if (aEndTime > bEndTime) {\n return -1;\n }\n if (aEndTime < bEndTime) {\n return 1;\n }\n return 0;\n}\n/**\n * Sorts all the events in place, in order, by their start time. If they have\n * the same start time, orders them by longest first.\n */\nexport function sortTraceEventsInPlace(events: {ts: Types.Timing.Micro, dur?: Types.Timing.Micro}[]): void {\n events.sort(eventTimeComparator);\n}\n\n/**\n * Returns an array of ordered events that results after merging the two\n * ordered input arrays.\n */\nexport function mergeEventsInOrder<T1 extends Types.Events.Event, T2 extends Types.Events.Event>(\n eventsArray1: readonly T1[], eventsArray2: readonly T2[]): (T1|T2)[] {\n const result = [];\n let i = 0;\n let j = 0;\n while (i < eventsArray1.length && j < eventsArray2.length) {\n const event1 = eventsArray1[i];\n const event2 = eventsArray2[j];\n const compareValue = eventTimeComparator(event1, event2);\n if (compareValue <= 0) {\n result.push(event1);\n i++;\n }\n if (compareValue === 1) {\n result.push(event2);\n j++;\n }\n }\n while (i < eventsArray1.length) {\n result.push(eventsArray1[i++]);\n }\n while (j < eventsArray2.length) {\n result.push(eventsArray2[j++]);\n }\n return result;\n}\n\nexport function getNavigationForTraceEvent(\n event: Types.Events.Event,\n eventFrameId: string,\n navigationsByFrameId: Map<string, Types.Events.NavigationStart[]>,\n ): Types.Events.NavigationStart|null {\n const navigations = navigationsByFrameId.get(eventFrameId);\n if (!navigations || eventFrameId === '') {\n // This event's navigation has been filtered out by the meta handler as a noise event\n // or contains an empty frameId.\n return null;\n }\n\n const eventNavigationIndex =\n Platform.ArrayUtilities.nearestIndexFromEnd(navigations, navigation => navigation.ts <= event.ts);\n\n if (eventNavigationIndex === null) {\n // This event's navigation has been filtered out by the meta handler as a noise event.\n return null;\n }\n return navigations[eventNavigationIndex];\n}\n\nexport function extractId(event: Types.Events.PairableAsync|\n Types.Events.SyntheticEventPair<Types.Events.PairableAsync>): string|undefined {\n return event.id ?? event.id2?.global ?? event.id2?.local;\n}\n\nexport function activeURLForFrameAtTime(\n frameId: string, time: Types.Timing.Micro,\n rendererProcessesByFrame:\n Map<string,\n Map<Types.Events.ProcessID, {frame: Types.Events.TraceFrame, window: Types.Timing.TraceWindowMicro}[]>>):\n string|null {\n const processData = rendererProcessesByFrame.get(frameId);\n if (!processData) {\n return null;\n }\n for (const processes of processData.values()) {\n for (const processInfo of processes) {\n if (processInfo.window.min > time || processInfo.window.max < time) {\n continue;\n }\n return processInfo.frame.url;\n }\n }\n return null;\n}\n\n/**\n * @param node the node attached to the profile call. Here a node represents a function in the call tree.\n * @param profileId the profile ID that the sample came from that backs this call.\n * @param sampleIndex the index of the sample in the given profile that this call was created from\n * @param ts the timestamp of the profile call\n * @param pid the process ID of the profile call\n * @param tid the thread ID of the profile call\n *\n * See `panels/timeline/docs/profile_calls.md` for more context on how these events are created.\n */\nexport function makeProfileCall(\n node: CPUProfile.ProfileTreeModel.ProfileNode, profileId: Types.Events.ProfileID, sampleIndex: number,\n ts: Types.Timing.Micro, pid: Types.Events.ProcessID,\n tid: Types.Events.ThreadID): Types.Events.SyntheticProfileCall {\n return {\n cat: '',\n name: 'ProfileCall',\n nodeId: node.id,\n args: {},\n ph: Types.Events.Phase.COMPLETE,\n pid,\n tid,\n ts,\n dur: Types.Timing.Micro(0),\n callFrame: node.callFrame,\n sampleIndex,\n profileId,\n };\n}\n\n/**\n * Matches beginning events with PairableAsyncEnd and PairableAsyncInstant (ASYNC_NESTABLE_INSTANT)\n * if provided, though currently only coming from Animations. Traces may contain multiple instant events so we need to\n * account for that.\n *\n * @returns {Map<string, MatchingPairableAsyncEvents>} Map of the animation's ID to it's matching events.\n */\nexport function matchEvents(unpairedEvents: Types.Events.PairableAsync[]): Map<string, MatchingPairableAsyncEvents> {\n // map to store begin and end of the event\n const matchedPairs: Map<string, MatchingPairableAsyncEvents> = new Map();\n\n // looking for start and end\n for (const event of unpairedEvents) {\n const syntheticId = getSyntheticId(event);\n if (syntheticId === undefined) {\n continue;\n }\n // Create a synthetic id to prevent collisions across categories.\n // Console timings can be dispatched with the same id, so use the\n // event name as well to generate unique ids.\n const otherEventsWithID = Platform.MapUtilities.getWithDefault(matchedPairs, syntheticId, () => {\n return {begin: null, end: null, instant: []};\n });\n\n const isStartEvent = event.ph === Types.Events.Phase.ASYNC_NESTABLE_START;\n const isEndEvent = event.ph === Types.Events.Phase.ASYNC_NESTABLE_END;\n const isInstantEvent = event.ph === Types.Events.Phase.ASYNC_NESTABLE_INSTANT;\n\n if (isStartEvent) {\n otherEventsWithID.begin = event as Types.Events.PairableAsyncBegin;\n } else if (isEndEvent) {\n otherEventsWithID.end = event as Types.Events.PairableAsyncEnd;\n } else if (isInstantEvent) {\n if (!otherEventsWithID.instant) {\n otherEventsWithID.instant = [];\n }\n otherEventsWithID.instant.push(event as Types.Events.PairableAsyncInstant);\n }\n }\n return matchedPairs;\n}\n\nfunction getSyntheticId(event: Types.Events.PairableAsync): string|undefined {\n const id = extractId(event);\n return id && `${event.cat}:${id}:${event.name}`;\n}\n\nexport function createSortedSyntheticEvents<T extends Types.Events.PairableAsync>(\n matchedPairs: Map<string, {\n begin: Types.Events.PairableAsyncBegin | null,\n end: Types.Events.PairableAsyncEnd | null,\n instant?: Types.Events.PairableAsyncInstant[],\n }>,\n syntheticEventCallback?: (syntheticEvent: Types.Events.SyntheticEventPair<T>) => void,\n ): Types.Events.SyntheticEventPair<T>[] {\n const syntheticEvents: Types.Events.SyntheticEventPair<T>[] = [];\n for (const [id, eventsTriplet] of matchedPairs.entries()) {\n const beginEvent = eventsTriplet.begin;\n const endEvent = eventsTriplet.end;\n const instantEvents = eventsTriplet.instant;\n if (!beginEvent || !(endEvent || instantEvents)) {\n // This should never happen, the backend only creates the events once it\n // has them both (beginEvent & endEvent/instantEvents), so we should never get into this state.\n // If we do, something is very wrong, so let's just drop that problematic event.\n continue;\n }\n const triplet = {beginEvent, endEvent, instantEvents};\n /**\n * When trying to pair events with instant events present, there are times when these\n * ASYNC_NESTABLE_INSTANT ('n') don't have a corresponding ASYNC_NESTABLE_END ('e') event.\n * In these cases, pair without needing the endEvent.\n */\n function eventsArePairable(data: {\n beginEvent: Types.Events.PairableAsyncBegin,\n endEvent: Types.Events.PairableAsyncEnd|null,\n instantEvents?: Types.Events.PairableAsyncInstant[],\n }): data is Types.Events.SyntheticEventPair<T>['args']['data'] {\n const instantEventsMatch = data.instantEvents ? data.instantEvents.some(e => id === getSyntheticId(e)) : false;\n const endEventMatch = data.endEvent ? id === getSyntheticId(data.endEvent) : false;\n return Boolean(id) && (instantEventsMatch || endEventMatch);\n }\n if (!eventsArePairable(triplet)) {\n continue;\n }\n const targetEvent = endEvent || beginEvent;\n\n const event = SyntheticEventsManager.registerSyntheticEvent<Types.Events.SyntheticEventPair<T>>({\n rawSourceEvent: triplet.beginEvent,\n cat: targetEvent.cat,\n ph: targetEvent.ph,\n pid: targetEvent.pid,\n tid: targetEvent.tid,\n id,\n // Both events have the same name, so it doesn't matter which we pick to\n // use as the description\n name: beginEvent.name,\n dur: Types.Timing.Micro(targetEvent.ts - beginEvent.ts),\n ts: beginEvent.ts,\n args: {\n data: triplet,\n },\n });\n\n if (event.dur < 0) {\n // We have seen in the backend that sometimes animation events get\n // generated with multiple begin entries, or multiple end entries, and this\n // can cause invalid data on the performance panel, so we drop them.\n // crbug.com/1472375\n continue;\n }\n syntheticEventCallback?.(event);\n syntheticEvents.push(event);\n }\n return syntheticEvents.sort((a, b) => a.ts - b.ts);\n}\n\nexport function createMatchedSortedSyntheticEvents<T extends Types.Events.PairableAsync>(\n unpairedAsyncEvents: T[], syntheticEventCallback?: (syntheticEvent: Types.Events.SyntheticEventPair<T>) => void):\n Types.Events.SyntheticEventPair<T>[] {\n const matchedPairs = matchEvents(unpairedAsyncEvents);\n const syntheticEvents = createSortedSyntheticEvents<T>(matchedPairs, syntheticEventCallback);\n return syntheticEvents;\n}\n\n/**\n * Different trace events return line/column numbers that are 1 or 0 indexed.\n * This function knows which events return 1 indexed numbers and normalizes\n * them. The UI expects 0 indexed line numbers, so that is what we return.\n */\nexport function getZeroIndexedLineAndColumnForEvent(event: Types.Events.Event): {\n lineNumber?: number,\n columnNumber?: number,\n} {\n // Some events emit line numbers that are 1 indexed, but the UI layer expects\n // numbers to be 0 indexed. So here, if the event matches a known 1-indexed\n // number event, we subtract one from the line and column numbers.\n // Otherwise, if the event has args.data.lineNumber/colNumber, we return it\n // as is.\n const numbers = getRawLineAndColumnNumbersForEvent(event);\n const {lineNumber, columnNumber} = numbers;\n\n switch (event.name) {\n // All these events have line/column numbers which are 1 indexed; so we\n // subtract to make them 0 indexed.\n case Types.Events.Name.FUNCTION_CALL:\n case Types.Events.Name.EVALUATE_SCRIPT:\n case Types.Events.Name.COMPILE:\n case Types.Events.Name.CACHE_SCRIPT: {\n return {\n lineNumber: typeof lineNumber === 'number' ? lineNumber - 1 : undefined,\n columnNumber: typeof columnNumber === 'number' ? columnNumber - 1 : undefined,\n };\n }\n default: {\n return numbers;\n }\n }\n}\n\n/**\n * Different trace events contain stack traces with line/column numbers\n * that are 1 or 0 indexed.\n * This function knows which events return 1 indexed numbers and normalizes\n * them. The UI expects 0 indexed line numbers, so that is what we return.\n *\n * Note: this only returns the stack trace contained in the payload of\n * an event, which only contains the synchronous portion of the call\n * stack. If you want to obtain the whole stack trace you might need to\n * use the @see Trace.Extras.StackTraceForEvent util.\n */\nexport function getZeroIndexedStackTraceForEvent(event: Types.Events.Event): Types.Events.CallFrame[]|null {\n const stack = stackTraceInEvent(event);\n if (!stack) {\n return null;\n }\n return stack.map(callFrame => {\n switch (event.name) {\n case Types.Events.Name.SCHEDULE_STYLE_RECALCULATION:\n case Types.Events.Name.INVALIDATE_LAYOUT:\n case Types.Events.Name.FUNCTION_CALL:\n case Types.Events.Name.UPDATE_LAYOUT_TREE: {\n return makeZeroBasedCallFrame(callFrame);\n }\n default: {\n if (Types.Events.isUserTiming(event) || Types.Extensions.isSyntheticExtensionEntry(event)) {\n return makeZeroBasedCallFrame(callFrame);\n }\n }\n }\n return callFrame;\n });\n}\n\n/**\n * Given a 1-based call frame creates a 0-based one.\n */\nexport function makeZeroBasedCallFrame(callFrame: Types.Events.CallFrame): Types.Events.CallFrame {\n const normalizedCallFrame = {...callFrame};\n\n normalizedCallFrame.lineNumber = callFrame.lineNumber && callFrame.lineNumber - 1;\n normalizedCallFrame.columnNumber = callFrame.columnNumber && callFrame.columnNumber - 1;\n return normalizedCallFrame;\n}\n\n/**\n * NOTE: you probably do not want this function! (Which is why it is not exported).\n *\n * Some trace events have 0 indexed line/column numbers, and others have 1\n * indexed. This function does NOT normalize them, but\n * `getZeroIndexedLineAndColumnNumbersForEvent` does. It is best to use that!\n *\n * @see {@link getZeroIndexedLineAndColumnForEvent}\n **/\nfunction getRawLineAndColumnNumbersForEvent(event: Types.Events.Event): {\n lineNumber?: number,\n columnNumber?: number,\n} {\n if (!event.args?.data) {\n return {\n lineNumber: undefined,\n columnNumber: undefined,\n };\n }\n let lineNumber: number|undefined = undefined;\n let columnNumber: number|undefined = undefined;\n if ('lineNumber' in event.args.data && typeof event.args.data.lineNumber === 'number') {\n lineNumber = event.args.data.lineNumber;\n }\n if ('columnNumber' in event.args.data && typeof event.args.data.columnNumber === 'number') {\n columnNumber = event.args.data.columnNumber;\n }\n\n return {lineNumber, columnNumber};\n}\n\nexport function frameIDForEvent(event: Types.Events.Event): string|null {\n // There are a few events (for example UpdateLayoutTree, ParseHTML) that have\n // the frame stored in args.beginData\n // Rather than list them all we just check for the presence of the field, so\n // we are robust against future trace events also doing this.\n // This check seems very robust, but it also helps satisfy TypeScript and\n // prevents us against unexpected data.\n if (event.args && 'beginData' in event.args && typeof event.args.beginData === 'object' &&\n event.args.beginData !== null && 'frame' in event.args.beginData &&\n typeof event.args.beginData.frame === 'string') {\n return event.args.beginData.frame;\n }\n // Otherwise, we expect frame to be in args.data\n if (event.args?.data?.frame) {\n return event.args.data.frame;\n }\n\n // No known frame for this event.\n return null;\n}\n\nconst DevToolsTimelineEventCategory = 'disabled-by-default-devtools.timeline';\nexport function isTopLevelEvent(event: Types.Events.Event): boolean {\n if (event.name === 'JSRoot' && event.cat === 'toplevel') {\n // This is used in TimelineJSProfile to insert a fake event prior to the\n // CPU Profile in order to ensure the trace isn't truncated. So if we see\n // this, we want to treat it as a top level event.\n // TODO(crbug.com/341234884): do we need this?\n return true;\n }\n return event.cat.includes(DevToolsTimelineEventCategory) && event.name === Types.Events.Name.RUN_TASK;\n}\n\nfunction topLevelEventIndexEndingAfter(events: Types.Events.Event[], time: Types.Timing.Micro): number {\n let index = Platform.ArrayUtilities.upperBound(events, time, (time, event) => time - event.ts) - 1;\n while (index > 0 && !isTopLevelEvent(events[index])) {\n index--;\n }\n return Math.max(index, 0);\n}\nexport function findUpdateLayoutTreeEvents(\n events: Types.Events.Event[], startTime: Types.Timing.Micro,\n endTime?: Types.Timing.Micro): Types.Events.UpdateLayoutTree[] {\n const foundEvents: Types.Events.UpdateLayoutTree[] = [];\n const startEventIndex = topLevelEventIndexEndingAfter(events, startTime);\n for (let i = startEventIndex; i < events.length; i++) {\n const event = events[i];\n if (!Types.Events.isUpdateLayoutTree(event)) {\n continue;\n }\n if (event.ts >= (endTime || Infinity)) {\n continue;\n }\n foundEvents.push(event);\n }\n return foundEvents;\n}\n\nexport function findNextEventAfterTimestamp<T extends Types.Events.Event>(candidates: T[], ts: Types.Timing.Micro): T|\n null {\n const index = Platform.ArrayUtilities.nearestIndexFromBeginning(candidates, candidate => ts < candidate.ts);\n return index === null ? null : candidates[index];\n}\n\nexport function findPreviousEventBeforeTimestamp<T extends Types.Events.Event>(\n candidates: T[], ts: Types.Timing.Micro): T|null {\n const index = Platform.ArrayUtilities.nearestIndexFromEnd(candidates, candidate => candidate.ts < ts);\n return index === null ? null : candidates[index];\n}\n\nexport interface ForEachEventConfig {\n onStartEvent: (event: Types.Events.Event) => void;\n onEndEvent: (event: Types.Events.Event) => void;\n onInstantEvent?: (event: Types.Events.Event) => void;\n eventFilter?: (event: Types.Events.Event) => boolean;\n startTime?: Types.Timing.Micro;\n endTime?: Types.Timing.Micro;\n /* If async events should be skipped. Defaults to true */\n ignoreAsyncEvents?: boolean;\n}\n\n/**\n * Iterates events in a tree hierarchically, from top to bottom,\n * calling back on every event's start and end in the order\n * dictated by the corresponding timestamp.\n *\n * Events are assumed to be in ascendent order by timestamp.\n *\n * Events with 0 duration are treated as instant events. These do not have a\n * begin and end, but will be passed to the config.onInstantEvent callback as\n * they are discovered. Do not provide this callback if you are not interested\n * in them.\n *\n * For example, given this tree, the following callbacks\n * are expected to be made in the following order\n * |---------------A---------------|\n * |------B------||-------D------|\n * |---C---|\n *\n * 1. Start A\n * 3. Start B\n * 4. Start C\n * 5. End C\n * 6. End B\n * 7. Start D\n * 8. End D\n * 9. End A\n *\n * By default, async events are skipped. This behaviour can be\n * overridden making use of the config.ignoreAsyncEvents parameter.\n */\nexport function forEachEvent(\n events: Types.Events.Event[],\n config: ForEachEventConfig,\n ): void {\n const globalStartTime = config.startTime ?? Types.Timing.Micro(0);\n const globalEndTime = config.endTime || Types.Timing.Micro(Infinity);\n const ignoreAsyncEvents = config.ignoreAsyncEvents === false ? false : true;\n\n const stack: Types.Events.Event[] = [];\n const startEventIndex = topLevelEventIndexEndingAfter(events, globalStartTime);\n for (let i = startEventIndex; i < events.length; i++) {\n const currentEvent = events[i];\n const currentEventTimings = eventTimingsMicroSeconds(currentEvent);\n if (currentEventTimings.endTime < globalStartTime) {\n continue;\n }\n if (currentEventTimings.startTime > globalEndTime) {\n break;\n }\n\n const isIgnoredAsyncEvent = ignoreAsyncEvents && Types.Events.isPhaseAsync(currentEvent.ph);\n if (isIgnoredAsyncEvent || Types.Events.isFlowPhase(currentEvent.ph)) {\n continue;\n }\n\n // If we have now reached an event that is after a bunch of events, we need\n // to call the onEndEvent callback for those events before moving on.\n let lastEventOnStack = stack.at(-1);\n let lastEventEndTime = lastEventOnStack ? eventTimingsMicroSeconds(lastEventOnStack).endTime : null;\n while (lastEventOnStack && lastEventEndTime && lastEventEndTime <= currentEventTimings.startTime) {\n stack.pop();\n config.onEndEvent(lastEventOnStack);\n lastEventOnStack = stack.at(-1);\n lastEventEndTime = lastEventOnStack ? eventTimingsMicroSeconds(lastEventOnStack).endTime : null;\n }\n\n // Now we have dealt with all events prior to this one, see if we need to care about this one.\n if (config.eventFilter && !config.eventFilter(currentEvent)) {\n // The user has chosen to filter this event out, so continue on and do nothing\n continue;\n }\n\n if (currentEventTimings.duration) {\n config.onStartEvent(currentEvent);\n stack.push(currentEvent);\n } else if (config.onInstantEvent) {\n // An event with 0 duration is an instant event.\n config.onInstantEvent(currentEvent);\n }\n }\n\n // Now we have finished looping over all events; any events remaining on the\n // stack need to have their onEndEvent called.\n while (stack.length) {\n const last = stack.pop();\n if (last) {\n config.onEndEvent(last);\n }\n }\n}\n\n// Parsed categories are cached to prevent calling cat.split()\n// multiple times on the same categories string.\nconst parsedCategories = new Map<string, Set<string>>();\nexport function eventHasCategory(event: Types.Events.Event, category: string): boolean {\n let parsedCategoriesForEvent = parsedCategories.get(event.cat);\n if (!parsedCategoriesForEvent) {\n parsedCategoriesForEvent = new Set(event.cat.split(',') || []);\n }\n return parsedCategoriesForEvent.has(category);\n}\n\n/**\n * This compares Types.Events.CallFrame with Protocol.Runtime.CallFrame and checks for equality.\n */\nexport function isMatchingCallFrame(\n eventFrame: Types.Events.CallFrame, nodeFrame: Protocol.Runtime.CallFrame): boolean {\n return eventFrame.columnNumber === nodeFrame.columnNumber && eventFrame.lineNumber === nodeFrame.lineNumber &&\n String(eventFrame.scriptId) === nodeFrame.scriptId && eventFrame.url === nodeFrame.url &&\n eventFrame.functionName === nodeFrame.functionName;\n}\n\nexport function eventContainsTimestamp(event: Types.Events.Event, ts: Types.Timing.Micro): boolean {\n return event.ts <= ts && event.ts + (event.dur || 0) >= ts;\n}\n\nexport function extractSampleTraceId(event: Types.Events.Event): number|null {\n if (Types.Events.isConsoleRunTask(event) || Types.Events.isConsoleTimeStamp(event)) {\n return event.args?.data?.sampleTraceId || null;\n }\n return null;\n}\n"]}
|
|
@@ -57,7 +57,7 @@ export const UIStrings = {
|
|
|
57
57
|
noCulprits: 'Could not detect any layout shift culprits',
|
|
58
58
|
};
|
|
59
59
|
// const str_ = i18n.i18n.registerUIStrings('models/trace/insights/CLSCulprits.ts', UIStrings);
|
|
60
|
-
export const i18nString =
|
|
60
|
+
export const i18nString = (i18nId, values) => ({i18nId, values}); // i18n.i18n.getLocalizedString.bind(undefined, str_);
|
|
61
61
|
export function deps() {
|
|
62
62
|
return ['Meta', 'Animations', 'LayoutShifts', 'NetworkRequests'];
|
|
63
63
|
}
|
|
@@ -41,7 +41,7 @@ export const UIStrings = {
|
|
|
41
41
|
maxChildren: 'Most children',
|
|
42
42
|
};
|
|
43
43
|
// const str_ = i18n.i18n.registerUIStrings('models/trace/insights/DOMSize.ts', UIStrings);
|
|
44
|
-
export const i18nString =
|
|
44
|
+
export const i18nString = (i18nId, values) => ({i18nId, values}); // i18n.i18n.getLocalizedString.bind(undefined, str_);
|
|
45
45
|
const DOM_SIZE_DURATION_THRESHOLD = Helpers.Timing.milliToMicro(Types.Timing.Milli(40));
|
|
46
46
|
// These thresholds were selected to maximize the number of long (>40ms) events above
|
|
47
47
|
// the threshold while maximizing the number of short (<40ms) events below the threshold.
|
|
@@ -52,7 +52,7 @@ export const UIStrings = {
|
|
|
52
52
|
uncompressedDownload: 'Uncompressed download',
|
|
53
53
|
};
|
|
54
54
|
// const str_ = i18n.i18n.registerUIStrings('models/trace/insights/DocumentLatency.ts', UIStrings);
|
|
55
|
-
export const i18nString =
|
|
55
|
+
export const i18nString = (i18nId, values) => ({i18nId, values}); // i18n.i18n.getLocalizedString.bind(undefined, str_);
|
|
56
56
|
// Due to the way that DevTools throttling works we cannot see if server response took less than ~570ms.
|
|
57
57
|
// We set our failure threshold to 600ms to avoid those false positives but we want devs to shoot for 100ms.
|
|
58
58
|
const TOO_SLOW_THRESHOLD_MS = 600;
|
|
@@ -19,7 +19,7 @@ export const UIStrings = {
|
|
|
19
19
|
wastedTimeColumn: 'Wasted time',
|
|
20
20
|
};
|
|
21
21
|
// const str_ = i18n.i18n.registerUIStrings('models/trace/insights/FontDisplay.ts', UIStrings);
|
|
22
|
-
export const i18nString =
|
|
22
|
+
export const i18nString = (i18nId, values) => ({i18nId, values}); // i18n.i18n.getLocalizedString.bind(undefined, str_);
|
|
23
23
|
export function deps() {
|
|
24
24
|
return ['Meta', 'NetworkRequests', 'LayoutShifts'];
|
|
25
25
|
}
|
|
@@ -31,7 +31,7 @@ export const UIStrings = {
|
|
|
31
31
|
totalReflowTime: 'Total reflow time',
|
|
32
32
|
};
|
|
33
33
|
// const str_ = i18n.i18n.registerUIStrings('models/trace/insights/ForcedReflow.ts', UIStrings);
|
|
34
|
-
export const i18nString =
|
|
34
|
+
export const i18nString = (i18nId, values) => ({i18nId, values}); // i18n.i18n.getLocalizedString.bind(undefined, str_);
|
|
35
35
|
function aggregateForcedReflow(data, entryToNodeMap) {
|
|
36
36
|
const dataByTopLevelFunction = new Map();
|
|
37
37
|
const bottomUpDataMap = new Map();
|
|
@@ -81,6 +81,7 @@ export interface OptimizableImage {
|
|
|
81
81
|
largestImagePaint: Types.Events.PaintImage;
|
|
82
82
|
}
|
|
83
83
|
export type ImageDeliveryInsightModel = InsightModel<typeof UIStrings, {
|
|
84
|
+
/** Sorted by potential byte savings, then by size of image. */
|
|
84
85
|
optimizableImages: OptimizableImage[];
|
|
85
86
|
totalByteSavings: number;
|
|
86
87
|
}>;
|
|
@@ -51,7 +51,7 @@ export const UIStrings = {
|
|
|
51
51
|
noOptimizableImages: 'No optimizable images',
|
|
52
52
|
};
|
|
53
53
|
// const str_ = i18n.i18n.registerUIStrings('models/trace/insights/ImageDelivery.ts', UIStrings);
|
|
54
|
-
export const i18nString =
|
|
54
|
+
export const i18nString = (i18nId, values) => ({i18nId, values}); // i18n.i18n.getLocalizedString.bind(undefined, str_);
|
|
55
55
|
/**
|
|
56
56
|
* Even JPEGs with lots of detail can usually be compressed down to <1 byte per pixel
|
|
57
57
|
* Using 4:2:2 subsampling already gets an uncompressed bitmap to 2 bytes per pixel.
|
|
@@ -85,7 +85,7 @@ export var ImageOptimizationType;
|
|
|
85
85
|
ImageOptimizationType["RESPONSIVE_SIZE"] = "RESPONSIVE_SIZE";
|
|
86
86
|
})(ImageOptimizationType || (ImageOptimizationType = {}));
|
|
87
87
|
function getOptimizationMessage(optimization) {
|
|
88
|
-
const byteSavingsText =
|
|
88
|
+
const byteSavingsText = (bytes => ({__i18nBytes: bytes}))(optimization.byteSavings);
|
|
89
89
|
switch (optimization.type) {
|
|
90
90
|
case ImageOptimizationType.ADJUST_COMPRESSION:
|
|
91
91
|
return i18nString(UIStrings.useCompression, { PH1: byteSavingsText });
|
|
@@ -211,6 +211,13 @@ export function generateInsight(parsedTrace, context) {
|
|
|
211
211
|
for (const image of optimizableImages) {
|
|
212
212
|
wastedBytesByRequestId.set(image.request.args.data.requestId, image.byteSavings);
|
|
213
213
|
}
|
|
214
|
+
// Sort by savings, then by size of image.
|
|
215
|
+
optimizableImages.sort((a, b) => {
|
|
216
|
+
if (b.byteSavings !== a.byteSavings) {
|
|
217
|
+
return b.byteSavings - a.byteSavings;
|
|
218
|
+
}
|
|
219
|
+
return b.request.args.data.decodedBodyLength - a.request.args.data.decodedBodyLength;
|
|
220
|
+
});
|
|
214
221
|
return finalize({
|
|
215
222
|
optimizableImages,
|
|
216
223
|
totalByteSavings: optimizableImages.reduce((total, img) => total + img.byteSavings, 0),
|