@workflow/web-shared 5.0.0-beta.38 → 5.0.0-beta.39

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 (307) hide show
  1. package/README.md +3 -3
  2. package/dist/components/event-list-view.d.ts.map +1 -1
  3. package/dist/components/event-list-view.js +10 -10
  4. package/dist/components/index.d.ts +3 -5
  5. package/dist/components/index.d.ts.map +1 -1
  6. package/dist/components/index.js +3 -5
  7. package/dist/components/sidebar/attribute-panel.d.ts.map +1 -1
  8. package/dist/components/sidebar/attribute-panel.js +32 -8
  9. package/dist/components/sidebar/attributes-block.js +3 -3
  10. package/dist/components/sidebar/copyable-data-block.js +2 -2
  11. package/dist/components/sidebar/entity-detail-panel.js +3 -3
  12. package/dist/components/sidebar/events-list.js +2 -2
  13. package/dist/components/stream-viewer.js +2 -2
  14. package/dist/components/trace-viewer/components/copy-button.d.ts.map +1 -0
  15. package/dist/components/trace-viewer/components/copy-button.js +27 -0
  16. package/dist/components/trace-viewer/components/detail-panel-width.d.ts.map +1 -0
  17. package/dist/components/trace-viewer/components/detail-panel-width.js +67 -0
  18. package/dist/components/trace-viewer/components/detail-panel.d.ts.map +1 -0
  19. package/dist/components/trace-viewer/components/detail-panel.js +122 -0
  20. package/dist/components/trace-viewer/components/draggable-border.d.ts.map +1 -0
  21. package/dist/components/trace-viewer/components/draggable-border.js +140 -0
  22. package/dist/components/trace-viewer/components/event-list.d.ts.map +1 -0
  23. package/dist/components/trace-viewer/components/event-list.js +47 -0
  24. package/dist/components/trace-viewer/components/middle-truncate/copy-selection.d.ts.map +1 -0
  25. package/dist/components/trace-viewer/components/middle-truncate/copy-selection.js +54 -0
  26. package/dist/components/trace-viewer/components/middle-truncate/middle-truncate.d.ts.map +1 -0
  27. package/dist/components/trace-viewer/components/middle-truncate/middle-truncate.js +81 -0
  28. package/dist/components/trace-viewer/components/middle-truncate/truncate.d.ts.map +1 -0
  29. package/dist/components/trace-viewer/components/middle-truncate/truncate.js +101 -0
  30. package/dist/components/trace-viewer/components/middle-truncate/use-middle-truncate.d.ts.map +1 -0
  31. package/dist/components/trace-viewer/components/middle-truncate/use-middle-truncate.js +114 -0
  32. package/dist/components/trace-viewer/components/minimap.d.ts.map +1 -0
  33. package/dist/components/trace-viewer/components/minimap.js +337 -0
  34. package/dist/components/trace-viewer/components/pane-constants.d.ts.map +1 -0
  35. package/dist/components/trace-viewer/components/pane-constants.js +16 -0
  36. package/dist/components/trace-viewer/components/span-markers.d.ts.map +1 -0
  37. package/dist/components/trace-viewer/components/span-markers.js +85 -0
  38. package/dist/components/trace-viewer/components/split-pane.d.ts.map +1 -0
  39. package/dist/components/trace-viewer/components/split-pane.js +41 -0
  40. package/dist/components/trace-viewer/components/timeline.d.ts.map +1 -0
  41. package/dist/components/trace-viewer/components/timeline.js +321 -0
  42. package/dist/components/trace-viewer/components/trace-shortcut-helper.d.ts.map +1 -0
  43. package/dist/components/trace-viewer/components/trace-shortcut-helper.js +55 -0
  44. package/dist/components/trace-viewer/components/trace-viewer-skeleton.d.ts.map +1 -0
  45. package/dist/components/trace-viewer/components/trace-viewer-skeleton.js +26 -0
  46. package/dist/components/trace-viewer/components/use-element-width.d.ts.map +1 -0
  47. package/dist/components/trace-viewer/components/use-element-width.js +25 -0
  48. package/dist/components/trace-viewer/components/use-row-window.d.ts.map +1 -0
  49. package/dist/components/trace-viewer/components/use-row-window.js +107 -0
  50. package/dist/components/trace-viewer/context.d.ts +14 -182
  51. package/dist/components/trace-viewer/context.d.ts.map +1 -1
  52. package/dist/components/trace-viewer/context.js +44 -351
  53. package/dist/components/trace-viewer/icons.d.ts.map +1 -0
  54. package/dist/components/trace-viewer/icons.js +15 -0
  55. package/dist/components/trace-viewer/search.d.ts.map +1 -0
  56. package/dist/components/trace-viewer/search.js +134 -0
  57. package/dist/components/trace-viewer/trace-viewer.d.ts +7 -28
  58. package/dist/components/trace-viewer/trace-viewer.d.ts.map +1 -1
  59. package/dist/components/trace-viewer/trace-viewer.js +306 -356
  60. package/dist/components/trace-viewer/types.d.ts +2 -211
  61. package/dist/components/trace-viewer/types.d.ts.map +1 -1
  62. package/dist/components/trace-viewer/types.js +1 -1
  63. package/dist/components/trace-viewer/utils.d.ts.map +1 -0
  64. package/dist/components/trace-viewer/utils.js +430 -0
  65. package/dist/components/{trace-viewer-new.d.ts → trace-viewer.d.ts} +3 -3
  66. package/dist/components/trace-viewer.d.ts.map +1 -0
  67. package/dist/components/trace-viewer.js +21 -0
  68. package/dist/components/ui/alert.js +2 -2
  69. package/dist/components/ui/button.d.ts +1 -1
  70. package/dist/components/ui/button.d.ts.map +1 -1
  71. package/dist/components/ui/button.js +3 -3
  72. package/dist/components/ui/card.d.ts.map +1 -1
  73. package/dist/components/ui/card.js +3 -3
  74. package/dist/components/ui/error-card.js +2 -2
  75. package/dist/components/ui/error-stack-block.js +4 -4
  76. package/dist/components/ui/kbd.js +3 -3
  77. package/dist/components/ui/timestamp-tooltip.js +3 -3
  78. package/dist/components/workflow-traces/trace-span-construction.d.ts +1 -1
  79. package/dist/components/workflow-traces/trace-span-construction.js +1 -1
  80. package/dist/lib/trace-builder.d.ts +1 -1
  81. package/dist/lib/trace-builder.d.ts.map +1 -1
  82. package/dist/lib/trace-builder.js +1 -1
  83. package/dist/lib/trace-types.d.ts +54 -0
  84. package/dist/lib/trace-types.d.ts.map +1 -0
  85. package/dist/lib/trace-types.js +2 -0
  86. package/package.json +5 -5
  87. package/src/components/event-list-view.tsx +12 -9
  88. package/src/components/index.ts +3 -5
  89. package/src/components/sidebar/attribute-panel.tsx +46 -8
  90. package/src/components/sidebar/attributes-block.tsx +2 -2
  91. package/src/components/sidebar/copyable-data-block.tsx +1 -1
  92. package/src/components/sidebar/entity-detail-panel.tsx +3 -3
  93. package/src/components/sidebar/events-list.tsx +1 -1
  94. package/src/components/stream-viewer.tsx +1 -1
  95. package/src/components/{new-trace-viewer → trace-viewer}/components/event-list.tsx +1 -1
  96. package/src/components/{new-trace-viewer → trace-viewer}/components/minimap.tsx +1 -4
  97. package/src/components/{new-trace-viewer → trace-viewer}/components/timeline.tsx +2 -5
  98. package/src/components/{new-trace-viewer → trace-viewer}/components/trace-shortcut-helper.tsx +1 -1
  99. package/src/components/trace-viewer/context.tsx +63 -656
  100. package/src/components/trace-viewer/trace-viewer.tsx +563 -531
  101. package/src/components/trace-viewer/types.ts +2 -234
  102. package/src/components/{new-trace-viewer → trace-viewer}/utils.ts +2 -2
  103. package/src/components/{trace-viewer-new.tsx → trace-viewer.tsx} +5 -5
  104. package/src/components/ui/alert.tsx +1 -1
  105. package/src/components/ui/button.tsx +3 -3
  106. package/src/components/ui/card.tsx +2 -9
  107. package/src/components/ui/error-card.tsx +3 -3
  108. package/src/components/ui/error-stack-block.tsx +3 -3
  109. package/src/components/ui/kbd.tsx +2 -2
  110. package/src/components/ui/timestamp-tooltip.tsx +4 -4
  111. package/src/components/workflow-traces/trace-span-construction.ts +1 -1
  112. package/src/lib/trace-builder.ts +1 -1
  113. package/src/lib/trace-types.ts +56 -0
  114. package/dist/components/new-trace-viewer/components/copy-button.d.ts.map +0 -1
  115. package/dist/components/new-trace-viewer/components/copy-button.js +0 -27
  116. package/dist/components/new-trace-viewer/components/detail-panel-width.d.ts.map +0 -1
  117. package/dist/components/new-trace-viewer/components/detail-panel-width.js +0 -67
  118. package/dist/components/new-trace-viewer/components/detail-panel.d.ts.map +0 -1
  119. package/dist/components/new-trace-viewer/components/detail-panel.js +0 -122
  120. package/dist/components/new-trace-viewer/components/draggable-border.d.ts.map +0 -1
  121. package/dist/components/new-trace-viewer/components/draggable-border.js +0 -140
  122. package/dist/components/new-trace-viewer/components/event-list.d.ts.map +0 -1
  123. package/dist/components/new-trace-viewer/components/event-list.js +0 -47
  124. package/dist/components/new-trace-viewer/components/middle-truncate/copy-selection.d.ts.map +0 -1
  125. package/dist/components/new-trace-viewer/components/middle-truncate/copy-selection.js +0 -54
  126. package/dist/components/new-trace-viewer/components/middle-truncate/middle-truncate.d.ts.map +0 -1
  127. package/dist/components/new-trace-viewer/components/middle-truncate/middle-truncate.js +0 -81
  128. package/dist/components/new-trace-viewer/components/middle-truncate/truncate.d.ts.map +0 -1
  129. package/dist/components/new-trace-viewer/components/middle-truncate/truncate.js +0 -101
  130. package/dist/components/new-trace-viewer/components/middle-truncate/use-middle-truncate.d.ts.map +0 -1
  131. package/dist/components/new-trace-viewer/components/middle-truncate/use-middle-truncate.js +0 -114
  132. package/dist/components/new-trace-viewer/components/minimap.d.ts.map +0 -1
  133. package/dist/components/new-trace-viewer/components/minimap.js +0 -337
  134. package/dist/components/new-trace-viewer/components/pane-constants.d.ts.map +0 -1
  135. package/dist/components/new-trace-viewer/components/pane-constants.js +0 -16
  136. package/dist/components/new-trace-viewer/components/span-markers.d.ts.map +0 -1
  137. package/dist/components/new-trace-viewer/components/span-markers.js +0 -85
  138. package/dist/components/new-trace-viewer/components/split-pane.d.ts.map +0 -1
  139. package/dist/components/new-trace-viewer/components/split-pane.js +0 -41
  140. package/dist/components/new-trace-viewer/components/timeline.d.ts.map +0 -1
  141. package/dist/components/new-trace-viewer/components/timeline.js +0 -321
  142. package/dist/components/new-trace-viewer/components/trace-shortcut-helper.d.ts.map +0 -1
  143. package/dist/components/new-trace-viewer/components/trace-shortcut-helper.js +0 -55
  144. package/dist/components/new-trace-viewer/components/trace-viewer-skeleton.d.ts.map +0 -1
  145. package/dist/components/new-trace-viewer/components/trace-viewer-skeleton.js +0 -26
  146. package/dist/components/new-trace-viewer/components/use-element-width.d.ts.map +0 -1
  147. package/dist/components/new-trace-viewer/components/use-element-width.js +0 -25
  148. package/dist/components/new-trace-viewer/components/use-row-window.d.ts.map +0 -1
  149. package/dist/components/new-trace-viewer/components/use-row-window.js +0 -107
  150. package/dist/components/new-trace-viewer/context.d.ts +0 -17
  151. package/dist/components/new-trace-viewer/context.d.ts.map +0 -1
  152. package/dist/components/new-trace-viewer/context.js +0 -48
  153. package/dist/components/new-trace-viewer/icons.d.ts.map +0 -1
  154. package/dist/components/new-trace-viewer/icons.js +0 -15
  155. package/dist/components/new-trace-viewer/search.d.ts.map +0 -1
  156. package/dist/components/new-trace-viewer/search.js +0 -134
  157. package/dist/components/new-trace-viewer/trace-viewer.d.ts +0 -11
  158. package/dist/components/new-trace-viewer/trace-viewer.d.ts.map +0 -1
  159. package/dist/components/new-trace-viewer/trace-viewer.js +0 -336
  160. package/dist/components/new-trace-viewer/types.d.ts +0 -3
  161. package/dist/components/new-trace-viewer/types.d.ts.map +0 -1
  162. package/dist/components/new-trace-viewer/types.js +0 -2
  163. package/dist/components/new-trace-viewer/utils.d.ts.map +0 -1
  164. package/dist/components/new-trace-viewer/utils.js +0 -430
  165. package/dist/components/run-trace-view.d.ts +0 -23
  166. package/dist/components/run-trace-view.d.ts.map +0 -1
  167. package/dist/components/run-trace-view.js +0 -11
  168. package/dist/components/trace-viewer/components/map.d.ts +0 -8
  169. package/dist/components/trace-viewer/components/map.d.ts.map +0 -1
  170. package/dist/components/trace-viewer/components/map.js +0 -162
  171. package/dist/components/trace-viewer/components/markers.d.ts +0 -23
  172. package/dist/components/trace-viewer/components/markers.d.ts.map +0 -1
  173. package/dist/components/trace-viewer/components/markers.js +0 -416
  174. package/dist/components/trace-viewer/components/node.d.ts +0 -35
  175. package/dist/components/trace-viewer/components/node.d.ts.map +0 -1
  176. package/dist/components/trace-viewer/components/node.js +0 -286
  177. package/dist/components/trace-viewer/components/search-input.d.ts +0 -9
  178. package/dist/components/trace-viewer/components/search-input.d.ts.map +0 -1
  179. package/dist/components/trace-viewer/components/search-input.js +0 -9
  180. package/dist/components/trace-viewer/components/search.d.ts +0 -3
  181. package/dist/components/trace-viewer/components/search.d.ts.map +0 -1
  182. package/dist/components/trace-viewer/components/search.js +0 -25
  183. package/dist/components/trace-viewer/components/span-content.d.ts +0 -19
  184. package/dist/components/trace-viewer/components/span-content.d.ts.map +0 -1
  185. package/dist/components/trace-viewer/components/span-content.js +0 -137
  186. package/dist/components/trace-viewer/components/span-detail-panel.d.ts +0 -10
  187. package/dist/components/trace-viewer/components/span-detail-panel.d.ts.map +0 -1
  188. package/dist/components/trace-viewer/components/span-detail-panel.js +0 -285
  189. package/dist/components/trace-viewer/components/span-segments.d.ts +0 -50
  190. package/dist/components/trace-viewer/components/span-segments.d.ts.map +0 -1
  191. package/dist/components/trace-viewer/components/span-segments.js +0 -445
  192. package/dist/components/trace-viewer/components/span-strategies.d.ts +0 -46
  193. package/dist/components/trace-viewer/components/span-strategies.d.ts.map +0 -1
  194. package/dist/components/trace-viewer/components/span-strategies.js +0 -108
  195. package/dist/components/trace-viewer/components/ui.d.ts +0 -28
  196. package/dist/components/trace-viewer/components/ui.d.ts.map +0 -1
  197. package/dist/components/trace-viewer/components/ui.js +0 -39
  198. package/dist/components/trace-viewer/components/zoom-button.d.ts +0 -3
  199. package/dist/components/trace-viewer/components/zoom-button.d.ts.map +0 -1
  200. package/dist/components/trace-viewer/components/zoom-button.js +0 -29
  201. package/dist/components/trace-viewer/components/zoom-icons.d.ts +0 -11
  202. package/dist/components/trace-viewer/components/zoom-icons.d.ts.map +0 -1
  203. package/dist/components/trace-viewer/components/zoom-icons.js +0 -11
  204. package/dist/components/trace-viewer/index.d.ts +0 -5
  205. package/dist/components/trace-viewer/index.d.ts.map +0 -1
  206. package/dist/components/trace-viewer/index.js +0 -4
  207. package/dist/components/trace-viewer/trace-viewer.module.css +0 -1465
  208. package/dist/components/trace-viewer/util/constants.d.ts +0 -9
  209. package/dist/components/trace-viewer/util/constants.d.ts.map +0 -1
  210. package/dist/components/trace-viewer/util/constants.js +0 -9
  211. package/dist/components/trace-viewer/util/scrollbar-width.d.ts +0 -2
  212. package/dist/components/trace-viewer/util/scrollbar-width.d.ts.map +0 -1
  213. package/dist/components/trace-viewer/util/scrollbar-width.js +0 -14
  214. package/dist/components/trace-viewer/util/tree.d.ts +0 -13
  215. package/dist/components/trace-viewer/util/tree.d.ts.map +0 -1
  216. package/dist/components/trace-viewer/util/tree.js +0 -227
  217. package/dist/components/trace-viewer/util/use-immediate-style.d.ts +0 -15
  218. package/dist/components/trace-viewer/util/use-immediate-style.d.ts.map +0 -1
  219. package/dist/components/trace-viewer/util/use-immediate-style.js +0 -23
  220. package/dist/components/trace-viewer/util/use-streaming-spans.d.ts +0 -8
  221. package/dist/components/trace-viewer/util/use-streaming-spans.d.ts.map +0 -1
  222. package/dist/components/trace-viewer/util/use-streaming-spans.js +0 -345
  223. package/dist/components/trace-viewer/util/use-trackpad-zoom.d.ts +0 -6
  224. package/dist/components/trace-viewer/util/use-trackpad-zoom.d.ts.map +0 -1
  225. package/dist/components/trace-viewer/util/use-trackpad-zoom.js +0 -39
  226. package/dist/components/trace-viewer/worker.d.ts +0 -2
  227. package/dist/components/trace-viewer/worker.d.ts.map +0 -1
  228. package/dist/components/trace-viewer/worker.js +0 -109
  229. package/dist/components/trace-viewer-new.d.ts.map +0 -1
  230. package/dist/components/trace-viewer-new.js +0 -21
  231. package/dist/components/workflow-trace-view.d.ts +0 -39
  232. package/dist/components/workflow-trace-view.d.ts.map +0 -1
  233. package/dist/components/workflow-trace-view.js +0 -690
  234. package/dist/components/workflow-traces/trace-colors.d.ts +0 -15
  235. package/dist/components/workflow-traces/trace-colors.d.ts.map +0 -1
  236. package/dist/components/workflow-traces/trace-colors.js +0 -86
  237. package/src/components/new-trace-viewer/context.tsx +0 -93
  238. package/src/components/new-trace-viewer/trace-viewer.tsx +0 -632
  239. package/src/components/new-trace-viewer/types.ts +0 -2
  240. package/src/components/run-trace-view.tsx +0 -80
  241. package/src/components/trace-viewer/components/map.tsx +0 -226
  242. package/src/components/trace-viewer/components/markers.tsx +0 -612
  243. package/src/components/trace-viewer/components/node.tsx +0 -506
  244. package/src/components/trace-viewer/components/search-input.tsx +0 -52
  245. package/src/components/trace-viewer/components/search.tsx +0 -47
  246. package/src/components/trace-viewer/components/span-content.tsx +0 -247
  247. package/src/components/trace-viewer/components/span-detail-panel.tsx +0 -655
  248. package/src/components/trace-viewer/components/span-segments.ts +0 -585
  249. package/src/components/trace-viewer/components/span-strategies.ts +0 -205
  250. package/src/components/trace-viewer/components/ui.tsx +0 -156
  251. package/src/components/trace-viewer/components/zoom-button.tsx +0 -61
  252. package/src/components/trace-viewer/components/zoom-icons.tsx +0 -65
  253. package/src/components/trace-viewer/index.tsx +0 -4
  254. package/src/components/trace-viewer/trace-viewer.module.css +0 -1465
  255. package/src/components/trace-viewer/util/constants.ts +0 -8
  256. package/src/components/trace-viewer/util/scrollbar-width.ts +0 -13
  257. package/src/components/trace-viewer/util/tree.ts +0 -277
  258. package/src/components/trace-viewer/util/use-immediate-style.ts +0 -38
  259. package/src/components/trace-viewer/util/use-streaming-spans.ts +0 -426
  260. package/src/components/trace-viewer/util/use-trackpad-zoom.tsx +0 -51
  261. package/src/components/trace-viewer/worker.ts +0 -131
  262. package/src/components/workflow-trace-view.tsx +0 -1166
  263. package/src/components/workflow-traces/trace-colors.ts +0 -112
  264. package/dist/components/{new-trace-viewer → trace-viewer}/components/copy-button.d.ts +0 -0
  265. package/dist/components/{new-trace-viewer → trace-viewer}/components/detail-panel-width.d.ts +0 -0
  266. package/dist/components/{new-trace-viewer → trace-viewer}/components/detail-panel.d.ts +0 -0
  267. package/dist/components/{new-trace-viewer → trace-viewer}/components/draggable-border.d.ts +0 -0
  268. package/dist/components/{new-trace-viewer → trace-viewer}/components/event-list.d.ts +0 -0
  269. package/dist/components/{new-trace-viewer → trace-viewer}/components/middle-truncate/copy-selection.d.ts +0 -0
  270. package/dist/components/{new-trace-viewer → trace-viewer}/components/middle-truncate/middle-truncate.d.ts +0 -0
  271. package/dist/components/{new-trace-viewer → trace-viewer}/components/middle-truncate/truncate.d.ts +0 -0
  272. package/dist/components/{new-trace-viewer → trace-viewer}/components/middle-truncate/use-middle-truncate.d.ts +0 -0
  273. package/dist/components/{new-trace-viewer → trace-viewer}/components/minimap.d.ts +0 -0
  274. package/dist/components/{new-trace-viewer → trace-viewer}/components/pane-constants.d.ts +0 -0
  275. package/dist/components/{new-trace-viewer → trace-viewer}/components/span-markers.d.ts +0 -0
  276. package/dist/components/{new-trace-viewer → trace-viewer}/components/split-pane.d.ts +0 -0
  277. package/dist/components/{new-trace-viewer → trace-viewer}/components/timeline.d.ts +0 -0
  278. package/dist/components/{new-trace-viewer → trace-viewer}/components/timeline.module.css +0 -0
  279. package/dist/components/{new-trace-viewer → trace-viewer}/components/trace-shortcut-helper.d.ts +0 -0
  280. package/dist/components/{new-trace-viewer → trace-viewer}/components/trace-shortcut-helper.module.css +0 -0
  281. package/dist/components/{new-trace-viewer → trace-viewer}/components/trace-viewer-skeleton.d.ts +0 -0
  282. package/dist/components/{new-trace-viewer → trace-viewer}/components/use-element-width.d.ts +0 -0
  283. package/dist/components/{new-trace-viewer → trace-viewer}/components/use-row-window.d.ts +0 -0
  284. package/dist/components/{new-trace-viewer → trace-viewer}/icons.d.ts +0 -0
  285. package/dist/components/{new-trace-viewer → trace-viewer}/search.d.ts +0 -0
  286. package/dist/components/{new-trace-viewer → trace-viewer}/utils.d.ts +0 -0
  287. package/src/components/{new-trace-viewer → trace-viewer}/components/copy-button.tsx +0 -0
  288. package/src/components/{new-trace-viewer → trace-viewer}/components/detail-panel-width.test.ts +0 -0
  289. package/src/components/{new-trace-viewer → trace-viewer}/components/detail-panel-width.ts +0 -0
  290. package/src/components/{new-trace-viewer → trace-viewer}/components/detail-panel.tsx +0 -0
  291. package/src/components/{new-trace-viewer → trace-viewer}/components/draggable-border.tsx +0 -0
  292. package/src/components/{new-trace-viewer → trace-viewer}/components/middle-truncate/copy-selection.ts +0 -0
  293. package/src/components/{new-trace-viewer → trace-viewer}/components/middle-truncate/middle-truncate.tsx +1 -1
  294. /package/src/components/{new-trace-viewer → trace-viewer}/components/middle-truncate/truncate.ts +0 -0
  295. /package/src/components/{new-trace-viewer → trace-viewer}/components/middle-truncate/use-middle-truncate.ts +0 -0
  296. /package/src/components/{new-trace-viewer → trace-viewer}/components/pane-constants.ts +0 -0
  297. /package/src/components/{new-trace-viewer → trace-viewer}/components/span-markers.tsx +0 -0
  298. /package/src/components/{new-trace-viewer → trace-viewer}/components/split-pane.tsx +0 -0
  299. /package/src/components/{new-trace-viewer → trace-viewer}/components/timeline.module.css +0 -0
  300. /package/src/components/{new-trace-viewer → trace-viewer}/components/trace-shortcut-helper.module.css +0 -0
  301. /package/src/components/{new-trace-viewer → trace-viewer}/components/trace-viewer-skeleton.tsx +0 -0
  302. /package/src/components/{new-trace-viewer → trace-viewer}/components/use-element-width.ts +0 -0
  303. /package/src/components/{new-trace-viewer → trace-viewer}/components/use-row-window.ts +0 -0
  304. /package/src/components/{new-trace-viewer → trace-viewer}/icons.tsx +0 -0
  305. /package/src/components/{new-trace-viewer → trace-viewer}/search.ts +0 -0
  306. /package/src/components/{new-trace-viewer → trace-viewer}/utils.test.ts +0 -0
  307. /package/src/{components/trace-viewer/modules.d.ts → modules.d.ts} +0 -0
@@ -1,386 +1,336 @@
1
1
  'use client';
2
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
- import { clsx } from 'clsx';
4
- import { useCallback, useEffect, useLayoutEffect, useRef } from 'react';
5
- import { MiniMap } from './components/map';
6
- import { CursorMarker, EventMarkers, Markers } from './components/markers';
7
- import { SpanNodes } from './components/node';
8
- import { SearchBar } from './components/search';
9
- import { SpanDetailPanel } from './components/span-detail-panel';
10
- import { ZoomButton } from './components/zoom-button';
11
- import { TraceViewerContextProvider, useTraceViewer } from './context';
12
- import styles from './trace-viewer.module.css';
13
- import { MAP_HEIGHT, MARKER_HEIGHT, MARKER_NOTCH_HEIGHT, ROW_HEIGHT, ROW_PADDING, SEARCH_GAP, SEARCH_HEIGHT, TIMELINE_PADDING, } from './util/constants';
14
- import { parseTrace } from './util/tree';
15
- import { useStreamingSpans } from './util/use-streaming-spans';
16
- export function TraceViewerProvider({ getQuickLinks, children, }) {
17
- return (_jsx(TraceViewerContextProvider, { getQuickLinks: getQuickLinks, children: children }));
18
- }
19
- const skeletonTrace = {
20
- traceId: 'skeleton',
21
- spans: [
22
- {
23
- parentSpanId: '',
24
- spanId: 'root',
25
- name: 'root span',
26
- kind: 1,
27
- resource: 'vercel.runtime',
28
- startTime: [5000, 0],
29
- endTime: [6000, 0],
30
- duration: [1000, 0],
31
- library: {
32
- name: 'vercel-site',
33
- },
34
- status: {
35
- code: 1,
36
- },
37
- attributes: {
38
- 'vercel.ownerId': 'team_abc',
39
- },
40
- traceFlags: 1,
41
- events: [],
42
- links: [],
43
- },
44
- ],
45
- resources: [
46
- {
47
- name: 'vercel.runtime',
48
- attributes: {},
49
- },
50
- ],
51
- rootSpanId: 'root',
52
- };
53
- export function TraceViewerTimeline({ trace = skeletonTrace, className = '', scrollLock = false, height, withPanel = false, highlightedSpans, eagerRender = false, isLive = false, footer, knownDurationMs, hasMoreData = false, }) {
54
- const isSkeleton = trace === skeletonTrace;
55
- const { state, dispatch } = useTraceViewer();
56
- const { timelineRef, scrollSnapshotRef } = state;
57
- const memoCache = state.memoCacheRef.current;
58
- const hideSearchBar = (highlightedSpans?.length ?? 0) > 0;
59
- const hasInitializedRef = useRef(false);
60
- const prevSpanKeyRef = useRef('');
61
- const prevRootRef = useRef(null);
62
- const prevSpanMapRef = useRef({});
63
- const prevSizeRef = useRef(null);
64
- useEffect(() => {
65
- const { root: newRoot, map: newSpanMap } = parseTrace(trace);
66
- const isInitial = !hasInitializedRef.current;
67
- hasInitializedRef.current = true;
68
- // Build a structural key from span IDs + lightweight event signatures.
69
- // When only timing changes (same spans and boundary events), we can skip the
70
- // worker restart. When events change (step completed, etc.) we need a
71
- // full update because the VisibleSpan objects rendered by React hold
72
- // copies of the events from the worker — in-place mutation won't reach them.
73
- const spanKey = Object.keys(newSpanMap)
74
- .sort()
75
- .map((id) => {
76
- const events = newSpanMap[id].events;
77
- const count = events?.length ?? 0;
78
- const first = count ? events?.[0] : undefined;
79
- const last = count ? events?.[count - 1] : undefined;
80
- const eventSignature = `${first?.event.name ?? 'none'}@${first?.timestamp ?? 0}|${last?.event.name ?? 'none'}@${last?.timestamp ?? 0}`;
81
- return `${id}:${count}:${eventSignature}`;
82
- })
83
- .join(',');
84
- if (!isInitial &&
85
- spanKey === prevSpanKeyRef.current &&
86
- prevRootRef.current) {
87
- // Same span set, same event counts — only timing changed.
88
- // Mutate in-place so the worker effect (which depends on root/spanMap
89
- // references) does NOT restart.
90
- const oldRoot = prevRootRef.current;
91
- const oldSpanMap = prevSpanMapRef.current;
92
- let didChange = false;
93
- if (oldRoot.endTime !== newRoot.endTime ||
94
- oldRoot.duration !== newRoot.duration) {
95
- oldRoot.endTime = newRoot.endTime;
96
- oldRoot.duration = newRoot.duration;
97
- didChange = true;
98
- }
99
- for (const [id, newNode] of Object.entries(newSpanMap)) {
100
- const oldNode = oldSpanMap[id];
101
- if (oldNode) {
102
- if (oldNode.endTime !== newNode.endTime ||
103
- oldNode.duration !== newNode.duration) {
104
- oldNode.endTime = newNode.endTime;
105
- oldNode.duration = newNode.duration;
106
- didChange = true;
107
- }
108
- Object.assign(oldNode.span, newNode.span);
109
- }
110
- }
111
- if (!didChange) {
112
- return;
113
- }
114
- // Trigger re-render (scale/markers) without restarting the worker.
115
- // useLiveTick handles continuous scale recalculation for live runs.
116
- dispatch({ type: 'forceRender' });
117
- return;
2
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
3
+ import { RotateCcw, Search, ZoomIn, ZoomOut } from 'lucide-react';
4
+ import { useCallback, useDeferredValue, useEffect, useMemo, useRef, useState, } from 'react';
5
+ import { useLoadMoreOnScroll } from '../../hooks/use-load-more-on-scroll';
6
+ import { useReducedMotion } from '../../hooks/use-reduced-motion';
7
+ import { IconButton } from '../ui/icon-button';
8
+ import { Kbd } from '../ui/kbd';
9
+ import { Spinner } from '../ui/spinner';
10
+ import { TooltipProvider } from '../ui/tooltip';
11
+ import { TraceDetailPanel } from './components/detail-panel';
12
+ import EventList from './components/event-list';
13
+ import { Minimap } from './components/minimap';
14
+ import { SplitPane } from './components/split-pane';
15
+ import { TIMELINE_PADDING_PX, Timeline, TimelineHeader, } from './components/timeline';
16
+ import { TraceShortcutHelper } from './components/trace-shortcut-helper';
17
+ import { ROW_HEIGHT_PX, scrollRowIntoView } from './components/use-row-window';
18
+ import { ActiveSpanProvider, useActiveSpan } from './context';
19
+ import { searchSpans } from './search';
20
+ import { formatDurationPrecise, getHighResInMs } from './util/timing';
21
+ import { clampViewportToRoot, computeRootBounds, computeTimeMarkers, wheelDeltaToPixels, wheelZoomScaleFactor, } from './utils';
22
+ const MIN_VIEWPORT_MS = 0.001;
23
+ const ZOOM_DEBOUNCE_MS = 150;
24
+ function useAnimatedViewport(initial) {
25
+ const [viewport, setViewportState] = useState(initial);
26
+ const animRef = useRef(null);
27
+ const currentRef = useRef(initial);
28
+ currentRef.current = viewport;
29
+ const reducedMotion = useReducedMotion();
30
+ const cancel = useCallback(() => {
31
+ if (animRef.current) {
32
+ cancelAnimationFrame(animRef.current.raf);
33
+ animRef.current = null;
118
34
  }
119
- // Structure changed or initial load — full dispatch (worker computes new rows)
120
- prevSpanKeyRef.current = spanKey;
121
- prevRootRef.current = newRoot;
122
- prevSpanMapRef.current = newSpanMap;
123
- dispatch({
124
- type: isInitial ? 'setRoot' : 'updateRoot',
125
- root: newRoot,
126
- spanMap: newSpanMap,
127
- resources: trace.resources || [],
128
- });
129
- }, [dispatch, trace]);
130
- const { rows, spans, events, scale } = useStreamingSpans(highlightedSpans, eagerRender);
131
- const ref = useRef(null);
132
- useLayoutEffect(() => {
133
- const $el = ref.current;
134
- if (!$el)
35
+ }, []);
36
+ const animateTo = useCallback((target) => {
37
+ cancel();
38
+ if (reducedMotion) {
39
+ currentRef.current = target;
40
+ setViewportState(target);
135
41
  return;
136
- const onResize = () => {
137
- const padding = 2 * TIMELINE_PADDING;
138
- const rect = $el.getBoundingClientRect();
139
- const nextWidth = rect.width - padding;
140
- const nextHeight = rect.height;
141
- const prevSize = prevSizeRef.current;
142
- if (prevSize &&
143
- prevSize.width === nextWidth &&
144
- prevSize.height === nextHeight) {
145
- return;
146
- }
147
- prevSizeRef.current = { width: nextWidth, height: nextHeight };
148
- dispatch({
149
- type: 'setSize',
150
- width: nextWidth,
151
- height: nextHeight,
42
+ }
43
+ const from = currentRef.current;
44
+ const anim = { raf: 0, from, to: target, start: performance.now() };
45
+ const tick = () => {
46
+ const t = Math.min((performance.now() - anim.start) / 240, 1);
47
+ const e = t < 0.5 ? 8 * t * t * t * t : 1 - (-2 * t + 2) ** 4 / 2;
48
+ setViewportState({
49
+ start: anim.from.start + (anim.to.start - anim.from.start) * e,
50
+ end: anim.from.end + (anim.to.end - anim.from.end) * e,
152
51
  });
52
+ if (t < 1)
53
+ anim.raf = requestAnimationFrame(tick);
54
+ else
55
+ animRef.current = null;
153
56
  };
154
- onResize();
155
- const observer = new ResizeObserver(onResize);
156
- observer.observe($el);
157
- window.addEventListener('resize', onResize);
158
- return () => {
159
- observer.disconnect();
160
- window.removeEventListener('resize', onResize);
161
- };
162
- }, [dispatch]);
163
- const lastClickRef = useRef({
164
- t: 0,
165
- x: -1,
166
- y: -1,
167
- spanId: '',
57
+ animRef.current = anim;
58
+ anim.raf = requestAnimationFrame(tick);
59
+ }, [cancel, reducedMotion]);
60
+ const setViewport = useCallback((update) => {
61
+ cancel();
62
+ if (typeof update === 'function') {
63
+ setViewportState((prev) => {
64
+ const next = update(prev);
65
+ currentRef.current = next;
66
+ return next;
67
+ });
68
+ }
69
+ else {
70
+ currentRef.current = update;
71
+ setViewportState(update);
72
+ }
73
+ }, [cancel]);
74
+ useEffect(() => cancel, [cancel]);
75
+ return { viewport, setViewport, animateTo };
76
+ }
77
+ // ---------------------------------------------------------------------------
78
+ // Root component
79
+ // ---------------------------------------------------------------------------
80
+ export function TraceViewer({ trace, onLoadMore, hasMore, isLoadingMore, }) {
81
+ return (_jsx(TooltipProvider, { delayDuration: 300, children: _jsx(ActiveSpanProvider, { spans: trace.spans, children: _jsx(TraceViewerContent, { trace: trace, onLoadMore: onLoadMore, hasMore: hasMore, isLoadingMore: isLoadingMore }) }) }));
82
+ }
83
+ function TraceViewerContent({ trace, onLoadMore, hasMore, isLoadingMore, }) {
84
+ const { activeSpanId, setActiveSpan, clearActiveSpan } = useActiveSpan();
85
+ const reducedMotion = useReducedMotion();
86
+ const [searchQuery, setSearchQuery] = useState('');
87
+ const deferredSearchQuery = useDeferredValue(searchQuery);
88
+ const paneRootRef = useRef(null);
89
+ const searchResult = useMemo(() => searchSpans(trace.spans, deferredSearchQuery), [trace.spans, deferredSearchQuery]);
90
+ const root = useMemo(() => computeRootBounds(trace.spans), [trace.spans]);
91
+ const scrollContainerRef = useRef(null);
92
+ const loadMore = useCallback(() => {
93
+ void onLoadMore?.();
94
+ }, [onLoadMore]);
95
+ const loadMoreSentinelRef = useLoadMoreOnScroll(loadMore, {
96
+ hasMore: Boolean(onLoadMore && hasMore),
97
+ isLoadingMore: Boolean(isLoadingMore),
98
+ rootRef: scrollContainerRef,
168
99
  });
169
- const onClick = useCallback((event) => {
170
- // NOTE(wits): We manually implement double-click logic here so that we can support double
171
- // clicking a span even if the first click moves the span that the user is clicking on due
172
- // to the panel opening. If we used a regular double click listener we would need to delay
173
- // the opening of the panel artificially. This implementation allows us to always be
174
- // FAST while also avoiding a FRUSTRATING situation.
175
- const prev = lastClickRef.current;
176
- const t = Date.now();
177
- const { clientX: x, clientY: y } = event;
178
- const d = Math.sqrt((x - prev.x) ** 2 + (y - prev.y) ** 2);
179
- // double click
180
- if (t - prev.t <= 500 && d <= 8) {
181
- event.stopPropagation();
182
- event.preventDefault();
183
- if (!prev.spanId) {
184
- dispatch({
185
- type: 'resetScale',
186
- });
187
- return;
100
+ const { viewport, setViewport, animateTo } = useAnimatedViewport({
101
+ start: root.startTime,
102
+ end: root.startTime + root.duration,
103
+ });
104
+ const prevRootRef = useRef({
105
+ start: root.startTime,
106
+ end: root.startTime + root.duration,
107
+ });
108
+ useEffect(() => {
109
+ const prevRoot = prevRootRef.current;
110
+ const newStart = root.startTime;
111
+ const newEnd = root.startTime + root.duration;
112
+ setViewport((prev) => {
113
+ const wasAtFullExtent = Math.abs(prev.start - prevRoot.start) < 0.01 &&
114
+ Math.abs(prev.end - prevRoot.end) < 0.01;
115
+ if (wasAtFullExtent) {
116
+ return { start: newStart, end: newEnd };
188
117
  }
189
- dispatch({
190
- type: 'select',
191
- id: prev.spanId,
192
- });
193
- dispatch({
194
- type: 'scaleToNode',
195
- id: prev.spanId,
196
- });
118
+ return prev;
119
+ });
120
+ prevRootRef.current = { start: newStart, end: newEnd };
121
+ }, [root.startTime, root.duration, setViewport]);
122
+ const viewDuration = viewport.end - viewport.start;
123
+ // Keep a ref to the live viewport so zoom callbacks can read the current
124
+ // range without being recreated on every pan (which would bust TimelineBar's
125
+ // memo and re-render every row each animation frame).
126
+ const viewportRef = useRef(viewport);
127
+ viewportRef.current = viewport;
128
+ const timeMarkers = useMemo(() => computeTimeMarkers(viewDuration, viewport.start - root.startTime), [viewDuration, viewport.start, root.startTime]);
129
+ const resetZoom = useCallback(() => {
130
+ animateTo({ start: root.startTime, end: root.startTime + root.duration });
131
+ }, [animateTo, root.startTime, root.duration]);
132
+ const clampToRoot = useCallback((next) => clampViewportToRoot(next, root.startTime, root.endTime, MIN_VIEWPORT_MS), [root.startTime, root.endTime]);
133
+ // Pan (keeping the current zoom) so `timeMs` is centered in view — used by the
134
+ // off-screen marker indicators to scroll their marker into view.
135
+ const handleRevealTime = useCallback((timeMs) => {
136
+ const { start, end } = viewportRef.current;
137
+ const duration = end - start;
138
+ animateTo(clampToRoot({
139
+ start: timeMs - duration / 2,
140
+ end: timeMs + duration / 2,
141
+ }));
142
+ }, [animateTo, clampToRoot]);
143
+ const ZOOM_FACTOR = 0.5;
144
+ const zoomBy = useCallback((factor) => {
145
+ const { start, end } = viewportRef.current;
146
+ const center = (start + end) / 2;
147
+ const newDuration = Math.max(MIN_VIEWPORT_MS, (end - start) * factor);
148
+ animateTo(clampToRoot({
149
+ start: center - newDuration / 2,
150
+ end: center + newDuration / 2,
151
+ }));
152
+ }, [animateTo, clampToRoot]);
153
+ const zoomIn = useCallback(() => zoomBy(ZOOM_FACTOR), [zoomBy]);
154
+ const zoomOut = useCallback(() => zoomBy(1 / ZOOM_FACTOR), [zoomBy]);
155
+ const isAtMinZoom = viewDuration >= root.duration;
156
+ const isAtMaxZoom = viewDuration <= MIN_VIEWPORT_MS;
157
+ const focusViewportOnSpan = useCallback((spanId) => {
158
+ const span = trace.spans.find((s) => s.spanId === spanId);
159
+ if (!span)
197
160
  return;
198
- }
199
- const target = event.target;
200
- if (!target.closest(`.${String(styles.timeline)}`))
161
+ const spanStart = getHighResInMs(span.startTime);
162
+ const spanEnd = getHighResInMs(span.endTime);
163
+ const spanDuration = spanEnd - spanStart;
164
+ if (spanDuration > root.duration * 0.8) {
165
+ animateTo({ start: root.startTime, end: root.endTime });
201
166
  return;
202
- const $button = target.closest('[data-span-id]');
203
- const spanId = $button?.dataset.spanId || '';
204
- lastClickRef.current = {
205
- x,
206
- y,
207
- t,
208
- spanId,
209
- };
210
- if (!spanId)
167
+ }
168
+ const padding = Math.max(spanDuration * 0.2, MIN_VIEWPORT_MS / 2);
169
+ let newStart = spanStart - padding;
170
+ let newEnd = spanEnd + padding;
171
+ if (newEnd - newStart < MIN_VIEWPORT_MS) {
172
+ const center = (spanStart + spanEnd) / 2;
173
+ newStart = center - MIN_VIEWPORT_MS / 2;
174
+ newEnd = center + MIN_VIEWPORT_MS / 2;
175
+ }
176
+ animateTo(clampToRoot({ start: newStart, end: newEnd }));
177
+ }, [
178
+ animateTo,
179
+ trace.spans,
180
+ root.startTime,
181
+ root.endTime,
182
+ root.duration,
183
+ clampToRoot,
184
+ ]);
185
+ // Bring a row into view when keyboard/button navigation lands on a span that
186
+ // sits outside the shared scroll container's visible area. The list is
187
+ // windowed, so an off-screen row has no DOM node to `scrollIntoView` —
188
+ // `scrollRowIntoView` computes the target offset from the span's index.
189
+ const scrollSpanIntoView = useCallback((spanId) => {
190
+ const index = trace.spans.findIndex((s) => s.spanId === spanId);
191
+ if (index === -1)
211
192
  return;
212
- dispatch({
213
- type: 'toggleSelection',
214
- id: spanId,
193
+ const list = scrollContainerRef.current?.querySelector('#event-list') ??
194
+ null;
195
+ scrollRowIntoView(list, index, ROW_HEIGHT_PX, {
196
+ behavior: reducedMotion ? 'auto' : 'smooth',
215
197
  });
216
- event.stopPropagation();
217
- }, [dispatch]);
218
- // Zoom helper apply the scroll snapshot once after a zoom operation so
219
- // the anchor point stays at the same screen position, then clear it.
220
- // Without clearing, live runs (where scale changes every frame via
221
- // detectBaseScale) would continuously reset scrollLeft and prevent the
222
- // user from scrolling horizontally.
223
- useLayoutEffect(() => {
224
- const $timeline = timelineRef.current;
225
- if (!$timeline)
226
- return;
227
- const snapshot = scrollSnapshotRef.current;
228
- if (snapshot) {
229
- $timeline.scrollLeft = snapshot.anchorT * scale - snapshot.anchorX;
230
- scrollSnapshotRef.current = undefined;
198
+ }, [trace.spans, reducedMotion]);
199
+ const zoomTimerRef = useRef(null);
200
+ const cancelPendingZoom = useCallback(() => {
201
+ if (zoomTimerRef.current !== null) {
202
+ clearTimeout(zoomTimerRef.current);
203
+ zoomTimerRef.current = null;
231
204
  }
232
- }, [scrollSnapshotRef, timelineRef, scale]);
233
- // Selection helper
234
- useEffect(() => {
235
- const spanId = state.selected?.span.spanId;
236
- if (!spanId)
205
+ }, []);
206
+ useEffect(() => cancelPendingZoom, [cancelPendingZoom]);
207
+ const handleClearActiveSpan = useCallback(() => {
208
+ cancelPendingZoom();
209
+ clearActiveSpan();
210
+ }, [cancelPendingZoom, clearActiveSpan]);
211
+ const handleSelectSpan = useCallback((spanId) => {
212
+ cancelPendingZoom();
213
+ if (spanId === activeSpanId) {
214
+ clearActiveSpan();
237
215
  return;
238
- const timeout = setTimeout(() => {
239
- const $timeline = state.timelineRef.current;
240
- const $span = $timeline?.querySelector(`[data-span-id="${spanId}"]`);
241
- if (!$timeline || !$span)
242
- return;
243
- const viewRect = $timeline.getBoundingClientRect();
244
- const spanRect = $span.getBoundingClientRect();
245
- // If the selected span is narrower than the timeline, scroll it into view
246
- if (spanRect.width < viewRect.width &&
247
- (spanRect.left < viewRect.left ||
248
- spanRect.right > viewRect.right ||
249
- spanRect.top < viewRect.top ||
250
- spanRect.bottom > viewRect.bottom)) {
251
- $span.scrollIntoView({
252
- block: 'nearest',
253
- inline: 'center',
254
- behavior: 'smooth',
255
- });
256
- }
257
- }, 500);
258
- return () => {
259
- clearTimeout(timeout);
260
- };
261
- }, [state.selected, state.timelineRef]);
262
- // Global keyboard shortcuts
216
+ }
217
+ setActiveSpan(spanId);
218
+ focusViewportOnSpan(spanId);
219
+ }, [
220
+ cancelPendingZoom,
221
+ activeSpanId,
222
+ clearActiveSpan,
223
+ setActiveSpan,
224
+ focusViewportOnSpan,
225
+ ]);
226
+ const navigateToSpan = useCallback((spanId) => {
227
+ setActiveSpan(spanId);
228
+ scrollSpanIntoView(spanId);
229
+ cancelPendingZoom();
230
+ zoomTimerRef.current = setTimeout(() => {
231
+ zoomTimerRef.current = null;
232
+ focusViewportOnSpan(spanId);
233
+ }, ZOOM_DEBOUNCE_MS);
234
+ }, [setActiveSpan, scrollSpanIntoView, cancelPendingZoom, focusViewportOnSpan]);
235
+ const [altHeld, setAltHeld] = useState(false);
263
236
  useEffect(() => {
264
237
  const onKeyDown = (e) => {
265
238
  if (e.key === 'Escape') {
266
- dispatch({
267
- type: 'escape',
268
- });
239
+ handleClearActiveSpan();
269
240
  }
241
+ else if (e.key === 'Alt') {
242
+ setAltHeld(true);
243
+ }
244
+ };
245
+ const onKeyUp = (e) => {
246
+ if (e.key === 'Alt')
247
+ setAltHeld(false);
270
248
  };
249
+ const onBlur = () => setAltHeld(false);
271
250
  window.addEventListener('keydown', onKeyDown);
251
+ window.addEventListener('keyup', onKeyUp);
252
+ window.addEventListener('blur', onBlur);
272
253
  return () => {
273
254
  window.removeEventListener('keydown', onKeyDown);
255
+ window.removeEventListener('keyup', onKeyUp);
256
+ window.removeEventListener('blur', onBlur);
274
257
  };
275
- }, [dispatch]);
276
- // Scroll locking
258
+ }, [handleClearActiveSpan]);
259
+ const timelineRef = useRef(null);
260
+ const [hover, setHover] = useState(null);
261
+ const hoverInfo = useMemo(() => {
262
+ if (hover == null)
263
+ return null;
264
+ const absTime = viewport.start + hover.fraction * viewDuration;
265
+ const offset = absTime - root.startTime;
266
+ return { fraction: hover.fraction, label: formatDurationPrecise(offset) };
267
+ }, [hover, viewport.start, viewDuration, root.startTime]);
268
+ const handleTimelineMouseMove = useCallback((e) => {
269
+ const el = timelineRef.current;
270
+ if (!el)
271
+ return;
272
+ const rect = el.getBoundingClientRect();
273
+ const contentWidth = rect.width - TIMELINE_PADDING_PX * 2;
274
+ if (contentWidth <= 0)
275
+ return;
276
+ const fraction = Math.max(0, Math.min(1, (e.clientX - rect.left - TIMELINE_PADDING_PX) / contentWidth));
277
+ setHover({
278
+ fraction,
279
+ rowIndex: Math.floor((e.clientY - rect.top) / ROW_HEIGHT_PX),
280
+ });
281
+ }, []);
282
+ const handleTimelineMouseLeave = useCallback(() => {
283
+ setHover(null);
284
+ }, []);
277
285
  useEffect(() => {
278
- if (!scrollLock)
286
+ const el = timelineRef.current;
287
+ if (!el || root.duration <= 0)
279
288
  return;
280
- const $html = document.documentElement;
281
- const $body = document.body;
282
- $html.style.overflow = 'clip';
283
- $body.style.overflow = 'clip';
284
- const onScroll = (event) => {
285
- if (event?.cancelable) {
286
- event.preventDefault();
289
+ const onWheel = (e) => {
290
+ const isZoomGesture = e.ctrlKey || e.metaKey;
291
+ const hasDeltaX = Math.abs(e.deltaX) > Math.abs(e.deltaY);
292
+ if (!isZoomGesture && !hasDeltaX)
293
+ return;
294
+ e.preventDefault();
295
+ const rect = el.getBoundingClientRect();
296
+ const contentWidth = rect.width - TIMELINE_PADDING_PX * 2;
297
+ if (contentWidth <= 0)
298
+ return;
299
+ if (isZoomGesture) {
300
+ const cursorFraction = Math.max(0, Math.min(1, (e.clientX - rect.left - TIMELINE_PADDING_PX) / contentWidth));
301
+ const scaleFactor = wheelZoomScaleFactor(e);
302
+ setViewport((prev) => {
303
+ const prevDuration = prev.end - prev.start;
304
+ const cursorTime = prev.start + cursorFraction * prevDuration;
305
+ // Clamp the duration before anchoring so the cursor keeps its
306
+ // fraction even when the zoom hits the min/max bounds.
307
+ const newDuration = Math.max(MIN_VIEWPORT_MS, Math.min(root.duration, prevDuration * scaleFactor));
308
+ return clampToRoot({
309
+ start: cursorTime - cursorFraction * newDuration,
310
+ end: cursorTime + (1 - cursorFraction) * newDuration,
311
+ });
312
+ });
287
313
  }
288
314
  else {
289
- window.scrollTo({
290
- left: 0,
291
- top: 0,
292
- behavior: 'instant',
315
+ const dx = wheelDeltaToPixels(e.deltaX, e.deltaMode);
316
+ setViewport((prev) => {
317
+ const panAmount = (dx / contentWidth) * (prev.end - prev.start);
318
+ return clampToRoot({
319
+ start: prev.start + panAmount,
320
+ end: prev.end + panAmount,
321
+ });
293
322
  });
294
323
  }
295
324
  };
296
- onScroll();
297
- window.addEventListener('scroll', onScroll, {
298
- passive: false,
299
- });
300
- return () => {
301
- $html.style.overflow = '';
302
- $body.style.overflow = '';
303
- window.removeEventListener('scroll', onScroll);
304
- };
305
- }, [scrollLock]);
306
- const timelineHeight = Math.max(state.timelineHeight - state.scrollbarWidth, MARKER_HEIGHT +
307
- ROW_PADDING +
308
- rows.length * (ROW_HEIGHT + ROW_PADDING) -
309
- ROW_PADDING +
310
- // When there are enough spans to be near the bottom edge, add some extra padding
311
- // to avoid overlapping with the zoom buttons, etc.
312
- 84);
313
- const inert = Boolean(state.isMobile && state.selected);
314
- return (_jsxs("div", { className: clsx(styles.traceViewer, isSkeleton && styles.skeleton, className), onClickCapture: onClick, ref: ref, style: {
315
- height,
316
- '--timeline-padding': `${TIMELINE_PADDING}px`,
317
- '--row-height': `${ROW_HEIGHT}px`,
318
- '--row-padding': `${ROW_PADDING}px`,
319
- '--search-height': `${!hideSearchBar ? SEARCH_HEIGHT : 0}px`,
320
- '--search-gap': `${!hideSearchBar ? SEARCH_GAP : 2}px`,
321
- '--map-height': `${MAP_HEIGHT}px`,
322
- '--timeline-width': `${state.timelineWidth}px`,
323
- '--timeline-height': `${state.timelineHeight}px`,
324
- '--timeline-scroll-width': `${Math.round(state.root.duration * state.scale)}px`,
325
- '--panel-width': `${state.panelWidth}px`,
326
- '--panel-height': `${state.panelHeight}px`,
327
- '--height': `${state.height}px`,
328
- '--scrollbar-width': `${state.scrollbarWidth}px`,
329
- '--marker-height': `${MARKER_HEIGHT}px`,
330
- '--marker-notch-height': `${MARKER_NOTCH_HEIGHT}px`,
331
- }, children: [!hideSearchBar ? _jsx(SearchBar, {}) : null, _jsx(MiniMap, { rows: rows, scale: scale, timelineRef: timelineRef }), _jsxs("div", { className: clsx(styles.traceViewerContent, inert && styles.inert), children: [_jsxs("div", { className: styles.timeline, ref: timelineRef, children: [_jsx("div", { style: {
332
- position: 'relative',
333
- width: state.timelineWidth,
334
- minHeight: state.timelineHeight - TIMELINE_PADDING * 2,
335
- padding: TIMELINE_PADDING,
336
- paddingBottom: 0,
337
- }, children: _jsxs("div", { className: styles.traceNode, style: {
338
- width: state.root.duration * scale || undefined,
339
- height: timelineHeight - TIMELINE_PADDING * 2,
340
- }, children: [_jsx(Markers, { scale: scale, isLive: isLive }), _jsx(EventMarkers, { events: events, root: state.root, scale: scale }), _jsx(CursorMarker, { dispatch: dispatch, events: events, memoCacheRef: state.memoCacheRef, root: state.root, scale: scale, scrollSnapshotRef: scrollSnapshotRef, spans: spans, timelineRef: timelineRef }), _jsx(SpanNodes, { cacheKey: memoCache.get(''), cache: memoCache, customSpanClassNameFunc: state.customSpanClassNameFunc, customSpanEventClassNameFunc: state.customSpanEventClassNameFunc, isLive: isLive, root: state.root, scale: scale, scrollSnapshotRef: scrollSnapshotRef, spans: spans }), knownDurationMs != null &&
341
- knownDurationMs > 0 &&
342
- (hasMoreData || isLive) &&
343
- state.root.duration > 0 &&
344
- (() => {
345
- const knownPx = knownDurationMs * scale;
346
- const totalPx = state.root.duration * scale;
347
- const unknownWidth = totalPx - knownPx;
348
- // Only show if the unknown region is meaningfully wide
349
- if (unknownWidth < 4)
350
- return null;
351
- // Offset ~5% into the unknown region so it doesn't touch spans
352
- const insetPx = Math.min(unknownWidth * 0.05, 20);
353
- return (_jsx("div", { style: {
354
- position: 'absolute',
355
- top: 0,
356
- left: knownPx + insetPx,
357
- width: unknownWidth - insetPx,
358
- height: '100%',
359
- pointerEvents: 'none',
360
- zIndex: 1,
361
- maskImage: 'linear-gradient(to right, transparent 1%, black 3%)',
362
- WebkitMaskImage: 'linear-gradient(to right, transparent 1%, black 3%)',
363
- background: 'repeating-linear-gradient(-45deg, var(--ds-background-200) 0, var(--ds-background-200) 11px, var(--ds-gray-200) 11px, var(--ds-gray-200) 12px)',
364
- } }));
365
- })()] }) }), footer] }), _jsx("div", { className: styles.zoomButtonTraceViewer, children: _jsx(ZoomButton, {}) })] }), withPanel ? (_jsx("div", { className: clsx(styles.spanDetailPanelTraceViewer, !state.selected && styles.hidden, state.isMobile && styles.mobile), children: _jsx(SpanDetailPanel, { attached: true }) })) : null] }));
366
- }
367
- export function TraceViewerPanel({ className = '', children = null, }) {
368
- const { state } = useTraceViewer();
369
- if (!state.selected) {
370
- return children;
371
- }
372
- return (_jsx("div", { className: clsx(styles.spanDetailPanelTraceViewer, className), style: {
373
- position: 'relative',
374
- '--search-height': '0',
375
- '--search-gap': '0',
376
- '--map-height': '0',
377
- '--panel-width': `100%`,
378
- '--panel-height': `100%`,
379
- '--height': `100%`,
380
- '--scrollbar-width': `${state.scrollbarWidth}px`,
381
- }, children: _jsx(SpanDetailPanel, {}) }));
382
- }
383
- export function TraceViewer(props) {
384
- return (_jsx(TraceViewerContextProvider, { getQuickLinks: props.getQuickLinks, withPanel: true, children: _jsx(TraceViewerTimeline, { withPanel: true, ...props }) }));
325
+ el.addEventListener('wheel', onWheel, { passive: false });
326
+ return () => el.removeEventListener('wheel', onWheel);
327
+ }, [root.duration, setViewport, clampToRoot]);
328
+ return (_jsxs("div", { ref: paneRootRef, "data-pane": "pane-root", className: "relative flex w-full h-full max-h-full", children: [_jsxs("div", { id: "trace-parent", className: "@container flex-1 min-w-0 grid grid-rows-[auto_1fr] h-full min-h-0 overflow-hidden relative bg-background-100", children: [_jsx(Minimap, { spans: trace.spans, root: root, viewport: viewport, minViewportMs: MIN_VIEWPORT_MS, onViewportChange: setViewport, onAnimateTo: animateTo }), _jsxs(SplitPane, { scrollContainerRef: scrollContainerRef, startHeader: _jsxs("div", { className: "bg-background-100 border-b border-gray-alpha-400 h-10 min-h-10 flex items-center pl-4 pr-2 gap-1.5", children: [_jsx(Search, { className: "w-3.5 h-3.5 shrink-0 text-gray-800" }), _jsx("input", { id: "trace-viewer-search", name: "trace-viewer-search", type: "text", value: searchQuery, onChange: (e) => setSearchQuery(e.target.value), onKeyDown: (e) => {
329
+ if (e.key === 'Escape' && searchQuery) {
330
+ e.preventDefault();
331
+ e.stopPropagation();
332
+ setSearchQuery('');
333
+ }
334
+ }, placeholder: "Search spans...", "aria-label": "Search spans", className: "flex-1 min-w-0 bg-transparent text-label-14 text-gray-1000 placeholder:text-gray-800 outline-none" }), searchQuery && (_jsx("button", { type: "button", "aria-label": "Clear search", onClick: () => setSearchQuery(''), className: "-mr-2 hidden h-full max-w-full shrink-0 cursor-pointer items-center rounded-r-md border-0 bg-transparent px-2.5 font-inherit text-label-16 text-gray-900 no-underline transition-colors duration-150 ease-in hover:text-gray-1000 focus-visible:-outline-offset-1 focus-visible:outline focus-visible:outline-2 focus-visible:outline-[var(--ds-focus-color)] min-[961px]:flex", children: _jsx(Kbd, { variant: "outline", size: "search", children: "Esc" }) }))] }), endHeader: _jsx(TimelineHeader, { markers: timeMarkers, hoverInfo: hoverInfo }), children: [_jsxs("div", { className: "block overflow-visible", children: [_jsx(EventList, { spans: trace.spans, activeSpanId: activeSpanId, searchResult: searchResult, onSelectSpan: handleSelectSpan }), _jsx("div", { ref: loadMoreSentinelRef, className: "flex justify-center", children: isLoadingMore ? (_jsxs("div", { className: "flex items-center justify-center gap-2 py-3 text-label-14 text-gray-800", children: [_jsx(Spinner, { size: 14 }), _jsx("span", { children: "Loading spans\u2026" })] })) : null })] }), _jsx("div", { ref: timelineRef, id: "trace-timeline", className: "@container block min-h-0 overflow-visible relative", onDoubleClick: resetZoom, onMouseMove: handleTimelineMouseMove, onMouseLeave: handleTimelineMouseLeave, children: _jsx(Timeline, { spans: trace.spans, viewStart: viewport.start, viewEnd: viewport.end, markers: timeMarkers, selectedId: activeSpanId, searchResult: searchResult, onSelect: handleSelectSpan, onRevealTime: handleRevealTime, hover: hover, altHeld: altHeld }) }), _jsxs(_Fragment, { children: [_jsx(TraceShortcutHelper, { hasMultipleSpans: trace.spans.length > 1, reducedMotion: reducedMotion }), _jsxs("div", { className: "pointer-events-auto flex items-center border border-gray-alpha-400 rounded-md bg-background-100 shadow-sm overflow-hidden divide-x divide-gray-alpha-400", children: [_jsx(IconButton, { variant: "muted", size: "small", onClick: zoomOut, disabled: isAtMinZoom, "aria-label": "Zoom out", children: _jsx(ZoomOut, { className: "w-4 h-4" }) }), _jsx(IconButton, { variant: "muted", size: "small", onClick: resetZoom, "aria-label": "Reset zoom", children: _jsx(RotateCcw, { className: "w-3.5 h-3.5" }) }), _jsx(IconButton, { variant: "muted", size: "small", onClick: zoomIn, disabled: isAtMaxZoom, "aria-label": "Zoom in", children: _jsx(ZoomIn, { className: "w-4 h-4" }) })] })] })] })] }), _jsx(TraceDetailPanel, { containerRef: paneRootRef, onNavigateToSpan: navigateToSpan, onClose: handleClearActiveSpan })] }));
385
335
  }
386
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHJhY2Utdmlld2VyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2NvbXBvbmVudHMvdHJhY2Utdmlld2VyL3RyYWNlLXZpZXdlci50c3giXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsWUFBWSxDQUFDOztBQUViLE9BQU8sRUFBRSxJQUFJLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFFNUIsT0FBTyxFQUFFLFdBQVcsRUFBRSxTQUFTLEVBQUUsZUFBZSxFQUFFLE1BQU0sRUFBRSxNQUFNLE9BQU8sQ0FBQztBQUN4RSxPQUFPLEVBQUUsT0FBTyxFQUFFLE1BQU0sa0JBQWtCLENBQUM7QUFDM0MsT0FBTyxFQUFFLFlBQVksRUFBRSxZQUFZLEVBQUUsT0FBTyxFQUFFLE1BQU0sc0JBQXNCLENBQUM7QUFDM0UsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLG1CQUFtQixDQUFDO0FBQzlDLE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQztBQUNoRCxPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0sZ0NBQWdDLENBQUM7QUFDakUsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLDBCQUEwQixDQUFDO0FBQ3RELE9BQU8sRUFBRSwwQkFBMEIsRUFBRSxjQUFjLEVBQUUsTUFBTSxXQUFXLENBQUM7QUFDdkUsT0FBTyxNQUFNLE1BQU0sMkJBQTJCLENBQUM7QUFFL0MsT0FBTyxFQUNMLFVBQVUsRUFDVixhQUFhLEVBQ2IsbUJBQW1CLEVBQ25CLFVBQVUsRUFDVixXQUFXLEVBQ1gsVUFBVSxFQUNWLGFBQWEsRUFDYixnQkFBZ0IsR0FDakIsTUFBTSxrQkFBa0IsQ0FBQztBQUMxQixPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sYUFBYSxDQUFDO0FBQ3pDLE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxNQUFNLDRCQUE0QixDQUFDO0FBZ0IvRCxNQUFNLFVBQVUsbUJBQW1CLENBQUMsRUFDbEMsYUFBYSxFQUNiLFFBQVEsR0FHVDtJQUND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RUFBRSxLQUFLLEVBQUUsR0FBRyxjQUFjLEVBQUUsQ0FBQztJQUVuQyxJQUFJLENBQUMsS0FBSyxDQUFDLFFBQVEsRUFBRSxDQUFDO1FBQ3BCLE9BQU8sUUFBUSxDQUFDO0lBQ2xCLENBQUM7SUFFRCxPQUFPLENBQ0wsY0FDRSxTQUFTLEVBQUUsSUFBSSxDQUFDLE1BQU0sQ0FBQywwQkFBMEIsRUFBRSxTQUFTLENBQUMsRUFDN0QsS0FBSyxFQUNIO1lBQ0UsUUFBUSxFQUFFLFVBQVU7WUFDcEIsaUJBQWlCLEVBQUUsR0FBRztZQUN0QixjQUFjLEVBQUUsR0FBRztZQUNuQixjQUFjLEVBQUUsR0FBRztZQUNuQixlQUFlLEVBQUUsTUFBTTtZQUN2QixnQkFBZ0IsRUFBRSxNQUFNO1lBQ3hCLFVBQVUsRUFBRSxNQUFNO1lBQ2xCLG1CQUFtQixFQUFFLEdBQUcsS0FBSyxDQUFDLGNBQWMsSUFBSTtTQUNoQyxZQUdwQixLQUFDLGVBQWUsS0FBRyxHQUNmLENBQ1AsQ0FBQztBQUNKLENBQUM7QUFFRCxNQUFNLFVBQVUsV0FBVyxDQUFDLEtBQXVCO0lBQ2pELE9BQU8sQ0FDTCxLQUFDLDBCQUEwQixJQUFDLGFBQWEsRUFBRSxLQUFLLENBQUMsYUFBYSxFQUFFLFNBQVMsa0JBQ3ZFLEtBQUMsbUJBQW1CLElBQUMsU0FBUyxXQUFLLEtBQUssR0FBSSxHQUNqQixDQUM5QixDQUFDO0FBQ0osQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIid1c2UgY2xpZW50JztcblxuaW1wb3J0IHsgY2xzeCB9IGZyb20gJ2Nsc3gnO1xuaW1wb3J0IHR5cGUgeyBDU1NQcm9wZXJ0aWVzLCBNb3VzZUV2ZW50SGFuZGxlciwgUmVhY3ROb2RlIH0gZnJvbSAncmVhY3QnO1xuaW1wb3J0IHsgdXNlQ2FsbGJhY2ssIHVzZUVmZmVjdCwgdXNlTGF5b3V0RWZmZWN0LCB1c2VSZWYgfSBmcm9tICdyZWFjdCc7XG5pbXBvcnQgeyBNaW5pTWFwIH0gZnJvbSAnLi9jb21wb25lbnRzL21hcCc7XG5pbXBvcnQgeyBDdXJzb3JNYXJrZXIsIEV2ZW50TWFya2VycywgTWFya2VycyB9IGZyb20gJy4vY29tcG9uZW50cy9tYXJrZXJzJztcbmltcG9ydCB7IFNwYW5Ob2RlcyB9IGZyb20gJy4vY29tcG9uZW50cy9ub2RlJztcbmltcG9ydCB7IFNlYXJjaEJhciB9IGZyb20gJy4vY29tcG9uZW50cy9zZWFyY2gnO1xuaW1wb3J0IHsgU3BhbkRldGFpbFBhbmVsIH0gZnJvbSAnLi9jb21wb25lbnRzL3NwYW4tZGV0YWlsLXBhbmVsJztcbmltcG9ydCB7IFpvb21CdXR0b24gfSBmcm9tICcuL2NvbXBvbmVudHMvem9vbS1idXR0b24nO1xuaW1wb3J0IHsgVHJhY2VWaWV3ZXJDb250ZXh0UHJvdmlkZXIsIHVzZVRyYWNlVmlld2VyIH0gZnJvbSAnLi9jb250ZXh0JztcbmltcG9ydCBzdHlsZXMgZnJvbSAnLi90cmFjZS12aWV3ZXIubW9kdWxlLmNzcyc7XG5pbXBvcnQgdHlwZSB7IEdldFF1aWNrTGlua3MsIFRyYWNlIH0gZnJvbSAnLi90eXBlcyc7XG5pbXBvcnQge1xuICBNQVBfSEVJR0hULFxuICBNQVJLRVJfSEVJR0hULFxuICBNQVJLRVJfTk9UQ0hfSEVJR0hULFxuICBST1dfSEVJR0hULFxuICBST1dfUEFERElORyxcbiAgU0VBUkNIX0dBUCxcbiAgU0VBUkNIX0hFSUdIVCxcbiAgVElNRUxJTkVfUEFERElORyxcbn0gZnJvbSAnLi91dGlsL2NvbnN0YW50cyc7XG5pbXBvcnQgeyBwYXJzZVRyYWNlIH0gZnJvbSAnLi91dGlsL3RyZWUnO1xuaW1wb3J0IHsgdXNlU3RyZWFtaW5nU3BhbnMgfSBmcm9tICcuL3V0aWwvdXNlLXN0cmVhbWluZy1zcGFucyc7XG5cbmludGVyZmFjZSBUcmFjZVZpZXdlclByb3BzIHtcbiAgdHJhY2U/OiBUcmFjZTtcbiAgY2xhc3NOYW1lPzogc3RyaW5nO1xuICBzY3JvbGxMb2NrPzogYm9vbGVhbjtcbiAgaGVpZ2h0Pzogc3RyaW5nIHwgbnVtYmVyO1xuICB3aXRoUGFuZWw/OiBib29sZWFuO1xuICBnZXRRdWlja0xpbmtzPzogR2V0UXVpY2tMaW5rcztcbiAgaGlnaGxpZ2h0ZWRTcGFucz86IHN0cmluZ1tdO1xuICAvKiogUmVuZGVyIGFsbCBzcGFucyBpbW1lZGlhdGVseSAobm8gcHJvZ3Jlc3NpdmUgc3RyZWFtaW5nKS4gKi9cbiAgZWFnZXJSZW5kZXI/OiBib29sZWFuO1xuICAvKiogV2hldGhlciB0aGUgdHJhY2UgaXMgbGl2ZSAoZm9yIGNvbnRpbnVvdXMgdGljayB1cGRhdGVzKS4gKi9cbiAgaXNMaXZlPzogYm9vbGVhbjtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIFRyYWNlVmlld2VyUHJvdmlkZXIoe1xuICBnZXRRdWlja0xpbmtzLFxuICBjaGlsZHJlbixcbn06IFBpY2s8VHJhY2VWaWV3ZXJQcm9wcywgJ2dldFF1aWNrTGlua3MnPiAmIHtcbiAgY2hpbGRyZW46IFJlYWN0Tm9kZTtcbn0pOiBSZWFjdE5vZGUge1xuICByZXR1cm4gKFxuICAgIDxUcmFjZVZpZXdlckNvbnRleHRQcm92aWRlciBnZXRRdWlja0xpbmtzPXtnZXRRdWlja0xpbmtzfT5cbiAgICAgIHtjaGlsZHJlbn1cbiAgICA8L1RyYWNlVmlld2VyQ29udGV4dFByb3ZpZGVyPlxuICApO1xufVxuXG5pbnRlcmZhY2UgTGFzdENsaWNrUmVmIHtcbiAgeDogbnVtYmVyO1xuICB5OiBudW1iZXI7XG4gIHQ6IG51bWJlcjtcbiAgc3BhbklkOiBzdHJpbmc7XG59XG5cbmNvbnN0IHNrZWxldG9uVHJhY2U6IFRyYWNlID0ge1xuICB0cmFjZUlkOiAnc2tlbGV0b24nLFxuICBzcGFuczogW1xuICAgIHtcbiAgICAgIHBhcmVudFNwYW5JZDogJycsXG4gICAgICBzcGFuSWQ6ICdyb290JyxcbiAgICAgIG5hbWU6ICdyb290IHNwYW4nLFxuICAgICAga2luZDogMSxcbiAgICAgIHJlc291cmNlOiAndmVyY2VsLnJ1bnRpbWUnLFxuICAgICAgc3RhcnRUaW1lOiBbNTAwMCwgMF0sXG4gICAgICBlbmRUaW1lOiBbNjAwMCwgMF0sXG4gICAgICBkdXJhdGlvbjogWzEwMDAsIDBdLFxuICAgICAgbGlicmFyeToge1xuICAgICAgICBuYW1lOiAndmVyY2VsLXNpdGUnLFxuICAgICAgfSxcbiAgICAgIHN0YXR1czoge1xuICAgICAgICBjb2RlOiAxLFxuICAgICAgfSxcbiAgICAgIGF0dHJpYnV0ZXM6IHtcbiAgICAgICAgJ3ZlcmNlbC5vd25lcklkJzogJ3RlYW1fYWJjJyxcbiAgICAgIH0sXG4gICAgICB0cmFjZUZsYWdzOiAxLFxuICAgICAgZXZlbnRzOiBbXSxcbiAgICAgIGxpbmtzOiBbXSxcbiAgICB9LFxuICBdLFxuICByZXNvdXJjZXM6IFtcbiAgICB7XG4gICAgICBuYW1lOiAndmVyY2VsLnJ1bnRpbWUnLFxuICAgICAgYXR0cmlidXRlczoge30sXG4gICAgfSxcbiAgXSxcbiAgcm9vdFNwYW5JZDogJ3Jvb3QnLFxufTtcblxuZXhwb3J0IGZ1bmN0aW9uIFRyYWNlVmlld2VyVGltZWxpbmUoe1xuICB0cmFjZSA9IHNrZWxldG9uVHJhY2UsXG4gIGNsYXNzTmFtZSA9ICcnLFxuICBzY3JvbGxMb2NrID0gZmFsc2UsXG4gIGhlaWdodCxcbiAgd2l0aFBhbmVsID0gZmFsc2UsXG4gIGhpZ2hsaWdodGVkU3BhbnMsXG4gIGVhZ2VyUmVuZGVyID0gZmFsc2UsXG4gIGlzTGl2ZSA9IGZhbHNlLFxuICBmb290ZXIsXG4gIGtub3duRHVyYXRpb25NcyxcbiAgaGFzTW9yZURhdGEgPSBmYWxzZSxcbn06IE9taXQ8VHJhY2VWaWV3ZXJQcm9wcywgJ2dldFF1aWNrTGlua3MnPiAmIHtcbiAgZm9vdGVyPzogUmVhY3ROb2RlO1xuICAvKiogRHVyYXRpb24gaW4gbXMgZnJvbSB0cmFjZSBzdGFydCB0byB0aGUgbGF0ZXN0IGtub3duIGV2ZW50LiBVc2VkIHRvIHJlbmRlciB0aGUgdW5rbm93bi10aW1lIG92ZXJsYXkuICovXG4gIGtub3duRHVyYXRpb25Ncz86IG51bWJlcjtcbiAgLyoqIFdoZXRoZXIgbW9yZSBkYXRhIHBhZ2VzIGFyZSBleHBlY3RlZC4gQ29udHJvbHMgdGhlIHVua25vd24tZGF0YSBvdmVybGF5IHZpc2liaWxpdHkuICovXG4gIGhhc01vcmVEYXRhPzogYm9vbGVhbjtcbn0pOiBSZWFjdE5vZGUge1xuICBjb25zdCBpc1NrZWxldG9uID0gdHJhY2UgPT09IHNrZWxldG9uVHJhY2U7XG4gIGNvbnN0IHsgc3RhdGUsIGRpc3BhdGNoIH0gPSB1c2VUcmFjZVZpZXdlcigpO1xuICBjb25zdCB7IHRpbWVsaW5lUmVmLCBzY3JvbGxTbmFwc2hvdFJlZiB9ID0gc3RhdGU7XG4gIGNvbnN0IG1lbW9DYWNoZSA9IHN0YXRlLm1lbW9DYWNoZVJlZi5jdXJyZW50O1xuICBjb25zdCBoaWRlU2VhcmNoQmFyID0gKGhpZ2hsaWdodGVkU3BhbnM/Lmxlbmd0aCA/PyAwKSA+IDA7XG5cbiAgY29uc3QgaGFzSW5pdGlhbGl6ZWRSZWYgPSB1c2VSZWYoZmFsc2UpO1xuICBjb25zdCBwcmV2U3BhbktleVJlZiA9IHVzZVJlZignJyk7XG4gIGNvbnN0IHByZXZSb290UmVmID0gdXNlUmVmPFJldHVyblR5cGU8dHlwZW9mIHBhcnNlVHJhY2U+Wydyb290J10gfCBudWxsPihcbiAgICBudWxsXG4gICk7XG4gIGNvbnN0IHByZXZTcGFuTWFwUmVmID0gdXNlUmVmPFJldHVyblR5cGU8dHlwZW9mIHBhcnNlVHJhY2U+WydtYXAnXT4oe30pO1xuICBjb25zdCBwcmV2U2l6ZVJlZiA9IHVzZVJlZjx7IHdpZHRoOiBudW1iZXI7IGhlaWdodDogbnVtYmVyIH0gfCBudWxsPihudWxsKTtcblxuICB1c2VFZmZlY3QoKCkgPT4ge1xuICAgIGNvbnN0IHsgcm9vdDogbmV3Um9vdCwgbWFwOiBuZXdTcGFuTWFwIH0gPSBwYXJzZVRyYWNlKHRyYWNlKTtcbiAgICBjb25zdCBpc0luaXRpYWwgPSAhaGFzSW5pdGlhbGl6ZWRSZWYuY3VycmVudDtcbiAgICBoYXNJbml0aWFsaXplZFJlZi5jdXJyZW50ID0gdHJ1ZTtcblxuICAgIC8vIEJ1aWxkIGEgc3RydWN0dXJhbCBrZXkgZnJvbSBzcGFuIElEcyArIGxpZ2h0d2VpZ2h0IGV2ZW50IHNpZ25hdHVyZXMuXG4gICAgLy8gV2hlbiBvbmx5IHRpbWluZyBjaGFuZ2VzIChzYW1lIHNwYW5zIGFuZCBib3VuZGFyeSBldmVudHMpLCB3ZSBjYW4gc2tpcCB0aGVcbiAgICAvLyB3b3JrZXIgcmVzdGFydC4gV2hlbiBldmVudHMgY2hhbmdlIChzdGVwIGNvbXBsZXRlZCwgZXRjLikgd2UgbmVlZCBhXG4gICAgLy8gZnVsbCB1cGRhdGUgYmVjYXVzZSB0aGUgVmlzaWJsZVNwYW4gb2JqZWN0cyByZW5kZXJlZCBieSBSZWFjdCBob2xkXG4gICAgLy8gY29waWVzIG9mIHRoZSBldmVudHMgZnJvbSB0aGUgd29ya2VyIOKAlCBpbi1wbGFjZSBtdXRhdGlvbiB3b24ndCByZWFjaCB0aGVtLlxuICAgIGNvbnN0IHNwYW5LZXkgPSBPYmplY3Qua2V5cyhuZXdTcGFuTWFwKVxuICAgICAgLnNvcnQoKVxuICAgICAgLm1hcCgoaWQpID0+IHtcbiAgICAgICAgY29uc3QgZXZlbnRzID0gbmV3U3Bhbk1hcFtpZF0uZXZlbnRzO1xuICAgICAgICBjb25zdCBjb3VudCA9IGV2ZW50cz8ubGVuZ3RoID8/IDA7XG4gICAgICAgIGNvbnN0IGZpcnN0ID0gY291bnQgPyBldmVudHM/LlswXSA6IHVuZGVmaW5lZDtcbiAgICAgICAgY29uc3QgbGFzdCA9IGNvdW50ID8gZXZlbnRzPy5bY291bnQgLSAxXSA6IHVuZGVmaW5lZDtcbiAgICAgICAgY29uc3QgZXZlbnRTaWduYXR1cmUgPSBgJHtmaXJzdD8uZXZlbnQubmFtZSA/PyAnbm9uZSd9QCR7Zmlyc3Q/LnRpbWVzdGFtcCA/PyAwfXwke2xhc3Q/LmV2ZW50Lm5hbWUgPz8gJ25vbmUnfUAke2xhc3Q/LnRpbWVzdGFtcCA/PyAwfWA7XG4gICAgICAgIHJldHVybiBgJHtpZH06JHtjb3VudH06JHtldmVudFNpZ25hdHVyZX1gO1xuICAgICAgfSlcbiAgICAgIC5qb2luKCcsJyk7XG5cbiAgICBpZiAoXG4gICAgICAhaXNJbml0aWFsICYmXG4gICAgICBzcGFuS2V5ID09PSBwcmV2U3BhbktleVJlZi5jdXJyZW50ICYmXG4gICAgICBwcmV2Um9vdFJlZi5jdXJyZW50XG4gICAgKSB7XG4gICAgICAvLyBTYW1lIHNwYW4gc2V0LCBzYW1lIGV2ZW50IGNvdW50cyDigJQgb25seSB0aW1pbmcgY2hhbmdlZC5cbiAgICAgIC8vIE11dGF0ZSBpbi1wbGFjZSBzbyB0aGUgd29ya2VyIGVmZmVjdCAod2hpY2ggZGVwZW5kcyBvbiByb290L3NwYW5NYXBcbiAgICAgIC8vIHJlZmVyZW5jZXMpIGRvZXMgTk9UIHJlc3RhcnQuXG4gICAgICBjb25zdCBvbGRSb290ID0gcHJldlJvb3RSZWYuY3VycmVudDtcbiAgICAgIGNvbnN0IG9sZFNwYW5NYXAgPSBwcmV2U3Bhbk1hcFJlZi5jdXJyZW50O1xuICAgICAgbGV0IGRpZENoYW5nZSA9IGZhbHNlO1xuXG4gICAgICBpZiAoXG4gICAgICAgIG9sZFJvb3QuZW5kVGltZSAhPT0gbmV3Um9vdC5lbmRUaW1lIHx8XG4gICAgICAgIG9sZFJvb3QuZHVyYXRpb24gIT09IG5ld1Jvb3QuZHVyYXRpb25cbiAgICAgICkge1xuICAgICAgICBvbGRSb290LmVuZFRpbWUgPSBuZXdSb290LmVuZFRpbWU7XG4gICAgICAgIG9sZFJvb3QuZHVyYXRpb24gPSBuZXdSb290LmR1cmF0aW9uO1xuICAgICAgICBkaWRDaGFuZ2UgPSB0cnVlO1xuICAgICAgfVxuXG4gICAgICBmb3IgKGNvbnN0IFtpZCwgbmV3Tm9kZV0gb2YgT2JqZWN0LmVudHJpZXMobmV3U3Bhbk1hcCkpIHtcbiAgICAgICAgY29uc3Qgb2xkTm9kZSA9IG9sZFNwYW5NYXBbaWRdO1xuICAgICAgICBpZiAob2xkTm9kZSkge1xuICAgICAgICAgIGlmIChcbiAgICAgICAgICAgIG9sZE5vZGUuZW5kVGltZSAhPT0gbmV3Tm9kZS5lbmRUaW1lIHx8XG4gICAgICAgICAgICBvbGROb2RlLmR1cmF0aW9uICE9PSBuZXdOb2RlLmR1cmF0aW9uXG4gICAgICAgICAgKSB7XG4gICAgICAgICAgICBvbGROb2RlLmVuZFRpbWUgPSBuZXdOb2RlLmVuZFRpbWU7XG4gICAgICAgICAgICBvbGROb2RlLmR1cmF0aW9uID0gbmV3Tm9kZS5kdXJhdGlvbjtcbiAgICAgICAgICAgIGRpZENoYW5nZSA9IHRydWU7XG4gICAgICAgICAgfVxuICAgICAgICAgIE9iamVjdC5hc3NpZ24ob2xkTm9kZS5zcGFuLCBuZXdOb2RlLnNwYW4pO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGlmICghZGlkQ2hhbmdlKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgLy8gVHJpZ2dlciByZS1yZW5kZXIgKHNjYWxlL21hcmtlcnMpIHdpdGhvdXQgcmVzdGFydGluZyB0aGUgd29ya2VyLlxuICAgICAgLy8gdXNlTGl2ZVRpY2sgaGFuZGxlcyBjb250aW51b3VzIHNjYWxlIHJlY2FsY3VsYXRpb24gZm9yIGxpdmUgcnVucy5cbiAgICAgIGRpc3BhdGNoKHsgdHlwZTogJ2ZvcmNlUmVuZGVyJyB9KTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICAvLyBTdHJ1Y3R1cmUgY2hhbmdlZCBvciBpbml0aWFsIGxvYWQg4oCUIGZ1bGwgZGlzcGF0Y2ggKHdvcmtlciBjb21wdXRlcyBuZXcgcm93cylcbiAgICBwcmV2U3BhbktleVJlZi5jdXJyZW50ID0gc3BhbktleTtcbiAgICBwcmV2Um9vdFJlZi5jdXJyZW50ID0gbmV3Um9vdDtcbiAgICBwcmV2U3Bhbk1hcFJlZi5jdXJyZW50ID0gbmV3U3Bhbk1hcDtcbiAgICBkaXNwYXRjaCh7XG4gICAgICB0eXBlOiBpc0luaXRpYWwgPyAnc2V0Um9vdCcgOiAndXBkYXRlUm9vdCcsXG4gICAgICByb290OiBuZXdSb290LFxuICAgICAgc3Bhbk1hcDogbmV3U3Bhbk1hcCxcbiAgICAgIHJlc291cmNlczogdHJhY2UucmVzb3VyY2VzIHx8IFtdLFxuICAgIH0pO1xuICB9LCBbZGlzcGF0Y2gsIHRyYWNlXSk7XG5cbiAgY29uc3QgeyByb3dzLCBzcGFucywgZXZlbnRzLCBzY2FsZSB9ID0gdXNlU3RyZWFtaW5nU3BhbnMoXG4gICAgaGlnaGxpZ2h0ZWRTcGFucyxcbiAgICBlYWdlclJlbmRlclxuICApO1xuXG4gIGNvbnN0IHJlZiA9IHVzZVJlZjxIVE1MRGl2RWxlbWVudD4obnVsbCk7XG4gIHVzZUxheW91dEVmZmVjdCgoKSA9PiB7XG4gICAgY29uc3QgJGVsID0gcmVmLmN1cnJlbnQ7XG4gICAgaWYgKCEkZWwpIHJldHVybjtcblxuICAgIGNvbnN0IG9uUmVzaXplID0gKCk6IHZvaWQgPT4ge1xuICAgICAgY29uc3QgcGFkZGluZyA9IDIgKiBUSU1FTElORV9QQURESU5HO1xuICAgICAgY29uc3QgcmVjdCA9ICRlbC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcbiAgICAgIGNvbnN0IG5leHRXaWR0aCA9IHJlY3Qud2lkdGggLSBwYWRkaW5nO1xuICAgICAgY29uc3QgbmV4dEhlaWdodCA9IHJlY3QuaGVpZ2h0O1xuICAgICAgY29uc3QgcHJldlNpemUgPSBwcmV2U2l6ZVJlZi5jdXJyZW50O1xuXG4gICAgICBpZiAoXG4gICAgICAgIHByZXZTaXplICYmXG4gICAgICAgIHByZXZTaXplLndpZHRoID09PSBuZXh0V2lkdGggJiZcbiAgICAgICAgcHJldlNpemUuaGVpZ2h0ID09PSBuZXh0SGVpZ2h0XG4gICAgICApIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgcHJldlNpemVSZWYuY3VycmVudCA9IHsgd2lkdGg6IG5leHRXaWR0aCwgaGVpZ2h0OiBuZXh0SGVpZ2h0IH07XG5cbiAgICAgIGRpc3BhdGNoKHtcbiAgICAgICAgdHlwZTogJ3NldFNpemUnLFxuICAgICAgICB3aWR0aDogbmV4dFdpZHRoLFxuICAgICAgICBoZWlnaHQ6IG5leHRIZWlnaHQsXG4gICAgICB9KTtcbiAgICB9O1xuXG4gICAgb25SZXNpemUoKTtcblxuICAgIGNvbnN0IG9ic2VydmVyID0gbmV3IFJlc2l6ZU9ic2VydmVyKG9uUmVzaXplKTtcbiAgICBvYnNlcnZlci5vYnNlcnZlKCRlbCk7XG4gICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoJ3Jlc2l6ZScsIG9uUmVzaXplKTtcblxuICAgIHJldHVybiAoKSA9PiB7XG4gICAgICBvYnNlcnZlci5kaXNjb25uZWN0KCk7XG4gICAgICB3aW5kb3cucmVtb3ZlRXZlbnRMaXN0ZW5lcigncmVzaXplJywgb25SZXNpemUpO1xuICAgIH07XG4gIH0sIFtkaXNwYXRjaF0pO1xuXG4gIGNvbnN0IGxhc3RDbGlja1JlZiA9IHVzZVJlZjxMYXN0Q2xpY2tSZWY+KHtcbiAgICB0OiAwLFxuICAgIHg6IC0xLFxuICAgIHk6IC0xLFxuICAgIHNwYW5JZDogJycsXG4gIH0pO1xuICBjb25zdCBvbkNsaWNrOiBNb3VzZUV2ZW50SGFuZGxlciA9IHVzZUNhbGxiYWNrKFxuICAgIChldmVudCkgPT4ge1xuICAgICAgLy8gTk9URSh3aXRzKTogV2UgbWFudWFsbHkgaW1wbGVtZW50IGRvdWJsZS1jbGljayBsb2dpYyBoZXJlIHNvIHRoYXQgd2UgY2FuIHN1cHBvcnQgZG91YmxlXG4gICAgICAvLyBjbGlja2luZyBhIHNwYW4gZXZlbiBpZiB0aGUgZmlyc3QgY2xpY2sgbW92ZXMgdGhlIHNwYW4gdGhhdCB0aGUgdXNlciBpcyBjbGlja2luZyBvbiBkdWVcbiAgICAgIC8vIHRvIHRoZSBwYW5lbCBvcGVuaW5nLiBJZiB3ZSB1c2VkIGEgcmVndWxhciBkb3VibGUgY2xpY2sgbGlzdGVuZXIgd2Ugd291bGQgbmVlZCB0byBkZWxheVxuICAgICAgLy8gdGhlIG9wZW5pbmcgb2YgdGhlIHBhbmVsIGFydGlmaWNpYWxseS4gVGhpcyBpbXBsZW1lbnRhdGlvbiBhbGxvd3MgdXMgdG8gYWx3YXlzIGJlXG4gICAgICAvLyBGQVNUIHdoaWxlIGFsc28gYXZvaWRpbmcgYSBGUlVTVFJBVElORyBzaXR1YXRpb24uXG4gICAgICBjb25zdCBwcmV2ID0gbGFzdENsaWNrUmVmLmN1cnJlbnQ7XG4gICAgICBjb25zdCB0ID0gRGF0ZS5ub3coKTtcbiAgICAgIGNvbnN0IHsgY2xpZW50WDogeCwgY2xpZW50WTogeSB9ID0gZXZlbnQ7XG4gICAgICBjb25zdCBkID0gTWF0aC5zcXJ0KCh4IC0gcHJldi54KSAqKiAyICsgKHkgLSBwcmV2LnkpICoqIDIpO1xuICAgICAgLy8gZG91YmxlIGNsaWNrXG4gICAgICBpZiAodCAtIHByZXYudCA8PSA1MDAgJiYgZCA8PSA4KSB7XG4gICAgICAgIGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpO1xuICAgICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICBpZiAoIXByZXYuc3BhbklkKSB7XG4gICAgICAgICAgZGlzcGF0Y2goe1xuICAgICAgICAgICAgdHlwZTogJ3Jlc2V0U2NhbGUnLFxuICAgICAgICAgIH0pO1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBkaXNwYXRjaCh7XG4gICAgICAgICAgdHlwZTogJ3NlbGVjdCcsXG4gICAgICAgICAgaWQ6IHByZXYuc3BhbklkLFxuICAgICAgICB9KTtcbiAgICAgICAgZGlzcGF0Y2goe1xuICAgICAgICAgIHR5cGU6ICdzY2FsZVRvTm9kZScsXG4gICAgICAgICAgaWQ6IHByZXYuc3BhbklkLFxuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgY29uc3QgdGFyZ2V0ID0gZXZlbnQudGFyZ2V0IGFzIEhUTUxFbGVtZW50O1xuICAgICAgaWYgKCF0YXJnZXQuY2xvc2VzdChgLiR7U3RyaW5nKHN0eWxlcy50aW1lbGluZSl9YCkpIHJldHVybjtcbiAgICAgIGNvbnN0ICRidXR0b24gPSB0YXJnZXQuY2xvc2VzdDxIVE1MQnV0dG9uRWxlbWVudD4oJ1tkYXRhLXNwYW4taWRdJyk7XG4gICAgICBjb25zdCBzcGFuSWQgPSAkYnV0dG9uPy5kYXRhc2V0LnNwYW5JZCB8fCAnJztcbiAgICAgIGxhc3RDbGlja1JlZi5jdXJyZW50ID0ge1xuICAgICAgICB4LFxuICAgICAgICB5LFxuICAgICAgICB0LFxuICAgICAgICBzcGFuSWQsXG4gICAgICB9O1xuICAgICAgaWYgKCFzcGFuSWQpIHJldHVybjtcbiAgICAgIGRpc3BhdGNoKHtcbiAgICAgICAgdHlwZTogJ3RvZ2dsZVNlbGVjdGlvbicsXG4gICAgICAgIGlkOiBzcGFuSWQsXG4gICAgICB9KTtcbiAgICAgIGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpO1xuICAgIH0sXG4gICAgW2Rpc3BhdGNoXVxuICApO1xuXG4gIC8vIFpvb20gaGVscGVyIOKAlCBhcHBseSB0aGUgc2Nyb2xsIHNuYXBzaG90IG9uY2UgYWZ0ZXIgYSB6b29tIG9wZXJhdGlvbiBzb1xuICAvLyB0aGUgYW5jaG9yIHBvaW50IHN0YXlzIGF0IHRoZSBzYW1lIHNjcmVlbiBwb3NpdGlvbiwgdGhlbiBjbGVhciBpdC5cbiAgLy8gV2l0aG91dCBjbGVhcmluZywgbGl2ZSBydW5zICh3aGVyZSBzY2FsZSBjaGFuZ2VzIGV2ZXJ5IGZyYW1lIHZpYVxuICAvLyBkZXRlY3RCYXNlU2NhbGUpIHdvdWxkIGNvbnRpbnVvdXNseSByZXNldCBzY3JvbGxMZWZ0IGFuZCBwcmV2ZW50IHRoZVxuICAvLyB1c2VyIGZyb20gc2Nyb2xsaW5nIGhvcml6b250YWxseS5cbiAgdXNlTGF5b3V0RWZmZWN0KCgpID0+IHtcbiAgICBjb25zdCAkdGltZWxpbmUgPSB0aW1lbGluZVJlZi5jdXJyZW50O1xuICAgIGlmICghJHRpbWVsaW5lKSByZXR1cm47XG5cbiAgICBjb25zdCBzbmFwc2hvdCA9IHNjcm9sbFNuYXBzaG90UmVmLmN1cnJlbnQ7XG4gICAgaWYgKHNuYXBzaG90KSB7XG4gICAgICAkdGltZWxpbmUuc2Nyb2xsTGVmdCA9IHNuYXBzaG90LmFuY2hvclQgKiBzY2FsZSAtIHNuYXBzaG90LmFuY2hvclg7XG4gICAgICBzY3JvbGxTbmFwc2hvdFJlZi5jdXJyZW50ID0gdW5kZWZpbmVkO1xuICAgIH1cbiAgfSwgW3Njcm9sbFNuYXBzaG90UmVmLCB0aW1lbGluZVJlZiwgc2NhbGVdKTtcblxuICAvLyBTZWxlY3Rpb24gaGVscGVyXG4gIHVzZUVmZmVjdCgoKSA9PiB7XG4gICAgY29uc3Qgc3BhbklkID0gc3RhdGUuc2VsZWN0ZWQ/LnNwYW4uc3BhbklkO1xuICAgIGlmICghc3BhbklkKSByZXR1cm47XG5cbiAgICBjb25zdCB0aW1lb3V0ID0gc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICBjb25zdCAkdGltZWxpbmUgPSBzdGF0ZS50aW1lbGluZVJlZi5jdXJyZW50O1xuICAgICAgY29uc3QgJHNwYW4gPSAkdGltZWxpbmU/LnF1ZXJ5U2VsZWN0b3IoYFtkYXRhLXNwYW4taWQ9XCIke3NwYW5JZH1cIl1gKTtcbiAgICAgIGlmICghJHRpbWVsaW5lIHx8ICEkc3BhbikgcmV0dXJuO1xuXG4gICAgICBjb25zdCB2aWV3UmVjdCA9ICR0aW1lbGluZS5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcbiAgICAgIGNvbnN0IHNwYW5SZWN0ID0gJHNwYW4uZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG5cbiAgICAgIC8vIElmIHRoZSBzZWxlY3RlZCBzcGFuIGlzIG5hcnJvd2VyIHRoYW4gdGhlIHRpbWVsaW5lLCBzY3JvbGwgaXQgaW50byB2aWV3XG4gICAgICBpZiAoXG4gICAgICAgIHNwYW5SZWN0LndpZHRoIDwgdmlld1JlY3Qud2lkdGggJiZcbiAgICAgICAgKHNwYW5SZWN0LmxlZnQgPCB2aWV3UmVjdC5sZWZ0IHx8XG4gICAgICAgICAgc3BhblJlY3QucmlnaHQgPiB2aWV3UmVjdC5yaWdodCB8fFxuICAgICAgICAgIHNwYW5SZWN0LnRvcCA8IHZpZXdSZWN0LnRvcCB8fFxuICAgICAgICAgIHNwYW5SZWN0LmJvdHRvbSA+IHZpZXdSZWN0LmJvdHRvbSlcbiAgICAgICkge1xuICAgICAgICAkc3Bhbi5zY3JvbGxJbnRvVmlldyh7XG4gICAgICAgICAgYmxvY2s6ICduZWFyZXN0JyxcbiAgICAgICAgICBpbmxpbmU6ICdjZW50ZXInLFxuICAgICAgICAgIGJlaGF2aW9yOiAnc21vb3RoJyxcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfSwgNTAwKTtcblxuICAgIHJldHVybiAoKSA9PiB7XG4gICAgICBjbGVhclRpbWVvdXQodGltZW91dCk7XG4gICAgfTtcbiAgfSwgW3N0YXRlLnNlbGVjdGVkLCBzdGF0ZS50aW1lbGluZVJlZl0pO1xuXG4gIC8vIEdsb2JhbCBrZXlib2FyZCBzaG9ydGN1dHNcbiAgdXNlRWZmZWN0KCgpID0+IHtcbiAgICBjb25zdCBvbktleURvd24gPSAoZTogS2V5Ym9hcmRFdmVudCk6IHZvaWQgPT4ge1xuICAgICAgaWYgKGUua2V5ID09PSAnRXNjYXBlJykge1xuICAgICAgICBkaXNwYXRjaCh7XG4gICAgICAgICAgdHlwZTogJ2VzY2FwZScsXG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH07XG4gICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoJ2tleWRvd24nLCBvbktleURvd24pO1xuXG4gICAgcmV0dXJuICgpID0+IHtcbiAgICAgIHdpbmRvdy5yZW1vdmVFdmVudExpc3RlbmVyKCdrZXlkb3duJywgb25LZXlEb3duKTtcbiAgICB9O1xuICB9LCBbZGlzcGF0Y2hdKTtcblxuICAvLyBTY3JvbGwgbG9ja2luZ1xuICB1c2VFZmZlY3QoKCkgPT4ge1xuICAgIGlmICghc2Nyb2xsTG9jaykgcmV0dXJuO1xuXG4gICAgY29uc3QgJGh0bWwgPSBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQ7XG4gICAgY29uc3QgJGJvZHkgPSBkb2N1bWVudC5ib2R5O1xuXG4gICAgJGh0bWwuc3R5bGUub3ZlcmZsb3cgPSAnY2xpcCc7XG4gICAgJGJvZHkuc3R5bGUub3ZlcmZsb3cgPSAnY2xpcCc7XG5cbiAgICBjb25zdCBvblNjcm9sbCA9IChldmVudD86IEV2ZW50KTogdm9pZCA9PiB7XG4gICAgICBpZiAoZXZlbnQ/LmNhbmNlbGFibGUpIHtcbiAgICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHdpbmRvdy5zY3JvbGxUbyh7XG4gICAgICAgICAgbGVmdDogMCxcbiAgICAgICAgICB0b3A6IDAsXG4gICAgICAgICAgYmVoYXZpb3I6ICdpbnN0YW50JyxcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfTtcbiAgICBvblNjcm9sbCgpO1xuICAgIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKCdzY3JvbGwnLCBvblNjcm9sbCwge1xuICAgICAgcGFzc2l2ZTogZmFsc2UsXG4gICAgfSk7XG5cbiAgICByZXR1cm4gKCkgPT4ge1xuICAgICAgJGh0bWwuc3R5bGUub3ZlcmZsb3cgPSAnJztcbiAgICAgICRib2R5LnN0eWxlLm92ZXJmbG93ID0gJyc7XG4gICAgICB3aW5kb3cucmVtb3ZlRXZlbnRMaXN0ZW5lcignc2Nyb2xsJywgb25TY3JvbGwpO1xuICAgIH07XG4gIH0sIFtzY3JvbGxMb2NrXSk7XG5cbiAgY29uc3QgdGltZWxpbmVIZWlnaHQgPSBNYXRoLm1heChcbiAgICBzdGF0ZS50aW1lbGluZUhlaWdodCAtIHN0YXRlLnNjcm9sbGJhcldpZHRoLFxuICAgIE1BUktFUl9IRUlHSFQgK1xuICAgICAgUk9XX1BBRERJTkcgK1xuICAgICAgcm93cy5sZW5ndGggKiAoUk9XX0hFSUdIVCArIFJPV19QQURESU5HKSAtXG4gICAgICBST1dfUEFERElORyArXG4gICAgICAvLyBXaGVuIHRoZXJlIGFyZSBlbm91Z2ggc3BhbnMgdG8gYmUgbmVhciB0aGUgYm90dG9tIGVkZ2UsIGFkZCBzb21lIGV4dHJhIHBhZGRpbmdcbiAgICAgIC8vIHRvIGF2b2lkIG92ZXJsYXBwaW5nIHdpdGggdGhlIHpvb20gYnV0dG9ucywgZXRjLlxuICAgICAgODRcbiAgKTtcblxuICBjb25zdCBpbmVydCA9IEJvb2xlYW4oc3RhdGUuaXNNb2JpbGUgJiYgc3RhdGUuc2VsZWN0ZWQpO1xuXG4gIHJldHVybiAoXG4gICAgPGRpdlxuICAgICAgY2xhc3NOYW1lPXtjbHN4KFxuICAgICAgICBzdHlsZXMudHJhY2VWaWV3ZXIsXG4gICAgICAgIGlzU2tlbGV0b24gJiYgc3R5bGVzLnNrZWxldG9uLFxuICAgICAgICBjbGFzc05hbWVcbiAgICAgICl9XG4gICAgICBvbkNsaWNrQ2FwdHVyZT17b25DbGlja31cbiAgICAgIHJlZj17cmVmfVxuICAgICAgc3R5bGU9e1xuICAgICAgICB7XG4gICAgICAgICAgaGVpZ2h0LFxuICAgICAgICAgICctLXRpbWVsaW5lLXBhZGRpbmcnOiBgJHtUSU1FTElORV9QQURESU5HfXB4YCxcbiAgICAgICAgICAnLS1yb3ctaGVpZ2h0JzogYCR7Uk9XX0hFSUdIVH1weGAsXG4gICAgICAgICAgJy0tcm93LXBhZGRpbmcnOiBgJHtST1dfUEFERElOR31weGAsXG4gICAgICAgICAgJy0tc2VhcmNoLWhlaWdodCc6IGAkeyFoaWRlU2VhcmNoQmFyID8gU0VBUkNIX0hFSUdIVCA6IDB9cHhgLFxuICAgICAgICAgICctLXNlYXJjaC1nYXAnOiBgJHshaGlkZVNlYXJjaEJhciA/IFNFQVJDSF9HQVAgOiAyfXB4YCxcbiAgICAgICAgICAnLS1tYXAtaGVpZ2h0JzogYCR7TUFQX0hFSUdIVH1weGAsXG4gICAgICAgICAgJy0tdGltZWxpbmUtd2lkdGgnOiBgJHtzdGF0ZS50aW1lbGluZVdpZHRofXB4YCxcbiAgICAgICAgICAnLS10aW1lbGluZS1oZWlnaHQnOiBgJHtzdGF0ZS50aW1lbGluZUhlaWdodH1weGAsXG4gICAgICAgICAgJy0tdGltZWxpbmUtc2Nyb2xsLXdpZHRoJzogYCR7TWF0aC5yb3VuZChzdGF0ZS5yb290LmR1cmF0aW9uICogc3RhdGUuc2NhbGUpfXB4YCxcbiAgICAgICAgICAnLS1wYW5lbC13aWR0aCc6IGAke3N0YXRlLnBhbmVsV2lkdGh9cHhgLFxuICAgICAgICAgICctLXBhbmVsLWhlaWdodCc6IGAke3N0YXRlLnBhbmVsSGVpZ2h0fXB4YCxcbiAgICAgICAgICAnLS1oZWlnaHQnOiBgJHtzdGF0ZS5oZWlnaHR9cHhgLFxuICAgICAgICAgICctLXNjcm9sbGJhci13aWR0aCc6IGAke3N0YXRlLnNjcm9sbGJhcldpZHRofXB4YCxcbiAgICAgICAgICAnLS1tYXJrZXItaGVpZ2h0JzogYCR7TUFSS0VSX0hFSUdIVH1weGAsXG4gICAgICAgICAgJy0tbWFya2VyLW5vdGNoLWhlaWdodCc6IGAke01BUktFUl9OT1RDSF9IRUlHSFR9cHhgLFxuICAgICAgICB9IGFzIENTU1Byb3BlcnRpZXNcbiAgICAgIH1cbiAgICA+XG4gICAgICB7IWhpZGVTZWFyY2hCYXIgPyA8U2VhcmNoQmFyIC8+IDogbnVsbH1cbiAgICAgIDxNaW5pTWFwIHJvd3M9e3Jvd3N9IHNjYWxlPXtzY2FsZX0gdGltZWxpbmVSZWY9e3RpbWVsaW5lUmVmfSAvPlxuICAgICAgPGRpdiBjbGFzc05hbWU9e2Nsc3goc3R5bGVzLnRyYWNlVmlld2VyQ29udGVudCwgaW5lcnQgJiYgc3R5bGVzLmluZXJ0KX0+XG4gICAgICAgIDxkaXYgY2xhc3NOYW1lPXtzdHlsZXMudGltZWxpbmV9IHJlZj17dGltZWxpbmVSZWZ9PlxuICAgICAgICAgIDxkaXZcbiAgICAgICAgICAgIHN0eWxlPXt7XG4gICAgICAgICAgICAgIHBvc2l0aW9uOiAncmVsYXRpdmUnLFxuICAgICAgICAgICAgICB3aWR0aDogc3RhdGUudGltZWxpbmVXaWR0aCxcbiAgICAgICAgICAgICAgbWluSGVpZ2h0OiBzdGF0ZS50aW1lbGluZUhlaWdodCAtIFRJTUVMSU5FX1BBRERJTkcgKiAyLFxuICAgICAgICAgICAgICBwYWRkaW5nOiBUSU1FTElORV9QQURESU5HLFxuICAgICAgICAgICAgICBwYWRkaW5nQm90dG9tOiAwLFxuICAgICAgICAgICAgfX1cbiAgICAgICAgICA+XG4gICAgICAgICAgICA8ZGl2XG4gICAgICAgICAgICAgIGNsYXNzTmFtZT17c3R5bGVzLnRyYWNlTm9kZX1cbiAgICAgICAgICAgICAgc3R5bGU9e3tcbiAgICAgICAgICAgICAgICB3aWR0aDogc3RhdGUucm9vdC5kdXJhdGlvbiAqIHNjYWxlIHx8IHVuZGVmaW5lZCxcbiAgICAgICAgICAgICAgICBoZWlnaHQ6IHRpbWVsaW5lSGVpZ2h0IC0gVElNRUxJTkVfUEFERElORyAqIDIsXG4gICAgICAgICAgICAgIH19XG4gICAgICAgICAgICA+XG4gICAgICAgICAgICAgIDxNYXJrZXJzIHNjYWxlPXtzY2FsZX0gaXNMaXZlPXtpc0xpdmV9IC8+XG4gICAgICAgICAgICAgIDxFdmVudE1hcmtlcnMgZXZlbnRzPXtldmVudHN9IHJvb3Q9e3N0YXRlLnJvb3R9IHNjYWxlPXtzY2FsZX0gLz5cbiAgICAgICAgICAgICAgPEN1cnNvck1hcmtlclxuICAgICAgICAgICAgICAgIGRpc3BhdGNoPXtkaXNwYXRjaH1cbiAgICAgICAgICAgICAgICBldmVudHM9e2V2ZW50c31cbiAgICAgICAgICAgICAgICBtZW1vQ2FjaGVSZWY9e3N0YXRlLm1lbW9DYWNoZVJlZn1cbiAgICAgICAgICAgICAgICByb290PXtzdGF0ZS5yb290fVxuICAgICAgICAgICAgICAgIHNjYWxlPXtzY2FsZX1cbiAgICAgICAgICAgICAgICBzY3JvbGxTbmFwc2hvdFJlZj17c2Nyb2xsU25hcHNob3RSZWZ9XG4gICAgICAgICAgICAgICAgc3BhbnM9e3NwYW5zfVxuICAgICAgICAgICAgICAgIHRpbWVsaW5lUmVmPXt0aW1lbGluZVJlZn1cbiAgICAgICAgICAgICAgLz5cbiAgICAgICAgICAgICAgPFNwYW5Ob2Rlc1xuICAgICAgICAgICAgICAgIGNhY2hlS2V5PXttZW1vQ2FjaGUuZ2V0KCcnKX1cbiAgICAgICAgICAgICAgICBjYWNoZT17bWVtb0NhY2hlfVxuICAgICAgICAgICAgICAgIGN1c3RvbVNwYW5DbGFzc05hbWVGdW5jPXtzdGF0ZS5jdXN0b21TcGFuQ2xhc3NOYW1lRnVuY31cbiAgICAgICAgICAgICAgICBjdXN0b21TcGFuRXZlbnRDbGFzc05hbWVGdW5jPXtcbiAgICAgICAgICAgICAgICAgIHN0YXRlLmN1c3RvbVNwYW5FdmVudENsYXNzTmFtZUZ1bmNcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaXNMaXZlPXtpc0xpdmV9XG4gICAgICAgICAgICAgICAgcm9vdD17c3RhdGUucm9vdH1cbiAgICAgICAgICAgICAgICBzY2FsZT17c2NhbGV9XG4gICAgICAgICAgICAgICAgc2Nyb2xsU25hcHNob3RSZWY9e3Njcm9sbFNuYXBzaG90UmVmfVxuICAgICAgICAgICAgICAgIHNwYW5zPXtzcGFuc31cbiAgICAgICAgICAgICAgLz5cbiAgICAgICAgICAgICAgey8qIEhvcml6b250YWwgXCJ1bmtub3duIHRpbWVcIiBvdmVybGF5IOKAlCBjb3ZlcnMgdGhlIHJlZ2lvbiB0byB0aGVcbiAgICAgICAgICAgICAgICAgIHJpZ2h0IG9mIHRoZSBsYXRlc3Qga25vd24gZXZlbnQsIGluZGljYXRpbmcgZGF0YSBiZXlvbmQgdGhpc1xuICAgICAgICAgICAgICAgICAgcG9pbnQgaGFzbid0IGJlZW4gbG9hZGVkIHlldC4gKi99XG4gICAgICAgICAgICAgIHtrbm93bkR1cmF0aW9uTXMgIT0gbnVsbCAmJlxuICAgICAgICAgICAgICAgIGtub3duRHVyYXRpb25NcyA+IDAgJiZcbiAgICAgICAgICAgICAgICAoaGFzTW9yZURhdGEgfHwgaXNMaXZlKSAmJlxuICAgICAgICAgICAgICAgIHN0YXRlLnJvb3QuZHVyYXRpb24gPiAwICYmXG4gICAgICAgICAgICAgICAgKCgpID0+IHtcbiAgICAgICAgICAgICAgICAgIGNvbnN0IGtub3duUHggPSBrbm93bkR1cmF0aW9uTXMgKiBzY2FsZTtcbiAgICAgICAgICAgICAgICAgIGNvbnN0IHRvdGFsUHggPSBzdGF0ZS5yb290LmR1cmF0aW9uICogc2NhbGU7XG4gICAgICAgICAgICAgICAgICBjb25zdCB1bmtub3duV2lkdGggPSB0b3RhbFB4IC0ga25vd25QeDtcbiAgICAgICAgICAgICAgICAgIC8vIE9ubHkgc2hvdyBpZiB0aGUgdW5rbm93biByZWdpb24gaXMgbWVhbmluZ2Z1bGx5IHdpZGVcbiAgICAgICAgICAgICAgICAgIGlmICh1bmtub3duV2lkdGggPCA0KSByZXR1cm4gbnVsbDtcbiAgICAgICAgICAgICAgICAgIC8vIE9mZnNldCB+NSUgaW50byB0aGUgdW5rbm93biByZWdpb24gc28gaXQgZG9lc24ndCB0b3VjaCBzcGFuc1xuICAgICAgICAgICAgICAgICAgY29uc3QgaW5zZXRQeCA9IE1hdGgubWluKHVua25vd25XaWR0aCAqIDAuMDUsIDIwKTtcbiAgICAgICAgICAgICAgICAgIHJldHVybiAoXG4gICAgICAgICAgICAgICAgICAgIDxkaXZcbiAgICAgICAgICAgICAgICAgICAgICBzdHlsZT17e1xuICAgICAgICAgICAgICAgICAgICAgICAgcG9zaXRpb246ICdhYnNvbHV0ZScsXG4gICAgICAgICAgICAgICAgICAgICAgICB0b3A6IDAsXG4gICAgICAgICAgICAgICAgICAgICAgICBsZWZ0OiBrbm93blB4ICsgaW5zZXRQeCxcbiAgICAgICAgICAgICAgICAgICAgICAgIHdpZHRoOiB1bmtub3duV2lkdGggLSBpbnNldFB4LFxuICAgICAgICAgICAgICAgICAgICAgICAgaGVpZ2h0OiAnMTAwJScsXG4gICAgICAgICAgICAgICAgICAgICAgICBwb2ludGVyRXZlbnRzOiAnbm9uZScsXG4gICAgICAgICAgICAgICAgICAgICAgICB6SW5kZXg6IDEsXG4gICAgICAgICAgICAgICAgICAgICAgICBtYXNrSW1hZ2U6XG4gICAgICAgICAgICAgICAgICAgICAgICAgICdsaW5lYXItZ3JhZGllbnQodG8gcmlnaHQsIHRyYW5zcGFyZW50IDElLCBibGFjayAzJSknLFxuICAgICAgICAgICAgICAgICAgICAgICAgV2Via2l0TWFza0ltYWdlOlxuICAgICAgICAgICAgICAgICAgICAgICAgICAnbGluZWFyLWdyYWRpZW50KHRvIHJpZ2h0LCB0cmFuc3BhcmVudCAxJSwgYmxhY2sgMyUpJyxcbiAgICAgICAgICAgICAgICAgICAgICAgIGJhY2tncm91bmQ6XG4gICAgICAgICAgICAgICAgICAgICAgICAgICdyZXBlYXRpbmctbGluZWFyLWdyYWRpZW50KC00NWRlZywgdmFyKC0tZHMtYmFja2dyb3VuZC0yMDApIDAsIHZhcigtLWRzLWJhY2tncm91bmQtMjAwKSAxMXB4LCB2YXIoLS1kcy1ncmF5LTIwMCkgMTFweCwgdmFyKC0tZHMtZ3JheS0yMDApIDEycHgpJyxcbiAgICAgICAgICAgICAgICAgICAgICB9fVxuICAgICAgICAgICAgICAgICAgICAvPlxuICAgICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICB9KSgpfVxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgICAge2Zvb3Rlcn1cbiAgICAgICAgPC9kaXY+XG4gICAgICAgIDxkaXYgY2xhc3NOYW1lPXtzdHlsZXMuem9vbUJ1dHRvblRyYWNlVmlld2VyfT5cbiAgICAgICAgICA8Wm9vbUJ1dHRvbiAvPlxuICAgICAgICA8L2Rpdj5cbiAgICAgIDwvZGl2PlxuICAgICAge3dpdGhQYW5lbCA/IChcbiAgICAgICAgPGRpdlxuICAgICAgICAgIGNsYXNzTmFtZT17Y2xzeChcbiAgICAgICAgICAgIHN0eWxlcy5zcGFuRGV0YWlsUGFuZWxUcmFjZVZpZXdlcixcbiAgICAgICAgICAgICFzdGF0ZS5zZWxlY3RlZCAmJiBzdHlsZXMuaGlkZGVuLFxuICAgICAgICAgICAgc3RhdGUuaXNNb2JpbGUgJiYgc3R5bGVzLm1vYmlsZVxuICAgICAgICAgICl9XG4gICAgICAgID5cbiAgICAgICAgICA8U3BhbkRldGFpbFBhbmVsIGF0dGFjaGVkIC8+XG4gICAgICAgIDwvZGl2PlxuICAgICAgKSA6IG51bGx9XG4gICAgPC9kaXY+XG4gICk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBUcmFjZVZpZXdlclBhbmVsKHtcbiAgY2xhc3NOYW1lID0gJycsXG4gIGNoaWxkcmVuID0gbnVsbCxcbn06IHtcbiAgY2xhc3NOYW1lPzogc3RyaW5nO1xuICBjaGlsZHJlbj86IFJlYWN0Tm9kZTtcbn0pOiBSZWFjdE5vZGUge1xuICBjb25zdCB7IHN0YXRlIH0gPSB1c2VUcmFjZVZpZXdlcigpO1xuXG4gIGlmICghc3RhdGUuc2VsZWN0ZWQpIHtcbiAgICByZXR1cm4gY2hpbGRyZW47XG4gIH1cblxuICByZXR1cm4gKFxuICAgIDxkaXZcbiAgICAgIGNsYXNzTmFtZT17Y2xzeChzdHlsZXMuc3BhbkRldGFpbFBhbmVsVHJhY2VWaWV3ZXIsIGNsYXNzTmFtZSl9XG4gICAgICBzdHlsZT17XG4gICAgICAgIHtcbiAgICAgICAgICBwb3NpdGlvbjogJ3JlbGF0aXZlJyxcbiAgICAgICAgICAnLS1zZWFyY2gtaGVpZ2h0JzogJzAnLFxuICAgICAgICAgICctLXNlYXJjaC1nYXAnOiAnMCcsXG4gICAgICAgICAgJy0tbWFwLWhlaWdodCc6ICcwJyxcbiAgICAgICAgICAnLS1wYW5lbC13aWR0aCc6IGAxMDAlYCxcbiAgICAgICAgICAnLS1wYW5lbC1oZWlnaHQnOiBgMTAwJWAsXG4gICAgICAgICAgJy0taGVpZ2h0JzogYDEwMCVgLFxuICAgICAgICAgICctLXNjcm9sbGJhci13aWR0aCc6IGAke3N0YXRlLnNjcm9sbGJhcldpZHRofXB4YCxcbiAgICAgICAgfSBhcyBDU1NQcm9wZXJ0aWVzXG4gICAgICB9XG4gICAgPlxuICAgICAgPFNwYW5EZXRhaWxQYW5lbCAvPlxuICAgIDwvZGl2PlxuICApO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gVHJhY2VWaWV3ZXIocHJvcHM6IFRyYWNlVmlld2VyUHJvcHMpOiBSZWFjdE5vZGUge1xuICByZXR1cm4gKFxuICAgIDxUcmFjZVZpZXdlckNvbnRleHRQcm92aWRlciBnZXRRdWlja0xpbmtzPXtwcm9wcy5nZXRRdWlja0xpbmtzfSB3aXRoUGFuZWw+XG4gICAgICA8VHJhY2VWaWV3ZXJUaW1lbGluZSB3aXRoUGFuZWwgey4uLnByb3BzfSAvPlxuICAgIDwvVHJhY2VWaWV3ZXJDb250ZXh0UHJvdmlkZXI+XG4gICk7XG59XG4iXX0=
336
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHJhY2Utdmlld2VyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2NvbXBvbmVudHMvdHJhY2Utdmlld2VyL3RyYWNlLXZpZXdlci50c3giXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsWUFBWSxDQUFDOztBQUViLE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSxFQUFFLE1BQU0sRUFBRSxPQUFPLEVBQUUsTUFBTSxjQUFjLENBQUM7QUFDbEUsT0FBTyxFQUVMLFdBQVcsRUFDWCxnQkFBZ0IsRUFDaEIsU0FBUyxFQUNULE9BQU8sRUFDUCxNQUFNLEVBQ04sUUFBUSxHQUNULE1BQU0sT0FBTyxDQUFDO0FBQ2YsT0FBTyxFQUFFLG1CQUFtQixFQUFFLE1BQU0scUNBQXFDLENBQUM7QUFDMUUsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0sZ0NBQWdDLENBQUM7QUFDbEUsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLG1CQUFtQixDQUFDO0FBQy9DLE9BQU8sRUFBRSxHQUFHLEVBQUUsTUFBTSxXQUFXLENBQUM7QUFDaEMsT0FBTyxFQUFFLE9BQU8sRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUN4QyxPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQ2hELE9BQU8sRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLDJCQUEyQixDQUFDO0FBQzdELE9BQU8sU0FBUyxNQUFNLHlCQUF5QixDQUFDO0FBQ2hELE9BQU8sRUFBRSxPQUFPLEVBQUUsTUFBTSxzQkFBc0IsQ0FBQztBQUMvQyxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0seUJBQXlCLENBQUM7QUFDcEQsT0FBTyxFQUNMLG1CQUFtQixFQUNuQixRQUFRLEVBQ1IsY0FBYyxHQUVmLE1BQU0sdUJBQXVCLENBQUM7QUFDL0IsT0FBTyxFQUFFLG1CQUFtQixFQUFFLE1BQU0sb0NBQW9DLENBQUM7QUFDekUsT0FBTyxFQUFFLGFBQWEsRUFBRSxpQkFBaUIsRUFBRSxNQUFNLDZC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RSxnQkFBZ0IsRUFDOUIsS0FBSyxFQUFFLEtBQUssRUFDWixPQUFPLEVBQUUsT0FBTyxHQUNoQixHQUNFLEVBQ04sOEJBQ0UsS0FBQyxtQkFBbUIsSUFDbEIsZ0JBQWdCLEVBQUUsS0FBSyxDQUFDLEtBQUssQ0FBQyxNQUFNLEdBQUcsQ0FBQyxFQUN4QyxhQUFhLEVBQUUsYUFBYSxHQUM1QixFQUNGLGVBQUssU0FBUyxFQUFDLDBKQUEwSixhQUN2SyxLQUFDLFVBQVUsSUFDVCxPQUFPLEVBQUMsT0FBTyxFQUNmLElBQUksRUFBQyxPQUFPLEVBQ1osT0FBTyxFQUFFLE9BQU8sRUFDaEIsUUFBUSxFQUFFLFdBQVcsZ0JBQ1YsVUFBVSxZQUVyQixLQUFDLE9BQU8sSUFBQyxTQUFTLEVBQUMsU0FBUyxHQUFHLEdBQ3BCLEVBQ2IsS0FBQyxVQUFVLElBQ1QsT0FBTyxFQUFDLE9BQU8sRUFDZixJQUFJLEVBQUMsT0FBTyxFQUNaLE9BQU8sRUFBRSxTQUFTLGdCQUNQLFlBQVksWUFFdkIsS0FBQyxTQUFTLElBQUMsU0FBUyxFQUFDLGFBQWEsR0FBRyxHQUMxQixFQUNiLEtBQUMsVUFBVSxJQUNULE9BQU8sRUFBQyxPQUFPLEVBQ2YsSUFBSSxFQUFDLE9BQU8sRUFDWixPQUFPLEVBQUUsTUFBTSxFQUNmLFFBQVEsRUFBRSxXQUFXLGdCQUNWLFNBQVMsWUFFcEIsS0FBQyxNQUFNLElBQUMsU0FBUyxFQUFDLFNBQVMsR0FBRyxHQUNuQixJQUNULElBQ0wsSUFDTyxJQUNSLEVBRU4sS0FBQyxnQkFBZ0IsSUFDZixZQUFZLEVBQUUsV0FBVyxFQUN6QixnQkFBZ0IsRUFBRSxjQUFjLEVBQ2hDLE9BQU8sRUFBRSxxQkFBcUIsR0FDOUIsSUFDRSxDQUNQLENBQUM7QUFDSixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBjbGllbnQnO1xuXG5pbXBvcnQgeyBSb3RhdGVDY3csIFNlYXJjaCwgWm9vbUluLCBab29tT3V0IH0gZnJvbSAnbHVjaWRlLXJlYWN0JztcbmltcG9ydCB7XG4gIHR5cGUgUmVhY3ROb2RlLFxuICB1c2VDYWxsYmFjayxcbiAgdXNlRGVmZXJyZWRWYWx1ZSxcbiAgdXNlRWZmZWN0LFxuICB1c2VNZW1vLFxuICB1c2VSZWYsXG4gIHVzZVN0YXRlLFxufSBmcm9tICdyZWFjdCc7XG5pbXBvcnQgeyB1c2VMb2FkTW9yZU9uU2Nyb2xsIH0gZnJvbSAnLi4vLi4vaG9va3MvdXNlLWxvYWQtbW9yZS1vbi1zY3JvbGwnO1xuaW1wb3J0IHsgdXNlUmVkdWNlZE1vdGlvbiB9IGZyb20gJy4uLy4uL2hvb2tzL3VzZS1yZWR1Y2VkLW1vdGlvbic7XG5pbXBvcnQgeyBJY29uQnV0dG9uIH0gZnJvbSAnLi4vdWkvaWNvbi1idXR0b24nO1xuaW1wb3J0IHsgS2JkIH0gZnJvbSAnLi4vdWkva2JkJztcbmltcG9ydCB7IFNwaW5uZXIgfSBmcm9tICcuLi91aS9zcGlubmVyJztcbmltcG9ydCB7IFRvb2x0aXBQcm92aWRlciB9IGZyb20gJy4uL3VpL3Rvb2x0aXAnO1xuaW1wb3J0IHsgVHJhY2VEZXRhaWxQYW5lbCB9IGZyb20gJy4vY29tcG9uZW50cy9kZXRhaWwtcGFuZWwnO1xuaW1wb3J0IEV2ZW50TGlzdCBmcm9tICcuL2NvbXBvbmVudHMvZXZlbnQtbGlzdCc7XG5pbXBvcnQgeyBNaW5pbWFwIH0gZnJvbSAnLi9jb21wb25lbnRzL21pbmltYXAnO1xuaW1wb3J0IHsgU3BsaXRQYW5lIH0gZnJvbSAnLi9jb21wb25lbnRzL3NwbGl0LXBhbmUnO1xuaW1wb3J0IHtcbiAgVElNRUxJTkVfUEFERElOR19QWCxcbiAgVGltZWxpbmUsXG4gIFRpbWVsaW5lSGVhZGVyLFxuICB0eXBlIFRpbWVsaW5lSG92ZXIsXG59IGZyb20gJy4vY29tcG9uZW50cy90aW1lbGluZSc7XG5pbXBvcnQgeyBUcmFjZVNob3J0Y3V0SGVscGVyIH0gZnJvbSAnLi9jb21wb25lbnRzL3RyYWNlLXNob3J0Y3V0LWhlbHBlcic7XG5pbXBvcnQgeyBST1dfSEVJR0hUX1BYLCBzY3JvbGxSb3dJbnRvVmlldyB9IGZyb20gJy4vY29tcG9uZW50cy91c2Utcm93LXdpbmRvdyc7XG5pbXBvcnQgeyBBY3RpdmVTcGFuUHJvdmlkZXIsIHVzZUFjdGl2ZVNwYW4gfSBmcm9tICcuL2NvbnRleHQnO1xuaW1wb3J0IHsgc2VhcmNoU3BhbnMgfSBmcm9tICcuL3NlYXJjaCc7XG5pbXBvcnQgdHlwZSB7IFRyYWNlV2l0aE1ldGEgfSBmcm9tICcuL3R5cGVzJztcbmltcG9ydCB7IGZvcm1hdER1cmF0aW9uUHJlY2lzZSwgZ2V0SGlnaFJlc0luTXMgfSBmcm9tICcuL3V0aWwvdGltaW5nJztcbmltcG9ydCB7XG4gIGNsYW1wVmlld3BvcnRUb1Jvb3QsXG4gIGNvbXB1dGVSb290Qm91bmRzLFxuICBjb21wdXRlVGltZU1hcmtlcnMsXG4gIHR5cGUgVmlld3BvcnRSYW5nZSxcbiAgd2hlZWxEZWx0YVRvUGl4ZWxzLFxuICB3aGVlbFpvb21TY2FsZUZhY3Rvcixcbn0gZnJvbSAnLi91dGlscyc7XG5cbmludGVyZmFjZSBUcmFjZVZpZXdlclByb3BzIHtcbiAgdHJhY2U6IFRyYWNlV2l0aE1ldGE7XG4gIG9uTG9hZE1vcmU/OiAoKSA9PiB2b2lkIHwgUHJvbWlzZTx2b2lkPjtcbiAgaGFzTW9yZT86IGJvb2xlYW47XG4gIGlzTG9hZGluZ01vcmU/OiBib29sZWFuO1xufVxuXG5jb25zdCBNSU5fVklFV1BPUlRfTVMgPSAwLjAwMTtcblxuY29uc3QgWk9PTV9ERUJPVU5DRV9NUyA9IDE1MDtcblxuZnVuY3Rpb24gdXNlQW5pbWF0ZWRWaWV3cG9ydChpbml0aWFsOiBWaWV3cG9ydFJhbmdlKSB7XG4gIGNvbnN0IFt2aWV3cG9ydCwgc2V0Vmlld3BvcnRTdGF0ZV0gPSB1c2VTdGF0ZTxWaWV3cG9ydFJhbmdlPihpbml0aWFsKTtcbiAgY29uc3QgYW5pbVJlZiA9IHVzZVJlZjx7XG4gICAgcmFmOiBudW1iZXI7XG4gICAgZnJvbTogVmlld3BvcnRSYW5nZTtcbiAgICB0bzogVmlld3BvcnRSYW5nZTtcbiAgICBzdGFydDogbnVtYmVyO1xuICB9IHwgbnVsbD4obnVsbCk7XG4gIGNvbnN0IGN1cnJlbnRSZWYgPSB1c2VSZWYoaW5pdGlhbCk7XG4gIGN1cnJlbnRSZWYuY3VycmVudCA9IHZpZXdwb3J0O1xuICBjb25zdCByZWR1Y2VkTW90aW9uID0gdXNlUmVkdWNlZE1vdGlvbigpO1xuXG4gIGNvbnN0IGNhbmNlbCA9IHVzZUNhbGxiYWNrKCgpID0+IHtcbiAgICBpZiAoYW5pbVJlZi5jdXJyZW50KSB7XG4gICAgICBjYW5jZWxBbmltYXRpb25GcmFtZShhbmltUmVmLmN1cnJlbnQucmFmKTtcbiAgICAgIGFuaW1SZWYuY3VycmVudCA9IG51bGw7XG4gICAgfVxuICB9LCBbXSk7XG5cbiAgY29uc3QgYW5pbWF0ZVRvID0gdXNlQ2FsbGJhY2soXG4gICAgKHRhcmdldDogVmlld3BvcnRSYW5nZSkgPT4ge1xuICAgICAgY2FuY2VsKCk7XG5cbiAgICAgIGlmIChyZWR1Y2VkTW90aW9uKSB7XG4gICAgICAgIGN1cnJlbnRSZWYuY3VycmVudCA9IHRhcmdldDtcbiAgICAgICAgc2V0Vmlld3BvcnRTdGF0ZSh0YXJnZXQpO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IGZyb20gPSBjdXJyZW50UmVmLmN1cnJlbnQ7XG4gICAgICBjb25zdCBhbmltID0geyByYWY6IDAsIGZyb20sIHRvOiB0YXJnZXQsIHN0YXJ0OiBwZXJmb3JtYW5jZS5ub3coKSB9O1xuXG4gICAgICBjb25zdCB0aWNrID0gKCkgPT4ge1xuICAgICAgICBjb25zdCB0ID0gTWF0aC5taW4oKHBlcmZvcm1hbmNlLm5vdygpIC0gYW5pbS5zdGFydCkgLyAyNDAsIDEpO1xuICAgICAgICBjb25zdCBlID0gdCA8IDAuNSA/IDggKiB0ICogdCAqIHQgKiB0IDogMSAtICgtMiAqIHQgKyAyKSAqKiA0IC8gMjtcbiAgICAgICAgc2V0Vmlld3BvcnRTdGF0ZSh7XG4gICAgICAgICAgc3RhcnQ6IGFuaW0uZnJvbS5zdGFydCArIChhbmltLnRvLnN0YXJ0IC0gYW5pbS5mcm9tLnN0YXJ0KSAqIGUsXG4gICAgICAgICAgZW5kOiBhbmltLmZyb20uZW5kICsgKGFuaW0udG8uZW5kIC0gYW5pbS5mcm9tLmVuZCkgKiBlLFxuICAgICAgICB9KTtcbiAgICAgICAgaWYgKHQgPCAxKSBhbmltLnJhZiA9IHJlcXVlc3RBbmltYXRpb25GcmFtZSh0aWNrKTtcbiAgICAgICAgZWxzZSBhbmltUmVmLmN1cnJlbnQgPSBudWxsO1xuICAgICAgfTtcblxuICAgICAgYW5pbVJlZi5jdXJyZW50ID0gYW5pbTtcbiAgICAgIGFuaW0ucmFmID0gcmVxdWVzdEFuaW1hdGlvbkZyYW1lKHRpY2spO1xuICAgIH0sXG4gICAgW2NhbmNlbCwgcmVkdWNlZE1vdGlvbl1cbiAgKTtcblxuICBjb25zdCBzZXRWaWV3cG9ydCA9IHVzZUNhbGxiYWNrKFxuICAgICh1cGRhdGU6IFZpZXdwb3J0UmFuZ2UgfCAoKHByZXY6IFZpZXdwb3J0UmFuZ2UpID0+IFZpZXdwb3J0UmFuZ2UpKSA9PiB7XG4gICAgICBjYW5jZWwoKTtcbiAgICAgIGlmICh0eXBlb2YgdXBkYXRlID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgIHNldFZpZXdwb3J0U3RhdGUoKHByZXYpID0+IHtcbiAgICAgICAgICBjb25zdCBuZXh0ID0gdXBkYXRlKHByZXYpO1xuICAgICAgICAgIGN1cnJlbnRSZWYuY3VycmVudCA9IG5leHQ7XG4gICAgICAgICAgcmV0dXJuIG5leHQ7XG4gICAgICAgIH0pO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY3VycmVudFJlZi5jdXJyZW50ID0gdXBkYXRlO1xuICAgICAgICBzZXRWaWV3cG9ydFN0YXRlKHVwZGF0ZSk7XG4gICAgICB9XG4gICAgfSxcbiAgICBbY2FuY2VsXVxuICApO1xuXG4gIHVzZUVmZmVjdCgoKSA9PiBjYW5jZWwsIFtjYW5jZWxdKTtcblxuICByZXR1cm4geyB2aWV3cG9ydCwgc2V0Vmlld3BvcnQsIGFuaW1hdGVUbyB9O1xufVxuXG4vLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbi8vIFJvb3QgY29tcG9uZW50XG4vLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cblxuZXhwb3J0IGZ1bmN0aW9uIFRyYWNlVmlld2VyKHtcbiAgdHJhY2UsXG4gIG9uTG9hZE1vcmUsXG4gIGhhc01vcmUsXG4gIGlzTG9hZGluZ01vcmUsXG59OiBUcmFjZVZpZXdlclByb3BzKTogUmVhY3ROb2RlIHtcbiAgcmV0dXJuIChcbiAgICA8VG9vbHRpcFByb3ZpZGVyIGRlbGF5RHVyYXRpb249ezMwMH0+XG4gICAgICA8QWN0aXZlU3BhblByb3ZpZGVyIHNwYW5zPXt0cmFjZS5zcGFuc30+XG4gICAgICAgIDxUcmFjZVZpZXdlckNvbnRlbnRcbiAgICAgICAgICB0cmFjZT17dHJhY2V9XG4gICAgICAgICAgb25Mb2FkTW9yZT17b25Mb2FkTW9yZX1cbiAgICAgICAgICBoYXNNb3JlPXtoYXNNb3JlfVxuICAgICAgICAgIGlzTG9hZGluZ01vcmU9e2lzTG9hZGluZ01vcmV9XG4gICAgICAgIC8+XG4gICAgICA8L0FjdGl2ZVNwYW5Qcm92aWRlcj5cbiAgICA8L1Rvb2x0aXBQcm92aWRlcj5cbiAgKTtcbn1cblxuZnVuY3Rpb24gVHJhY2VWaWV3ZXJDb250ZW50KHtcbiAgdHJhY2UsXG4gIG9uTG9hZE1vcmUsXG4gIGhhc01vcmUsXG4gIGlzTG9hZGluZ01vcmUsXG59OiBUcmFjZVZpZXdlclByb3BzKTogUmVhY3ROb2RlIHtcbiAgY29uc3QgeyBhY3RpdmVTcGFuSWQsIHNldEFjdGl2ZVNwYW4sIGNsZWFyQWN0aXZlU3BhbiB9ID0gdXNlQWN0aXZlU3BhbigpO1xuXG4gIGNvbnN0IHJlZHVjZWRNb3Rpb24gPSB1c2VSZWR1Y2VkTW90aW9uKCk7XG5cbiAgY29uc3QgW3NlYXJjaFF1ZXJ5LCBzZXRTZWFyY2hRdWVyeV0gPSB1c2VTdGF0ZSgnJyk7XG4gIGNvbnN0IGRlZmVycmVkU2VhcmNoUXVlcnkgPSB1c2VEZWZlcnJlZFZhbHVlKHNlYXJjaFF1ZXJ5KTtcblxuICBjb25zdCBwYW5lUm9vdFJlZiA9IHVzZVJlZjxIVE1MRGl2RWxlbWVudD4obnVsbCk7XG5cbiAgY29uc3Qgc2VhcmNoUmVzdWx0ID0gdXNlTWVtbyhcbiAgICAoKSA9PiBzZWFyY2hTcGFucyh0cmFjZS5zcGFucywgZGVmZXJyZWRTZWFyY2hRdWVyeSksXG4gICAgW3RyYWNlLnNwYW5zLCBkZWZlcnJlZFNlYXJjaFF1ZXJ5XVxuICApO1xuXG4gIGNvbnN0IHJvb3QgPSB1c2VNZW1vKCgpID0+IGNvbXB1dGVSb290Qm91bmRzKHRyYWNlLnNwYW5zKSwgW3RyYWNlLnNwYW5zXSk7XG5cbiAgY29uc3Qgc2Nyb2xsQ29udGFpbmVyUmVmID0gdXNlUmVmPEhUTUxEaXZFbGVtZW50PihudWxsKTtcbiAgY29uc3QgbG9hZE1vcmUgPSB1c2VDYWxsYmFjaygoKSA9PiB7XG4gICAgdm9pZCBvbkxvYWRNb3JlPy4oKTtcbiAgfSwgW29uTG9hZE1vcmVdKTtcbiAgY29uc3QgbG9hZE1vcmVTZW50aW5lbFJlZiA9IHVzZUxvYWRNb3JlT25TY3JvbGwobG9hZE1vcmUsIHtcbiAgICBoYXNNb3JlOiBCb29sZWFuKG9uTG9hZE1vcmUgJiYgaGFzTW9yZSksXG4gICAgaXNMb2FkaW5nTW9yZTogQm9vbGVhbihpc0xvYWRpbmdNb3JlKSxcbiAgICByb290UmVmOiBzY3JvbGxDb250YWluZXJSZWYsXG4gIH0pO1xuXG4gIGNvbnN0IHsgdmlld3BvcnQsIHNldFZpZXdwb3J0LCBhbmltYXRlVG8gfSA9IHVzZUFuaW1hdGVkVmlld3BvcnQoe1xuICAgIHN0YXJ0OiByb290LnN0YXJ0VGltZSxcbiAgICBlbmQ6IHJvb3Quc3RhcnRUaW1lICsgcm9vdC5kdXJhdGlvbixcbiAgfSk7XG5cbiAgY29uc3QgcHJldlJvb3RSZWYgPSB1c2VSZWY8Vmlld3BvcnRSYW5nZT4oe1xuICAgIHN0YXJ0OiByb290LnN0YXJ0VGltZSxcbiAgICBlbmQ6IHJvb3Quc3RhcnRUaW1lICsgcm9vdC5kdXJhdGlvbixcbiAgfSk7XG5cbiAgdXNlRWZmZWN0KCgpID0+IHtcbiAgICBjb25zdCBwcmV2Um9vdCA9IHByZXZSb290UmVmLmN1cnJlbnQ7XG4gICAgY29uc3QgbmV3U3RhcnQgPSByb290LnN0YXJ0VGltZTtcbiAgICBjb25zdCBuZXdFbmQgPSByb290LnN0YXJ0VGltZSArIHJvb3QuZHVyYXRpb247XG5cbiAgICBzZXRWaWV3cG9ydCgocHJldikgPT4ge1xuICAgICAgY29uc3Qgd2FzQXRGdWxsRXh0ZW50ID1cbiAgICAgICAgTWF0aC5hYnMocHJldi5zdGFydCAtIHByZXZSb290LnN0YXJ0KSA8IDAuMDEgJiZcbiAgICAgICAgTWF0aC5hYnMocHJldi5lbmQgLSBwcmV2Um9vdC5lbmQpIDwgMC4wMTtcblxuICAgICAgaWYgKHdhc0F0RnVsbEV4dGVudCkge1xuICAgICAgICByZXR1cm4geyBzdGFydDogbmV3U3RhcnQsIGVuZDogbmV3RW5kIH07XG4gICAgICB9XG4gICAgICByZXR1cm4gcHJldjtcbiAgICB9KTtcblxuICAgIHByZXZSb290UmVmLmN1cnJlbnQgPSB7IHN0YXJ0OiBuZXdTdGFydCwgZW5kOiBuZXdFbmQgfTtcbiAgfSwgW3Jvb3Quc3RhcnRUaW1lLCByb290LmR1cmF0aW9uLCBzZXRWaWV3cG9ydF0pO1xuXG4gIGNvbnN0IHZpZXdEdXJhdGlvbiA9IHZpZXdwb3J0LmVuZCAtIHZpZXdwb3J0LnN0YXJ0O1xuXG4gIC8vIEtlZXAgYSByZWYgdG8gdGhlIGxpdmUgdmlld3BvcnQgc28gem9vbSBjYWxsYmFja3MgY2FuIHJlYWQgdGhlIGN1cnJlbnRcbiAgLy8gcmFuZ2Ugd2l0aG91dCBiZWluZyByZWNyZWF0ZWQgb24gZXZlcnkgcGFuICh3aGljaCB3b3VsZCBidXN0IFRpbWVsaW5lQmFyJ3NcbiAgLy8gbWVtbyBhbmQgcmUtcmVuZGVyIGV2ZXJ5IHJvdyBlYWNoIGFuaW1hdGlvbiBmcmFtZSkuXG4gIGNvbnN0IHZpZXdwb3J0UmVmID0gdXNlUmVmKHZpZXdwb3J0KTtcbiAgdmlld3BvcnRSZWYuY3VycmVudCA9IHZpZXdwb3J0O1xuXG4gIGNvbnN0IHRpbWVNYXJrZXJzID0gdXNlTWVtbyhcbiAgICAoKSA9PiBjb21wdXRlVGltZU1hcmtlcnModmlld0R1cmF0aW9uLCB2aWV3cG9ydC5zdGFydCAtIHJvb3Quc3RhcnRUaW1lKSxcbiAgICBbdmlld0R1cmF0aW9uLCB2aWV3cG9ydC5zdGFydCwgcm9vdC5zdGFydFRpbWVdXG4gICk7XG5cbiAgY29uc3QgcmVzZXRab29tID0gdXNlQ2FsbGJhY2soKCkgPT4ge1xuICAgIGFuaW1hdGVUbyh7IHN0YXJ0OiByb290LnN0YXJ0VGltZSwgZW5kOiByb290LnN0YXJ0VGltZSArIHJvb3QuZHVyYXRpb24gfSk7XG4gIH0sIFthbmltYXRlVG8sIHJvb3Quc3RhcnRUaW1lLCByb290LmR1cmF0aW9uXSk7XG5cbiAgY29uc3QgY2xhbXBUb1Jvb3QgPSB1c2VDYWxsYmFjayhcbiAgICAobmV4dDogVmlld3BvcnRSYW5nZSk6IFZpZXdwb3J0UmFuZ2UgPT5cbiAgICAgIGNsYW1wVmlld3BvcnRUb1Jvb3QobmV4dCwgcm9vdC5zdGFydFRpbWUsIHJvb3QuZW5kVGltZSwgTUlOX1ZJRVdQT1JUX01TKSxcbiAgICBbcm9vdC5zdGFydFRpbWUsIHJvb3QuZW5kVGltZV1cbiAgKTtcblxuICAvLyBQYW4gKGtlZXBpbmcgdGhlIGN1cnJlbnQgem9vbSkgc28gYHRpbWVNc2AgaXMgY2VudGVyZWQgaW4gdmlldyDigJQgdXNlZCBieSB0aGVcbiAgLy8gb2ZmLXNjcmVlbiBtYXJrZXIgaW5kaWNhdG9ycyB0byBzY3JvbGwgdGhlaXIgbWFya2VyIGludG8gdmlldy5cbiAgY29uc3QgaGFuZGxlUmV2ZWFsVGltZSA9IHVzZUNhbGxiYWNrKFxuICAgICh0aW1lTXM6IG51bWJlcikgPT4ge1xuICAgICAgY29uc3QgeyBzdGFydCwgZW5kIH0gPSB2aWV3cG9ydFJlZi5jdXJyZW50O1xuICAgICAgY29uc3QgZHVyYXRpb24gPSBlbmQgLSBzdGFydDtcbiAgICAgIGFuaW1hdGVUbyhcbiAgICAgICAgY2xhbXBUb1Jvb3Qoe1xuICAgICAgICAgIHN0YXJ0OiB0aW1lTXMgLSBkdXJhdGlvbiAvIDIsXG4gICAgICAgICAgZW5kOiB0aW1lTXMgKyBkdXJhdGlvbiAvIDIsXG4gICAgICAgIH0pXG4gICAgICApO1xuICAgIH0sXG4gICAgW2FuaW1hdGVUbywgY2xhbXBUb1Jvb3RdXG4gICk7XG5cbiAgY29uc3QgWk9PTV9GQUNUT1IgPSAwLjU7XG5cbiAgY29uc3Qgem9vbUJ5ID0gdXNlQ2FsbGJhY2soXG4gICAgKGZhY3RvcjogbnVtYmVyKSA9PiB7XG4gICAgICBjb25zdCB7IHN0YXJ0LCBlbmQgfSA9IHZpZXdwb3J0UmVmLmN1cnJlbnQ7XG4gICAgICBjb25zdCBjZW50ZXIgPSAoc3RhcnQgKyBlbmQpIC8gMjtcbiAgICAgIGNvbnN0IG5ld0R1cmF0aW9uID0gTWF0aC5tYXgoTUlOX1ZJRVdQT1JUX01TLCAoZW5kIC0gc3RhcnQpICogZmFjdG9yKTtcbiAgICAgIGFuaW1hdGVUbyhcbiAgICAgICAgY2xhbXBUb1Jvb3Qoe1xuICAgICAgICAgIHN0YXJ0OiBjZW50ZXIgLSBuZXdEdXJhdGlvbiAvIDIsXG4gICAgICAgICAgZW5kOiBjZW50ZXIgKyBuZXdEdXJhdGlvbiAvIDIsXG4gICAgICAgIH0pXG4gICAgICApO1xuICAgIH0sXG4gICAgW2FuaW1hdGVUbywgY2xhbXBUb1Jvb3RdXG4gICk7XG5cbiAgY29uc3Qgem9vbUluID0gdXNlQ2FsbGJhY2soKCkgPT4gem9vbUJ5KFpPT01fRkFDVE9SKSwgW3pvb21CeV0pO1xuICBjb25zdCB6b29tT3V0ID0gdXNlQ2FsbGJhY2soKCkgPT4gem9vbUJ5KDEgLyBaT09NX0ZBQ1RPUiksIFt6b29tQnldKTtcbiAgY29uc3QgaXNBdE1pblpvb20gPSB2aWV3RHVyYXRpb24gPj0gcm9vdC5kdXJhdGlvbjtcbiAgY29uc3QgaXNBdE1heFpvb20gPSB2aWV3RHVyYXRpb24gPD0gTUlOX1ZJRVdQT1JUX01TO1xuXG4gIGNvbnN0IGZvY3VzVmlld3BvcnRPblNwYW4gPSB1c2VDYWxsYmFjayhcbiAgICAoc3BhbklkOiBzdHJpbmcpID0+IHtcbiAgICAgIGNvbnN0IHNwYW4gPSB0cmFjZS5zcGFucy5maW5kKChzKSA9PiBzLnNwYW5JZCA9PT0gc3BhbklkKTtcbiAgICAgIGlmICghc3BhbikgcmV0dXJuO1xuXG4gICAgICBjb25zdCBzcGFuU3RhcnQgPSBnZXRIaWdoUmVzSW5NcyhzcGFuLnN0YXJ0VGltZSk7XG4gICAgICBjb25zdCBzcGFuRW5kID0gZ2V0SGlnaFJlc0luTXMoc3Bhbi5lbmRUaW1lKTtcbiAgICAgIGNvbnN0IHNwYW5EdXJhdGlvbiA9IHNwYW5FbmQgLSBzcGFuU3RhcnQ7XG5cbiAgICAgIGlmIChzcGFuRHVyYXRpb24gPiByb290LmR1cmF0aW9uICogMC44KSB7XG4gICAgICAgIGFuaW1hdGVUbyh7IHN0YXJ0OiByb290LnN0YXJ0VGltZSwgZW5kOiByb290LmVuZFRpbWUgfSk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgY29uc3QgcGFkZGluZyA9IE1hdGgubWF4KHNwYW5EdXJhdGlvbiAqIDAuMiwgTUlOX1ZJRVdQT1JUX01TIC8gMik7XG4gICAgICBsZXQgbmV3U3RhcnQgPSBzcGFuU3RhcnQgLSBwYWRkaW5nO1xuICAgICAgbGV0IG5ld0VuZCA9IHNwYW5FbmQgKyBwYWRkaW5nO1xuXG4gICAgICBpZiAobmV3RW5kIC0gbmV3U3RhcnQgPCBNSU5fVklFV1BPUlRfTVMpIHtcbiAgICAgICAgY29uc3QgY2VudGVyID0gKHNwYW5TdGFydCArIHNwYW5FbmQpIC8gMjtcbiAgICAgICAgbmV3U3RhcnQgPSBjZW50ZXIgLSBNSU5fVklFV1BPUlRfTVMgLyAyO1xuICAgICAgICBuZXdFbmQgPSBjZW50ZXIgKyBNSU5fVklFV1BPUlRfTVMgLyAyO1xuICAgICAgfVxuXG4gICAgICBhbmltYXRlVG8oY2xhbXBUb1Jvb3QoeyBzdGFydDogbmV3U3RhcnQsIGVuZDogbmV3RW5kIH0pKTtcbiAgICB9LFxuICAgIFtcbiAgICAgIGFuaW1hdGVUbyxcbiAgICAgIHRyYWNlLnNwYW5zLFxuICAgICAgcm9vdC5zdGFydFRpbWUsXG4gICAgICByb290LmVuZFRpbWUsXG4gICAgICByb290LmR1cmF0aW9uLFxuICAgICAgY2xhbXBUb1Jvb3QsXG4gICAgXVxuICApO1xuXG4gIC8vIEJyaW5nIGEgcm93IGludG8gdmlldyB3aGVuIGtleWJvYXJkL2J1dHRvbiBuYXZpZ2F0aW9uIGxhbmRzIG9uIGEgc3BhbiB0aGF0XG4gIC8vIHNpdHMgb3V0c2lkZSB0aGUgc2hhcmVkIHNjcm9sbCBjb250YWluZXIncyB2aXNpYmxlIGFyZWEuIFRoZSBsaXN0IGlzXG4gIC8vIHdpbmRvd2VkLCBzbyBhbiBvZmYtc2NyZWVuIHJvdyBoYXMgbm8gRE9NIG5vZGUgdG8gYHNjcm9sbEludG9WaWV3YCDigJRcbiAgLy8gYHNjcm9sbFJvd0ludG9WaWV3YCBjb21wdXRlcyB0aGUgdGFyZ2V0IG9mZnNldCBmcm9tIHRoZSBzcGFuJ3MgaW5kZXguXG4gIGNvbnN0IHNjcm9sbFNwYW5JbnRvVmlldyA9IHVzZUNhbGxiYWNrKFxuICAgIChzcGFuSWQ6IHN0cmluZykgPT4ge1xuICAgICAgY29uc3QgaW5kZXggPSB0cmFjZS5zcGFucy5maW5kSW5kZXgoKHMpID0+IHMuc3BhbklkID09PSBzcGFuSWQpO1xuICAgICAgaWYgKGluZGV4ID09PSAtMSkgcmV0dXJuO1xuXG4gICAgICBjb25zdCBsaXN0ID1cbiAgICAgICAgc2Nyb2xsQ29udGFpbmVyUmVmLmN1cnJlbnQ/LnF1ZXJ5U2VsZWN0b3I8SFRNTEVsZW1lbnQ+KCcjZXZlbnQtbGlzdCcpID8/XG4gICAgICAgIG51bGw7XG4gICAgICBzY3JvbGxSb3dJbnRvVmlldyhsaXN0LCBpbmRleCwgUk9XX0hFSUdIVF9QWCwge1xuICAgICAgICBiZWhhdmlvcjogcmVkdWNlZE1vdGlvbiA/ICdhdXRvJyA6ICdzbW9vdGgnLFxuICAgICAgfSk7XG4gICAgfSxcbiAgICBbdHJhY2Uuc3BhbnMsIHJlZHVjZWRNb3Rpb25dXG4gICk7XG5cbiAgY29uc3Qgem9vbVRpbWVyUmVmID0gdXNlUmVmPFJldHVyblR5cGU8dHlwZW9mIHNldFRpbWVvdXQ+IHwgbnVsbD4obnVsbCk7XG4gIGNvbnN0IGNhbmNlbFBlbmRpbmdab29tID0gdXNlQ2FsbGJhY2soKCkgPT4ge1xuICAgIGlmICh6b29tVGltZXJSZWYuY3VycmVudCAhPT0gbnVsbCkge1xuICAgICAgY2xlYXJUaW1lb3V0KHpvb21UaW1lclJlZi5jdXJyZW50KTtcbiAgICAgIHpvb21UaW1lclJlZi5jdXJyZW50ID0gbnVsbDtcbiAgICB9XG4gIH0sIFtdKTtcbiAgdXNlRWZmZWN0KCgpID0+IGNhbmNlbFBlbmRpbmdab29tLCBbY2FuY2VsUGVuZGluZ1pvb21dKTtcblxuICBjb25zdCBoYW5kbGVDbGVhckFjdGl2ZVNwYW4gPSB1c2VDYWxsYmFjaygoKSA9PiB7XG4gICAgY2FuY2VsUGVuZGluZ1pvb20oKTtcbiAgICBjbGVhckFjdGl2ZVNwYW4oKTtcbiAgfSwgW2NhbmNlbFBlbmRpbmdab29tLCBjbGVhckFjdGl2ZVNwYW5dKTtcblxuICBjb25zdCBoYW5kbGVTZWxlY3RTcGFuID0gdXNlQ2FsbGJhY2soXG4gICAgKHNwYW5JZDogc3RyaW5nKSA9PiB7XG4gICAgICBjYW5jZWxQZW5kaW5nWm9vbSgpO1xuICAgICAgaWYgKHNwYW5JZCA9PT0gYWN0aXZlU3BhbklkKSB7XG4gICAgICAgIGNsZWFyQWN0aXZlU3BhbigpO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICBzZXRBY3RpdmVTcGFuKHNwYW5JZCk7XG4gICAgICBmb2N1c1ZpZXdwb3J0T25TcGFuKHNwYW5JZCk7XG4gICAgfSxcbiAgICBbXG4gICAgICBjYW5jZWxQZW5kaW5nWm9vbSxcbiAgICAgIGFjdGl2ZVNwYW5JZCxcbiAgICAgIGNsZWFyQWN0aXZlU3BhbixcbiAgICAgIHNldEFjdGl2ZVNwYW4sXG4gICAgICBmb2N1c1ZpZXdwb3J0T25TcGFuLFxuICAgIF1cbiAgKTtcblxuICBjb25zdCBuYXZpZ2F0ZVRvU3BhbiA9IHVzZUNhbGxiYWNrKFxuICAgIChzcGFuSWQ6IHN0cmluZykgPT4ge1xuICAgICAgc2V0QWN0aXZlU3BhbihzcGFuSWQpO1xuICAgICAgc2Nyb2xsU3BhbkludG9WaWV3KHNwYW5JZCk7XG4gICAgICBjYW5jZWxQZW5kaW5nWm9vbSgpO1xuICAgICAgem9vbVRpbWVyUmVmLmN1cnJlbnQgPSBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgem9vbVRpbWVyUmVmLmN1cnJlbnQgPSBudWxsO1xuICAgICAgICBmb2N1c1ZpZXdwb3J0T25TcGFuKHNwYW5JZCk7XG4gICAgICB9LCBaT09NX0RFQk9VTkNFX01TKTtcbiAgICB9LFxuICAgIFtzZXRBY3RpdmVTcGFuLCBzY3JvbGxTcGFuSW50b1ZpZXcsIGNhbmNlbFBlbmRpbmdab29tLCBmb2N1c1ZpZXdwb3J0T25TcGFuXVxuICApO1xuXG4gIGNvbnN0IFthbHRIZWxkLCBzZXRBbHRIZWxkXSA9IHVzZVN0YXRlKGZhbHNlKTtcblxuICB1c2VFZmZlY3QoKCkgPT4ge1xuICAgIGNvbnN0IG9uS2V5RG93biA9IChlOiBLZXlib2FyZEV2ZW50KTogdm9pZCA9PiB7XG4gICAgICBpZiAoZS5rZXkgPT09ICdFc2NhcGUnKSB7XG4gICAgICAgIGhhbmRsZUNsZWFyQWN0aXZlU3BhbigpO1xuICAgICAgfSBlbHNlIGlmIChlLmtleSA9PT0gJ0FsdCcpIHtcbiAgICAgICAgc2V0QWx0SGVsZCh0cnVlKTtcbiAgICAgIH1cbiAgICB9O1xuICAgIGNvbnN0IG9uS2V5VXAgPSAoZTogS2V5Ym9hcmRFdmVudCk6IHZvaWQgPT4ge1xuICAgICAgaWYgKGUua2V5ID09PSAnQWx0Jykgc2V0QWx0SGVsZChmYWxzZSk7XG4gICAgfTtcbiAgICBjb25zdCBvbkJsdXIgPSAoKTogdm9pZCA9PiBzZXRBbHRIZWxkKGZhbHNlKTtcblxuICAgIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKCdrZXlkb3duJywgb25LZXlEb3duKTtcbiAgICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcigna2V5dXAnLCBvbktleVVwKTtcbiAgICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcignYmx1cicsIG9uQmx1cik7XG4gICAgcmV0dXJuICgpID0+IHtcbiAgICAgIHdpbmRvdy5yZW1vdmVFdmVudExpc3RlbmVyKCdrZXlkb3duJywgb25LZXlEb3duKTtcbiAgICAgIHdpbmRvdy5yZW1vdmVFdmVudExpc3RlbmVyKCdrZXl1cCcsIG9uS2V5VXApO1xuICAgICAgd2luZG93LnJlbW92ZUV2ZW50TGlzdGVuZXIoJ2JsdXInLCBvbkJsdXIpO1xuICAgIH07XG4gIH0sIFtoYW5kbGVDbGVhckFjdGl2ZVNwYW5dKTtcblxuICBjb25zdCB0aW1lbGluZVJlZiA9IHVzZVJlZjxIVE1MRGl2RWxlbWVudD4obnVsbCk7XG4gIGNvbnN0IFtob3Zlciwgc2V0SG92ZXJdID0gdXNlU3RhdGU8VGltZWxpbmVIb3ZlciB8IG51bGw+KG51bGwpO1xuXG4gIGNvbnN0IGhvdmVySW5mbyA9IHVzZU1lbW8oKCkgPT4ge1xuICAgIGlmIChob3ZlciA9PSBudWxsKSByZXR1cm4gbnVsbDtcbiAgICBjb25zdCBhYnNUaW1lID0gdmlld3BvcnQuc3RhcnQgKyBob3Zlci5mcmFjdGlvbiAqIHZpZXdEdXJhdGlvbjtcbiAgICBjb25zdCBvZmZzZXQgPSBhYnNUaW1lIC0gcm9vdC5zdGFydFRpbWU7XG4gICAgcmV0dXJuIHsgZnJhY3Rpb246IGhvdmVyLmZyYWN0aW9uLCBsYWJlbDogZm9ybWF0RHVyYXRpb25QcmVjaXNlKG9mZnNldCkgfTtcbiAgfSwgW2hvdmVyLCB2aWV3cG9ydC5zdGFydCwgdmlld0R1cmF0aW9uLCByb290LnN0YXJ0VGltZV0pO1xuXG4gIGNvbnN0IGhhbmRsZVRpbWVsaW5lTW91c2VNb3ZlID0gdXNlQ2FsbGJhY2soXG4gICAgKGU6IFJlYWN0Lk1vdXNlRXZlbnQ8SFRNTERpdkVsZW1lbnQ+KSA9PiB7XG4gICAgICBjb25zdCBlbCA9IHRpbWVsaW5lUmVmLmN1cnJlbnQ7XG4gICAgICBpZiAoIWVsKSByZXR1cm47XG4gICAgICBjb25zdCByZWN0ID0gZWwuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG4gICAgICBjb25zdCBjb250ZW50V2lkdGggPSByZWN0LndpZHRoIC0gVElNRUxJTkVfUEFERElOR19QWCAqIDI7XG4gICAgICBpZiAoY29udGVudFdpZHRoIDw9IDApIHJldHVybjtcbiAgICAgIGNvbnN0IGZyYWN0aW9uID0gTWF0aC5tYXgoXG4gICAgICAgIDAsXG4gICAgICAgIE1hdGgubWluKFxuICAgICAgICAgIDEsXG4gICAgICAgICAgKGUuY2xpZW50WCAtIHJlY3QubGVmdCAtIFRJTUVMSU5FX1BBRERJTkdfUFgpIC8gY29udGVudFdpZHRoXG4gICAgICAgIClcbiAgICAgICk7XG4gICAgICBzZXRIb3Zlcih7XG4gICAgICAgIGZyYWN0aW9uLFxuICAgICAgICByb3dJbmRleDogTWF0aC5mbG9vcigoZS5jbGllbnRZIC0gcmVjdC50b3ApIC8gUk9XX0hFSUdIVF9QWCksXG4gICAgICB9KTtcbiAgICB9LFxuICAgIFtdXG4gICk7XG5cbiAgY29uc3QgaGFuZGxlVGltZWxpbmVNb3VzZUxlYXZlID0gdXNlQ2FsbGJhY2soKCkgPT4ge1xuICAgIHNldEhvdmVyKG51bGwpO1xuICB9LCBbXSk7XG5cbiAgdXNlRWZmZWN0KCgpID0+IHtcbiAgICBjb25zdCBlbCA9IHRpbWVsaW5lUmVmLmN1cnJlbnQ7XG4gICAgaWYgKCFlbCB8fCByb290LmR1cmF0aW9uIDw9IDApIHJldHVybjtcblxuICAgIGNvbnN0IG9uV2hlZWwgPSAoZTogV2hlZWxFdmVudCk6IHZvaWQgPT4ge1xuICAgICAgY29uc3QgaXNab29tR2VzdHVyZSA9IGUuY3RybEtleSB8fCBlLm1ldGFLZXk7XG4gICAgICBjb25zdCBoYXNEZWx0YVggPSBNYXRoLmFicyhlLmRlbHRhWCkgPiBNYXRoLmFicyhlLmRlbHRhWSk7XG5cbiAgICAgIGlmICghaXNab29tR2VzdHVyZSAmJiAhaGFzRGVsdGFYKSByZXR1cm47XG4gICAgICBlLnByZXZlbnREZWZhdWx0KCk7XG5cbiAgICAgIGNvbnN0IHJlY3QgPSBlbC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcbiAgICAgIGNvbnN0IGNvbnRlbnRXaWR0aCA9IHJlY3Qud2lkdGggLSBUSU1FTElORV9QQURESU5HX1BYICogMjtcbiAgICAgIGlmIChjb250ZW50V2lkdGggPD0gMCkgcmV0dXJuO1xuXG4gICAgICBpZiAoaXNab29tR2VzdHVyZSkge1xuICAgICAgICBjb25zdCBjdXJzb3JGcmFjdGlvbiA9IE1hdGgubWF4KFxuICAgICAgICAgIDAsXG4gICAgICAgICAgTWF0aC5taW4oXG4gICAgICAgICAgICAxLFxuICAgICAgICAgICAgKGUuY2xpZW50WCAtIHJlY3QubGVmdCAtIFRJTUVMSU5FX1BBRERJTkdfUFgpIC8gY29udGVudFdpZHRoXG4gICAgICAgICAgKVxuICAgICAgICApO1xuICAgICAgICBjb25zdCBzY2FsZUZhY3RvciA9IHdoZWVsWm9vbVNjYWxlRmFjdG9yKGUpO1xuXG4gICAgICAgIHNldFZpZXdwb3J0KChwcmV2KSA9PiB7XG4gICAgICAgICAgY29uc3QgcHJldkR1cmF0aW9uID0gcHJldi5lbmQgLSBwcmV2LnN0YXJ0O1xuICAgICAgICAgIGNvbnN0IGN1cnNvclRpbWUgPSBwcmV2LnN0YXJ0ICsgY3Vyc29yRnJhY3Rpb24gKiBwcmV2RHVyYXRpb247XG4gICAgICAgICAgLy8gQ2xhbXAgdGhlIGR1cmF0aW9uIGJlZm9yZSBhbmNob3Jpbmcgc28gdGhlIGN1cnNvciBrZWVwcyBpdHNcbiAgICAgICAgICAvLyBmcmFjdGlvbiBldmVuIHdoZW4gdGhlIHpvb20gaGl0cyB0aGUgbWluL21heCBib3VuZHMuXG4gICAgICAgICAgY29uc3QgbmV3RHVyYXRpb24gPSBNYXRoLm1heChcbiAgICAgICAgICAgIE1JTl9WSUVXUE9SVF9NUyxcbiAgICAgICAgICAgIE1hdGgubWluKHJvb3QuZHVyYXRpb24sIHByZXZEdXJhdGlvbiAqIHNjYWxlRmFjdG9yKVxuICAgICAgICAgICk7XG4gICAgICAgICAgcmV0dXJuIGNsYW1wVG9Sb290KHtcbiAgICAgICAgICAgIHN0YXJ0OiBjdXJzb3JUaW1lIC0gY3Vyc29yRnJhY3Rpb24gKiBuZXdEdXJhdGlvbixcbiAgICAgICAgICAgIGVuZDogY3Vyc29yVGltZSArICgxIC0gY3Vyc29yRnJhY3Rpb24pICogbmV3RHVyYXRpb24sXG4gICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY29uc3QgZHggPSB3aGVlbERlbHRhVG9QaXhlbHMoZS5kZWx0YVgsIGUuZGVsdGFNb2RlKTtcbiAgICAgICAgc2V0Vmlld3BvcnQoKHByZXYpID0+IHtcbiAgICAgICAgICBjb25zdCBwYW5BbW91bnQgPSAoZHggLyBjb250ZW50V2lkdGgpICogKHByZXYuZW5kIC0gcHJldi5zdGFydCk7XG4gICAgICAgICAgcmV0dXJuIGNsYW1wVG9Sb290KHtcbiAgICAgICAgICAgIHN0YXJ0OiBwcmV2LnN0YXJ0ICsgcGFuQW1vdW50LFxuICAgICAgICAgICAgZW5kOiBwcmV2LmVuZCArIHBhbkFtb3VudCxcbiAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfTtcblxuICAgIGVsLmFkZEV2ZW50TGlzdGVuZXIoJ3doZWVsJywgb25XaGVlbCwgeyBwYXNzaXZlOiBmYWxzZSB9KTtcbiAgICByZXR1cm4gKCkgPT4gZWwucmVtb3ZlRXZlbnRMaXN0ZW5lcignd2hlZWwnLCBvbldoZWVsKTtcbiAgfSwgW3Jvb3QuZHVyYXRpb24sIHNldFZpZXdwb3J0LCBjbGFtcFRvUm9vdF0pO1xuXG4gIHJldHVybiAoXG4gICAgPGRpdlxuICAgICAgcmVmPXtwYW5lUm9vdFJlZn1cbiAgICAgIGRhdGEtcGFuZT1cInBhbmUtcm9vdFwiXG4gICAgICBjbGFzc05hbWU9XCJyZWxhdGl2ZSBmbGV4IHctZnVsbCBoLWZ1bGwgbWF4LWgtZnVsbFwiXG4gICAgPlxuICAgICAgPGRpdlxuICAgICAgICBpZD1cInRyYWNlLXBhcmVudFwiXG4gICAgICAgIGNsYXNzTmFtZT1cIkBjb250YWluZXIgZmxleC0xIG1pbi13LTAgZ3JpZCBncmlkLXJvd3MtW2F1dG9fMWZyXSBoLWZ1bGwgbWluLWgtMCBvdmVyZmxvdy1oaWRkZW4gcmVsYXRpdmUgYmctYmFja2dyb3VuZC0xMDBcIlxuICAgICAgPlxuICAgICAgICA8TWluaW1hcFxuICAgICAgICAgIHNwYW5zPXt0cmFjZS5zcGFuc31cbiAgICAgICAgICByb290PXtyb290fVxuICAgICAgICAgIHZpZXdwb3J0PXt2aWV3cG9ydH1cbiAgICAgICAgICBtaW5WaWV3cG9ydE1zPXtNSU5fVklFV1BPUlRfTVN9XG4gICAgICAgICAgb25WaWV3cG9ydENoYW5nZT17c2V0Vmlld3BvcnR9XG4gICAgICAgICAgb25BbmltYXRlVG89e2FuaW1hdGVUb31cbiAgICAgICAgLz5cbiAgICAgICAgPFNwbGl0UGFuZVxuICAgICAgICAgIHNjcm9sbENvbnRhaW5lclJlZj17c2Nyb2xsQ29udGFpbmVyUmVmfVxuICAgICAgICAgIHN0YXJ0SGVhZGVyPXtcbiAgICAgICAgICAgIDxkaXYgY2xhc3NOYW1lPVwiYmctYmFja2dyb3VuZC0xMDAgYm9yZGVyLWIgYm9yZGVyLWdyYXktYWxwaGEtNDAwIGgtMTAgbWluLWgtMTAgZmxleCBpdGVtcy1jZW50ZXIgcGwtNCBwci0yIGdhcC0xLjVcIj5cbiAgICAgICAgICAgICAgPFNlYXJjaCBjbGFzc05hbWU9XCJ3LTMuNSBoLTMuNSBzaHJpbmstMCB0ZXh0LWdyYXktODAwXCIgLz5cbiAgICAgICAgICAgICAgPGlucHV0XG4gICAgICAgICAgICAgICAgaWQ9XCJ0cmFjZS12aWV3ZXItc2VhcmNoXCJcbiAgICAgICAgICAgICAgICBuYW1lPVwidHJhY2Utdmlld2VyLXNlYXJjaFwiXG4gICAgICAgICAgICAgICAgdHlwZT1cInRleHRcIlxuICAgICAgICAgICAgICAgIHZhbHVlPXtzZWFyY2hRdWVyeX1cbiAgICAgICAgICAgICAgICBvbkNoYW5nZT17KGUpID0+IHNldFNlYXJjaFF1ZXJ5KGUudGFyZ2V0LnZhbHVlKX1cbiAgICAgICAgICAgICAgICBvbktleURvd249eyhlKSA9PiB7XG4gICAgICAgICAgICAgICAgICBpZiAoZS5rZXkgPT09ICdFc2NhcGUnICYmIHNlYXJjaFF1ZXJ5KSB7XG4gICAgICAgICAgICAgICAgICAgIGUucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgICAgICAgICAgICAgZS5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICAgICAgICAgICAgICAgICAgc2V0U2VhcmNoUXVlcnkoJycpO1xuICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH19XG4gICAgICAgICAgICAgICAgcGxhY2Vob2xkZXI9XCJTZWFyY2ggc3BhbnMuLi5cIlxuICAgICAgICAgICAgICAgIGFyaWEtbGFiZWw9XCJTZWFyY2ggc3BhbnNcIlxuICAgICAgICAgICAgICAgIGNsYXNzTmFtZT1cImZsZXgtMSBtaW4tdy0wIGJnLXRyYW5zcGFyZW50IHRleHQtbGFiZWwtMTQgdGV4dC1ncmF5LTEwMDAgcGxhY2Vob2xkZXI6dGV4dC1ncmF5LTgwMCBvdXRsaW5lLW5vbmVcIlxuICAgICAgICAgICAgICAvPlxuICAgICAgICAgICAgICB7c2VhcmNoUXVlcnkgJiYgKFxuICAgICAgICAgICAgICAgIDxidXR0b25cbiAgICAgICAgICAgICAgICAgIHR5cGU9XCJidXR0b25cIlxuICAgICAgICAgICAgICAgICAgYXJpYS1sYWJlbD1cIkNsZWFyIHNlYXJjaFwiXG4gICAgICAgICAgICAgICAgICBvbkNsaWNrPXsoKSA9PiBzZXRTZWFyY2hRdWVyeSgnJyl9XG4gICAgICAgICAgICAgICAgICBjbGFzc05hbWU9XCItbXItMiBoaWRkZW4gaC1mdWxsIG1heC13LWZ1bGwgc2hyaW5rLTAgY3Vyc29yLXBvaW50ZXIgaXRlbXMtY2VudGVyIHJvdW5kZWQtci1tZCBib3JkZXItMCBiZy10cmFuc3BhcmVudCBweC0yLjUgZm9udC1pbmhlcml0IHRleHQtbGFiZWwtMTYgdGV4dC1ncmF5LTkwMCBuby11bmRlcmxpbmUgdHJhbnNpdGlvbi1jb2xvcnMgZHVyYXRpb24tMTUwIGVhc2UtaW4gaG92ZXI6dGV4dC1ncmF5LTEwMDAgZm9jdXMtdmlzaWJsZTotb3V0bGluZS1vZmZzZXQtMSBmb2N1cy12aXNpYmxlOm91dGxpbmUgZm9jdXMtdmlzaWJsZTpvdXRsaW5lLTIgZm9jdXMtdmlzaWJsZTpvdXRsaW5lLVt2YXIoLS1kcy1mb2N1cy1jb2xvcildIG1pbi1bOTYxcHhdOmZsZXhcIlxuICAgICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICAgIDxLYmQgdmFyaWFudD1cIm91dGxpbmVcIiBzaXplPVwic2VhcmNoXCI+XG4gICAgICAgICAgICAgICAgICAgIEVzY1xuICAgICAgICAgICAgICAgICAgPC9LYmQ+XG4gICAgICAgICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgICAgICl9XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICB9XG4gICAgICAgICAgZW5kSGVhZGVyPXtcbiAgICAgICAgICAgIDxUaW1lbGluZUhlYWRlciBtYXJrZXJzPXt0aW1lTWFya2Vyc30gaG92ZXJJbmZvPXtob3ZlckluZm99IC8+XG4gICAgICAgICAgfVxuICAgICAgICA+XG4gICAgICAgICAgPGRpdiBjbGFzc05hbWU9XCJibG9jayBvdmVyZmxvdy12aXNpYmxlXCI+XG4gICAgICAgICAgICA8RXZlbnRMaXN0XG4gICAgICAgICAgICAgIHNwYW5zPXt0cmFjZS5zcGFuc31cbiAgICAgICAgICAgICAgYWN0aXZlU3BhbklkPXthY3RpdmVTcGFuSWR9XG4gICAgICAgICAgICAgIHNlYXJjaFJlc3VsdD17c2VhcmNoUmVzdWx0fVxuICAgICAgICAgICAgICBvblNlbGVjdFNwYW49e2hhbmRsZVNlbGVjdFNwYW59XG4gICAgICAgICAgICAvPlxuICAgICAgICAgICAgPGRpdiByZWY9e2xvYWRNb3JlU2VudGluZWxSZWZ9IGNsYXNzTmFtZT1cImZsZXgganVzdGlmeS1jZW50ZXJcIj5cbiAgICAgICAgICAgICAge2lzTG9hZGluZ01vcmUgPyAoXG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzc05hbWU9XCJmbGV4IGl0ZW1zLWNlbnRlciBqdXN0aWZ5LWNlbnRlciBnYXAtMiBweS0zIHRleHQtbGFiZWwtMTQgdGV4dC1ncmF5LTgwMFwiPlxuICAgICAgICAgICAgICAgICAgPFNwaW5uZXIgc2l6ZT17MTR9IC8+XG4gICAgICAgICAgICAgICAgICA8c3Bhbj5Mb2FkaW5nIHNwYW5z4oCmPC9zcGFuPlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICApIDogbnVsbH1cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgIHsvKiBiaW9tZS1pZ25vcmUgbGludC9hMTF5L25vU3RhdGljRWxlbWVudEludGVyYWN0aW9uczogdGltZWxpbmUgaG92ZXIgYW5kIHdoZWVsIGdlc3R1cmVzIGFyZSBwb2ludGVyLW9ubHkgYW5ub3RhdGlvbnMgKi99XG4gICAgICAgICAgPGRpdlxuICAgICAgICAgICAgcmVmPXt0aW1lbGluZVJlZn1cbiAgICAgICAgICAgIGlkPVwidHJhY2UtdGltZWxpbmVcIlxuICAgICAgICAgICAgY2xhc3NOYW1lPVwiQGNvbnRhaW5lciBibG9jayBtaW4taC0wIG92ZXJmbG93LXZpc2libGUgcmVsYXRpdmVcIlxuICAgICAgICAgICAgb25Eb3VibGVDbGljaz17cmVzZXRab29tfVxuICAgICAgICAgICAgb25Nb3VzZU1vdmU9e2hhbmRsZVRpbWVsaW5lTW91c2VNb3ZlfVxuICAgICAgICAgICAgb25Nb3VzZUxlYXZlPXtoYW5kbGVUaW1lbGluZU1vdXNlTGVhdmV9XG4gICAgICAgICAgPlxuICAgICAgICAgICAgPFRpbWVsaW5lXG4gICAgICAgICAgICAgIHNwYW5zPXt0cmFjZS5zcGFuc31cbiAgICAgICAgICAgICAgdmlld1N0YXJ0PXt2aWV3cG9ydC5zdGFydH1cbiAgICAgICAgICAgICAgdmlld0VuZD17dmlld3BvcnQuZW5kfVxuICAgICAgICAgICAgICBtYXJrZXJzPXt0aW1lTWFya2Vyc31cbiAgICAgICAgICAgICAgc2VsZWN0ZWRJZD17YWN0aXZlU3BhbklkfVxuICAgICAgICAgICAgICBzZWFyY2hSZXN1bHQ9e3NlYXJjaFJlc3VsdH1cbiAgICAgICAgICAgICAgb25TZWxlY3Q9e2hhbmRsZVNlbGVjdFNwYW59XG4gICAgICAgICAgICAgIG9uUmV2ZWFsVGltZT17aGFuZGxlUmV2ZWFsVGltZX1cbiAgICAgICAgICAgICAgaG92ZXI9e2hvdmVyfVxuICAgICAgICAgICAgICBhbHRIZWxkPXthbHRIZWxkfVxuICAgICAgICAgICAgLz5cbiAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICA8PlxuICAgICAgICAgICAgPFRyYWNlU2hvcnRjdXRIZWxwZXJcbiAgICAgICAgICAgICAgaGFzTXVsdGlwbGVTcGFucz17dHJhY2Uuc3BhbnMubGVuZ3RoID4gMX1cbiAgICAgICAgICAgICAgcmVkdWNlZE1vdGlvbj17cmVkdWNlZE1vdGlvbn1cbiAgICAgICAgICAgIC8+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzTmFtZT1cInBvaW50ZXItZXZlbnRzLWF1dG8gZmxleCBpdGVtcy1jZW50ZXIgYm9yZGVyIGJvcmRlci1ncmF5LWFscGhhLTQwMCByb3VuZGVkLW1kIGJnLWJhY2tncm91bmQtMTAwIHNoYWRvdy1zbSBvdmVyZmxvdy1oaWRkZW4gZGl2aWRlLXggZGl2aWRlLWdyYXktYWxwaGEtNDAwXCI+XG4gICAgICAgICAgICAgIDxJY29uQnV0dG9uXG4gICAgICAgICAgICAgICAgdmFyaWFudD1cIm11dGVkXCJcbiAgICAgICAgICAgICAgICBzaXplPVwic21hbGxcIlxuICAgICAgICAgICAgICAgIG9uQ2xpY2s9e3pvb21PdXR9XG4gICAgICAgICAgICAgICAgZGlzYWJsZWQ9e2lzQXRNaW5ab29tfVxuICAgICAgICAgICAgICAgIGFyaWEtbGFiZWw9XCJab29tIG91dFwiXG4gICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICA8Wm9vbU91dCBjbGFzc05hbWU9XCJ3LTQgaC00XCIgLz5cbiAgICAgICAgICAgICAgPC9JY29uQnV0dG9uPlxuICAgICAgICAgICAgICA8SWNvbkJ1dHRvblxuICAgICAgICAgICAgICAgIHZhcmlhbnQ9XCJtdXRlZFwiXG4gICAgICAgICAgICAgICAgc2l6ZT1cInNtYWxsXCJcbiAgICAgICAgICAgICAgICBvbkNsaWNrPXtyZXNldFpvb219XG4gICAgICAgICAgICAgICAgYXJpYS1sYWJlbD1cIlJlc2V0IHpvb21cIlxuICAgICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAgPFJvdGF0ZUNjdyBjbGFzc05hbWU9XCJ3LTMuNSBoLTMuNVwiIC8+XG4gICAgICAgICAgICAgIDwvSWNvbkJ1dHRvbj5cbiAgICAgICAgICAgICAgPEljb25CdXR0b25cbiAgICAgICAgICAgICAgICB2YXJpYW50PVwibXV0ZWRcIlxuICAgICAgICAgICAgICAgIHNpemU9XCJzbWFsbFwiXG4gICAgICAgICAgICAgICAgb25DbGljaz17em9vbUlufVxuICAgICAgICAgICAgICAgIGRpc2FibGVkPXtpc0F0TWF4Wm9vbX1cbiAgICAgICAgICAgICAgICBhcmlhLWxhYmVsPVwiWm9vbSBpblwiXG4gICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICA8Wm9vbUluIGNsYXNzTmFtZT1cInctNCBoLTRcIiAvPlxuICAgICAgICAgICAgICA8L0ljb25CdXR0b24+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICA8Lz5cbiAgICAgICAgPC9TcGxpdFBhbmU+XG4gICAgICA8L2Rpdj5cblxuICAgICAgPFRyYWNlRGV0YWlsUGFuZWxcbiAgICAgICAgY29udGFpbmVyUmVmPXtwYW5lUm9vdFJlZn1cbiAgICAgICAgb25OYXZpZ2F0ZVRvU3Bhbj17bmF2aWdhdGVUb1NwYW59XG4gICAgICAgIG9uQ2xvc2U9e2hhbmRsZUNsZWFyQWN0aXZlU3Bhbn1cbiAgICAgIC8+XG4gICAgPC9kaXY+XG4gICk7XG59XG4iXX0=