@paulirish/trace_engine 0.0.57 → 0.0.58

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (272) hide show
  1. package/.tmp/tsbuildinfo/tsconfig.tsbuildinfo +1 -1
  2. package/core/platform/Brand.d.ts +8 -1
  3. package/core/platform/Brand.js.map +1 -1
  4. package/core/platform/DevToolsPath.d.ts +1 -1
  5. package/core/platform/DevToolsPath.js +1 -1
  6. package/core/platform/DevToolsPath.js.map +1 -1
  7. package/core/platform/StringUtilities.d.ts +12 -2
  8. package/core/platform/StringUtilities.js +31 -7
  9. package/core/platform/StringUtilities.js.map +1 -1
  10. package/generated/protocol.d.ts +8209 -7941
  11. package/locales/af.json +75 -60
  12. package/locales/am.json +75 -60
  13. package/locales/ar.json +86 -71
  14. package/locales/as.json +74 -59
  15. package/locales/az.json +75 -60
  16. package/locales/be.json +75 -60
  17. package/locales/bg.json +75 -60
  18. package/locales/bn.json +74 -59
  19. package/locales/bs.json +74 -59
  20. package/locales/ca.json +75 -60
  21. package/locales/cs.json +75 -60
  22. package/locales/cy.json +75 -60
  23. package/locales/da.json +75 -60
  24. package/locales/de.json +74 -59
  25. package/locales/el.json +75 -60
  26. package/locales/en-GB.json +74 -59
  27. package/locales/en-US.json +0 -6
  28. package/locales/en-XL.json +0 -6
  29. package/locales/es-419.json +74 -59
  30. package/locales/es.json +75 -60
  31. package/locales/et.json +74 -59
  32. package/locales/eu.json +75 -60
  33. package/locales/fa.json +77 -62
  34. package/locales/fi.json +74 -59
  35. package/locales/fil.json +75 -60
  36. package/locales/fr-CA.json +75 -60
  37. package/locales/fr.json +75 -60
  38. package/locales/gl.json +75 -60
  39. package/locales/gu.json +74 -59
  40. package/locales/he.json +97 -82
  41. package/locales/hi.json +75 -60
  42. package/locales/hr.json +75 -60
  43. package/locales/hu.json +75 -60
  44. package/locales/hy.json +75 -60
  45. package/locales/id.json +75 -60
  46. package/locales/is.json +74 -59
  47. package/locales/it.json +74 -59
  48. package/locales/ja.json +75 -60
  49. package/locales/ka.json +74 -59
  50. package/locales/kk.json +75 -60
  51. package/locales/km.json +75 -60
  52. package/locales/kn.json +75 -60
  53. package/locales/ko.json +75 -60
  54. package/locales/ky.json +75 -60
  55. package/locales/lo.json +74 -59
  56. package/locales/lt.json +75 -60
  57. package/locales/lv.json +75 -60
  58. package/locales/mk.json +74 -59
  59. package/locales/ml.json +74 -59
  60. package/locales/mn.json +75 -60
  61. package/locales/mr.json +74 -59
  62. package/locales/ms.json +74 -59
  63. package/locales/my.json +75 -60
  64. package/locales/ne.json +76 -61
  65. package/locales/nl.json +74 -59
  66. package/locales/no.json +75 -60
  67. package/locales/or.json +75 -60
  68. package/locales/pa.json +75 -60
  69. package/locales/pl.json +74 -59
  70. package/locales/pt-PT.json +75 -60
  71. package/locales/pt.json +75 -60
  72. package/locales/ro.json +75 -60
  73. package/locales/ru.json +75 -60
  74. package/locales/si.json +75 -60
  75. package/locales/sk.json +74 -59
  76. package/locales/sl.json +75 -60
  77. package/locales/sq.json +75 -60
  78. package/locales/sr-Latn.json +74 -59
  79. package/locales/sr.json +74 -59
  80. package/locales/sv.json +75 -60
  81. package/locales/sw.json +75 -60
  82. package/locales/ta.json +75 -60
  83. package/locales/te.json +74 -59
  84. package/locales/th.json +77 -62
  85. package/locales/tr.json +75 -60
  86. package/locales/uk.json +75 -60
  87. package/locales/ur.json +74 -59
  88. package/locales/uz.json +75 -60
  89. package/locales/vi.json +74 -59
  90. package/locales/zh-HK.json +75 -60
  91. package/locales/zh-TW.json +75 -60
  92. package/locales/zh.json +75 -60
  93. package/locales/zu.json +75 -60
  94. package/models/trace/ModelImpl.d.ts +0 -1
  95. package/models/trace/ModelImpl.js +15 -3
  96. package/models/trace/ModelImpl.js.map +1 -1
  97. package/models/trace/Processor.js +8 -4
  98. package/models/trace/Processor.js.map +1 -1
  99. package/models/trace/extras/ThirdParties.js +1 -2
  100. package/models/trace/extras/ThirdParties.js.map +1 -1
  101. package/models/trace/extras/TraceTree.d.ts +4 -1
  102. package/models/trace/extras/TraceTree.js +7 -2
  103. package/models/trace/extras/TraceTree.js.map +1 -1
  104. package/models/trace/handlers/AnimationFramesHandler.d.ts +1 -0
  105. package/models/trace/handlers/AnimationFramesHandler.js +8 -0
  106. package/models/trace/handlers/AnimationFramesHandler.js.map +1 -1
  107. package/models/trace/handlers/ExtensionTraceDataHandler.d.ts +1 -1
  108. package/models/trace/handlers/ExtensionTraceDataHandler.js +1 -1
  109. package/models/trace/handlers/ExtensionTraceDataHandler.js.map +1 -1
  110. package/models/trace/handlers/FramesHandler.js +38 -28
  111. package/models/trace/handlers/FramesHandler.js.map +1 -1
  112. package/models/trace/handlers/ImagePaintingHandler.d.ts +2 -1
  113. package/models/trace/handlers/ImagePaintingHandler.js.map +1 -1
  114. package/models/trace/handlers/InitiatorsHandler.js +27 -0
  115. package/models/trace/handlers/InitiatorsHandler.js.map +1 -1
  116. package/models/trace/handlers/NetworkRequestsHandler.js +3 -0
  117. package/models/trace/handlers/NetworkRequestsHandler.js.map +1 -1
  118. package/models/trace/handlers/RendererHandler.d.ts +0 -5
  119. package/models/trace/handlers/RendererHandler.js +9 -12
  120. package/models/trace/handlers/RendererHandler.js.map +1 -1
  121. package/models/trace/handlers/SamplesHandler.js +4 -6
  122. package/models/trace/handlers/SamplesHandler.js.map +1 -1
  123. package/models/trace/handlers/ScriptsHandler.d.ts +4 -3
  124. package/models/trace/handlers/ScriptsHandler.js +3 -0
  125. package/models/trace/handlers/ScriptsHandler.js.map +1 -1
  126. package/models/trace/handlers/UserInteractionsHandler.d.ts +4 -2
  127. package/models/trace/handlers/UserInteractionsHandler.js.map +1 -1
  128. package/models/trace/handlers/helpers.d.ts +3 -6
  129. package/models/trace/handlers/helpers.js +17 -9
  130. package/models/trace/handlers/helpers.js.map +1 -1
  131. package/models/trace/handlers/types.d.ts +4 -1
  132. package/models/trace/handlers/types.js.map +1 -1
  133. package/models/trace/helpers/SamplesIntegrator.d.ts +1 -0
  134. package/models/trace/helpers/SamplesIntegrator.js +8 -0
  135. package/models/trace/helpers/SamplesIntegrator.js.map +1 -1
  136. package/models/trace/helpers/Timing.js +2 -0
  137. package/models/trace/helpers/Timing.js.map +1 -1
  138. package/models/trace/helpers/Trace.d.ts +1 -1
  139. package/models/trace/helpers/Trace.js +1 -1
  140. package/models/trace/helpers/Trace.js.map +1 -1
  141. package/models/trace/helpers/TreeHelpers.d.ts +1 -1
  142. package/models/trace/helpers/TreeHelpers.js.map +1 -1
  143. package/models/trace/insights/CLSCulprits.d.ts +2 -2
  144. package/models/trace/insights/CLSCulprits.js +2 -2
  145. package/models/trace/insights/CLSCulprits.js.map +1 -1
  146. package/models/trace/insights/Common.d.ts +6 -5
  147. package/models/trace/insights/Common.js +29 -17
  148. package/models/trace/insights/Common.js.map +1 -1
  149. package/models/trace/insights/DOMSize.d.ts +1 -1
  150. package/models/trace/insights/DOMSize.js +1 -1
  151. package/models/trace/insights/DOMSize.js.map +1 -1
  152. package/models/trace/insights/DocumentLatency.d.ts +2 -2
  153. package/models/trace/insights/DocumentLatency.js +2 -2
  154. package/models/trace/insights/DocumentLatency.js.map +1 -1
  155. package/models/trace/insights/DuplicatedJavaScript.d.ts +1 -0
  156. package/models/trace/insights/DuplicatedJavaScript.js +3 -3
  157. package/models/trace/insights/DuplicatedJavaScript.js.map +1 -1
  158. package/models/trace/insights/ForcedReflow.d.ts +3 -3
  159. package/models/trace/insights/ForcedReflow.js +3 -3
  160. package/models/trace/insights/ForcedReflow.js.map +1 -1
  161. package/models/trace/insights/INPBreakdown.d.ts +5 -5
  162. package/models/trace/insights/INPBreakdown.js +5 -5
  163. package/models/trace/insights/INPBreakdown.js.map +1 -1
  164. package/models/trace/insights/ImageDelivery.d.ts +2 -0
  165. package/models/trace/insights/ImageDelivery.js +3 -0
  166. package/models/trace/insights/ImageDelivery.js.map +1 -1
  167. package/models/trace/insights/LCPBreakdown.d.ts +6 -6
  168. package/models/trace/insights/LCPBreakdown.js +10 -8
  169. package/models/trace/insights/LCPBreakdown.js.map +1 -1
  170. package/models/trace/insights/LCPDiscovery.d.ts +2 -2
  171. package/models/trace/insights/LCPDiscovery.js +3 -3
  172. package/models/trace/insights/LCPDiscovery.js.map +1 -1
  173. package/models/trace/insights/LegacyJavaScript.d.ts +1 -0
  174. package/models/trace/insights/LegacyJavaScript.js +3 -3
  175. package/models/trace/insights/LegacyJavaScript.js.map +1 -1
  176. package/models/trace/insights/ModernHTTP.js +1 -1
  177. package/models/trace/insights/ModernHTTP.js.map +1 -1
  178. package/models/trace/insights/RenderBlocking.d.ts +1 -1
  179. package/models/trace/insights/RenderBlocking.js +1 -1
  180. package/models/trace/insights/RenderBlocking.js.map +1 -1
  181. package/models/trace/insights/SlowCSSSelector.d.ts +8 -8
  182. package/models/trace/insights/SlowCSSSelector.js +8 -8
  183. package/models/trace/insights/SlowCSSSelector.js.map +1 -1
  184. package/models/trace/lantern/graph/BaseNode.d.ts +1 -1
  185. package/models/trace/lantern/graph/BaseNode.js +1 -1
  186. package/models/trace/lantern/graph/BaseNode.js.map +1 -1
  187. package/models/trace/lantern/simulation/SimulationTimingMap.js +1 -1
  188. package/models/trace/lantern/simulation/SimulationTimingMap.js.map +1 -1
  189. package/models/trace/types/Configuration.d.ts +7 -0
  190. package/models/trace/types/Configuration.js +1 -0
  191. package/models/trace/types/Configuration.js.map +1 -1
  192. package/models/trace/types/Extensions.d.ts +1 -1
  193. package/models/trace/types/Extensions.js.map +1 -1
  194. package/models/trace/types/File.d.ts +3 -0
  195. package/models/trace/types/File.js.map +1 -1
  196. package/models/trace/types/Overlays.d.ts +6 -1
  197. package/models/trace/types/Overlays.js.map +1 -1
  198. package/models/trace/types/TraceEvents.d.ts +54 -29
  199. package/models/trace/types/TraceEvents.js +7 -1
  200. package/models/trace/types/TraceEvents.js.map +1 -1
  201. package/package.json +1 -1
  202. package/test/test-trace-engine.mjs +0 -1
  203. package/core/platform/devtools_entrypoint-bundle-tsconfig-tsconfig.json +0 -43
  204. package/core/platform/platform.prebundle.d.ts +0 -18
  205. package/core/platform/platform.prebundle.js +0 -53
  206. package/core/platform/platform.prebundle.js.map +0 -1
  207. package/core/platform/platform.prebundle.ts +0 -71
  208. package/models/cpu_profile/cpu_profile.prebundle.d.ts +0 -3
  209. package/models/cpu_profile/cpu_profile.prebundle.js +0 -7
  210. package/models/cpu_profile/cpu_profile.prebundle.js.map +0 -1
  211. package/models/cpu_profile/cpu_profile.prebundle.ts +0 -11
  212. package/models/cpu_profile/devtools_entrypoint-bundle-tsconfig-tsconfig.json +0 -43
  213. package/models/trace/devtools_entrypoint-bundle-tsconfig-tsconfig.json +0 -61
  214. package/models/trace/extras/devtools_entrypoint-bundle-tsconfig-tsconfig.json +0 -43
  215. package/models/trace/extras/extras.prebundle.d.ts +0 -7
  216. package/models/trace/extras/extras.prebundle.js +0 -11
  217. package/models/trace/extras/extras.prebundle.js.map +0 -1
  218. package/models/trace/extras/extras.prebundle.ts +0 -11
  219. package/models/trace/handlers/devtools_entrypoint-bundle-tsconfig-tsconfig.json +0 -43
  220. package/models/trace/handlers/handlers.prebundle.d.ts +0 -4
  221. package/models/trace/handlers/handlers.prebundle.js +0 -8
  222. package/models/trace/handlers/handlers.prebundle.js.map +0 -1
  223. package/models/trace/handlers/handlers.prebundle.ts +0 -8
  224. package/models/trace/helpers/devtools_entrypoint-bundle-tsconfig-tsconfig.json +0 -43
  225. package/models/trace/helpers/helpers.prebundle.d.ts +0 -7
  226. package/models/trace/helpers/helpers.prebundle.js +0 -11
  227. package/models/trace/helpers/helpers.prebundle.js.map +0 -1
  228. package/models/trace/helpers/helpers.prebundle.ts +0 -11
  229. package/models/trace/insights/devtools_entrypoint-bundle-tsconfig-tsconfig.json +0 -43
  230. package/models/trace/insights/insights.prebundle.d.ts +0 -4
  231. package/models/trace/insights/insights.prebundle.js +0 -8
  232. package/models/trace/insights/insights.prebundle.js.map +0 -1
  233. package/models/trace/insights/insights.prebundle.ts +0 -8
  234. package/models/trace/lantern/core/core.prebundle.d.ts +0 -2
  235. package/models/trace/lantern/core/core.prebundle.js +0 -6
  236. package/models/trace/lantern/core/core.prebundle.js.map +0 -1
  237. package/models/trace/lantern/core/core.prebundle.ts +0 -6
  238. package/models/trace/lantern/core/devtools_entrypoint-bundle-tsconfig-tsconfig.json +0 -43
  239. package/models/trace/lantern/devtools_entrypoint-bundle-tsconfig-tsconfig.json +0 -43
  240. package/models/trace/lantern/graph/devtools_entrypoint-bundle-tsconfig-tsconfig.json +0 -43
  241. package/models/trace/lantern/graph/graph.prebundle.d.ts +0 -4
  242. package/models/trace/lantern/graph/graph.prebundle.js +0 -8
  243. package/models/trace/lantern/graph/graph.prebundle.js.map +0 -1
  244. package/models/trace/lantern/graph/graph.prebundle.ts +0 -8
  245. package/models/trace/lantern/lantern.prebundle.d.ts +0 -6
  246. package/models/trace/lantern/lantern.prebundle.js +0 -10
  247. package/models/trace/lantern/lantern.prebundle.js.map +0 -1
  248. package/models/trace/lantern/lantern.prebundle.ts +0 -17
  249. package/models/trace/lantern/metrics/devtools_entrypoint-bundle-tsconfig-tsconfig.json +0 -43
  250. package/models/trace/lantern/metrics/metrics.prebundle.d.ts +0 -8
  251. package/models/trace/lantern/metrics/metrics.prebundle.js +0 -12
  252. package/models/trace/lantern/metrics/metrics.prebundle.js.map +0 -1
  253. package/models/trace/lantern/metrics/metrics.prebundle.ts +0 -12
  254. package/models/trace/lantern/simulation/devtools_entrypoint-bundle-tsconfig-tsconfig.json +0 -43
  255. package/models/trace/lantern/simulation/simulation.prebundle.d.ts +0 -6
  256. package/models/trace/lantern/simulation/simulation.prebundle.js +0 -10
  257. package/models/trace/lantern/simulation/simulation.prebundle.js.map +0 -1
  258. package/models/trace/lantern/simulation/simulation.prebundle.ts +0 -10
  259. package/models/trace/lantern/types/devtools_entrypoint-bundle-tsconfig-tsconfig.json +0 -43
  260. package/models/trace/lantern/types/types.prebundle.d.ts +0 -1
  261. package/models/trace/lantern/types/types.prebundle.js +0 -5
  262. package/models/trace/lantern/types/types.prebundle.js.map +0 -1
  263. package/models/trace/lantern/types/types.prebundle.ts +0 -5
  264. package/models/trace/trace.prebundle.d.ts +0 -10
  265. package/models/trace/trace.prebundle.js +0 -14
  266. package/models/trace/trace.prebundle.js.map +0 -1
  267. package/models/trace/trace.prebundle.ts +0 -25
  268. package/models/trace/types/devtools_entrypoint-bundle-tsconfig-tsconfig.json +0 -43
  269. package/models/trace/types/types.prebundle.d.ts +0 -5
  270. package/models/trace/types/types.prebundle.js +0 -9
  271. package/models/trace/types/types.prebundle.js.map +0 -1
  272. package/models/trace/types/types.prebundle.ts +0 -9
@@ -1 +1 @@
1
- {"version":3,"file":"AnimationFramesHandler.js","sourceRoot":"","sources":["../../../../../../../front_end/models/trace/handlers/AnimationFramesHandler.ts"],"names":[],"mappings":"AAAA,4DAA4D;AAC5D,yEAAyE;AACzE,6BAA6B;AAC7B,OAAO,KAAK,OAAO,MAAM,uBAAuB,CAAC;AACjD,OAAO,KAAK,KAAK,MAAM,mBAAmB,CAAC;AAS3C,SAAS,SAAS,CAAC,IAAwB;IACzC,OAAO,GAAG,IAAI,CAAC,GAAG,IAAI,IAAI,CAAC,GAAG,EAAE,CAAC;AACnC,CAAC;AACD,2EAA2E;AAC3E,8CAA8C;AAC9C,MAAM,oBAAoB,GAAG,IAAI,GAAG,EAAmD,CAAC;AACxF,MAAM,kBAAkB,GAAG,IAAI,GAAG,EAAiD,CAAC;AACpF,8EAA8E;AAC9E,2EAA2E;AAC3E,MAAM,2BAA2B,GAAG,IAAI,GAAG,EAAmD,CAAC;AAE/F,qDAAqD;AACrD,MAAM,eAAe,GAA+C,EAAE,CAAC;AAEvE,MAAM,oBAAoB,GACtB,IAAI,GAAG,EAAqF,CAAC;AAEjG,MAAM,UAAU,KAAK;IACnB,oBAAoB,CAAC,KAAK,EAAE,CAAC;IAC7B,kBAAkB,CAAC,KAAK,EAAE,CAAC;IAC3B,eAAe,CAAC,MAAM,GAAG,CAAC,CAAC;IAC3B,oBAAoB,CAAC,KAAK,EAAE,CAAC;IAC7B,2BAA2B,CAAC,KAAK,EAAE,CAAC;AACtC,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,KAAyB;IACnD,IAAI,KAAK,CAAC,MAAM,CAAC,0BAA0B,CAAC,KAAK,CAAC,EAAE,CAAC;QACnD,MAAM,GAAG,GAAG,SAAS,CAAC,KAAK,CAAC,CAAC;QAC7B,MAAM,QAAQ,GAAG,oBAAoB,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC;QACrD,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACrB,oBAAoB,CAAC,GAAG,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;IAC1C,CAAC;SAAM,IAAI,KAAK,CAAC,MAAM,CAAC,wBAAwB,CAAC,KAAK,CAAC,EAAE,CAAC;QACxD,MAAM,GAAG,GAAG,SAAS,CAAC,KAAK,CAAC,CAAC;QAC7B,MAAM,QAAQ,GAAG,kBAAkB,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC;QACnD,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACrB,kBAAkB,CAAC,GAAG,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;IACxC,CAAC;SAAM,IAAI,KAAK,CAAC,MAAM,CAAC,4BAA4B,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,IAAI,EAAE,EAAE,EAAE,CAAC;QAC9E,2BAA2B,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,EAAE,KAAK,CAAC,CAAC;IACxD,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,QAAQ;IAC5B,4EAA4E;IAC5E,6EAA6E;IAC7E,0EAA0E;IAC1E,aAAa;IACb,0EAA0E;IAC1E,iBAAiB;IACjB,2EAA2E;IAC3E,yEAAyE;IACzE,2EAA2E;IAC3E,oBAAoB;IACpB,KAAK,MAAM,CAAC,GAAG,EAAE,WAAW,CAAC,IAAI,oBAAoB,CAAC,OAAO,EAAE,EAAE,CAAC;QAChE,MAAM,SAAS,GAAG,kBAAkB,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QAC9C,IAAI,CAAC,SAAS,EAAE,CAAC;YACf,SAAS;QACX,CAAC;QAED,OAAO,CAAC,KAAK,CAAC,sBAAsB,CAAC,WAAW,CAAC,CAAC;QAClD,OAAO,CAAC,KAAK,CAAC,sBAAsB,CAAC,SAAS,CAAC,CAAC;QAEhD,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,WAAW,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YAC5C,MAAM,QAAQ,GAAG,SAAS,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;YACjC,IAAI,CAAC,QAAQ,EAAE,CAAC;gBACd,0DAA0D;gBAC1D,MAAM;YACR,CAAC;YACD,MAAM,UAAU,GAAG,WAAW,CAAC,CAAC,CAAC,CAAC;YAElC,MAAM,cAAc,GAAG,OAAO,CAAC,eAAe,CAAC,sBAAsB;iBACzC,sBAAsB,CAA2C;gBAChE,cAAc,EAAE,UAAU;gBAC1B,GAAG,UAAU;gBACb,GAAG,EAAE,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,EAAE,GAAG,UAAU,CAAC,EAAE,CAAC;gBACpD,IAAI,EAAE;oBACJ,IAAI,EAAE;wBACJ,UAAU,EAAE,UAAU;wBACtB,QAAQ;qBACT;iBACF;aACF,CAAC,CAAC;YAC9B,eAAe,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;YAErC,0EAA0E;YAC1E,oDAAoD;YACpD,MAAM,EAAE,GAAG,UAAU,CAAC,IAAI,EAAE,EAAE,CAAC;YAC/B,IAAI,EAAE,EAAE,CAAC;gBACP,MAAM,iBAAiB,GAAG,2BAA2B,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;gBAC9D,IAAI,iBAAiB,EAAE,CAAC;oBACtB,oBAAoB,CAAC,GAAG,CAAC,cAAc,EAAE,iBAAiB,CAAC,CAAC;gBAC9D,CAAC;YACH,CAAC;QACH,CAAC;IACH,CAAC;AACH,CAAC;AAED,MAAM,UAAU,IAAI;IAClB,OAAO;QACL,eAAe;QACf,oBAAoB;KACrB,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,IAAI;IAClB,OAAO,CAAC,MAAM,CAAC,CAAC;AAClB,CAAC","sourcesContent":["// Copyright 2024 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.\nimport * as Helpers from '../helpers/helpers.js';\nimport * as Types from '../types/types.js';\n\nimport type {HandlerName} from './types.js';\n\nexport interface Data {\n animationFrames: Types.Events.SyntheticAnimationFramePair[];\n presentationForFrame: Map<Types.Events.SyntheticAnimationFramePair, Types.Events.AnimationFramePresentation>;\n}\n\nfunction threadKey(data: Types.Events.Event): string {\n return `${data.pid}-${data.tid}`;\n}\n// Track all the start + end events. We key them by the PID+TID so we don't\n// accidentally pair across different threads.\nconst animationFrameStarts = new Map<string, Types.Events.AnimationFrameAsyncStart[]>();\nconst animationFrameEnds = new Map<string, Types.Events.AnimationFrameAsyncEnd[]>();\n// Store all the AnimationFrame::Presentation events. Key them by their ID for\n// easy look-up later on when we associate one to the AnimationFrame event.\nconst animationFramePresentations = new Map<string, Types.Events.AnimationFramePresentation>();\n\n// The final list of animation frames that we return.\nconst animationFrames: Types.Events.SyntheticAnimationFramePair[] = [];\n\nconst presentationForFrame =\n new Map<Types.Events.SyntheticAnimationFramePair, Types.Events.AnimationFramePresentation>();\n\nexport function reset(): void {\n animationFrameStarts.clear();\n animationFrameEnds.clear();\n animationFrames.length = 0;\n presentationForFrame.clear();\n animationFramePresentations.clear();\n}\n\nexport function handleEvent(event: Types.Events.Event): void {\n if (Types.Events.isAnimationFrameAsyncStart(event)) {\n const key = threadKey(event);\n const existing = animationFrameStarts.get(key) ?? [];\n existing.push(event);\n animationFrameStarts.set(key, existing);\n } else if (Types.Events.isAnimationFrameAsyncEnd(event)) {\n const key = threadKey(event);\n const existing = animationFrameEnds.get(key) ?? [];\n existing.push(event);\n animationFrameEnds.set(key, existing);\n } else if (Types.Events.isAnimationFramePresentation(event) && event.args?.id) {\n animationFramePresentations.set(event.args.id, event);\n }\n}\n\nexport async function finalize(): Promise<void> {\n // AnimationFrames are represented with begin & end events on a stack; so we\n // can pair them by walking through the list of start events and pairing with\n // the same index in the list of end events, once both lists are sorted by\n // timestamp.\n // We walk through the set of begin/end events we gathered per pid+tid and\n // pair those up.\n // Unfortunately we cannot use the pairing helpers in Helpers.Trace because\n // only the begin event has an ID; the end event does not. But because we\n // know that AnimationFrames are sequential and do not overlap, we can pair\n // up events easily.\n for (const [key, startEvents] of animationFrameStarts.entries()) {\n const endEvents = animationFrameEnds.get(key);\n if (!endEvents) {\n continue;\n }\n\n Helpers.Trace.sortTraceEventsInPlace(startEvents);\n Helpers.Trace.sortTraceEventsInPlace(endEvents);\n\n for (let i = 0; i < startEvents.length; i++) {\n const endEvent = endEvents.at(i);\n if (!endEvent) {\n // Invalid data: break. We can't pair any other events up.\n break;\n }\n const startEvent = startEvents[i];\n\n const syntheticEvent = Helpers.SyntheticEvents.SyntheticEventsManager\n .registerSyntheticEvent<Types.Events.SyntheticAnimationFramePair>({\n rawSourceEvent: startEvent,\n ...startEvent,\n dur: Types.Timing.Micro(endEvent.ts - startEvent.ts),\n args: {\n data: {\n beginEvent: startEvent,\n endEvent,\n },\n },\n });\n animationFrames.push(syntheticEvent);\n\n // AnimationFrame begin events + AnimationFrame::Presentation events share\n // an args.id, so we can pair them up based on that.\n const id = startEvent.args?.id;\n if (id) {\n const presentationEvent = animationFramePresentations.get(id);\n if (presentationEvent) {\n presentationForFrame.set(syntheticEvent, presentationEvent);\n }\n }\n }\n }\n}\n\nexport function data(): Data {\n return {\n animationFrames,\n presentationForFrame,\n };\n}\n\nexport function deps(): HandlerName[] {\n return ['Meta'];\n}\n"]}
1
+ {"version":3,"file":"AnimationFramesHandler.js","sourceRoot":"","sources":["../../../../../../../front_end/models/trace/handlers/AnimationFramesHandler.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright 2024 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.\nimport * as Helpers from '../helpers/helpers.js';\nimport * as Types from '../types/types.js';\n\nimport type {HandlerName} from './types.js';\n\nexport interface Data {\n animationFrames: Types.Events.SyntheticAnimationFramePair[];\n presentationForFrame: Map<Types.Events.SyntheticAnimationFramePair, Types.Events.AnimationFramePresentation>;\n}\n\nfunction threadKey(data: Types.Events.Event): string {\n return `${data.pid}-${data.tid}`;\n}\n// Track all the start + end events. We key them by the PID+TID so we don't\n// accidentally pair across different threads.\nconst animationFrameStarts = new Map<string, Types.Events.AnimationFrameAsyncStart[]>();\nconst animationFrameEnds = new Map<string, Types.Events.AnimationFrameAsyncEnd[]>();\n// Store all the AnimationFrame::Presentation events. Key them by their ID for\n// easy look-up later on when we associate one to the AnimationFrame event.\nconst animationFramePresentations = new Map<string, Types.Events.AnimationFramePresentation>();\n\n// The final list of animation frames that we return.\nconst animationFrames: Types.Events.SyntheticAnimationFramePair[] = [];\n\nconst presentationForFrame =\n new Map<Types.Events.SyntheticAnimationFramePair, Types.Events.AnimationFramePresentation>();\n\nexport function reset(): void {\n animationFrameStarts.clear();\n animationFrameEnds.clear();\n animationFrames.length = 0;\n presentationForFrame.clear();\n animationFramePresentations.clear();\n isEnabled = false;\n}\n\nlet isEnabled = false;\nexport function handleUserConfig(config: Types.Configuration.Configuration): void {\n isEnabled = config.enableAnimationsFrameHandler;\n}\n\nexport function handleEvent(event: Types.Events.Event): void {\n if (!isEnabled) {\n return;\n }\n\n if (Types.Events.isAnimationFrameAsyncStart(event)) {\n const key = threadKey(event);\n const existing = animationFrameStarts.get(key) ?? [];\n existing.push(event);\n animationFrameStarts.set(key, existing);\n } else if (Types.Events.isAnimationFrameAsyncEnd(event)) {\n const key = threadKey(event);\n const existing = animationFrameEnds.get(key) ?? [];\n existing.push(event);\n animationFrameEnds.set(key, existing);\n } else if (Types.Events.isAnimationFramePresentation(event) && event.args?.id) {\n animationFramePresentations.set(event.args.id, event);\n }\n}\n\nexport async function finalize(): Promise<void> {\n // AnimationFrames are represented with begin & end events on a stack; so we\n // can pair them by walking through the list of start events and pairing with\n // the same index in the list of end events, once both lists are sorted by\n // timestamp.\n // We walk through the set of begin/end events we gathered per pid+tid and\n // pair those up.\n // Unfortunately we cannot use the pairing helpers in Helpers.Trace because\n // only the begin event has an ID; the end event does not. But because we\n // know that AnimationFrames are sequential and do not overlap, we can pair\n // up events easily.\n for (const [key, startEvents] of animationFrameStarts.entries()) {\n const endEvents = animationFrameEnds.get(key);\n if (!endEvents) {\n continue;\n }\n\n Helpers.Trace.sortTraceEventsInPlace(startEvents);\n Helpers.Trace.sortTraceEventsInPlace(endEvents);\n\n for (let i = 0; i < startEvents.length; i++) {\n const endEvent = endEvents.at(i);\n if (!endEvent) {\n // Invalid data: break. We can't pair any other events up.\n break;\n }\n const startEvent = startEvents[i];\n\n const syntheticEvent = Helpers.SyntheticEvents.SyntheticEventsManager\n .registerSyntheticEvent<Types.Events.SyntheticAnimationFramePair>({\n rawSourceEvent: startEvent,\n ...startEvent,\n dur: Types.Timing.Micro(endEvent.ts - startEvent.ts),\n args: {\n data: {\n beginEvent: startEvent,\n endEvent,\n },\n },\n });\n animationFrames.push(syntheticEvent);\n\n // AnimationFrame begin events + AnimationFrame::Presentation events share\n // an args.id, so we can pair them up based on that.\n const id = startEvent.args?.id;\n if (id) {\n const presentationEvent = animationFramePresentations.get(id);\n if (presentationEvent) {\n presentationForFrame.set(syntheticEvent, presentationEvent);\n }\n }\n }\n }\n}\n\nexport function data(): Data {\n return {\n animationFrames,\n presentationForFrame,\n };\n}\n\nexport function deps(): HandlerName[] {\n return ['Meta'];\n}\n"]}
@@ -85,7 +85,7 @@ export declare function extensionDataInPerformanceTiming(timing: Types.Events.Sy
85
85
  * `ExtensionUI::extensionEntryColor`).
86
86
  *
87
87
  * @param timeStamp The `ConsoleTimeStamp` event to extract data from.
88
- * @return An `ExtensionTrackEntryPayload` object if the event contains
88
+ * @returns An `ExtensionTrackEntryPayload` object if the event contains
89
89
  * valid extension data for a track entry, or `null` otherwise.
90
90
  */
91
91
  export declare function extensionDataInConsoleTimeStamp(timeStamp: Types.Events.ConsoleTimeStamp): Types.Extensions.ExtensionTrackEntryPayload | null;
@@ -234,7 +234,7 @@ export function extensionDataInPerformanceTiming(timing) {
234
234
  * `ExtensionUI::extensionEntryColor`).
235
235
  *
236
236
  * @param timeStamp The `ConsoleTimeStamp` event to extract data from.
237
- * @return An `ExtensionTrackEntryPayload` object if the event contains
237
+ * @returns An `ExtensionTrackEntryPayload` object if the event contains
238
238
  * valid extension data for a track entry, or `null` otherwise.
239
239
  */
240
240
  export function extensionDataInConsoleTimeStamp(timeStamp) {
@@ -1 +1 @@
1
- {"version":3,"file":"ExtensionTraceDataHandler.js","sourceRoot":"","sources":["../../../../../../../front_end/models/trace/handlers/ExtensionTraceDataHandler.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright 2024 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 type {HandlerName} from './types.js';\nimport {data as userTimingsData} from './UserTimingsHandler.js';\n\nconst extensionTrackEntries: Types.Extensions.SyntheticExtensionTrackEntry[] = [];\nconst extensionTrackData: Types.Extensions.ExtensionTrackData[] = [];\nconst extensionMarkers: Types.Extensions.SyntheticExtensionMarker[] = [];\nconst entryToNode = new Map<Types.Events.Event, Helpers.TreeHelpers.TraceEntryNode>();\nconst timeStampByName = new Map<string, Types.Events.ConsoleTimeStamp>();\n\nconst syntheticConsoleEntriesForTimingsTrack: Types.Events.SyntheticConsoleTimeStamp[] = [];\n\nexport interface ExtensionTraceData {\n extensionTrackData: readonly Types.Extensions.ExtensionTrackData[];\n extensionMarkers: readonly Types.Extensions.SyntheticExtensionMarker[];\n // TODO(andoli): Can we augment Renderer's entryToNode instead? To avoid the split of TimelineUIUtils's getEventSelfTime()?\n entryToNode: Map<Types.Events.Event, Helpers.TreeHelpers.TraceEntryNode>;\n syntheticConsoleEntriesForTimingsTrack: Types.Events.SyntheticConsoleTimeStamp[];\n}\n\nexport function handleEvent(_event: Types.Events.Event): void {\n // Implementation not needed because data is sourced from UserTimingsHandler\n}\n\nexport function reset(): void {\n extensionTrackEntries.length = 0;\n syntheticConsoleEntriesForTimingsTrack.length = 0;\n extensionTrackData.length = 0;\n extensionMarkers.length = 0;\n entryToNode.clear();\n timeStampByName.clear();\n}\n\nexport async function finalize(): Promise<void> {\n createExtensionFlameChartEntries();\n}\n\nfunction createExtensionFlameChartEntries(): void {\n const pairedMeasures: readonly Types.Events.SyntheticUserTimingPair[] = userTimingsData().performanceMeasures;\n const marks: readonly Types.Events.PerformanceMark[] = userTimingsData().performanceMarks;\n const mergedRawExtensionEvents = Helpers.Trace.mergeEventsInOrder(pairedMeasures, marks);\n\n extractPerformanceAPIExtensionEntries(mergedRawExtensionEvents);\n extractConsoleAPIExtensionEntries();\n // extensionTrackEntries is filled by the above two calls.\n Helpers.Trace.sortTraceEventsInPlace(extensionTrackEntries);\n Helpers.Extensions.buildTrackDataFromExtensionEntries(extensionTrackEntries, extensionTrackData, entryToNode);\n}\n\n/**\n * Extracts extension entries from console.timeStamp events.\n *\n * Entries are built by pairing `console.timeStamp` events based on\n * their names. When a `console.timeStamp` event includes a `start`\n * argument (and optionally an `end` argument), it attempts to find\n * previously recorded `console.timeStamp` events with names matching\n * the `start` and `end` values. These matching events are then used to\n * determine the start and end times of the new entry.\n *\n * If a `console.timeStamp` event includes data for a custom track\n * (specified by the `track` argument), an extension track entry is\n * created and added to the `extensionTrackEntries` array. These entries\n * are used to visualize custom tracks in the Performance panel.\n *\n * If a `console.timeStamp` event includes data for a custom track\n * (specified by the `track` argument), an extension track entry is\n * created and added to the `extensionTrackEntries` array. These entries\n * are used to visualize custom tracks in the Performance panel.\n *\n * If a `console.timeStamp` event does not specify a custom track but\n * includes a start and/or end time (referencing other\n * `console.timeStamp` names), a synthetic console time stamp entry is\n * created and added to the `syntheticConsoleEntriesForTimingsTrack`\n * array. These entries are displayed in the \"Timings\" track.\n */\nexport function extractConsoleAPIExtensionEntries(): void {\n const consoleTimeStamps: readonly Types.Events.ConsoleTimeStamp[] = userTimingsData().timestampEvents;\n for (const currentTimeStamp of consoleTimeStamps) {\n if (!currentTimeStamp.args.data) {\n continue;\n }\n const timeStampName = String(currentTimeStamp.args.data.name ?? currentTimeStamp.args.data.message);\n timeStampByName.set(timeStampName, currentTimeStamp);\n const extensionData = extensionDataInConsoleTimeStamp(currentTimeStamp);\n const start = currentTimeStamp.args.data.start;\n const end = currentTimeStamp.args.data.end;\n if (!extensionData && !start && !end) {\n continue;\n }\n // If the start or end is a number, it's assumed to be a timestamp\n // from the tracing clock, so we use that directly, otherwise we\n // assume it's the label of a previous console timestamp, in which\n // case we use its corresponding timestamp.\n const startTimeStamp =\n typeof start === 'number' ? Types.Timing.Micro(start) : timeStampByName.get(String(start))?.ts;\n const endTimeStamp = typeof end === 'number' ? Types.Timing.Micro(end) : timeStampByName.get(String(end))?.ts;\n if (endTimeStamp !== undefined && startTimeStamp === undefined) {\n // Invalid data\n continue;\n }\n const entryStartTime = startTimeStamp ?? currentTimeStamp.ts;\n const entryEndTime = endTimeStamp ?? currentTimeStamp.ts;\n if (extensionData) {\n const unregisteredExtensionEntry: Omit<Types.Extensions.SyntheticExtensionTrackEntry, '_tag'> = {\n ...currentTimeStamp,\n name: timeStampName,\n cat: 'devtools.extension',\n args: extensionData,\n rawSourceEvent: currentTimeStamp,\n dur: Types.Timing.Micro(entryEndTime - entryStartTime),\n ts: entryStartTime,\n ph: Types.Events.Phase.COMPLETE,\n };\n const extensionEntry =\n Helpers.SyntheticEvents.SyntheticEventsManager\n .registerSyntheticEvent<Types.Extensions.SyntheticExtensionTrackEntry>(unregisteredExtensionEntry);\n extensionTrackEntries.push(extensionEntry);\n continue;\n }\n // If no extension data is found in the entry (no custom track name\n // was passed), but the entry has a duration. we still save it here\n // to be added in the timings track. Note that timings w/o duration\n // and extension data are already handled by the UserTimingsHandler.\n const unregisteredSyntheticTimeStamp: Omit<Types.Events.SyntheticConsoleTimeStamp, '_tag'> = {\n ...currentTimeStamp,\n name: timeStampName,\n cat: 'disabled-by-default-v8.inspector',\n ph: Types.Events.Phase.COMPLETE,\n ts: entryStartTime,\n dur: Types.Timing.Micro(entryEndTime - entryStartTime),\n rawSourceEvent: currentTimeStamp\n };\n const syntheticTimeStamp =\n Helpers.SyntheticEvents.SyntheticEventsManager.registerSyntheticEvent<Types.Events.SyntheticConsoleTimeStamp>(\n unregisteredSyntheticTimeStamp);\n syntheticConsoleEntriesForTimingsTrack.push(syntheticTimeStamp);\n }\n}\n\n/**\n * Extracts extension entries from Performance API events (marks and\n * measures).\n * It specifically looks for events that contain extension-specific data\n * within their `detail` property.\n *\n * If an event's `detail` property can be parsed as a JSON object and\n * contains a `devtools` field with a valid extension payload, a\n * synthetic extension entry is created. The type of extension entry\n * created depends on the payload:\n *\n * - If the payload conforms to `ExtensionPayloadMarker`, a\n * `SyntheticExtensionMarker` is created and added to the\n * `extensionMarkers` array. These markers represent single points in\n * time.\n * - If the payload conforms to `ExtensionPayloadTrackEntry`, a\n * `SyntheticExtensionTrackEntry` is created and added to the\n * `extensionTrackEntries` array. These entries represent events with\n * a duration and are displayed on custom tracks in the Performance\n * panel.\n *\n * **Note:** Only events with a `detail` property that contains valid\n * extension data are processed. Other `performance.mark` and\n * `performance.measure` events are ignored.\n *\n * @param timings An array of `SyntheticUserTimingPair` or\n * `PerformanceMark` events, typically obtained from the\n * `UserTimingsHandler`.\n */\nexport function extractPerformanceAPIExtensionEntries(\n timings: Array<Types.Events.SyntheticUserTimingPair|Types.Events.PerformanceMark>): void {\n for (const timing of timings) {\n const extensionPayload = extensionDataInPerformanceTiming(timing);\n if (!extensionPayload) {\n // Not an extension user timing.\n continue;\n }\n\n const extensionSyntheticEntry = {\n name: timing.name,\n ph: Types.Extensions.isExtensionPayloadMarker(extensionPayload) ? Types.Events.Phase.INSTANT :\n Types.Events.Phase.COMPLETE,\n pid: timing.pid,\n tid: timing.tid,\n ts: timing.ts,\n dur: timing.dur as Types.Timing.Micro,\n cat: 'devtools.extension',\n args: extensionPayload,\n rawSourceEvent: Types.Events.isSyntheticUserTiming(timing) ? timing.rawSourceEvent : timing,\n };\n\n if (Types.Extensions.isExtensionPayloadMarker(extensionPayload)) {\n const extensionMarker =\n Helpers.SyntheticEvents.SyntheticEventsManager\n .registerSyntheticEvent<Types.Extensions.SyntheticExtensionMarker>(\n extensionSyntheticEntry as Omit<Types.Extensions.SyntheticExtensionMarker, '_tag'>);\n extensionMarkers.push(extensionMarker);\n continue;\n }\n\n if (Types.Extensions.isExtensionPayloadTrackEntry(extensionSyntheticEntry.args)) {\n const extensionTrackEntry =\n Helpers.SyntheticEvents.SyntheticEventsManager\n .registerSyntheticEvent<Types.Extensions.SyntheticExtensionTrackEntry>(\n extensionSyntheticEntry as Omit<Types.Extensions.SyntheticExtensionTrackEntry, '_tag'>);\n extensionTrackEntries.push(extensionTrackEntry);\n continue;\n }\n }\n}\n\nfunction parseDetail(timingDetail: string, key: string): Types.Extensions.ExtensionDataPayload|\n Types.Extensions.ExtensionTrackEntryPayloadDeeplink|null {\n try {\n // Attempt to parse the detail as an object that might be coming from a\n // DevTools Perf extension.\n // Wrapped in a try-catch because timingDetail might either:\n // 1. Not be `json.parse`-able (it should, but just in case...)\n // 2.Not be an object - in which case the `in` check will error.\n // If we hit either of these cases, we just ignore this mark and move on.\n const detailObj = JSON.parse(timingDetail);\n if (!(key in detailObj)) {\n return null;\n }\n if (!Types.Extensions.isValidExtensionPayload(detailObj[key])) {\n return null;\n }\n return detailObj[key];\n } catch {\n // No need to worry about this error, just discard this event and don't\n // treat it as having any useful information for the purposes of extensions\n return null;\n }\n}\n\nfunction extensionPayloadForConsoleApi(timing: Types.Events.ConsoleTimeStamp):\n Types.Extensions.ExtensionTrackEntryPayloadDeeplink|null {\n if (!timing.args.data || !('devtools' in timing.args.data)) {\n return null;\n }\n\n return parseDetail(`{\"additionalContext\": ${timing.args.data.devtools} }`, 'additionalContext') as\n Types.Extensions.ExtensionTrackEntryPayloadDeeplink;\n}\n\nexport function extensionDataInPerformanceTiming(\n timing: Types.Events.SyntheticUserTimingPair|Types.Events.PerformanceMark): Types.Extensions.ExtensionDataPayload|\n null {\n const timingDetail =\n Types.Events.isPerformanceMark(timing) ? timing.args.data?.detail : timing.args.data.beginEvent.args.detail;\n if (!timingDetail) {\n return null;\n }\n return parseDetail(timingDetail, 'devtools') as Types.Extensions.ExtensionDataPayload;\n}\n\n/**\n * Extracts extension data from a `console.timeStamp` event.\n *\n * Checks if a `console.timeStamp` event contains data intended for\n * creating a custom track entry in the DevTools Performance panel. It\n * specifically looks for a `track` argument within the event's data.\n *\n * If a `track` argument is present (and not an empty string), the\n * function constructs an `ExtensionTrackEntryPayload` object containing\n * the track name, an optional color, an optional track group. This\n * payload is then used to create a `SyntheticExtensionTrackEntry`.\n *\n * **Note:** The `color` argument is optional and its type is validated\n * against a predefined palette (see\n * `ExtensionUI::extensionEntryColor`).\n *\n * @param timeStamp The `ConsoleTimeStamp` event to extract data from.\n * @return An `ExtensionTrackEntryPayload` object if the event contains\n * valid extension data for a track entry, or `null` otherwise.\n */\nexport function extensionDataInConsoleTimeStamp(timeStamp: Types.Events.ConsoleTimeStamp):\n Types.Extensions.ExtensionTrackEntryPayload|null {\n if (!timeStamp.args.data) {\n return null;\n }\n const trackName = timeStamp.args.data.track;\n if (trackName === '' || trackName === undefined) {\n return null;\n }\n\n let additionalContext: Types.Extensions.ExtensionTrackEntryPayloadDeeplink|undefined;\n const payload = extensionPayloadForConsoleApi(timeStamp);\n if (payload) {\n additionalContext = payload;\n }\n\n return {\n // the color is defaulted to primary if it's value isn't one from\n // the defined palette (see ExtensionUI::extensionEntryColor) so\n // we don't need to check the value is valid here.\n color: String(timeStamp.args.data.color) as Types.Extensions.ExtensionTrackEntryPayload['color'],\n track: String(trackName),\n dataType: 'track-entry',\n trackGroup: timeStamp.args.data.trackGroup !== undefined ? String(timeStamp.args.data.trackGroup) : undefined,\n additionalContext\n };\n}\n\nexport function data(): ExtensionTraceData {\n return {\n entryToNode,\n extensionTrackData,\n extensionMarkers,\n syntheticConsoleEntriesForTimingsTrack,\n };\n}\n\nexport function deps(): HandlerName[] {\n return ['UserTimings'];\n}\n"]}
1
+ {"version":3,"file":"ExtensionTraceDataHandler.js","sourceRoot":"","sources":["../../../../../../../front_end/models/trace/handlers/ExtensionTraceDataHandler.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright 2024 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 type {HandlerName} from './types.js';\nimport {data as userTimingsData} from './UserTimingsHandler.js';\n\nconst extensionTrackEntries: Types.Extensions.SyntheticExtensionTrackEntry[] = [];\nconst extensionTrackData: Types.Extensions.ExtensionTrackData[] = [];\nconst extensionMarkers: Types.Extensions.SyntheticExtensionMarker[] = [];\nconst entryToNode = new Map<Types.Events.Event, Helpers.TreeHelpers.TraceEntryNode>();\nconst timeStampByName = new Map<string, Types.Events.ConsoleTimeStamp>();\n\nconst syntheticConsoleEntriesForTimingsTrack: Types.Events.SyntheticConsoleTimeStamp[] = [];\n\nexport interface ExtensionTraceData {\n extensionTrackData: readonly Types.Extensions.ExtensionTrackData[];\n extensionMarkers: readonly Types.Extensions.SyntheticExtensionMarker[];\n // TODO(andoli): Can we augment Renderer's entryToNode instead? To avoid the split of TimelineUIUtils's getEventSelfTime()?\n entryToNode: Map<Types.Events.Event, Helpers.TreeHelpers.TraceEntryNode>;\n syntheticConsoleEntriesForTimingsTrack: Types.Events.SyntheticConsoleTimeStamp[];\n}\n\nexport function handleEvent(_event: Types.Events.Event): void {\n // Implementation not needed because data is sourced from UserTimingsHandler\n}\n\nexport function reset(): void {\n extensionTrackEntries.length = 0;\n syntheticConsoleEntriesForTimingsTrack.length = 0;\n extensionTrackData.length = 0;\n extensionMarkers.length = 0;\n entryToNode.clear();\n timeStampByName.clear();\n}\n\nexport async function finalize(): Promise<void> {\n createExtensionFlameChartEntries();\n}\n\nfunction createExtensionFlameChartEntries(): void {\n const pairedMeasures: readonly Types.Events.SyntheticUserTimingPair[] = userTimingsData().performanceMeasures;\n const marks: readonly Types.Events.PerformanceMark[] = userTimingsData().performanceMarks;\n const mergedRawExtensionEvents = Helpers.Trace.mergeEventsInOrder(pairedMeasures, marks);\n\n extractPerformanceAPIExtensionEntries(mergedRawExtensionEvents);\n extractConsoleAPIExtensionEntries();\n // extensionTrackEntries is filled by the above two calls.\n Helpers.Trace.sortTraceEventsInPlace(extensionTrackEntries);\n Helpers.Extensions.buildTrackDataFromExtensionEntries(extensionTrackEntries, extensionTrackData, entryToNode);\n}\n\n/**\n * Extracts extension entries from console.timeStamp events.\n *\n * Entries are built by pairing `console.timeStamp` events based on\n * their names. When a `console.timeStamp` event includes a `start`\n * argument (and optionally an `end` argument), it attempts to find\n * previously recorded `console.timeStamp` events with names matching\n * the `start` and `end` values. These matching events are then used to\n * determine the start and end times of the new entry.\n *\n * If a `console.timeStamp` event includes data for a custom track\n * (specified by the `track` argument), an extension track entry is\n * created and added to the `extensionTrackEntries` array. These entries\n * are used to visualize custom tracks in the Performance panel.\n *\n * If a `console.timeStamp` event includes data for a custom track\n * (specified by the `track` argument), an extension track entry is\n * created and added to the `extensionTrackEntries` array. These entries\n * are used to visualize custom tracks in the Performance panel.\n *\n * If a `console.timeStamp` event does not specify a custom track but\n * includes a start and/or end time (referencing other\n * `console.timeStamp` names), a synthetic console time stamp entry is\n * created and added to the `syntheticConsoleEntriesForTimingsTrack`\n * array. These entries are displayed in the \"Timings\" track.\n */\nexport function extractConsoleAPIExtensionEntries(): void {\n const consoleTimeStamps: readonly Types.Events.ConsoleTimeStamp[] = userTimingsData().timestampEvents;\n for (const currentTimeStamp of consoleTimeStamps) {\n if (!currentTimeStamp.args.data) {\n continue;\n }\n const timeStampName = String(currentTimeStamp.args.data.name ?? currentTimeStamp.args.data.message);\n timeStampByName.set(timeStampName, currentTimeStamp);\n const extensionData = extensionDataInConsoleTimeStamp(currentTimeStamp);\n const start = currentTimeStamp.args.data.start;\n const end = currentTimeStamp.args.data.end;\n if (!extensionData && !start && !end) {\n continue;\n }\n // If the start or end is a number, it's assumed to be a timestamp\n // from the tracing clock, so we use that directly, otherwise we\n // assume it's the label of a previous console timestamp, in which\n // case we use its corresponding timestamp.\n const startTimeStamp =\n typeof start === 'number' ? Types.Timing.Micro(start) : timeStampByName.get(String(start))?.ts;\n const endTimeStamp = typeof end === 'number' ? Types.Timing.Micro(end) : timeStampByName.get(String(end))?.ts;\n if (endTimeStamp !== undefined && startTimeStamp === undefined) {\n // Invalid data\n continue;\n }\n const entryStartTime = startTimeStamp ?? currentTimeStamp.ts;\n const entryEndTime = endTimeStamp ?? currentTimeStamp.ts;\n if (extensionData) {\n const unregisteredExtensionEntry: Omit<Types.Extensions.SyntheticExtensionTrackEntry, '_tag'> = {\n ...currentTimeStamp,\n name: timeStampName,\n cat: 'devtools.extension',\n args: extensionData,\n rawSourceEvent: currentTimeStamp,\n dur: Types.Timing.Micro(entryEndTime - entryStartTime),\n ts: entryStartTime,\n ph: Types.Events.Phase.COMPLETE,\n };\n const extensionEntry =\n Helpers.SyntheticEvents.SyntheticEventsManager\n .registerSyntheticEvent<Types.Extensions.SyntheticExtensionTrackEntry>(unregisteredExtensionEntry);\n extensionTrackEntries.push(extensionEntry);\n continue;\n }\n // If no extension data is found in the entry (no custom track name\n // was passed), but the entry has a duration. we still save it here\n // to be added in the timings track. Note that timings w/o duration\n // and extension data are already handled by the UserTimingsHandler.\n const unregisteredSyntheticTimeStamp: Omit<Types.Events.SyntheticConsoleTimeStamp, '_tag'> = {\n ...currentTimeStamp,\n name: timeStampName,\n cat: 'disabled-by-default-v8.inspector',\n ph: Types.Events.Phase.COMPLETE,\n ts: entryStartTime,\n dur: Types.Timing.Micro(entryEndTime - entryStartTime),\n rawSourceEvent: currentTimeStamp\n };\n const syntheticTimeStamp =\n Helpers.SyntheticEvents.SyntheticEventsManager.registerSyntheticEvent<Types.Events.SyntheticConsoleTimeStamp>(\n unregisteredSyntheticTimeStamp);\n syntheticConsoleEntriesForTimingsTrack.push(syntheticTimeStamp);\n }\n}\n\n/**\n * Extracts extension entries from Performance API events (marks and\n * measures).\n * It specifically looks for events that contain extension-specific data\n * within their `detail` property.\n *\n * If an event's `detail` property can be parsed as a JSON object and\n * contains a `devtools` field with a valid extension payload, a\n * synthetic extension entry is created. The type of extension entry\n * created depends on the payload:\n *\n * - If the payload conforms to `ExtensionPayloadMarker`, a\n * `SyntheticExtensionMarker` is created and added to the\n * `extensionMarkers` array. These markers represent single points in\n * time.\n * - If the payload conforms to `ExtensionPayloadTrackEntry`, a\n * `SyntheticExtensionTrackEntry` is created and added to the\n * `extensionTrackEntries` array. These entries represent events with\n * a duration and are displayed on custom tracks in the Performance\n * panel.\n *\n * **Note:** Only events with a `detail` property that contains valid\n * extension data are processed. Other `performance.mark` and\n * `performance.measure` events are ignored.\n *\n * @param timings An array of `SyntheticUserTimingPair` or\n * `PerformanceMark` events, typically obtained from the\n * `UserTimingsHandler`.\n */\nexport function extractPerformanceAPIExtensionEntries(\n timings: Array<Types.Events.SyntheticUserTimingPair|Types.Events.PerformanceMark>): void {\n for (const timing of timings) {\n const extensionPayload = extensionDataInPerformanceTiming(timing);\n if (!extensionPayload) {\n // Not an extension user timing.\n continue;\n }\n\n const extensionSyntheticEntry = {\n name: timing.name,\n ph: Types.Extensions.isExtensionPayloadMarker(extensionPayload) ? Types.Events.Phase.INSTANT :\n Types.Events.Phase.COMPLETE,\n pid: timing.pid,\n tid: timing.tid,\n ts: timing.ts,\n dur: timing.dur as Types.Timing.Micro,\n cat: 'devtools.extension',\n args: extensionPayload,\n rawSourceEvent: Types.Events.isSyntheticUserTiming(timing) ? timing.rawSourceEvent : timing,\n };\n\n if (Types.Extensions.isExtensionPayloadMarker(extensionPayload)) {\n const extensionMarker =\n Helpers.SyntheticEvents.SyntheticEventsManager\n .registerSyntheticEvent<Types.Extensions.SyntheticExtensionMarker>(\n extensionSyntheticEntry as Omit<Types.Extensions.SyntheticExtensionMarker, '_tag'>);\n extensionMarkers.push(extensionMarker);\n continue;\n }\n\n if (Types.Extensions.isExtensionPayloadTrackEntry(extensionSyntheticEntry.args)) {\n const extensionTrackEntry =\n Helpers.SyntheticEvents.SyntheticEventsManager\n .registerSyntheticEvent<Types.Extensions.SyntheticExtensionTrackEntry>(\n extensionSyntheticEntry as Omit<Types.Extensions.SyntheticExtensionTrackEntry, '_tag'>);\n extensionTrackEntries.push(extensionTrackEntry);\n continue;\n }\n }\n}\n\nfunction parseDetail(timingDetail: string, key: string): Types.Extensions.ExtensionDataPayload|\n Types.Extensions.ExtensionTrackEntryPayloadDeeplink|null {\n try {\n // Attempt to parse the detail as an object that might be coming from a\n // DevTools Perf extension.\n // Wrapped in a try-catch because timingDetail might either:\n // 1. Not be `json.parse`-able (it should, but just in case...)\n // 2.Not be an object - in which case the `in` check will error.\n // If we hit either of these cases, we just ignore this mark and move on.\n const detailObj = JSON.parse(timingDetail);\n if (!(key in detailObj)) {\n return null;\n }\n if (!Types.Extensions.isValidExtensionPayload(detailObj[key])) {\n return null;\n }\n return detailObj[key];\n } catch {\n // No need to worry about this error, just discard this event and don't\n // treat it as having any useful information for the purposes of extensions\n return null;\n }\n}\n\nfunction extensionPayloadForConsoleApi(timing: Types.Events.ConsoleTimeStamp):\n Types.Extensions.ExtensionTrackEntryPayloadDeeplink|null {\n if (!timing.args.data || !('devtools' in timing.args.data)) {\n return null;\n }\n\n return parseDetail(`{\"additionalContext\": ${timing.args.data.devtools} }`, 'additionalContext') as\n Types.Extensions.ExtensionTrackEntryPayloadDeeplink;\n}\n\nexport function extensionDataInPerformanceTiming(\n timing: Types.Events.SyntheticUserTimingPair|Types.Events.PerformanceMark): Types.Extensions.ExtensionDataPayload|\n null {\n const timingDetail =\n Types.Events.isPerformanceMark(timing) ? timing.args.data?.detail : timing.args.data.beginEvent.args.detail;\n if (!timingDetail) {\n return null;\n }\n return parseDetail(timingDetail, 'devtools') as Types.Extensions.ExtensionDataPayload;\n}\n\n/**\n * Extracts extension data from a `console.timeStamp` event.\n *\n * Checks if a `console.timeStamp` event contains data intended for\n * creating a custom track entry in the DevTools Performance panel. It\n * specifically looks for a `track` argument within the event's data.\n *\n * If a `track` argument is present (and not an empty string), the\n * function constructs an `ExtensionTrackEntryPayload` object containing\n * the track name, an optional color, an optional track group. This\n * payload is then used to create a `SyntheticExtensionTrackEntry`.\n *\n * **Note:** The `color` argument is optional and its type is validated\n * against a predefined palette (see\n * `ExtensionUI::extensionEntryColor`).\n *\n * @param timeStamp The `ConsoleTimeStamp` event to extract data from.\n * @returns An `ExtensionTrackEntryPayload` object if the event contains\n * valid extension data for a track entry, or `null` otherwise.\n */\nexport function extensionDataInConsoleTimeStamp(timeStamp: Types.Events.ConsoleTimeStamp):\n Types.Extensions.ExtensionTrackEntryPayload|null {\n if (!timeStamp.args.data) {\n return null;\n }\n const trackName = timeStamp.args.data.track;\n if (trackName === '' || trackName === undefined) {\n return null;\n }\n\n let additionalContext: Types.Extensions.ExtensionTrackEntryPayloadDeeplink|undefined;\n const payload = extensionPayloadForConsoleApi(timeStamp);\n if (payload) {\n additionalContext = payload;\n }\n\n return {\n // the color is defaulted to primary if it's value isn't one from\n // the defined palette (see ExtensionUI::extensionEntryColor) so\n // we don't need to check the value is valid here.\n color: String(timeStamp.args.data.color) as Types.Extensions.ExtensionTrackEntryPayload['color'],\n track: String(trackName),\n dataType: 'track-entry',\n trackGroup: timeStamp.args.data.trackGroup !== undefined ? String(timeStamp.args.data.trackGroup) : undefined,\n additionalContext\n };\n}\n\nexport function data(): ExtensionTraceData {\n return {\n entryToNode,\n extensionTrackData,\n extensionMarkers,\n syntheticConsoleEntriesForTimingsTrack,\n };\n}\n\nexport function deps(): HandlerName[] {\n return ['UserTimings'];\n}\n"]}
@@ -19,19 +19,50 @@ import * as Threads from './Threads.js';
19
19
  *
20
20
  * In time we expect to migrate this code to a more "typical" handler.
21
21
  */
22
- const allEvents = [];
23
22
  let model = null;
23
+ const relevantFrameEvents = [];
24
+ function isFrameEvent(event) {
25
+ return (Types.Events.isSetLayerId(event) || Types.Events.isBeginFrame(event) || Types.Events.isDroppedFrame(event) ||
26
+ Types.Events.isRequestMainThreadFrame(event) || Types.Events.isBeginMainThreadFrame(event) ||
27
+ Types.Events.isNeedsBeginFrameChanged(event) ||
28
+ // Note that "Commit" is the replacement for "CompositeLayers" so in a trace
29
+ // we wouldn't expect to see a combination of these. All "new" trace
30
+ // recordings use "Commit", but we can easily support "CompositeLayers" too
31
+ // to not break older traces being imported.
32
+ Types.Events.isCommit(event) || Types.Events.isCompositeLayers(event) ||
33
+ Types.Events.isActivateLayerTree(event) || Types.Events.isDrawFrame(event));
34
+ }
35
+ function entryIsTopLevel(entry) {
36
+ const devtoolsTimelineCategory = 'disabled-by-default-devtools.timeline';
37
+ return entry.name === Types.Events.Name.RUN_TASK && entry.cat.includes(devtoolsTimelineCategory);
38
+ }
39
+ const MAIN_FRAME_MARKERS = new Set([
40
+ Types.Events.Name.SCHEDULE_STYLE_RECALCULATION,
41
+ Types.Events.Name.INVALIDATE_LAYOUT,
42
+ Types.Events.Name.BEGIN_MAIN_THREAD_FRAME,
43
+ Types.Events.Name.SCROLL_LAYER,
44
+ ]);
24
45
  export function reset() {
25
- allEvents.length = 0;
46
+ model = null;
47
+ relevantFrameEvents.length = 0;
26
48
  }
27
49
  export function handleEvent(event) {
28
- allEvents.push(event);
50
+ // This might seem like a wide set of events to filter for, but these are all
51
+ // the types of events that we care about in the TimelineFrameModel class at
52
+ // the bottom of this file. Previously we would take a copy of an array of
53
+ // all trace events, but on a few test traces, this set of filtered events
54
+ // accounts for about 10% of the total events, so it's a big performance win
55
+ // to deal with a much smaller subset of the data.
56
+ if (isFrameEvent(event) || Types.Events.isLayerTreeHostImplSnapshot(event) || entryIsTopLevel(event) ||
57
+ MAIN_FRAME_MARKERS.has(event.name) || Types.Events.isPaint(event)) {
58
+ relevantFrameEvents.push(event);
59
+ }
29
60
  }
30
61
  export async function finalize() {
31
- // Snapshot events can be emitted out of order, so we need to sort before
32
- // building the frames model.
33
- Helpers.Trace.sortTraceEventsInPlace(allEvents);
34
- const modelForTrace = new TimelineFrameModel(allEvents, rendererHandlerData(), auctionWorkletsData(), metaHandlerData(), layerTreeHandlerData());
62
+ // We have to sort the events by timestamp, because the model code expects to
63
+ // process events in order.
64
+ Helpers.Trace.sortTraceEventsInPlace(relevantFrameEvents);
65
+ const modelForTrace = new TimelineFrameModel(relevantFrameEvents, rendererHandlerData(), auctionWorkletsData(), metaHandlerData(), layerTreeHandlerData());
35
66
  model = modelForTrace;
36
67
  }
37
68
  export function data() {
@@ -43,21 +74,6 @@ export function data() {
43
74
  export function deps() {
44
75
  return ['Meta', 'Renderer', 'AuctionWorklets', 'LayerTree'];
45
76
  }
46
- function isFrameEvent(event) {
47
- return (Types.Events.isSetLayerId(event) || Types.Events.isBeginFrame(event) || Types.Events.isDroppedFrame(event) ||
48
- Types.Events.isRequestMainThreadFrame(event) || Types.Events.isBeginMainThreadFrame(event) ||
49
- Types.Events.isNeedsBeginFrameChanged(event) ||
50
- // Note that "Commit" is the replacement for "CompositeLayers" so in a trace
51
- // we wouldn't expect to see a combination of these. All "new" trace
52
- // recordings use "Commit", but we can easily support "CompositeLayers" too
53
- // to not break older traces being imported.
54
- Types.Events.isCommit(event) || Types.Events.isCompositeLayers(event) ||
55
- Types.Events.isActivateLayerTree(event) || Types.Events.isDrawFrame(event));
56
- }
57
- function entryIsTopLevel(entry) {
58
- const devtoolsTimelineCategory = 'disabled-by-default-devtools.timeline';
59
- return entry.name === Types.Events.Name.RUN_TASK && entry.cat.includes(devtoolsTimelineCategory);
60
- }
61
77
  export class TimelineFrameModel {
62
78
  #frames = [];
63
79
  #frameById = {};
@@ -303,12 +319,6 @@ export class TimelineFrameModel {
303
319
  }
304
320
  }
305
321
  }
306
- const MAIN_FRAME_MARKERS = new Set([
307
- Types.Events.Name.SCHEDULE_STYLE_RECALCULATION,
308
- Types.Events.Name.INVALIDATE_LAYOUT,
309
- Types.Events.Name.BEGIN_MAIN_THREAD_FRAME,
310
- Types.Events.Name.SCROLL_LAYER,
311
- ]);
312
322
  /**
313
323
  * Legacy class that represents TimelineFrames that was ported from the old SDK.
314
324
  * This class is purposefully not exported as it breaks the abstraction that
@@ -1 +1 @@
1
- {"version":3,"file":"FramesHandler.js","sourceRoot":"","sources":["../../../../../../../front_end/models/trace/handlers/FramesHandler.ts"],"names":[],"mappings":"AAAA,4DAA4D;AAC5D,yEAAyE;AACzE,6BAA6B;AAE7B,OAAO,KAAK,QAAQ,MAAM,oCAAoC,CAAC;AAC/D,OAAO,KAAK,OAAO,MAAM,uBAAuB,CAAC;AACjD,OAAO,KAAK,KAAK,MAAM,mBAAmB,CAAC;AAE3C,OAAO,EAA2B,IAAI,IAAI,mBAAmB,EAAC,MAAM,6BAA6B,CAAC;AAClG,OAAO,EAAC,IAAI,IAAI,oBAAoB,EAAqB,MAAM,uBAAuB,CAAC;AACvF,OAAO,EAAC,IAAI,IAAI,eAAe,EAAuB,MAAM,kBAAkB,CAAC;AAC/E,OAAO,EAAC,IAAI,IAAI,mBAAmB,EAA2B,MAAM,sBAAsB,CAAC;AAC3F,OAAO,KAAK,OAAO,MAAM,cAAc,CAAC;AAGxC;;;;;;;;;GASG;AAEH,MAAM,SAAS,GAAyB,EAAE,CAAC;AAC3C,IAAI,KAAK,GAA4B,IAAI,CAAC;AAE1C,MAAM,UAAU,KAAK;IACnB,SAAS,CAAC,MAAM,GAAG,CAAC,CAAC;AACvB,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,KAAyB;IACnD,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;AACxB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,QAAQ;IAC5B,yEAAyE;IACzE,6BAA6B;IAC7B,OAAO,CAAC,KAAK,CAAC,sBAAsB,CAAC,SAAS,CAAC,CAAC;IAEhD,MAAM,aAAa,GAAG,IAAI,kBAAkB,CACxC,SAAS,EACT,mBAAmB,EAAE,EACrB,mBAAmB,EAAE,EACrB,eAAe,EAAE,EACjB,oBAAoB,EAAE,CACzB,CAAC;IACF,KAAK,GAAG,aAAa,CAAC;AACxB,CAAC;AAOD,MAAM,UAAU,IAAI;IAClB,OAAO;QACL,MAAM,EAAE,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE;QAC/C,UAAU,EAAE,KAAK,CAAC,CAAC,CAAC,EAAC,GAAG,KAAK,CAAC,UAAU,EAAE,EAAC,CAAC,CAAC,CAAC,EAAE;KACjD,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,IAAI;IAClB,OAAO,CAAC,MAAM,EAAE,UAAU,EAAE,iBAAiB,EAAE,WAAW,CAAC,CAAC;AAC9D,CAAC;AAMD,SAAS,YAAY,CAAC,KAAyB;IAC7C,OAAO,CACH,KAAK,CAAC,MAAM,CAAC,YAAY,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,YAAY,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,cAAc,CAAC,KAAK,CAAC;QAC1G,KAAK,CAAC,MAAM,CAAC,wBAAwB,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,sBAAsB,CAAC,KAAK,CAAC;QAC1F,KAAK,CAAC,MAAM,CAAC,wBAAwB,CAAC,KAAK,CAAC;QAC5C,4EAA4E;QAC5E,oEAAoE;QACpE,2EAA2E;QAC3E,4CAA4C;QAC5C,KAAK,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,iBAAiB,CAAC,KAAK,CAAC;QACrE,KAAK,CAAC,MAAM,CAAC,mBAAmB,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,CAAC;AAClF,CAAC;AAED,SAAS,eAAe,CAAC,KAAyB;IAChD,MAAM,wBAAwB,GAAG,uCAAuC,CAAC;IACzE,OAAO,KAAK,CAAC,IAAI,KAAK,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,IAAI,KAAK,CAAC,GAAG,CAAC,QAAQ,CAAC,wBAAwB,CAAC,CAAC;AACnG,CAAC;AAED,MAAM,OAAO,kBAAkB;IAC7B,OAAO,GAAoB,EAAE,CAAC;IAC9B,UAAU,GAAkC,EAAE,CAAC;IAC/C,gBAAgB,GAAiC,IAAI,4BAA4B,EAAE,CAAC;IACpF,UAAU,GAAuB,IAAI,CAAC;IACtC,mBAAmB,GAAG,KAAK,CAAC;IAC5B,mBAAmB,GAAG,KAAK,CAAC;IAC5B,cAAc,GAA+C,IAAI,CAAC;IAClE,uBAAuB,GAAsB,IAAI,CAAC;IAClD,mBAAmB,GAAsB,IAAI,CAAC;IAC9C,eAAe,GAAgB,IAAI,CAAC;IACpC,oBAAoB,GAAgB,IAAI,CAAC;IACzC,kBAAkB,GAA4B,IAAI,CAAC;IACnD,YAAY,GAAgB,IAAI,CAAC;IACjC,gBAAgB,GAAgC,IAAI,CAAC;IACrD,eAAe,GAA+B,IAAI,CAAC;IACnD,cAAc,CAAgB;IAE9B,YACI,SAAwC,EAAE,YAAiC,EAC3E,mBAAwC,EAAE,QAAyB,EAAE,aAA4B;QACnG,qEAAqE;QACrE,yEAAyE;QACzE,YAAY;QACZ,MAAM,WAAW,GAAG,OAAO,CAAC,iBAAiB,CAAC,YAAY,EAAE,mBAAmB,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE;YAC/F,OAAO,MAAM,CAAC,IAAI,KAAK,OAAO,CAAC,UAAU,CAAC,WAAW,IAAI,MAAM,CAAC,oBAAoB,CAAC;QACvF,CAAC,CAAC,CAAC;QACH,MAAM,UAAU,GAAG,WAAW,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE;YAC1C,OAAO;gBACL,GAAG,EAAE,MAAM,CAAC,GAAG;gBACf,GAAG,EAAE,MAAM,CAAC,GAAG;gBACf,SAAS,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE;aAChC,CAAC;QACJ,CAAC,CAAC,CAAC;QAEH,IAAI,CAAC,cAAc,GAAG,aAAa,CAAC;QACpC,IAAI,CAAC,eAAe,CAAC,SAAS,EAAE,UAAU,EAAE,QAAQ,CAAC,WAAW,CAAC,CAAC;IACpE,CAAC;IAED,UAAU;QACR,OAAO,IAAI,CAAC,UAAU,CAAC;IACzB,CAAC;IAED,MAAM;QACJ,OAAO,IAAI,CAAC,OAAO,CAAC;IACtB,CAAC;IAED,iBAAiB,CAAC,SAA6B,EAAE,KAAa;QAC5D,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC;YACrB,IAAI,CAAC,WAAW,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC;QACrC,CAAC;QACD,IAAI,CAAC,eAAe,GAAG,SAAS,CAAC;QAEjC,IAAI,CAAC,gBAAgB,CAAC,mBAAmB,CAAC,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC;IAC5E,CAAC;IAED,mBAAmB,CAAC,SAA6B,EAAE,KAAa,EAAE,SAAkB;QAClF,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC;YACrB,IAAI,CAAC,WAAW,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC;QACrC,CAAC;QAED,qEAAqE;QACrE,sEAAsE;QACtE,8BAA8B;QAC9B,IAAI,CAAC,gBAAgB,CAAC,mBAAmB,CAAC,KAAK,EAAE,SAAS,EAAE,IAAI,EAAE,SAAS,CAAC,CAAC;QAC7E,IAAI,CAAC,gBAAgB,CAAC,UAAU,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;QAC9C,IAAI,CAAC,gBAAgB,CAAC,UAAU,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC;IACrD,CAAC;IAED,gBAAgB,CAAC,SAA6B,EAAE,KAAa;QAC3D,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC;YACrB,IAAI,CAAC,WAAW,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC;YACnC,OAAO;QACT,CAAC;QAED,0CAA0C;QAC1C,8FAA8F;QAC9F,IAAI,IAAI,CAAC,mBAAmB,IAAI,CAAC,IAAI,CAAC,mBAAmB,EAAE,CAAC;YAC1D,IAAI,IAAI,CAAC,oBAAoB,EAAE,CAAC;gBAC9B,MAAM,WAAW,GAAG,IAAI,CAAC,uBAAuB,CAAC,CAAC,CAAC,IAAI,CAAC,uBAAuB,CAAC,WAAW,CAAC,CAAC;oBAC1C,CAAC,IAAI,CAAC,eAAe,IAAI,IAAI,CAAC,oBAAoB,CAAC,CAAC;gBACvG,IAAI,WAAW,GAAG,IAAI,CAAC,UAAU,CAAC,SAAS,EAAE,CAAC;oBAC5C,IAAI,CAAC,UAAU,CAAC,IAAI,GAAG,IAAI,CAAC;oBAC5B,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC;gBAC9B,CAAC;gBACD,IAAI,CAAC,oBAAoB,GAAG,IAAI,CAAC;YACnC,CAAC;YAED,MAAM,iBAAiB,GAAG,IAAI,CAAC,gBAAgB,CAAC,oCAAoC,CAAC,KAAK,CAAC,CAAC;YAE5F,gEAAgE;YAChE,KAAK,MAAM,KAAK,IAAI,iBAAiB,EAAE,CAAC;gBACtC,MAAM,eAAe,GAAG,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC;gBAE7C,mEAAmE;gBACnE,4DAA4D;gBAC5D,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC;gBACzC,IAAI,eAAe,IAAI,IAAI,CAAC,uBAAuB,EAAE,CAAC;oBACpD,IAAI,CAAC,mBAAmB,EAAE,CAAC;gBAC7B,CAAC;gBACD,IAAI,KAAK,CAAC,SAAS,EAAE,CAAC;oBACpB,IAAI,CAAC,UAAU,CAAC,OAAO,GAAG,IAAI,CAAC;gBACjC,CAAC;gBACD,IAAI,KAAK,CAAC,SAAS,EAAE,CAAC;oBACpB,IAAI,CAAC,UAAU,CAAC,SAAS,GAAG,IAAI,CAAC;gBACnC,CAAC;YACH,CAAC;QACH,CAAC;QACD,IAAI,CAAC,mBAAmB,GAAG,KAAK,CAAC;IACnC,CAAC;IAED,wBAAwB;QACtB,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC;YACrB,OAAO;QACT,CAAC;QACD,IAAI,IAAI,CAAC,uBAAuB,IAAI,CAAC,IAAI,CAAC,oBAAoB,EAAE,CAAC;YAC/D,IAAI,CAAC,mBAAmB,EAAE,CAAC;QAC7B,CAAC;IACH,CAAC;IAED,6BAA6B;QAC3B,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC;YACrB,OAAO;QACT,CAAC;QACD,IAAI,CAAC,mBAAmB,GAAG,IAAI,CAAC;IAClC,CAAC;IAED,aAAa;QACX,IAAI,CAAC,IAAI,CAAC,mBAAmB,EAAE,CAAC;YAC9B,OAAO;QACT,CAAC;QACD,IAAI,CAAC,uBAAuB,GAAG,IAAI,CAAC,mBAAmB,CAAC;QACxD,IAAI,CAAC,mBAAmB,GAAG,IAAI,CAAC;QAChC,IAAI,CAAC,mBAAmB,GAAG,KAAK,CAAC;QACjC,IAAI,CAAC,mBAAmB,GAAG,IAAI,CAAC;IAClC,CAAC;IAED,wBAAwB,CAAC,SAAgD;QACvE,IAAI,CAAC,cAAc,GAAG,SAAS,CAAC;IAClC,CAAC;IAED,uBAAuB,CAAC,SAA6B,EAAE,eAAwB;QAC7E,IAAI,eAAe,EAAE,CAAC;YACpB,IAAI,CAAC,oBAAoB,GAAG,SAAS,CAAC;QACxC,CAAC;IACH,CAAC;IAED,WAAW,CAAC,SAA6B,EAAE,KAAa;QACtD,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;YACpB,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,UAAU,EAAE,SAAS,CAAC,CAAC;QAC/C,CAAC;QACD,IAAI,CAAC,UAAU;YACX,IAAI,aAAa,CAAC,KAAK,EAAE,SAAS,EAAE,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,SAAS,GAAG,eAAe,EAAE,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC;IAC7G,CAAC;IAED,WAAW,CAAC,KAAoB,EAAE,OAA2B;QAC3D,KAAK,CAAC,YAAY,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;QACxC,KAAK,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC;QAC1B,IAAI,IAAI,CAAC,cAAc,EAAE,CAAC;YACxB,IAAI,CAAC,cAAc,CAAC,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC;QAC5C,CAAC;QACD,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;QACxD,IAAI,IAAI,CAAC,OAAO,CAAC,MAAM,IAAI,SAAS;YAChC,CAAC,KAAK,CAAC,SAAS,KAAK,SAAS,CAAC,OAAO,IAAI,KAAK,CAAC,SAAS,GAAG,KAAK,CAAC,OAAO,CAAC,EAAE,CAAC;YAC/E,OAAO,CAAC,MAAM,CACV,KAAK,EAAE,qCAAqC,IAAI,CAAC,OAAO,CAAC,MAAM,KAAK,KAAK,CAAC,SAAS,MAAM,KAAK,CAAC,OAAO,GAAG,CAAC,CAAC;QACjH,CAAC;QACD,MAAM,eAAe,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACjD,KAAK,CAAC,QAAQ,CAAC,eAAe,GAAG,CAAC,CAAC,CAAC;QACpC,IAAI,OAAO,KAAK,CAAC,WAAW,KAAK,QAAQ,EAAE,CAAC;YAC1C,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,WAAW,CAAC,GAAG,KAAK,CAAC;QAC7C,CAAC;IACH,CAAC;IAED,mBAAmB;QACjB,IAAI,CAAC,IAAI,CAAC,uBAAuB,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC;YACtD,OAAO;QACT,CAAC;QAED,IAAI,CAAC,UAAU,CAAC,MAAM,GAAG,IAAI,CAAC,uBAAuB,CAAC,MAAM,CAAC;QAC7D,IAAI,CAAC,UAAU,CAAC,WAAW,GAAG,IAAI,CAAC,uBAAuB,CAAC,WAAW,CAAC;QACvE,IAAI,CAAC,uBAAuB,GAAG,IAAI,CAAC;IACtC,CAAC;IAED,eAAe,CACX,MAAqC,EAAE,UAIrC,EACF,WAAmB;QACrB,IAAI,CAAC,GAAG,CAAC,CAAC;QACV,IAAI,CAAC,eAAe,GAAG,UAAU,CAAC,MAAM,IAAI,UAAU,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,IAAI,CAAC;QACtE,IAAI,CAAC,gBAAgB,GAAG,UAAU,CAAC,MAAM,IAAI,UAAU,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,IAAI,CAAC;QACvE,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,EAAE,CAAC,EAAE,CAAC;YACvC,OAAO,CAAC,GAAG,CAAC,GAAG,UAAU,CAAC,MAAM,IAAI,UAAU,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,SAAS,IAAI,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;gBAChF,IAAI,CAAC,eAAe,GAAG,UAAU,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC;gBAC3C,IAAI,CAAC,gBAAgB,GAAG,UAAU,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC;YAC5C,CAAC;YACD,IAAI,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,WAAW,CAAC,CAAC;QAC9C,CAAC;QACD,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC;QAC5B,IAAI,CAAC,gBAAgB,GAAG,IAAI,CAAC;IAC/B,CAAC;IAED,cAAc,CAAC,KAAyB,EAAE,WAAmB;QAC3D,IAAI,KAAK,CAAC,MAAM,CAAC,YAAY,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,KAAK,WAAW,EAAE,CAAC;YAC9E,IAAI,CAAC,YAAY,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC;QAClD,CAAC;aAAM,IAAI,KAAK,CAAC,MAAM,CAAC,2BAA2B,CAAC,KAAK,CAAC,IAAI,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,IAAI,CAAC,YAAY,EAAE,CAAC;YACrG,IAAI,CAAC,wBAAwB,CAAC;gBAC5B,KAAK,EAAE,KAAK;gBACZ,MAAM,EAAE,EAAE;aACX,CAAC,CAAC;QACL,CAAC;aAAM,CAAC;YACN,IAAI,YAAY,CAAC,KAAK,CAAC,EAAE,CAAC;gBACxB,IAAI,CAAC,wBAAwB,CAAC,KAAK,CAAC,CAAC;YACvC,CAAC;YACD,yEAAyE;YACzE,8DAA8D;YAC9D,IAAI,KAAK,CAAC,GAAG,KAAK,IAAI,CAAC,eAAe,IAAI,KAAK,CAAC,GAAG,KAAK,IAAI,CAAC,gBAAgB,EAAE,CAAC;gBAC9E,IAAI,CAAC,wBAAwB,CAAC,KAAK,CAAC,CAAC;YACvC,CAAC;QACH,CAAC;IACH,CAAC;IAED,wBAAwB,CAAC,KAAiB;QACxC,IAAI,KAAK,CAAC,IAAI,CAAC,aAAa,CAAC,KAAK,IAAI,CAAC,YAAY,EAAE,CAAC;YACpD,OAAO;QACT,CAAC;QACD,IAAI,KAAK,CAAC,MAAM,CAAC,YAAY,CAAC,KAAK,CAAC,EAAE,CAAC;YACrC,IAAI,CAAC,iBAAiB,CAAC,KAAK,CAAC,EAAE,EAAE,KAAK,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC;QAC7D,CAAC;aAAM,IAAI,KAAK,CAAC,MAAM,CAAC,WAAW,CAAC,KAAK,CAAC,EAAE,CAAC;YAC3C,IAAI,CAAC,gBAAgB,CAAC,KAAK,CAAC,EAAE,EAAE,KAAK,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC;QAC5D,CAAC;aAAM,IAAI,KAAK,CAAC,MAAM,CAAC,mBAAmB,CAAC,KAAK,CAAC,EAAE,CAAC;YACnD,IAAI,CAAC,wBAAwB,EAAE,CAAC;QAClC,CAAC;aAAM,IAAI,KAAK,CAAC,MAAM,CAAC,wBAAwB,CAAC,KAAK,CAAC,EAAE,CAAC;YACxD,IAAI,CAAC,6BAA6B,EAAE,CAAC;QACvC,CAAC;aAAM,IAAI,KAAK,CAAC,MAAM,CAAC,wBAAwB,CAAC,KAAK,CAAC,EAAE,CAAC;YACxD,mEAAmE;YACnE,wDAAwD;YACxD,IAAI,CAAC,uBAAuB,CAAC,KAAK,CAAC,EAAE,EAAE,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC;QAC/G,CAAC;aAAM,IAAI,KAAK,CAAC,MAAM,CAAC,cAAc,CAAC,KAAK,CAAC,EAAE,CAAC;YAC9C,IAAI,CAAC,mBAAmB,CAAC,KAAK,CAAC,EAAE,EAAE,KAAK,CAAC,IAAI,CAAC,YAAY,CAAC,EAAE,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC,CAAC,CAAC;QACxG,CAAC;IACH,CAAC;IAED,wBAAwB,CAAC,KAAyB;QAChD,IAAI,eAAe,CAAC,KAAK,CAAC,EAAE,CAAC;YAC3B,IAAI,CAAC,kBAAkB,GAAG,KAAK,CAAC,EAAE,CAAC;QACrC,CAAC;QACD,IAAI,CAAC,IAAI,CAAC,mBAAmB,IAAI,kBAAkB,CAAC,GAAG,CAAC,KAAK,CAAC,IAAyB,CAAC,EAAE,CAAC;YACzF,IAAI,CAAC,mBAAmB,GAAG,IAAI,YAAY,CAAC,IAAI,CAAC,kBAAkB,IAAI,KAAK,CAAC,EAAE,CAAC,CAAC;QACnF,CAAC;QACD,IAAI,CAAC,IAAI,CAAC,mBAAmB,EAAE,CAAC;YAC9B,OAAO;QACT,CAAC;QAED,IAAI,KAAK,CAAC,MAAM,CAAC,sBAAsB,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC;YAC1E,IAAI,CAAC,mBAAmB,CAAC,WAAW,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC;QACjE,CAAC;QACD,IAAI,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;YAChC,MAAM,QAAQ,GAAG,IAAI,CAAC,cAAc,CAAC,iBAAiB,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;YAClE,IAAI,QAAQ,EAAE,CAAC;gBACb,IAAI,CAAC,mBAAmB,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,eAAe,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC,CAAC;YAC7E,CAAC;QACH,CAAC;QACD,uEAAuE;QACvE,sCAAsC;QACtC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,iBAAiB,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;YACvE,KAAK,CAAC,IAAI,CAAC,aAAa,CAAC,KAAK,IAAI,CAAC,YAAY,EAAE,CAAC;YACpD,IAAI,CAAC,aAAa,EAAE,CAAC;QACvB,CAAC;IACH,CAAC;CACF;AAED,MAAM,kBAAkB,GAAG,IAAI,GAAG,CAAoB;IACpD,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,4BAA4B;IAC9C,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,iBAAiB;IACnC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,uBAAuB;IACzC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,YAAY;CAC/B,CAAC,CAAC;AAEH;;;;;;GAMG;AACH,MAAM,aAAa;IACjB,8DAA8D;IAC9D,2EAA2E;IAC3E,6DAA6D;IAC7D,sBAAsB;IACtB,GAAG,GAAG,uBAAuB,CAAC;IAC9B,IAAI,GAAG,OAAO,CAAC;IACf,EAAE,GAAG,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC;IACjC,EAAE,CAAqB;IACvB,GAAG,GAAG,KAAK,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC;IACjC,GAAG,GAAG,KAAK,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC;IAEhC,KAAK,GAAG,CAAC,CAAC,CAAC;IACX,SAAS,CAAqB;IAC9B,eAAe,CAAqB;IACpC,OAAO,CAAqB;IAC5B,QAAQ,CAAqB;IAC7B,IAAI,CAAU;IACd,OAAO,CAAU;IACjB,SAAS,CAAU;IACnB,SAAS,CAA6C;IACtD,MAAM,CAAoB;IAC1B,WAAW,CAAmB;IACrB,KAAK,CAAS;IAEvB,YAAY,KAAa,EAAE,SAA6B,EAAE,eAAmC;QAC3F,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;QACnB,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;QAC3B,IAAI,CAAC,EAAE,GAAG,SAAS,CAAC;QACpB,IAAI,CAAC,eAAe,GAAG,eAAe,CAAC;QACvC,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,SAAS,CAAC;QAC9B,IAAI,CAAC,QAAQ,GAAG,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QACtC,IAAI,CAAC,IAAI,GAAG,KAAK,CAAC;QAClB,IAAI,CAAC,OAAO,GAAG,KAAK,CAAC;QACrB,IAAI,CAAC,SAAS,GAAG,KAAK,CAAC;QACvB,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC;QACtB,IAAI,CAAC,MAAM,GAAG,EAAE,CAAC;QACjB,IAAI,CAAC,WAAW,GAAG,SAAS,CAAC;IAC/B,CAAC;IAED,QAAQ,CAAC,CAAS;QAChB,IAAI,CAAC,KAAK,GAAG,CAAC,CAAC;IACjB,CAAC;IAED,UAAU,CAAC,OAA2B;QACpC,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;QACvB,IAAI,CAAC,QAAQ,GAAG,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC;IACpE,CAAC;IAED,YAAY,CAAC,SAAqD;QAChE,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;IAC7B,CAAC;IAED;;;OAGG;IACH,IAAI,GAAG;QACL,OAAO,IAAI,CAAC,QAAQ,CAAC;IACvB,CAAC;CACF;AAED,MAAM,OAAO,eAAe;IACjB,MAAM,CAAqB;IACpC,SAAS,CAAuC;IAEhD,YAAY,KAAyB,EAAE,QAA8C;QACnF,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC;QACpB,IAAI,CAAC,SAAS,GAAG,QAAQ,CAAC;IAC5B,CAAC;IAED,OAAO;QACL,OAAO,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC;IACvC,CAAC;IAED,KAAK;QACH,OAAO,IAAI,CAAC,MAAM,CAAC;IACrB,CAAC;IAED,OAAO;QACL,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,UAAU,CAAC;QAC7D,MAAM,WAAW,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC;QACvD,OAAO,IAAI,IAAI,WAAW,CAAC,CAAC,CAAC,EAAC,IAAI,EAAE,iBAAiB,EAAE,WAAW,EAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IAC7E,CAAC;CACF;AAED,MAAM,OAAO,YAAY;IACvB,MAAM,CAAoB;IAC1B,WAAW,CAAmB;IAC9B,WAAW,CAAS;IACpB,YAAY,WAAmB;QAC7B,IAAI,CAAC,MAAM,GAAG,EAAE,CAAC;QACjB,IAAI,CAAC,WAAW,GAAG,SAAS,CAAC;QAC7B,IAAI,CAAC,WAAW,GAAG,WAAW,CAAC;IACjC,CAAC;CACF;AAED,6CAA6C;AAC7C,MAAM,cAAc;IAClB,KAAK,CAAS;IACd,SAAS,CAAqB;IAC9B,SAAS,CAAU;IACnB,SAAS,CAAU;IACnB,YAAY,KAAa,EAAE,SAA6B,EAAE,SAAkB,EAAE,SAAkB;QAC9F,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;QACnB,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;QAC3B,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;QAC3B,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;IAC7B,CAAC;CACF;AAED,gDAAgD;AAChD,wEAAwE;AACxE,gFAAgF;AAChF,kEAAkE;AAClE,MAAM,OAAO,4BAA4B;IAC/B,WAAW,GAAa,EAAE,CAAC;IAEnC,qCAAqC;IAC7B,SAAS,GAAmC,EAAE,CAAC;IAEvD,8DAA8D;IAC9D,mBAAmB,CAAC,KAAa,EAAE,SAA6B,EAAE,SAAkB,EAAE,SAAkB;QACtG,IAAI,CAAC,CAAC,KAAK,IAAI,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC;YAC/B,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,GAAG,IAAI,cAAc,CAAC,KAAK,EAAE,SAAS,EAAE,SAAS,EAAE,SAAS,CAAC,CAAC;YACnF,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAC/B,CAAC;IACH,CAAC;IAED,wCAAwC;IACxC,UAAU,CAAC,KAAa,EAAE,SAAkB;QAC1C,IAAI,KAAK,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;YAC5B,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,SAAS,GAAG,SAAS,CAAC;QAC9C,CAAC;IACH,CAAC;IAED,UAAU,CAAC,KAAa,EAAE,SAAkB;QAC1C,IAAI,KAAK,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;YAC5B,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,SAAS,GAAG,SAAS,CAAC;QAC9C,CAAC;IACH,CAAC;IAED,oCAAoC,CAAC,KAAa;QAChD,MAAM,iBAAiB,GAAqB,EAAE,CAAC;QAE/C,2EAA2E;QAC3E,4CAA4C;QAC5C,IAAI,KAAK,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;YAC5B,yEAAyE;YACzE,iCAAiC;YACjC,gEAAgE;YAChE,6DAA6D;YAC7D,yEAAyE;YACzE,4DAA4D;YAC5D,OAAO,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,KAAK,KAAK,EAAE,CAAC;gBACrC,MAAM,YAAY,GAAG,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;gBACzC,IAAI,IAAI,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC,SAAS,EAAE,CAAC;oBAC3C,iBAAiB,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC,CAAC;gBACvD,CAAC;gBAED,OAAO,IAAI,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC;gBACpC,IAAI,CAAC,WAAW,CAAC,KAAK,EAAE,CAAC;YAC3B,CAAC;YAED,4DAA4D;YAC5D,iBAAiB,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC;YAC9C,OAAO,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;YAC7B,IAAI,CAAC,WAAW,CAAC,KAAK,EAAE,CAAC;QAC3B,CAAC;QACD,OAAO,iBAAiB,CAAC;IAC3B,CAAC;CACF;AAED,MAAM,UAAU,kBAAkB,CAC9B,MAAmD,EAAE,SAA6B,EAClF,OAA2B;IAC7B,MAAM,UAAU,GAAG,QAAQ,CAAC,cAAc,CAAC,UAAU,CAAC,MAAM,EAAE,SAAS,IAAI,CAAC,EAAE,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC,IAAI,GAAG,KAAK,CAAC,OAAO,CAAC,CAAC;IACrH,MAAM,SAAS,GACX,QAAQ,CAAC,cAAc,CAAC,UAAU,CAAC,MAAM,EAAE,OAAO,IAAI,QAAQ,EAAE,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC,IAAI,GAAG,KAAK,CAAC,SAAS,CAAC,CAAC;IAC7G,OAAO,MAAM,CAAC,KAAK,CAAC,UAAU,EAAE,SAAS,CAAC,CAAC;AAC7C,CAAC","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 Platform from '../../../core/platform/platform.js';\nimport * as Helpers from '../helpers/helpers.js';\nimport * as Types from '../types/types.js';\n\nimport {type AuctionWorkletsData, data as auctionWorkletsData} from './AuctionWorkletsHandler.js';\nimport {data as layerTreeHandlerData, type LayerTreeData} from './LayerTreeHandler.js';\nimport {data as metaHandlerData, type MetaHandlerData} from './MetaHandler.js';\nimport {data as rendererHandlerData, type RendererHandlerData} from './RendererHandler.js';\nimport * as Threads from './Threads.js';\nimport type {HandlerName} from './types.js';\n\n/**\n * IMPORTANT: this handler is slightly different to the rest. This is because\n * it is an adaptation of the TimelineFrameModel that has been used in DevTools\n * for many years. Rather than re-implement all the logic from scratch, instead\n * this handler gathers up the events and instantitates the class in the\n * finalize() method. Once the class has parsed all events, it is used to then\n * return the array of frames.\n *\n * In time we expect to migrate this code to a more \"typical\" handler.\n */\n\nconst allEvents: Types.Events.Event[] = [];\nlet model: TimelineFrameModel|null = null;\n\nexport function reset(): void {\n allEvents.length = 0;\n}\n\nexport function handleEvent(event: Types.Events.Event): void {\n allEvents.push(event);\n}\n\nexport async function finalize(): Promise<void> {\n // Snapshot events can be emitted out of order, so we need to sort before\n // building the frames model.\n Helpers.Trace.sortTraceEventsInPlace(allEvents);\n\n const modelForTrace = new TimelineFrameModel(\n allEvents,\n rendererHandlerData(),\n auctionWorkletsData(),\n metaHandlerData(),\n layerTreeHandlerData(),\n );\n model = modelForTrace;\n}\n\nexport interface FramesData {\n frames: readonly Types.Events.LegacyTimelineFrame[];\n framesById: Readonly<Record<number, Types.Events.LegacyTimelineFrame|undefined>>;\n}\n\nexport function data(): FramesData {\n return {\n frames: model ? Array.from(model.frames()) : [],\n framesById: model ? {...model.framesById()} : {},\n };\n}\n\nexport function deps(): HandlerName[] {\n return ['Meta', 'Renderer', 'AuctionWorklets', 'LayerTree'];\n}\n\ntype FrameEvent = Types.Events.BeginFrame|Types.Events.DroppedFrame|Types.Events.RequestMainThreadFrame|\n Types.Events.BeginMainThreadFrame|Types.Events.Commit|Types.Events.CompositeLayers|\n Types.Events.ActivateLayerTree|Types.Events.NeedsBeginFrameChanged|Types.Events.DrawFrame;\n\nfunction isFrameEvent(event: Types.Events.Event): event is FrameEvent {\n return (\n Types.Events.isSetLayerId(event) || Types.Events.isBeginFrame(event) || Types.Events.isDroppedFrame(event) ||\n Types.Events.isRequestMainThreadFrame(event) || Types.Events.isBeginMainThreadFrame(event) ||\n Types.Events.isNeedsBeginFrameChanged(event) ||\n // Note that \"Commit\" is the replacement for \"CompositeLayers\" so in a trace\n // we wouldn't expect to see a combination of these. All \"new\" trace\n // recordings use \"Commit\", but we can easily support \"CompositeLayers\" too\n // to not break older traces being imported.\n Types.Events.isCommit(event) || Types.Events.isCompositeLayers(event) ||\n Types.Events.isActivateLayerTree(event) || Types.Events.isDrawFrame(event));\n}\n\nfunction entryIsTopLevel(entry: Types.Events.Event): boolean {\n const devtoolsTimelineCategory = 'disabled-by-default-devtools.timeline';\n return entry.name === Types.Events.Name.RUN_TASK && entry.cat.includes(devtoolsTimelineCategory);\n}\n\nexport class TimelineFrameModel {\n #frames: TimelineFrame[] = [];\n #frameById: Record<number, TimelineFrame> = {};\n #beginFrameQueue: TimelineFrameBeginFrameQueue = new TimelineFrameBeginFrameQueue();\n #lastFrame: TimelineFrame|null = null;\n #mainFrameCommitted = false;\n #mainFrameRequested = false;\n #lastLayerTree: Types.Events.LegacyFrameLayerTreeData|null = null;\n #framePendingActivation: PendingFrame|null = null;\n #framePendingCommit: PendingFrame|null = null;\n #lastBeginFrame: number|null = null;\n #lastNeedsBeginFrame: number|null = null;\n #lastTaskBeginTime: Types.Timing.Micro|null = null;\n #layerTreeId: number|null = null;\n #activeProcessId: Types.Events.ProcessID|null = null;\n #activeThreadId: Types.Events.ThreadID|null = null;\n #layerTreeData: LayerTreeData;\n\n constructor(\n allEvents: readonly Types.Events.Event[], rendererData: RendererHandlerData,\n auctionWorkletsData: AuctionWorkletsData, metaData: MetaHandlerData, layerTreeData: LayerTreeData) {\n // We only care about getting threads from the Renderer, not Samples,\n // because Frames don't exist in a CPU Profile (which won't have Renderer\n // threads.)\n const mainThreads = Threads.threadsInRenderer(rendererData, auctionWorkletsData).filter(thread => {\n return thread.type === Threads.ThreadType.MAIN_THREAD && thread.processIsOnMainFrame;\n });\n const threadData = mainThreads.map(thread => {\n return {\n tid: thread.tid,\n pid: thread.pid,\n startTime: thread.entries[0].ts,\n };\n });\n\n this.#layerTreeData = layerTreeData;\n this.#addTraceEvents(allEvents, threadData, metaData.mainFrameId);\n }\n\n framesById(): Readonly<Record<number, TimelineFrame|undefined>> {\n return this.#frameById;\n }\n\n frames(): TimelineFrame[] {\n return this.#frames;\n }\n\n #handleBeginFrame(startTime: Types.Timing.Micro, seqId: number): void {\n if (!this.#lastFrame) {\n this.#startFrame(startTime, seqId);\n }\n this.#lastBeginFrame = startTime;\n\n this.#beginFrameQueue.addFrameIfNotExists(seqId, startTime, false, false);\n }\n\n #handleDroppedFrame(startTime: Types.Timing.Micro, seqId: number, isPartial: boolean): void {\n if (!this.#lastFrame) {\n this.#startFrame(startTime, seqId);\n }\n\n // This line handles the case where no BeginFrame event is issued for\n // the dropped frame. In this situation, add a BeginFrame to the queue\n // as if it actually occurred.\n this.#beginFrameQueue.addFrameIfNotExists(seqId, startTime, true, isPartial);\n this.#beginFrameQueue.setDropped(seqId, true);\n this.#beginFrameQueue.setPartial(seqId, isPartial);\n }\n\n #handleDrawFrame(startTime: Types.Timing.Micro, seqId: number): void {\n if (!this.#lastFrame) {\n this.#startFrame(startTime, seqId);\n return;\n }\n\n // - if it wasn't drawn, it didn't happen!\n // - only show frames that either did not wait for the main thread frame or had one committed.\n if (this.#mainFrameCommitted || !this.#mainFrameRequested) {\n if (this.#lastNeedsBeginFrame) {\n const idleTimeEnd = this.#framePendingActivation ? this.#framePendingActivation.triggerTime :\n (this.#lastBeginFrame || this.#lastNeedsBeginFrame);\n if (idleTimeEnd > this.#lastFrame.startTime) {\n this.#lastFrame.idle = true;\n this.#lastBeginFrame = null;\n }\n this.#lastNeedsBeginFrame = null;\n }\n\n const framesToVisualize = this.#beginFrameQueue.processPendingBeginFramesOnDrawFrame(seqId);\n\n // Visualize the current frame and all pending frames before it.\n for (const frame of framesToVisualize) {\n const isLastFrameIdle = this.#lastFrame.idle;\n\n // If |frame| is the first frame after an idle period, the CPU time\n // will be logged (\"committed\") under |frame| if applicable.\n this.#startFrame(frame.startTime, seqId);\n if (isLastFrameIdle && this.#framePendingActivation) {\n this.#commitPendingFrame();\n }\n if (frame.isDropped) {\n this.#lastFrame.dropped = true;\n }\n if (frame.isPartial) {\n this.#lastFrame.isPartial = true;\n }\n }\n }\n this.#mainFrameCommitted = false;\n }\n\n #handleActivateLayerTree(): void {\n if (!this.#lastFrame) {\n return;\n }\n if (this.#framePendingActivation && !this.#lastNeedsBeginFrame) {\n this.#commitPendingFrame();\n }\n }\n\n #handleRequestMainThreadFrame(): void {\n if (!this.#lastFrame) {\n return;\n }\n this.#mainFrameRequested = true;\n }\n\n #handleCommit(): void {\n if (!this.#framePendingCommit) {\n return;\n }\n this.#framePendingActivation = this.#framePendingCommit;\n this.#framePendingCommit = null;\n this.#mainFrameRequested = false;\n this.#mainFrameCommitted = true;\n }\n\n #handleLayerTreeSnapshot(layerTree: Types.Events.LegacyFrameLayerTreeData): void {\n this.#lastLayerTree = layerTree;\n }\n\n #handleNeedFrameChanged(startTime: Types.Timing.Micro, needsBeginFrame: boolean): void {\n if (needsBeginFrame) {\n this.#lastNeedsBeginFrame = startTime;\n }\n }\n\n #startFrame(startTime: Types.Timing.Micro, seqId: number): void {\n if (this.#lastFrame) {\n this.#flushFrame(this.#lastFrame, startTime);\n }\n this.#lastFrame =\n new TimelineFrame(seqId, startTime, Types.Timing.Micro(startTime - metaHandlerData().traceBounds.min));\n }\n\n #flushFrame(frame: TimelineFrame, endTime: Types.Timing.Micro): void {\n frame.setLayerTree(this.#lastLayerTree);\n frame.setEndTime(endTime);\n if (this.#lastLayerTree) {\n this.#lastLayerTree.paints = frame.paints;\n }\n const lastFrame = this.#frames[this.#frames.length - 1];\n if (this.#frames.length && lastFrame &&\n (frame.startTime !== lastFrame.endTime || frame.startTime > frame.endTime)) {\n console.assert(\n false, `Inconsistent frame time for frame ${this.#frames.length} (${frame.startTime} - ${frame.endTime})`);\n }\n const newFramesLength = this.#frames.push(frame);\n frame.setIndex(newFramesLength - 1);\n if (typeof frame.mainFrameId === 'number') {\n this.#frameById[frame.mainFrameId] = frame;\n }\n }\n\n #commitPendingFrame(): void {\n if (!this.#framePendingActivation || !this.#lastFrame) {\n return;\n }\n\n this.#lastFrame.paints = this.#framePendingActivation.paints;\n this.#lastFrame.mainFrameId = this.#framePendingActivation.mainFrameId;\n this.#framePendingActivation = null;\n }\n\n #addTraceEvents(\n events: readonly Types.Events.Event[], threadData: Array<{\n pid: Types.Events.ProcessID,\n tid: Types.Events.ThreadID,\n startTime: Types.Timing.Micro,\n }>,\n mainFrameId: string): void {\n let j = 0;\n this.#activeThreadId = threadData.length && threadData[0].tid || null;\n this.#activeProcessId = threadData.length && threadData[0].pid || null;\n for (let i = 0; i < events.length; ++i) {\n while (j + 1 < threadData.length && threadData[j + 1].startTime <= events[i].ts) {\n this.#activeThreadId = threadData[++j].tid;\n this.#activeProcessId = threadData[j].pid;\n }\n this.#addTraceEvent(events[i], mainFrameId);\n }\n this.#activeThreadId = null;\n this.#activeProcessId = null;\n }\n\n #addTraceEvent(event: Types.Events.Event, mainFrameId: string): void {\n if (Types.Events.isSetLayerId(event) && event.args.data.frame === mainFrameId) {\n this.#layerTreeId = event.args.data.layerTreeId;\n } else if (Types.Events.isLayerTreeHostImplSnapshot(event) && Number(event.id) === this.#layerTreeId) {\n this.#handleLayerTreeSnapshot({\n entry: event,\n paints: [],\n });\n } else {\n if (isFrameEvent(event)) {\n this.#processCompositorEvents(event);\n }\n // Make sure we only use events from the main thread: we check the PID as\n // well in case two processes have a thread with the same TID.\n if (event.tid === this.#activeThreadId && event.pid === this.#activeProcessId) {\n this.#addMainThreadTraceEvent(event);\n }\n }\n }\n\n #processCompositorEvents(entry: FrameEvent): void {\n if (entry.args['layerTreeId'] !== this.#layerTreeId) {\n return;\n }\n if (Types.Events.isBeginFrame(entry)) {\n this.#handleBeginFrame(entry.ts, entry.args['frameSeqId']);\n } else if (Types.Events.isDrawFrame(entry)) {\n this.#handleDrawFrame(entry.ts, entry.args['frameSeqId']);\n } else if (Types.Events.isActivateLayerTree(entry)) {\n this.#handleActivateLayerTree();\n } else if (Types.Events.isRequestMainThreadFrame(entry)) {\n this.#handleRequestMainThreadFrame();\n } else if (Types.Events.isNeedsBeginFrameChanged(entry)) {\n // needsBeginFrame property will either be 0 or 1, which represents\n // true/false in this case, hence the Boolean() wrapper.\n this.#handleNeedFrameChanged(entry.ts, entry.args['data'] && Boolean(entry.args['data']['needsBeginFrame']));\n } else if (Types.Events.isDroppedFrame(entry)) {\n this.#handleDroppedFrame(entry.ts, entry.args['frameSeqId'], Boolean(entry.args['hasPartialUpdate']));\n }\n }\n\n #addMainThreadTraceEvent(entry: Types.Events.Event): void {\n if (entryIsTopLevel(entry)) {\n this.#lastTaskBeginTime = entry.ts;\n }\n if (!this.#framePendingCommit && MAIN_FRAME_MARKERS.has(entry.name as Types.Events.Name)) {\n this.#framePendingCommit = new PendingFrame(this.#lastTaskBeginTime || entry.ts);\n }\n if (!this.#framePendingCommit) {\n return;\n }\n\n if (Types.Events.isBeginMainThreadFrame(entry) && entry.args.data.frameId) {\n this.#framePendingCommit.mainFrameId = entry.args.data.frameId;\n }\n if (Types.Events.isPaint(entry)) {\n const snapshot = this.#layerTreeData.paintsToSnapshots.get(entry);\n if (snapshot) {\n this.#framePendingCommit.paints.push(new LayerPaintEvent(entry, snapshot));\n }\n }\n // Commit will be replacing CompositeLayers but CompositeLayers is kept\n // around for backwards compatibility.\n if ((Types.Events.isCompositeLayers(entry) || Types.Events.isCommit(entry)) &&\n entry.args['layerTreeId'] === this.#layerTreeId) {\n this.#handleCommit();\n }\n }\n}\n\nconst MAIN_FRAME_MARKERS = new Set<Types.Events.Name>([\n Types.Events.Name.SCHEDULE_STYLE_RECALCULATION,\n Types.Events.Name.INVALIDATE_LAYOUT,\n Types.Events.Name.BEGIN_MAIN_THREAD_FRAME,\n Types.Events.Name.SCROLL_LAYER,\n]);\n\n/**\n * Legacy class that represents TimelineFrames that was ported from the old SDK.\n * This class is purposefully not exported as it breaks the abstraction that\n * every event shown on the timeline is a trace event. Instead, we use the Type\n * LegacyTimelineFrame to represent frames in the codebase. These do implement\n * the right interface to be treated just like they were a trace event.\n */\nclass TimelineFrame implements Types.Events.LegacyTimelineFrame {\n // These fields exist to satisfy the base Event type which all\n // \"trace events\" must implement. They aren't used, but doing this means we\n // can pass `TimelineFrame` instances into places that expect\n // Types.Events.Event.\n cat = 'devtools.legacy_frame';\n name = 'frame';\n ph = Types.Events.Phase.COMPLETE;\n ts: Types.Timing.Micro;\n pid = Types.Events.ProcessID(-1);\n tid = Types.Events.ThreadID(-1);\n\n index = -1;\n startTime: Types.Timing.Micro;\n startTimeOffset: Types.Timing.Micro;\n endTime: Types.Timing.Micro;\n duration: Types.Timing.Micro;\n idle: boolean;\n dropped: boolean;\n isPartial: boolean;\n layerTree: Types.Events.LegacyFrameLayerTreeData|null;\n paints: LayerPaintEvent[];\n mainFrameId: number|undefined;\n readonly seqId: number;\n\n constructor(seqId: number, startTime: Types.Timing.Micro, startTimeOffset: Types.Timing.Micro) {\n this.seqId = seqId;\n this.startTime = startTime;\n this.ts = startTime;\n this.startTimeOffset = startTimeOffset;\n this.endTime = this.startTime;\n this.duration = Types.Timing.Micro(0);\n this.idle = false;\n this.dropped = false;\n this.isPartial = false;\n this.layerTree = null;\n this.paints = [];\n this.mainFrameId = undefined;\n }\n\n setIndex(i: number): void {\n this.index = i;\n }\n\n setEndTime(endTime: Types.Timing.Micro): void {\n this.endTime = endTime;\n this.duration = Types.Timing.Micro(this.endTime - this.startTime);\n }\n\n setLayerTree(layerTree: Types.Events.LegacyFrameLayerTreeData|null): void {\n this.layerTree = layerTree;\n }\n\n /**\n * Fake the `dur` field to meet the expected value given that we pretend\n * these TimelineFrame classes are trace events across the codebase.\n */\n get dur(): Types.Timing.Micro {\n return this.duration;\n }\n}\n\nexport class LayerPaintEvent implements Types.Events.LegacyLayerPaintEvent {\n readonly #event: Types.Events.Paint;\n #snapshot: Types.Events.DisplayItemListSnapshot;\n\n constructor(event: Types.Events.Paint, snapshot: Types.Events.DisplayItemListSnapshot) {\n this.#event = event;\n this.#snapshot = snapshot;\n }\n\n layerId(): number {\n return this.#event.args.data.layerId;\n }\n\n event(): Types.Events.Paint {\n return this.#event;\n }\n\n picture(): Types.Events.LegacyLayerPaintEventPicture|null {\n const rect = this.#snapshot.args.snapshot.params?.layer_rect;\n const pictureData = this.#snapshot.args.snapshot.skp64;\n return rect && pictureData ? {rect, serializedPicture: pictureData} : null;\n }\n}\n\nexport class PendingFrame {\n paints: LayerPaintEvent[];\n mainFrameId: number|undefined;\n triggerTime: number;\n constructor(triggerTime: number) {\n this.paints = [];\n this.mainFrameId = undefined;\n this.triggerTime = triggerTime;\n }\n}\n\n// The parameters of an impl-side BeginFrame.\nclass BeginFrameInfo {\n seqId: number;\n startTime: Types.Timing.Micro;\n isDropped: boolean;\n isPartial: boolean;\n constructor(seqId: number, startTime: Types.Timing.Micro, isDropped: boolean, isPartial: boolean) {\n this.seqId = seqId;\n this.startTime = startTime;\n this.isDropped = isDropped;\n this.isPartial = isPartial;\n }\n}\n\n// A queue of BeginFrames pending visualization.\n// BeginFrames are added into this queue as they occur; later when their\n// corresponding DrawFrames occur (or lack thereof), the BeginFrames are removed\n// from the queue and their timestamps are used for visualization.\nexport class TimelineFrameBeginFrameQueue {\n private queueFrames: number[] = [];\n\n // Maps frameSeqId to BeginFrameInfo.\n private mapFrames: Record<number, BeginFrameInfo> = {};\n\n // Add a BeginFrame to the queue, if it does not already exit.\n addFrameIfNotExists(seqId: number, startTime: Types.Timing.Micro, isDropped: boolean, isPartial: boolean): void {\n if (!(seqId in this.mapFrames)) {\n this.mapFrames[seqId] = new BeginFrameInfo(seqId, startTime, isDropped, isPartial);\n this.queueFrames.push(seqId);\n }\n }\n\n // Set a BeginFrame in queue as dropped.\n setDropped(seqId: number, isDropped: boolean): void {\n if (seqId in this.mapFrames) {\n this.mapFrames[seqId].isDropped = isDropped;\n }\n }\n\n setPartial(seqId: number, isPartial: boolean): void {\n if (seqId in this.mapFrames) {\n this.mapFrames[seqId].isPartial = isPartial;\n }\n }\n\n processPendingBeginFramesOnDrawFrame(seqId: number): BeginFrameInfo[] {\n const framesToVisualize: BeginFrameInfo[] = [];\n\n // Do not visualize this frame in the rare case where the current DrawFrame\n // does not have a corresponding BeginFrame.\n if (seqId in this.mapFrames) {\n // Pop all BeginFrames before the current frame, and add only the dropped\n // ones in |frames_to_visualize|.\n // Non-dropped frames popped here are BeginFrames that are never\n // drawn (but not considered dropped either for some reason).\n // Those frames do not require an proactive visualization effort and will\n // be naturally presented as continuationss of other frames.\n while (this.queueFrames[0] !== seqId) {\n const currentSeqId = this.queueFrames[0];\n if (this.mapFrames[currentSeqId].isDropped) {\n framesToVisualize.push(this.mapFrames[currentSeqId]);\n }\n\n delete this.mapFrames[currentSeqId];\n this.queueFrames.shift();\n }\n\n // Pop the BeginFrame associated with the current DrawFrame.\n framesToVisualize.push(this.mapFrames[seqId]);\n delete this.mapFrames[seqId];\n this.queueFrames.shift();\n }\n return framesToVisualize;\n }\n}\n\nexport function framesWithinWindow(\n frames: readonly Types.Events.LegacyTimelineFrame[], startTime: Types.Timing.Micro,\n endTime: Types.Timing.Micro): Types.Events.LegacyTimelineFrame[] {\n const firstFrame = Platform.ArrayUtilities.lowerBound(frames, startTime || 0, (time, frame) => time - frame.endTime);\n const lastFrame =\n Platform.ArrayUtilities.lowerBound(frames, endTime || Infinity, (time, frame) => time - frame.startTime);\n return frames.slice(firstFrame, lastFrame);\n}\n"]}
1
+ {"version":3,"file":"FramesHandler.js","sourceRoot":"","sources":["../../../../../../../front_end/models/trace/handlers/FramesHandler.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 Platform from '../../../core/platform/platform.js';\nimport * as Helpers from '../helpers/helpers.js';\nimport * as Types from '../types/types.js';\n\nimport {type AuctionWorkletsData, data as auctionWorkletsData} from './AuctionWorkletsHandler.js';\nimport {data as layerTreeHandlerData, type LayerTreeData} from './LayerTreeHandler.js';\nimport {data as metaHandlerData, type MetaHandlerData} from './MetaHandler.js';\nimport {data as rendererHandlerData, type RendererHandlerData} from './RendererHandler.js';\nimport * as Threads from './Threads.js';\nimport type {HandlerName} from './types.js';\n\n/**\n * IMPORTANT: this handler is slightly different to the rest. This is because\n * it is an adaptation of the TimelineFrameModel that has been used in DevTools\n * for many years. Rather than re-implement all the logic from scratch, instead\n * this handler gathers up the events and instantitates the class in the\n * finalize() method. Once the class has parsed all events, it is used to then\n * return the array of frames.\n *\n * In time we expect to migrate this code to a more \"typical\" handler.\n */\n\nlet model: TimelineFrameModel|null = null;\nconst relevantFrameEvents: Types.Events.Event[] = [];\n\ntype FrameEvent = Types.Events.BeginFrame|Types.Events.DroppedFrame|Types.Events.RequestMainThreadFrame|\n Types.Events.BeginMainThreadFrame|Types.Events.Commit|Types.Events.CompositeLayers|\n Types.Events.ActivateLayerTree|Types.Events.NeedsBeginFrameChanged|Types.Events.DrawFrame;\n\nfunction isFrameEvent(event: Types.Events.Event): event is FrameEvent {\n return (\n Types.Events.isSetLayerId(event) || Types.Events.isBeginFrame(event) || Types.Events.isDroppedFrame(event) ||\n Types.Events.isRequestMainThreadFrame(event) || Types.Events.isBeginMainThreadFrame(event) ||\n Types.Events.isNeedsBeginFrameChanged(event) ||\n // Note that \"Commit\" is the replacement for \"CompositeLayers\" so in a trace\n // we wouldn't expect to see a combination of these. All \"new\" trace\n // recordings use \"Commit\", but we can easily support \"CompositeLayers\" too\n // to not break older traces being imported.\n Types.Events.isCommit(event) || Types.Events.isCompositeLayers(event) ||\n Types.Events.isActivateLayerTree(event) || Types.Events.isDrawFrame(event));\n}\n\nfunction entryIsTopLevel(entry: Types.Events.Event): boolean {\n const devtoolsTimelineCategory = 'disabled-by-default-devtools.timeline';\n return entry.name === Types.Events.Name.RUN_TASK && entry.cat.includes(devtoolsTimelineCategory);\n}\n\nconst MAIN_FRAME_MARKERS = new Set<Types.Events.Name>([\n Types.Events.Name.SCHEDULE_STYLE_RECALCULATION,\n Types.Events.Name.INVALIDATE_LAYOUT,\n Types.Events.Name.BEGIN_MAIN_THREAD_FRAME,\n Types.Events.Name.SCROLL_LAYER,\n]);\n\nexport function reset(): void {\n model = null;\n relevantFrameEvents.length = 0;\n}\nexport function handleEvent(event: Types.Events.Event): void {\n // This might seem like a wide set of events to filter for, but these are all\n // the types of events that we care about in the TimelineFrameModel class at\n // the bottom of this file. Previously we would take a copy of an array of\n // all trace events, but on a few test traces, this set of filtered events\n // accounts for about 10% of the total events, so it's a big performance win\n // to deal with a much smaller subset of the data.\n if (isFrameEvent(event) || Types.Events.isLayerTreeHostImplSnapshot(event) || entryIsTopLevel(event) ||\n MAIN_FRAME_MARKERS.has(event.name as Types.Events.Name) || Types.Events.isPaint(event)) {\n relevantFrameEvents.push(event);\n }\n}\n\nexport async function finalize(): Promise<void> {\n // We have to sort the events by timestamp, because the model code expects to\n // process events in order.\n Helpers.Trace.sortTraceEventsInPlace(relevantFrameEvents);\n\n const modelForTrace = new TimelineFrameModel(\n relevantFrameEvents,\n rendererHandlerData(),\n auctionWorkletsData(),\n metaHandlerData(),\n layerTreeHandlerData(),\n );\n model = modelForTrace;\n}\n\nexport interface FramesData {\n frames: readonly Types.Events.LegacyTimelineFrame[];\n framesById: Readonly<Record<number, Types.Events.LegacyTimelineFrame|undefined>>;\n}\n\nexport function data(): FramesData {\n return {\n frames: model ? Array.from(model.frames()) : [],\n framesById: model ? {...model.framesById()} : {},\n };\n}\n\nexport function deps(): HandlerName[] {\n return ['Meta', 'Renderer', 'AuctionWorklets', 'LayerTree'];\n}\n\nexport class TimelineFrameModel {\n #frames: TimelineFrame[] = [];\n #frameById: Record<number, TimelineFrame> = {};\n #beginFrameQueue: TimelineFrameBeginFrameQueue = new TimelineFrameBeginFrameQueue();\n #lastFrame: TimelineFrame|null = null;\n #mainFrameCommitted = false;\n #mainFrameRequested = false;\n #lastLayerTree: Types.Events.LegacyFrameLayerTreeData|null = null;\n #framePendingActivation: PendingFrame|null = null;\n #framePendingCommit: PendingFrame|null = null;\n #lastBeginFrame: number|null = null;\n #lastNeedsBeginFrame: number|null = null;\n #lastTaskBeginTime: Types.Timing.Micro|null = null;\n #layerTreeId: number|null = null;\n #activeProcessId: Types.Events.ProcessID|null = null;\n #activeThreadId: Types.Events.ThreadID|null = null;\n #layerTreeData: LayerTreeData;\n\n constructor(\n allEvents: readonly Types.Events.Event[], rendererData: RendererHandlerData,\n auctionWorkletsData: AuctionWorkletsData, metaData: MetaHandlerData, layerTreeData: LayerTreeData) {\n // We only care about getting threads from the Renderer, not Samples,\n // because Frames don't exist in a CPU Profile (which won't have Renderer\n // threads.)\n const mainThreads = Threads.threadsInRenderer(rendererData, auctionWorkletsData).filter(thread => {\n return thread.type === Threads.ThreadType.MAIN_THREAD && thread.processIsOnMainFrame;\n });\n const threadData = mainThreads.map(thread => {\n return {\n tid: thread.tid,\n pid: thread.pid,\n startTime: thread.entries[0].ts,\n };\n });\n\n this.#layerTreeData = layerTreeData;\n this.#addTraceEvents(allEvents, threadData, metaData.mainFrameId);\n }\n\n framesById(): Readonly<Record<number, TimelineFrame|undefined>> {\n return this.#frameById;\n }\n\n frames(): TimelineFrame[] {\n return this.#frames;\n }\n\n #handleBeginFrame(startTime: Types.Timing.Micro, seqId: number): void {\n if (!this.#lastFrame) {\n this.#startFrame(startTime, seqId);\n }\n this.#lastBeginFrame = startTime;\n\n this.#beginFrameQueue.addFrameIfNotExists(seqId, startTime, false, false);\n }\n\n #handleDroppedFrame(startTime: Types.Timing.Micro, seqId: number, isPartial: boolean): void {\n if (!this.#lastFrame) {\n this.#startFrame(startTime, seqId);\n }\n\n // This line handles the case where no BeginFrame event is issued for\n // the dropped frame. In this situation, add a BeginFrame to the queue\n // as if it actually occurred.\n this.#beginFrameQueue.addFrameIfNotExists(seqId, startTime, true, isPartial);\n this.#beginFrameQueue.setDropped(seqId, true);\n this.#beginFrameQueue.setPartial(seqId, isPartial);\n }\n\n #handleDrawFrame(startTime: Types.Timing.Micro, seqId: number): void {\n if (!this.#lastFrame) {\n this.#startFrame(startTime, seqId);\n return;\n }\n\n // - if it wasn't drawn, it didn't happen!\n // - only show frames that either did not wait for the main thread frame or had one committed.\n if (this.#mainFrameCommitted || !this.#mainFrameRequested) {\n if (this.#lastNeedsBeginFrame) {\n const idleTimeEnd = this.#framePendingActivation ? this.#framePendingActivation.triggerTime :\n (this.#lastBeginFrame || this.#lastNeedsBeginFrame);\n if (idleTimeEnd > this.#lastFrame.startTime) {\n this.#lastFrame.idle = true;\n this.#lastBeginFrame = null;\n }\n this.#lastNeedsBeginFrame = null;\n }\n\n const framesToVisualize = this.#beginFrameQueue.processPendingBeginFramesOnDrawFrame(seqId);\n\n // Visualize the current frame and all pending frames before it.\n for (const frame of framesToVisualize) {\n const isLastFrameIdle = this.#lastFrame.idle;\n\n // If |frame| is the first frame after an idle period, the CPU time\n // will be logged (\"committed\") under |frame| if applicable.\n this.#startFrame(frame.startTime, seqId);\n if (isLastFrameIdle && this.#framePendingActivation) {\n this.#commitPendingFrame();\n }\n if (frame.isDropped) {\n this.#lastFrame.dropped = true;\n }\n if (frame.isPartial) {\n this.#lastFrame.isPartial = true;\n }\n }\n }\n this.#mainFrameCommitted = false;\n }\n\n #handleActivateLayerTree(): void {\n if (!this.#lastFrame) {\n return;\n }\n if (this.#framePendingActivation && !this.#lastNeedsBeginFrame) {\n this.#commitPendingFrame();\n }\n }\n\n #handleRequestMainThreadFrame(): void {\n if (!this.#lastFrame) {\n return;\n }\n this.#mainFrameRequested = true;\n }\n\n #handleCommit(): void {\n if (!this.#framePendingCommit) {\n return;\n }\n this.#framePendingActivation = this.#framePendingCommit;\n this.#framePendingCommit = null;\n this.#mainFrameRequested = false;\n this.#mainFrameCommitted = true;\n }\n\n #handleLayerTreeSnapshot(layerTree: Types.Events.LegacyFrameLayerTreeData): void {\n this.#lastLayerTree = layerTree;\n }\n\n #handleNeedFrameChanged(startTime: Types.Timing.Micro, needsBeginFrame: boolean): void {\n if (needsBeginFrame) {\n this.#lastNeedsBeginFrame = startTime;\n }\n }\n\n #startFrame(startTime: Types.Timing.Micro, seqId: number): void {\n if (this.#lastFrame) {\n this.#flushFrame(this.#lastFrame, startTime);\n }\n this.#lastFrame =\n new TimelineFrame(seqId, startTime, Types.Timing.Micro(startTime - metaHandlerData().traceBounds.min));\n }\n\n #flushFrame(frame: TimelineFrame, endTime: Types.Timing.Micro): void {\n frame.setLayerTree(this.#lastLayerTree);\n frame.setEndTime(endTime);\n if (this.#lastLayerTree) {\n this.#lastLayerTree.paints = frame.paints;\n }\n const lastFrame = this.#frames[this.#frames.length - 1];\n if (this.#frames.length && lastFrame &&\n (frame.startTime !== lastFrame.endTime || frame.startTime > frame.endTime)) {\n console.assert(\n false, `Inconsistent frame time for frame ${this.#frames.length} (${frame.startTime} - ${frame.endTime})`);\n }\n const newFramesLength = this.#frames.push(frame);\n frame.setIndex(newFramesLength - 1);\n if (typeof frame.mainFrameId === 'number') {\n this.#frameById[frame.mainFrameId] = frame;\n }\n }\n\n #commitPendingFrame(): void {\n if (!this.#framePendingActivation || !this.#lastFrame) {\n return;\n }\n\n this.#lastFrame.paints = this.#framePendingActivation.paints;\n this.#lastFrame.mainFrameId = this.#framePendingActivation.mainFrameId;\n this.#framePendingActivation = null;\n }\n\n #addTraceEvents(\n events: readonly Types.Events.Event[], threadData: Array<{\n pid: Types.Events.ProcessID,\n tid: Types.Events.ThreadID,\n startTime: Types.Timing.Micro,\n }>,\n mainFrameId: string): void {\n let j = 0;\n this.#activeThreadId = threadData.length && threadData[0].tid || null;\n this.#activeProcessId = threadData.length && threadData[0].pid || null;\n for (let i = 0; i < events.length; ++i) {\n while (j + 1 < threadData.length && threadData[j + 1].startTime <= events[i].ts) {\n this.#activeThreadId = threadData[++j].tid;\n this.#activeProcessId = threadData[j].pid;\n }\n this.#addTraceEvent(events[i], mainFrameId);\n }\n this.#activeThreadId = null;\n this.#activeProcessId = null;\n }\n\n #addTraceEvent(event: Types.Events.Event, mainFrameId: string): void {\n if (Types.Events.isSetLayerId(event) && event.args.data.frame === mainFrameId) {\n this.#layerTreeId = event.args.data.layerTreeId;\n } else if (Types.Events.isLayerTreeHostImplSnapshot(event) && Number(event.id) === this.#layerTreeId) {\n this.#handleLayerTreeSnapshot({\n entry: event,\n paints: [],\n });\n } else {\n if (isFrameEvent(event)) {\n this.#processCompositorEvents(event);\n }\n // Make sure we only use events from the main thread: we check the PID as\n // well in case two processes have a thread with the same TID.\n if (event.tid === this.#activeThreadId && event.pid === this.#activeProcessId) {\n this.#addMainThreadTraceEvent(event);\n }\n }\n }\n\n #processCompositorEvents(entry: FrameEvent): void {\n if (entry.args['layerTreeId'] !== this.#layerTreeId) {\n return;\n }\n if (Types.Events.isBeginFrame(entry)) {\n this.#handleBeginFrame(entry.ts, entry.args['frameSeqId']);\n } else if (Types.Events.isDrawFrame(entry)) {\n this.#handleDrawFrame(entry.ts, entry.args['frameSeqId']);\n } else if (Types.Events.isActivateLayerTree(entry)) {\n this.#handleActivateLayerTree();\n } else if (Types.Events.isRequestMainThreadFrame(entry)) {\n this.#handleRequestMainThreadFrame();\n } else if (Types.Events.isNeedsBeginFrameChanged(entry)) {\n // needsBeginFrame property will either be 0 or 1, which represents\n // true/false in this case, hence the Boolean() wrapper.\n this.#handleNeedFrameChanged(entry.ts, entry.args['data'] && Boolean(entry.args['data']['needsBeginFrame']));\n } else if (Types.Events.isDroppedFrame(entry)) {\n this.#handleDroppedFrame(entry.ts, entry.args['frameSeqId'], Boolean(entry.args['hasPartialUpdate']));\n }\n }\n\n #addMainThreadTraceEvent(entry: Types.Events.Event): void {\n if (entryIsTopLevel(entry)) {\n this.#lastTaskBeginTime = entry.ts;\n }\n if (!this.#framePendingCommit && MAIN_FRAME_MARKERS.has(entry.name as Types.Events.Name)) {\n this.#framePendingCommit = new PendingFrame(this.#lastTaskBeginTime || entry.ts);\n }\n if (!this.#framePendingCommit) {\n return;\n }\n\n if (Types.Events.isBeginMainThreadFrame(entry) && entry.args.data.frameId) {\n this.#framePendingCommit.mainFrameId = entry.args.data.frameId;\n }\n if (Types.Events.isPaint(entry)) {\n const snapshot = this.#layerTreeData.paintsToSnapshots.get(entry);\n if (snapshot) {\n this.#framePendingCommit.paints.push(new LayerPaintEvent(entry, snapshot));\n }\n }\n // Commit will be replacing CompositeLayers but CompositeLayers is kept\n // around for backwards compatibility.\n if ((Types.Events.isCompositeLayers(entry) || Types.Events.isCommit(entry)) &&\n entry.args['layerTreeId'] === this.#layerTreeId) {\n this.#handleCommit();\n }\n }\n}\n\n/**\n * Legacy class that represents TimelineFrames that was ported from the old SDK.\n * This class is purposefully not exported as it breaks the abstraction that\n * every event shown on the timeline is a trace event. Instead, we use the Type\n * LegacyTimelineFrame to represent frames in the codebase. These do implement\n * the right interface to be treated just like they were a trace event.\n */\nclass TimelineFrame implements Types.Events.LegacyTimelineFrame {\n // These fields exist to satisfy the base Event type which all\n // \"trace events\" must implement. They aren't used, but doing this means we\n // can pass `TimelineFrame` instances into places that expect\n // Types.Events.Event.\n cat = 'devtools.legacy_frame';\n name = 'frame';\n ph = Types.Events.Phase.COMPLETE;\n ts: Types.Timing.Micro;\n pid = Types.Events.ProcessID(-1);\n tid = Types.Events.ThreadID(-1);\n\n index = -1;\n startTime: Types.Timing.Micro;\n startTimeOffset: Types.Timing.Micro;\n endTime: Types.Timing.Micro;\n duration: Types.Timing.Micro;\n idle: boolean;\n dropped: boolean;\n isPartial: boolean;\n layerTree: Types.Events.LegacyFrameLayerTreeData|null;\n paints: LayerPaintEvent[];\n mainFrameId: number|undefined;\n readonly seqId: number;\n\n constructor(seqId: number, startTime: Types.Timing.Micro, startTimeOffset: Types.Timing.Micro) {\n this.seqId = seqId;\n this.startTime = startTime;\n this.ts = startTime;\n this.startTimeOffset = startTimeOffset;\n this.endTime = this.startTime;\n this.duration = Types.Timing.Micro(0);\n this.idle = false;\n this.dropped = false;\n this.isPartial = false;\n this.layerTree = null;\n this.paints = [];\n this.mainFrameId = undefined;\n }\n\n setIndex(i: number): void {\n this.index = i;\n }\n\n setEndTime(endTime: Types.Timing.Micro): void {\n this.endTime = endTime;\n this.duration = Types.Timing.Micro(this.endTime - this.startTime);\n }\n\n setLayerTree(layerTree: Types.Events.LegacyFrameLayerTreeData|null): void {\n this.layerTree = layerTree;\n }\n\n /**\n * Fake the `dur` field to meet the expected value given that we pretend\n * these TimelineFrame classes are trace events across the codebase.\n */\n get dur(): Types.Timing.Micro {\n return this.duration;\n }\n}\n\nexport class LayerPaintEvent implements Types.Events.LegacyLayerPaintEvent {\n readonly #event: Types.Events.Paint;\n #snapshot: Types.Events.DisplayItemListSnapshot;\n\n constructor(event: Types.Events.Paint, snapshot: Types.Events.DisplayItemListSnapshot) {\n this.#event = event;\n this.#snapshot = snapshot;\n }\n\n layerId(): number {\n return this.#event.args.data.layerId;\n }\n\n event(): Types.Events.Paint {\n return this.#event;\n }\n\n picture(): Types.Events.LegacyLayerPaintEventPicture|null {\n const rect = this.#snapshot.args.snapshot.params?.layer_rect;\n const pictureData = this.#snapshot.args.snapshot.skp64;\n return rect && pictureData ? {rect, serializedPicture: pictureData} : null;\n }\n}\n\nexport class PendingFrame {\n paints: LayerPaintEvent[];\n mainFrameId: number|undefined;\n triggerTime: number;\n constructor(triggerTime: number) {\n this.paints = [];\n this.mainFrameId = undefined;\n this.triggerTime = triggerTime;\n }\n}\n\n// The parameters of an impl-side BeginFrame.\nclass BeginFrameInfo {\n seqId: number;\n startTime: Types.Timing.Micro;\n isDropped: boolean;\n isPartial: boolean;\n constructor(seqId: number, startTime: Types.Timing.Micro, isDropped: boolean, isPartial: boolean) {\n this.seqId = seqId;\n this.startTime = startTime;\n this.isDropped = isDropped;\n this.isPartial = isPartial;\n }\n}\n\n// A queue of BeginFrames pending visualization.\n// BeginFrames are added into this queue as they occur; later when their\n// corresponding DrawFrames occur (or lack thereof), the BeginFrames are removed\n// from the queue and their timestamps are used for visualization.\nexport class TimelineFrameBeginFrameQueue {\n private queueFrames: number[] = [];\n\n // Maps frameSeqId to BeginFrameInfo.\n private mapFrames: Record<number, BeginFrameInfo> = {};\n\n // Add a BeginFrame to the queue, if it does not already exit.\n addFrameIfNotExists(seqId: number, startTime: Types.Timing.Micro, isDropped: boolean, isPartial: boolean): void {\n if (!(seqId in this.mapFrames)) {\n this.mapFrames[seqId] = new BeginFrameInfo(seqId, startTime, isDropped, isPartial);\n this.queueFrames.push(seqId);\n }\n }\n\n // Set a BeginFrame in queue as dropped.\n setDropped(seqId: number, isDropped: boolean): void {\n if (seqId in this.mapFrames) {\n this.mapFrames[seqId].isDropped = isDropped;\n }\n }\n\n setPartial(seqId: number, isPartial: boolean): void {\n if (seqId in this.mapFrames) {\n this.mapFrames[seqId].isPartial = isPartial;\n }\n }\n\n processPendingBeginFramesOnDrawFrame(seqId: number): BeginFrameInfo[] {\n const framesToVisualize: BeginFrameInfo[] = [];\n\n // Do not visualize this frame in the rare case where the current DrawFrame\n // does not have a corresponding BeginFrame.\n if (seqId in this.mapFrames) {\n // Pop all BeginFrames before the current frame, and add only the dropped\n // ones in |frames_to_visualize|.\n // Non-dropped frames popped here are BeginFrames that are never\n // drawn (but not considered dropped either for some reason).\n // Those frames do not require an proactive visualization effort and will\n // be naturally presented as continuationss of other frames.\n while (this.queueFrames[0] !== seqId) {\n const currentSeqId = this.queueFrames[0];\n if (this.mapFrames[currentSeqId].isDropped) {\n framesToVisualize.push(this.mapFrames[currentSeqId]);\n }\n\n delete this.mapFrames[currentSeqId];\n this.queueFrames.shift();\n }\n\n // Pop the BeginFrame associated with the current DrawFrame.\n framesToVisualize.push(this.mapFrames[seqId]);\n delete this.mapFrames[seqId];\n this.queueFrames.shift();\n }\n return framesToVisualize;\n }\n}\n\nexport function framesWithinWindow(\n frames: readonly Types.Events.LegacyTimelineFrame[], startTime: Types.Timing.Micro,\n endTime: Types.Timing.Micro): Types.Events.LegacyTimelineFrame[] {\n const firstFrame = Platform.ArrayUtilities.lowerBound(frames, startTime || 0, (time, frame) => time - frame.endTime);\n const lastFrame =\n Platform.ArrayUtilities.lowerBound(frames, endTime || Infinity, (time, frame) => time - frame.startTime);\n return frames.slice(firstFrame, lastFrame);\n}\n"]}
@@ -1,7 +1,8 @@
1
1
  import * as Types from '../types/types.js';
2
+ import type { FinalizeOptions } from './types.js';
2
3
  export declare function reset(): void;
3
4
  export declare function handleEvent(event: Types.Events.Event): void;
4
- export declare function finalize(options: Types.Configuration.ParseOptions): Promise<void>;
5
+ export declare function finalize(options: FinalizeOptions): Promise<void>;
5
6
  export interface ImagePaintData {
6
7
  paintImageByDrawLazyPixelRef: Map<number, Types.Events.PaintImage>;
7
8
  paintImageForEvent: Map<Types.Events.Event, Types.Events.PaintImage>;
@@ -1 +1 @@
1
- {"version":3,"file":"ImagePaintingHandler.js","sourceRoot":"","sources":["../../../../../../../front_end/models/trace/handlers/ImagePaintingHandler.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright 2024 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 * as Types from '../types/types.js';\n\nimport {data as metaHandlerData} from './MetaHandler.js';\n\n/**\n * This handler is responsible for the relationships between:\n * DecodeImage/ResizeImage, PaintImage and DrawLazyPixelRef events.\n *\n * When we get a DecodeImage event, we want to associate it to a PaintImage\n * event, primarily so we can determine the NodeID of the image that was\n * decoded.\n * We can do this in two ways:\n *\n * 1. If there is a PaintImage event on the same thread, use that\n * (if there are multiple, use the latest one).\n *\n * 2. If not, we can find the DecodeLazyPixelRef event on the same thread, and\n * use the PaintImage event associated with it via the `LazyPixelRef` key.\n */\n\n// Track paintImageEvents across threads.\nconst paintImageEvents = new Map<Types.Events.ProcessID, Map<Types.Events.ThreadID, Types.Events.PaintImage[]>>();\nconst decodeLazyPixelRefEvents =\n new Map<Types.Events.ProcessID, Map<Types.Events.ThreadID, Types.Events.DecodeLazyPixelRef[]>>();\n\n// A DrawLazyPixelRef event will contain a numerical reference in\n// args.LazyPixelRef. As we parse each DrawLazyPixelRef, we can assign it to a\n// paint event. Later we want to look up paint events by this reference, so we\n// store them in this map.\nconst paintImageByLazyPixelRef = new Map<number, Types.Events.PaintImage>();\n\n// When we find events that we want to tie to a particular PaintImage event, we add them to this map.\n// These are currently only DecodeImage and ResizeImage events, but the type is\n// deliberately generic as in the future we might want to add more events that\n// have a relationship to a individual PaintImage event.\nconst eventToPaintImage = new Map<Types.Events.Event, Types.Events.PaintImage>();\n\nconst urlToPaintImage = new Map<string, Types.Events.PaintImage[]>();\n\nconst paintEventToCorrectedDisplaySize = new Map<Types.Events.PaintImage, {width: number, height: number}>();\n\nlet didCorrectForHostDpr = false;\n\nexport function reset(): void {\n paintImageEvents.clear();\n decodeLazyPixelRefEvents.clear();\n paintImageByLazyPixelRef.clear();\n eventToPaintImage.clear();\n urlToPaintImage.clear();\n paintEventToCorrectedDisplaySize.clear();\n didCorrectForHostDpr = false;\n}\n\nexport function handleEvent(event: Types.Events.Event): void {\n if (Types.Events.isPaintImage(event)) {\n const forProcess = paintImageEvents.get(event.pid) || new Map<Types.Events.ThreadID, Types.Events.PaintImage[]>();\n const forThread = forProcess.get(event.tid) || [];\n forThread.push(event);\n forProcess.set(event.tid, forThread);\n paintImageEvents.set(event.pid, forProcess);\n\n if (event.args.data.url) {\n const paintsForUrl = Platform.MapUtilities.getWithDefault(urlToPaintImage, event.args.data.url, () => []);\n paintsForUrl.push(event);\n }\n\n return;\n }\n\n if (Types.Events.isDecodeLazyPixelRef(event) && typeof event.args?.LazyPixelRef !== 'undefined') {\n // Store these because we use them to tie DecodeImage to a PaintEvent.\n const forProcess =\n decodeLazyPixelRefEvents.get(event.pid) || new Map<Types.Events.ThreadID, Types.Events.DecodeLazyPixelRef[]>();\n const forThread = forProcess.get(event.tid) || [];\n forThread.push(event);\n forProcess.set(event.tid, forThread);\n decodeLazyPixelRefEvents.set(event.pid, forProcess);\n }\n\n // If we see a DrawLazyPixelRef event, we need to find the last PaintImage\n // event on the thread and associate it to the LazyPixelRef that is supplied\n // in the DrawLazyPixelRef event.\n // This means that later on if we see a DecodeLazyPixelRef event with the\n // same LazyPixelRef key, we can find its associated PaintImage event by\n // looking it up.\n if (Types.Events.isDrawLazyPixelRef(event) && typeof event.args?.LazyPixelRef !== 'undefined') {\n const lastPaintEvent = paintImageEvents.get(event.pid)?.get(event.tid)?.at(-1);\n if (!lastPaintEvent) {\n return;\n }\n paintImageByLazyPixelRef.set(event.args.LazyPixelRef, lastPaintEvent);\n return;\n }\n\n if (Types.Events.isDecodeImage(event)) {\n // When we see a DecodeImage, we want to associate it to a PaintImage\n // event. We try two approaches:\n //\n // 1. If the thread of the DecodeImage event has a previous PaintImage\n // event, that is the associated event.\n //\n // 2. If that is false, we then look on the thread for a DecodeLazyPixelRef\n // event. If we find that, we then look for its associated PaintImage\n // event, which we associate via DrawLazyPixelRef events (the code block\n // above this one)\n //\n // 1. Find a PaintImage event on the same thread. If we find it, that's our association done.\n const lastPaintImageEventOnThread = paintImageEvents.get(event.pid)?.get(event.tid)?.at(-1);\n if (lastPaintImageEventOnThread) {\n eventToPaintImage.set(event, lastPaintImageEventOnThread);\n return;\n }\n\n // 2. Find the last DecodeLazyPixelRef event and, if we find it, find its associated PaintImage event.\n const lastDecodeLazyPixelRef = decodeLazyPixelRefEvents.get(event.pid)?.get(event.tid)?.at(-1);\n if (typeof lastDecodeLazyPixelRef?.args?.LazyPixelRef === 'undefined') {\n return;\n }\n\n const paintEvent = paintImageByLazyPixelRef.get(lastDecodeLazyPixelRef.args.LazyPixelRef);\n if (!paintEvent) {\n return;\n }\n eventToPaintImage.set(event, paintEvent);\n }\n}\n\nexport async function finalize(options: Types.Configuration.ParseOptions): Promise<void> {\n // Painting in Chrome never uses the emulated DPR, but instead used the host's DPR.\n // We need to correct for that for our responsive image checks in the ImageDelivery\n // insight.\n // See: crbug.com/427552461 crbug.com/416580500#comment5\n\n if (!options.metadata?.hostDPR) {\n return;\n }\n\n // Note: this isn't necessarily emulated (for desktop+no DPR emulation, it's equal\n // to host DPR).\n const {devicePixelRatio: emulatedDpr} = metaHandlerData();\n if (!emulatedDpr) {\n return;\n }\n\n for (const byThread of paintImageEvents.values()) {\n for (const paintEvents of byThread.values()) {\n for (const paintEvent of paintEvents) {\n const cssPixelsWidth = paintEvent.args.data.width / options.metadata.hostDPR;\n const cssPixelsHeight = paintEvent.args.data.height / options.metadata.hostDPR;\n const width = cssPixelsWidth * emulatedDpr;\n const height = cssPixelsHeight * emulatedDpr;\n paintEventToCorrectedDisplaySize.set(paintEvent, {width, height});\n }\n }\n }\n\n didCorrectForHostDpr = true;\n}\n\nexport interface ImagePaintData {\n paintImageByDrawLazyPixelRef: Map<number, Types.Events.PaintImage>;\n paintImageForEvent: Map<Types.Events.Event, Types.Events.PaintImage>;\n paintImageEventForUrl: Map<string, Types.Events.PaintImage[]>;\n paintEventToCorrectedDisplaySize: Map<Types.Events.PaintImage, {width: number, height: number}>;\n /** Go read the comment in finalize(). */\n didCorrectForHostDpr: boolean;\n}\n\nexport function data(): ImagePaintData {\n return {\n paintImageByDrawLazyPixelRef: paintImageByLazyPixelRef,\n paintImageForEvent: eventToPaintImage,\n paintImageEventForUrl: urlToPaintImage,\n paintEventToCorrectedDisplaySize,\n didCorrectForHostDpr,\n };\n}\n"]}
1
+ {"version":3,"file":"ImagePaintingHandler.js","sourceRoot":"","sources":["../../../../../../../front_end/models/trace/handlers/ImagePaintingHandler.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright 2024 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 * as Types from '../types/types.js';\n\nimport {data as metaHandlerData} from './MetaHandler.js';\nimport type {FinalizeOptions} from './types.js';\n\n/**\n * This handler is responsible for the relationships between:\n * DecodeImage/ResizeImage, PaintImage and DrawLazyPixelRef events.\n *\n * When we get a DecodeImage event, we want to associate it to a PaintImage\n * event, primarily so we can determine the NodeID of the image that was\n * decoded.\n * We can do this in two ways:\n *\n * 1. If there is a PaintImage event on the same thread, use that\n * (if there are multiple, use the latest one).\n *\n * 2. If not, we can find the DecodeLazyPixelRef event on the same thread, and\n * use the PaintImage event associated with it via the `LazyPixelRef` key.\n */\n\n// Track paintImageEvents across threads.\nconst paintImageEvents = new Map<Types.Events.ProcessID, Map<Types.Events.ThreadID, Types.Events.PaintImage[]>>();\nconst decodeLazyPixelRefEvents =\n new Map<Types.Events.ProcessID, Map<Types.Events.ThreadID, Types.Events.DecodeLazyPixelRef[]>>();\n\n// A DrawLazyPixelRef event will contain a numerical reference in\n// args.LazyPixelRef. As we parse each DrawLazyPixelRef, we can assign it to a\n// paint event. Later we want to look up paint events by this reference, so we\n// store them in this map.\nconst paintImageByLazyPixelRef = new Map<number, Types.Events.PaintImage>();\n\n// When we find events that we want to tie to a particular PaintImage event, we add them to this map.\n// These are currently only DecodeImage and ResizeImage events, but the type is\n// deliberately generic as in the future we might want to add more events that\n// have a relationship to a individual PaintImage event.\nconst eventToPaintImage = new Map<Types.Events.Event, Types.Events.PaintImage>();\n\nconst urlToPaintImage = new Map<string, Types.Events.PaintImage[]>();\n\nconst paintEventToCorrectedDisplaySize = new Map<Types.Events.PaintImage, {width: number, height: number}>();\n\nlet didCorrectForHostDpr = false;\n\nexport function reset(): void {\n paintImageEvents.clear();\n decodeLazyPixelRefEvents.clear();\n paintImageByLazyPixelRef.clear();\n eventToPaintImage.clear();\n urlToPaintImage.clear();\n paintEventToCorrectedDisplaySize.clear();\n didCorrectForHostDpr = false;\n}\n\nexport function handleEvent(event: Types.Events.Event): void {\n if (Types.Events.isPaintImage(event)) {\n const forProcess = paintImageEvents.get(event.pid) || new Map<Types.Events.ThreadID, Types.Events.PaintImage[]>();\n const forThread = forProcess.get(event.tid) || [];\n forThread.push(event);\n forProcess.set(event.tid, forThread);\n paintImageEvents.set(event.pid, forProcess);\n\n if (event.args.data.url) {\n const paintsForUrl = Platform.MapUtilities.getWithDefault(urlToPaintImage, event.args.data.url, () => []);\n paintsForUrl.push(event);\n }\n\n return;\n }\n\n if (Types.Events.isDecodeLazyPixelRef(event) && typeof event.args?.LazyPixelRef !== 'undefined') {\n // Store these because we use them to tie DecodeImage to a PaintEvent.\n const forProcess =\n decodeLazyPixelRefEvents.get(event.pid) || new Map<Types.Events.ThreadID, Types.Events.DecodeLazyPixelRef[]>();\n const forThread = forProcess.get(event.tid) || [];\n forThread.push(event);\n forProcess.set(event.tid, forThread);\n decodeLazyPixelRefEvents.set(event.pid, forProcess);\n }\n\n // If we see a DrawLazyPixelRef event, we need to find the last PaintImage\n // event on the thread and associate it to the LazyPixelRef that is supplied\n // in the DrawLazyPixelRef event.\n // This means that later on if we see a DecodeLazyPixelRef event with the\n // same LazyPixelRef key, we can find its associated PaintImage event by\n // looking it up.\n if (Types.Events.isDrawLazyPixelRef(event) && typeof event.args?.LazyPixelRef !== 'undefined') {\n const lastPaintEvent = paintImageEvents.get(event.pid)?.get(event.tid)?.at(-1);\n if (!lastPaintEvent) {\n return;\n }\n paintImageByLazyPixelRef.set(event.args.LazyPixelRef, lastPaintEvent);\n return;\n }\n\n if (Types.Events.isDecodeImage(event)) {\n // When we see a DecodeImage, we want to associate it to a PaintImage\n // event. We try two approaches:\n //\n // 1. If the thread of the DecodeImage event has a previous PaintImage\n // event, that is the associated event.\n //\n // 2. If that is false, we then look on the thread for a DecodeLazyPixelRef\n // event. If we find that, we then look for its associated PaintImage\n // event, which we associate via DrawLazyPixelRef events (the code block\n // above this one)\n //\n // 1. Find a PaintImage event on the same thread. If we find it, that's our association done.\n const lastPaintImageEventOnThread = paintImageEvents.get(event.pid)?.get(event.tid)?.at(-1);\n if (lastPaintImageEventOnThread) {\n eventToPaintImage.set(event, lastPaintImageEventOnThread);\n return;\n }\n\n // 2. Find the last DecodeLazyPixelRef event and, if we find it, find its associated PaintImage event.\n const lastDecodeLazyPixelRef = decodeLazyPixelRefEvents.get(event.pid)?.get(event.tid)?.at(-1);\n if (typeof lastDecodeLazyPixelRef?.args?.LazyPixelRef === 'undefined') {\n return;\n }\n\n const paintEvent = paintImageByLazyPixelRef.get(lastDecodeLazyPixelRef.args.LazyPixelRef);\n if (!paintEvent) {\n return;\n }\n eventToPaintImage.set(event, paintEvent);\n }\n}\n\nexport async function finalize(options: FinalizeOptions): Promise<void> {\n // Painting in Chrome never uses the emulated DPR, but instead used the host's DPR.\n // We need to correct for that for our responsive image checks in the ImageDelivery\n // insight.\n // See: crbug.com/427552461 crbug.com/416580500#comment5\n\n if (!options.metadata?.hostDPR) {\n return;\n }\n\n // Note: this isn't necessarily emulated (for desktop+no DPR emulation, it's equal\n // to host DPR).\n const {devicePixelRatio: emulatedDpr} = metaHandlerData();\n if (!emulatedDpr) {\n return;\n }\n\n for (const byThread of paintImageEvents.values()) {\n for (const paintEvents of byThread.values()) {\n for (const paintEvent of paintEvents) {\n const cssPixelsWidth = paintEvent.args.data.width / options.metadata.hostDPR;\n const cssPixelsHeight = paintEvent.args.data.height / options.metadata.hostDPR;\n const width = cssPixelsWidth * emulatedDpr;\n const height = cssPixelsHeight * emulatedDpr;\n paintEventToCorrectedDisplaySize.set(paintEvent, {width, height});\n }\n }\n }\n\n didCorrectForHostDpr = true;\n}\n\nexport interface ImagePaintData {\n paintImageByDrawLazyPixelRef: Map<number, Types.Events.PaintImage>;\n paintImageForEvent: Map<Types.Events.Event, Types.Events.PaintImage>;\n paintImageEventForUrl: Map<string, Types.Events.PaintImage[]>;\n paintEventToCorrectedDisplaySize: Map<Types.Events.PaintImage, {width: number, height: number}>;\n /** Go read the comment in finalize(). */\n didCorrectForHostDpr: boolean;\n}\n\nexport function data(): ImagePaintData {\n return {\n paintImageByDrawLazyPixelRef: paintImageByLazyPixelRef,\n paintImageForEvent: eventToPaintImage,\n paintImageEventForUrl: urlToPaintImage,\n paintEventToCorrectedDisplaySize,\n didCorrectForHostDpr,\n };\n}\n"]}
@@ -23,14 +23,20 @@ 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
+ const requestAnimationFrameEventsById = new Map();
27
+ const timerInstallEventsById = new Map();
28
+ const requestIdleCallbackEventsById = new Map();
26
29
  const webSocketCreateEventsById = new Map();
27
30
  const schedulePostTaskCallbackEventsById = new Map();
28
31
  export function reset() {
29
32
  lastScheduleStyleRecalcByFrame.clear();
30
33
  lastInvalidationEventForFrame.clear();
31
34
  lastUpdateLayoutTreeByFrame.clear();
35
+ timerInstallEventsById.clear();
32
36
  eventToInitiatorMap.clear();
33
37
  initiatorToEventsMap.clear();
38
+ requestAnimationFrameEventsById.clear();
39
+ requestIdleCallbackEventsById.clear();
34
40
  webSocketCreateEventsById.clear();
35
41
  schedulePostTaskCallbackEventsById.clear();
36
42
  }
@@ -108,6 +114,27 @@ export function handleEvent(event) {
108
114
  // 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.
109
115
  lastInvalidationEventForFrame.delete(event.args.beginData.frame);
110
116
  }
117
+ else if (Types.Events.isTimerInstall(event)) {
118
+ timerInstallEventsById.set(event.args.data.timerId, event);
119
+ }
120
+ else if (Types.Events.isTimerFire(event)) {
121
+ const matchingInstall = timerInstallEventsById.get(event.args.data.timerId);
122
+ if (matchingInstall) {
123
+ storeInitiator({ event, initiator: matchingInstall });
124
+ }
125
+ }
126
+ else if (Types.Events.isRequestIdleCallback(event)) {
127
+ requestIdleCallbackEventsById.set(event.args.data.id, event);
128
+ }
129
+ else if (Types.Events.isFireIdleCallback(event)) {
130
+ const matchingRequestEvent = requestIdleCallbackEventsById.get(event.args.data.id);
131
+ if (matchingRequestEvent) {
132
+ storeInitiator({
133
+ event,
134
+ initiator: matchingRequestEvent,
135
+ });
136
+ }
137
+ }
111
138
  else if (Types.Events.isWebSocketCreate(event)) {
112
139
  webSocketCreateEventsById.set(event.args.data.identifier, event);
113
140
  }