@workflow/web-shared 5.0.0-beta.3 → 5.0.0-beta.31

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 (402) hide show
  1. package/README.md +2 -10
  2. package/dist/components/error-boundary.js +1 -1
  3. package/dist/components/event-list-view.d.ts +46 -1
  4. package/dist/components/event-list-view.d.ts.map +1 -1
  5. package/dist/components/event-list-view.js +228 -90
  6. package/dist/components/hook-actions.js +1 -1
  7. package/dist/components/index.d.ts +6 -2
  8. package/dist/components/index.d.ts.map +1 -1
  9. package/dist/components/index.js +5 -2
  10. package/dist/components/new-trace-viewer/components/copy-button.js +3 -3
  11. package/dist/components/new-trace-viewer/components/detail-panel-width.d.ts +34 -0
  12. package/dist/components/new-trace-viewer/components/detail-panel-width.d.ts.map +1 -0
  13. package/dist/components/new-trace-viewer/components/detail-panel-width.js +67 -0
  14. package/dist/components/new-trace-viewer/components/detail-panel.d.ts +14 -0
  15. package/dist/components/new-trace-viewer/components/detail-panel.d.ts.map +1 -0
  16. package/dist/components/new-trace-viewer/components/detail-panel.js +122 -0
  17. package/dist/components/new-trace-viewer/components/draggable-border.d.ts +31 -0
  18. package/dist/components/new-trace-viewer/components/draggable-border.d.ts.map +1 -0
  19. package/dist/components/new-trace-viewer/components/draggable-border.js +140 -0
  20. package/dist/components/new-trace-viewer/components/event-list.d.ts +4 -2
  21. package/dist/components/new-trace-viewer/components/event-list.d.ts.map +1 -1
  22. package/dist/components/new-trace-viewer/components/event-list.js +22 -13
  23. package/dist/components/new-trace-viewer/components/middle-truncate/copy-selection.d.ts +18 -0
  24. package/dist/components/new-trace-viewer/components/middle-truncate/copy-selection.d.ts.map +1 -0
  25. package/dist/components/new-trace-viewer/components/middle-truncate/copy-selection.js +54 -0
  26. package/dist/components/new-trace-viewer/components/middle-truncate/middle-truncate.d.ts +20 -0
  27. package/dist/components/new-trace-viewer/components/middle-truncate/middle-truncate.d.ts.map +1 -0
  28. package/dist/components/new-trace-viewer/components/middle-truncate/middle-truncate.js +81 -0
  29. package/dist/components/new-trace-viewer/components/middle-truncate/truncate.d.ts +25 -0
  30. package/dist/components/new-trace-viewer/components/middle-truncate/truncate.d.ts.map +1 -0
  31. package/dist/components/new-trace-viewer/components/middle-truncate/truncate.js +101 -0
  32. package/dist/components/new-trace-viewer/components/middle-truncate/use-middle-truncate.d.ts +20 -0
  33. package/dist/components/new-trace-viewer/components/middle-truncate/use-middle-truncate.d.ts.map +1 -0
  34. package/dist/components/new-trace-viewer/components/middle-truncate/use-middle-truncate.js +114 -0
  35. package/dist/components/new-trace-viewer/components/minimap.d.ts +14 -0
  36. package/dist/components/new-trace-viewer/components/minimap.d.ts.map +1 -0
  37. package/dist/components/new-trace-viewer/components/minimap.js +337 -0
  38. package/dist/components/new-trace-viewer/components/pane-constants.d.ts +14 -0
  39. package/dist/components/new-trace-viewer/components/pane-constants.d.ts.map +1 -0
  40. package/dist/components/new-trace-viewer/components/pane-constants.js +16 -0
  41. package/dist/components/new-trace-viewer/components/span-markers.d.ts +46 -0
  42. package/dist/components/new-trace-viewer/components/span-markers.d.ts.map +1 -0
  43. package/dist/components/new-trace-viewer/components/span-markers.js +85 -0
  44. package/dist/components/new-trace-viewer/components/split-pane.d.ts +3 -7
  45. package/dist/components/new-trace-viewer/components/split-pane.d.ts.map +1 -1
  46. package/dist/components/new-trace-viewer/components/split-pane.js +25 -84
  47. package/dist/components/new-trace-viewer/components/timeline.d.ts +19 -15
  48. package/dist/components/new-trace-viewer/components/timeline.d.ts.map +1 -1
  49. package/dist/components/new-trace-viewer/components/timeline.js +229 -111
  50. package/dist/components/new-trace-viewer/components/timeline.module.css +46 -0
  51. package/dist/components/new-trace-viewer/components/trace-shortcut-helper.d.ts +5 -0
  52. package/dist/components/new-trace-viewer/components/trace-shortcut-helper.d.ts.map +1 -0
  53. package/dist/components/new-trace-viewer/components/trace-shortcut-helper.js +55 -0
  54. package/dist/components/new-trace-viewer/components/trace-shortcut-helper.module.css +20 -0
  55. package/dist/components/new-trace-viewer/components/trace-viewer-skeleton.d.ts +2 -0
  56. package/dist/components/new-trace-viewer/components/trace-viewer-skeleton.d.ts.map +1 -0
  57. package/dist/components/new-trace-viewer/components/trace-viewer-skeleton.js +26 -0
  58. package/dist/components/new-trace-viewer/components/use-element-width.d.ts +8 -0
  59. package/dist/components/new-trace-viewer/components/use-element-width.d.ts.map +1 -0
  60. package/dist/components/new-trace-viewer/components/use-element-width.js +25 -0
  61. package/dist/components/new-trace-viewer/components/use-row-window.d.ts +34 -0
  62. package/dist/components/new-trace-viewer/components/use-row-window.d.ts.map +1 -0
  63. package/dist/components/new-trace-viewer/components/use-row-window.js +107 -0
  64. package/dist/components/new-trace-viewer/context.d.ts +3 -1
  65. package/dist/components/new-trace-viewer/context.d.ts.map +1 -1
  66. package/dist/components/new-trace-viewer/context.js +9 -10
  67. package/dist/components/new-trace-viewer/icons.js +3 -3
  68. package/dist/components/new-trace-viewer/search.d.ts +19 -0
  69. package/dist/components/new-trace-viewer/search.d.ts.map +1 -0
  70. package/dist/components/new-trace-viewer/search.js +134 -0
  71. package/dist/components/new-trace-viewer/trace-viewer.d.ts +6 -3
  72. package/dist/components/new-trace-viewer/trace-viewer.d.ts.map +1 -1
  73. package/dist/components/new-trace-viewer/trace-viewer.js +167 -162
  74. package/dist/components/new-trace-viewer/types.d.ts +2 -0
  75. package/dist/components/new-trace-viewer/types.d.ts.map +1 -1
  76. package/dist/components/new-trace-viewer/types.js +2 -2
  77. package/dist/components/new-trace-viewer/utils.d.ts +48 -13
  78. package/dist/components/new-trace-viewer/utils.d.ts.map +1 -1
  79. package/dist/components/new-trace-viewer/utils.js +135 -107
  80. package/dist/components/run-trace-view.d.ts +5 -7
  81. package/dist/components/run-trace-view.d.ts.map +1 -1
  82. package/dist/components/run-trace-view.js +3 -3
  83. package/dist/components/sidebar/attribute-panel.d.ts +4 -1
  84. package/dist/components/sidebar/attribute-panel.d.ts.map +1 -1
  85. package/dist/components/sidebar/attribute-panel.js +133 -113
  86. package/dist/components/sidebar/attributes-block.d.ts +40 -0
  87. package/dist/components/sidebar/attributes-block.d.ts.map +1 -0
  88. package/dist/components/sidebar/attributes-block.js +140 -0
  89. package/dist/components/sidebar/conversation-view.js +1 -1
  90. package/dist/components/sidebar/copyable-data-block.d.ts +2 -0
  91. package/dist/components/sidebar/copyable-data-block.d.ts.map +1 -1
  92. package/dist/components/sidebar/copyable-data-block.js +17 -16
  93. package/dist/components/sidebar/entity-detail-panel.d.ts +11 -11
  94. package/dist/components/sidebar/entity-detail-panel.d.ts.map +1 -1
  95. package/dist/components/sidebar/entity-detail-panel.js +35 -69
  96. package/dist/components/sidebar/events-list.d.ts +6 -2
  97. package/dist/components/sidebar/events-list.d.ts.map +1 -1
  98. package/dist/components/sidebar/events-list.js +76 -62
  99. package/dist/components/sidebar/resolve-hook-modal.js +1 -1
  100. package/dist/components/sidebar/sidebar-data-context.d.ts +10 -7
  101. package/dist/components/sidebar/sidebar-data-context.d.ts.map +1 -1
  102. package/dist/components/sidebar/sidebar-data-context.js +1 -1
  103. package/dist/components/sidebar/span-detail-merge.d.ts +31 -0
  104. package/dist/components/sidebar/span-detail-merge.d.ts.map +1 -0
  105. package/dist/components/sidebar/span-detail-merge.js +92 -0
  106. package/dist/components/sidebar/use-selected-span-detail.d.ts +16 -0
  107. package/dist/components/sidebar/use-selected-span-detail.d.ts.map +1 -0
  108. package/dist/components/sidebar/use-selected-span-detail.js +93 -0
  109. package/dist/components/stream-viewer.js +1 -1
  110. package/dist/components/trace-viewer/components/map.d.ts +2 -2
  111. package/dist/components/trace-viewer/components/map.d.ts.map +1 -1
  112. package/dist/components/trace-viewer/components/map.js +1 -1
  113. package/dist/components/trace-viewer/components/markers.js +1 -1
  114. package/dist/components/trace-viewer/components/node.d.ts +7 -7
  115. package/dist/components/trace-viewer/components/node.d.ts.map +1 -1
  116. package/dist/components/trace-viewer/components/node.js +2 -1
  117. package/dist/components/trace-viewer/components/search-input.js +1 -1
  118. package/dist/components/trace-viewer/components/search.js +1 -1
  119. package/dist/components/trace-viewer/components/span-content.js +1 -1
  120. package/dist/components/trace-viewer/components/span-detail-panel.js +1 -1
  121. package/dist/components/trace-viewer/components/span-segments.js +1 -1
  122. package/dist/components/trace-viewer/components/span-strategies.js +1 -1
  123. package/dist/components/trace-viewer/components/ui.js +1 -1
  124. package/dist/components/trace-viewer/components/zoom-button.js +1 -1
  125. package/dist/components/trace-viewer/components/zoom-icons.js +1 -1
  126. package/dist/components/trace-viewer/context.js +1 -1
  127. package/dist/components/trace-viewer/index.js +1 -1
  128. package/dist/components/trace-viewer/trace-viewer.js +1 -1
  129. package/dist/components/trace-viewer/trace-viewer.module.css +4 -4
  130. package/dist/components/trace-viewer/types.js +1 -1
  131. package/dist/components/trace-viewer/util/constants.js +1 -1
  132. package/dist/components/trace-viewer/util/scrollbar-width.js +1 -1
  133. package/dist/components/trace-viewer/util/timing.d.ts +3 -3
  134. package/dist/components/trace-viewer/util/timing.d.ts.map +1 -1
  135. package/dist/components/trace-viewer/util/timing.js +8 -11
  136. package/dist/components/trace-viewer/util/tree.js +1 -1
  137. package/dist/components/trace-viewer/util/use-immediate-style.js +1 -1
  138. package/dist/components/trace-viewer/util/use-streaming-spans.js +1 -1
  139. package/dist/components/trace-viewer/util/use-trackpad-zoom.js +1 -1
  140. package/dist/components/trace-viewer/worker.js +1 -1
  141. package/dist/components/trace-viewer-new.d.ts +5 -1
  142. package/dist/components/trace-viewer-new.d.ts.map +1 -1
  143. package/dist/components/trace-viewer-new.js +8 -10
  144. package/dist/components/ui/alert.js +2 -2
  145. package/dist/components/ui/button.d.ts +10 -0
  146. package/dist/components/ui/button.d.ts.map +1 -0
  147. package/dist/components/ui/button.js +46 -0
  148. package/dist/components/ui/card.js +2 -2
  149. package/dist/components/ui/collapsible.d.ts +46 -0
  150. package/dist/components/ui/collapsible.d.ts.map +1 -0
  151. package/dist/components/ui/collapsible.js +66 -0
  152. package/dist/components/ui/context-card.d.ts +47 -0
  153. package/dist/components/ui/context-card.d.ts.map +1 -0
  154. package/dist/components/ui/context-card.js +471 -0
  155. package/dist/components/ui/data-inspector.d.ts +7 -6
  156. package/dist/components/ui/data-inspector.d.ts.map +1 -1
  157. package/dist/components/ui/data-inspector.js +232 -99
  158. package/dist/components/ui/data-inspector.styles.d.ts +29 -0
  159. package/dist/components/ui/data-inspector.styles.d.ts.map +1 -0
  160. package/dist/components/ui/data-inspector.styles.js +95 -0
  161. package/dist/components/ui/decrypt-button.js +1 -1
  162. package/dist/components/ui/error-card.js +2 -2
  163. package/dist/components/ui/error-stack-block.d.ts +17 -10
  164. package/dist/components/ui/error-stack-block.d.ts.map +1 -1
  165. package/dist/components/ui/error-stack-block.js +49 -30
  166. package/dist/components/ui/icon-button.d.ts +19 -0
  167. package/dist/components/ui/icon-button.d.ts.map +1 -0
  168. package/dist/components/ui/icon-button.js +29 -0
  169. package/dist/components/ui/kbd.d.ts +10 -0
  170. package/dist/components/ui/kbd.d.ts.map +1 -0
  171. package/dist/components/ui/kbd.js +25 -0
  172. package/dist/components/ui/load-more-button.js +1 -1
  173. package/dist/components/ui/menu-dropdown.js +1 -1
  174. package/dist/components/ui/skeleton.js +2 -2
  175. package/dist/components/ui/spinner.js +1 -1
  176. package/dist/components/ui/timestamp-tooltip.d.ts +34 -1
  177. package/dist/components/ui/timestamp-tooltip.d.ts.map +1 -1
  178. package/dist/components/ui/timestamp-tooltip.js +80 -132
  179. package/dist/components/ui/tooltip.d.ts +10 -0
  180. package/dist/components/ui/tooltip.d.ts.map +1 -0
  181. package/dist/components/ui/tooltip.js +12 -0
  182. package/dist/components/workflow-trace-view.d.ts +7 -8
  183. package/dist/components/workflow-trace-view.d.ts.map +1 -1
  184. package/dist/components/workflow-trace-view.js +11 -16
  185. package/dist/components/workflow-traces/event-colors.d.ts +2 -1
  186. package/dist/components/workflow-traces/event-colors.d.ts.map +1 -1
  187. package/dist/components/workflow-traces/event-colors.js +15 -7
  188. package/dist/components/workflow-traces/trace-colors.d.ts.map +1 -1
  189. package/dist/components/workflow-traces/trace-colors.js +3 -4
  190. package/dist/components/workflow-traces/trace-span-construction.d.ts +7 -4
  191. package/dist/components/workflow-traces/trace-span-construction.d.ts.map +1 -1
  192. package/dist/components/workflow-traces/trace-span-construction.js +87 -33
  193. package/dist/components/workflow-traces/trace-time-utils.js +1 -1
  194. package/dist/hooks/use-dark-mode.js +1 -1
  195. package/dist/hooks/use-intersection-observer.d.ts +17 -0
  196. package/dist/hooks/use-intersection-observer.d.ts.map +1 -0
  197. package/dist/hooks/use-intersection-observer.js +29 -0
  198. package/dist/hooks/use-load-more-on-scroll.d.ts +21 -0
  199. package/dist/hooks/use-load-more-on-scroll.d.ts.map +1 -0
  200. package/dist/hooks/use-load-more-on-scroll.js +28 -0
  201. package/dist/hooks/use-reduced-motion.d.ts +10 -0
  202. package/dist/hooks/use-reduced-motion.d.ts.map +1 -0
  203. package/dist/hooks/use-reduced-motion.js +29 -0
  204. package/dist/index.d.ts +3 -2
  205. package/dist/index.d.ts.map +1 -1
  206. package/dist/index.js +4 -3
  207. package/dist/lib/cn.d.ts +10 -0
  208. package/dist/lib/cn.d.ts.map +1 -0
  209. package/dist/lib/cn.js +83 -0
  210. package/dist/lib/event-analysis.d.ts +1 -1
  211. package/dist/lib/event-analysis.d.ts.map +1 -1
  212. package/dist/lib/event-analysis.js +3 -2
  213. package/dist/lib/event-materialization.d.ts +1 -1
  214. package/dist/lib/event-materialization.d.ts.map +1 -1
  215. package/dist/lib/event-materialization.js +29 -21
  216. package/dist/lib/exact-event-search-id.d.ts +25 -0
  217. package/dist/lib/exact-event-search-id.d.ts.map +1 -0
  218. package/dist/lib/exact-event-search-id.js +39 -0
  219. package/dist/lib/hydration.d.ts +17 -2
  220. package/dist/lib/hydration.d.ts.map +1 -1
  221. package/dist/lib/hydration.js +185 -22
  222. package/dist/lib/stream-display.js +1 -1
  223. package/dist/lib/toast.js +1 -1
  224. package/dist/lib/trace-builder.d.ts +16 -4
  225. package/dist/lib/trace-builder.d.ts.map +1 -1
  226. package/dist/lib/trace-builder.js +34 -15
  227. package/dist/lib/utils.d.ts +23 -9
  228. package/dist/lib/utils.d.ts.map +1 -1
  229. package/dist/lib/utils.js +73 -33
  230. package/dist/lib/zstd-browser-decoder.d.ts +7 -0
  231. package/dist/lib/zstd-browser-decoder.d.ts.map +1 -0
  232. package/dist/lib/zstd-browser-decoder.js +41 -0
  233. package/dist/styles.css +14 -0
  234. package/package.json +10 -7
  235. package/src/components/event-list-view.tsx +375 -116
  236. package/src/components/index.ts +12 -5
  237. package/src/components/new-trace-viewer/components/copy-button.tsx +2 -2
  238. package/src/components/new-trace-viewer/components/detail-panel-width.test.ts +123 -0
  239. package/src/components/new-trace-viewer/components/detail-panel-width.ts +76 -0
  240. package/src/components/new-trace-viewer/components/detail-panel.tsx +273 -0
  241. package/src/components/new-trace-viewer/components/draggable-border.tsx +216 -0
  242. package/src/components/new-trace-viewer/components/event-list.tsx +57 -32
  243. package/src/components/new-trace-viewer/components/middle-truncate/copy-selection.ts +114 -0
  244. package/src/components/new-trace-viewer/components/middle-truncate/middle-truncate.tsx +157 -0
  245. package/src/components/new-trace-viewer/components/middle-truncate/truncate.ts +132 -0
  246. package/src/components/new-trace-viewer/components/middle-truncate/use-middle-truncate.ts +167 -0
  247. package/src/components/new-trace-viewer/components/minimap.tsx +559 -0
  248. package/src/components/new-trace-viewer/components/pane-constants.ts +19 -0
  249. package/src/components/new-trace-viewer/components/span-markers.tsx +173 -0
  250. package/src/components/new-trace-viewer/components/split-pane.tsx +80 -135
  251. package/src/components/new-trace-viewer/components/timeline.module.css +46 -0
  252. package/src/components/new-trace-viewer/components/timeline.tsx +603 -239
  253. package/src/components/new-trace-viewer/components/trace-shortcut-helper.module.css +20 -0
  254. package/src/components/new-trace-viewer/components/trace-shortcut-helper.tsx +116 -0
  255. package/src/components/new-trace-viewer/components/trace-viewer-skeleton.tsx +114 -0
  256. package/src/components/new-trace-viewer/components/use-element-width.ts +29 -0
  257. package/src/components/new-trace-viewer/components/use-row-window.ts +140 -0
  258. package/src/components/new-trace-viewer/context.tsx +13 -14
  259. package/src/components/new-trace-viewer/icons.tsx +2 -2
  260. package/src/components/new-trace-viewer/search.ts +178 -0
  261. package/src/components/new-trace-viewer/trace-viewer.tsx +336 -293
  262. package/src/components/new-trace-viewer/types.ts +2 -0
  263. package/src/components/new-trace-viewer/utils.test.ts +247 -0
  264. package/src/components/new-trace-viewer/utils.ts +203 -134
  265. package/src/components/run-trace-view.tsx +10 -14
  266. package/src/components/sidebar/attribute-panel.tsx +276 -275
  267. package/src/components/sidebar/attributes-block.tsx +326 -0
  268. package/src/components/sidebar/copyable-data-block.tsx +50 -28
  269. package/src/components/sidebar/entity-detail-panel.tsx +89 -123
  270. package/src/components/sidebar/events-list.tsx +196 -178
  271. package/src/components/sidebar/sidebar-data-context.tsx +11 -11
  272. package/src/components/sidebar/span-detail-merge.ts +134 -0
  273. package/src/components/sidebar/use-selected-span-detail.ts +146 -0
  274. package/src/components/trace-viewer/components/node.tsx +3 -2
  275. package/src/components/trace-viewer/trace-viewer.module.css +4 -4
  276. package/src/components/trace-viewer/util/timing.ts +7 -11
  277. package/src/components/trace-viewer-new.tsx +21 -15
  278. package/src/components/ui/alert.tsx +1 -1
  279. package/src/components/ui/button.tsx +68 -0
  280. package/src/components/ui/card.tsx +1 -1
  281. package/src/components/ui/collapsible.tsx +219 -0
  282. package/src/components/ui/context-card.tsx +784 -0
  283. package/src/components/ui/data-inspector.styles.ts +96 -0
  284. package/src/components/ui/data-inspector.tsx +501 -204
  285. package/src/components/ui/error-card.tsx +1 -1
  286. package/src/components/ui/error-stack-block.tsx +84 -55
  287. package/src/components/ui/icon-button.tsx +53 -0
  288. package/src/components/ui/kbd.tsx +43 -0
  289. package/src/components/ui/skeleton.tsx +1 -1
  290. package/src/components/ui/timestamp-tooltip.tsx +132 -194
  291. package/src/components/ui/tooltip.tsx +47 -0
  292. package/src/components/workflow-trace-view.tsx +31 -36
  293. package/src/components/workflow-traces/event-colors.ts +15 -11
  294. package/src/components/workflow-traces/trace-colors.ts +6 -6
  295. package/src/components/workflow-traces/trace-span-construction.test.ts +85 -0
  296. package/src/components/workflow-traces/trace-span-construction.ts +118 -35
  297. package/src/hooks/use-intersection-observer.ts +57 -0
  298. package/src/hooks/use-load-more-on-scroll.ts +49 -0
  299. package/src/hooks/use-reduced-motion.ts +34 -0
  300. package/src/index.ts +9 -0
  301. package/src/lib/cn.ts +93 -0
  302. package/src/lib/event-analysis.ts +6 -4
  303. package/src/lib/event-materialization.ts +35 -21
  304. package/src/lib/exact-event-search-id.ts +67 -0
  305. package/src/lib/hydration.ts +203 -29
  306. package/src/lib/trace-builder.ts +44 -19
  307. package/src/lib/utils.test.ts +33 -0
  308. package/src/lib/utils.ts +82 -35
  309. package/src/lib/zstd-browser-decoder.ts +42 -0
  310. package/src/styles.css +14 -0
  311. package/dist/components/error-boundary.js.map +0 -1
  312. package/dist/components/event-list-view.js.map +0 -1
  313. package/dist/components/hook-actions.js.map +0 -1
  314. package/dist/components/index.js.map +0 -1
  315. package/dist/components/new-trace-viewer/components/copy-button.js.map +0 -1
  316. package/dist/components/new-trace-viewer/components/event-list.js.map +0 -1
  317. package/dist/components/new-trace-viewer/components/split-pane.js.map +0 -1
  318. package/dist/components/new-trace-viewer/components/timeline.js.map +0 -1
  319. package/dist/components/new-trace-viewer/context.js.map +0 -1
  320. package/dist/components/new-trace-viewer/detail-panel.d.ts +0 -10
  321. package/dist/components/new-trace-viewer/detail-panel.d.ts.map +0 -1
  322. package/dist/components/new-trace-viewer/detail-panel.js +0 -11
  323. package/dist/components/new-trace-viewer/detail-panel.js.map +0 -1
  324. package/dist/components/new-trace-viewer/icons.js.map +0 -1
  325. package/dist/components/new-trace-viewer/trace-viewer.js.map +0 -1
  326. package/dist/components/new-trace-viewer/types.js.map +0 -1
  327. package/dist/components/new-trace-viewer/util/constants.d.ts +0 -1
  328. package/dist/components/new-trace-viewer/util/constants.d.ts.map +0 -1
  329. package/dist/components/new-trace-viewer/util/constants.js +0 -2
  330. package/dist/components/new-trace-viewer/util/constants.js.map +0 -1
  331. package/dist/components/new-trace-viewer/utils.js.map +0 -1
  332. package/dist/components/run-trace-view.js.map +0 -1
  333. package/dist/components/sidebar/attribute-panel.js.map +0 -1
  334. package/dist/components/sidebar/conversation-view.js.map +0 -1
  335. package/dist/components/sidebar/copyable-data-block.js.map +0 -1
  336. package/dist/components/sidebar/detail-card.d.ts +0 -14
  337. package/dist/components/sidebar/detail-card.d.ts.map +0 -1
  338. package/dist/components/sidebar/detail-card.js +0 -20
  339. package/dist/components/sidebar/detail-card.js.map +0 -1
  340. package/dist/components/sidebar/entity-detail-panel.js.map +0 -1
  341. package/dist/components/sidebar/events-list.js.map +0 -1
  342. package/dist/components/sidebar/resolve-hook-modal.js.map +0 -1
  343. package/dist/components/sidebar/sidebar-data-context.js.map +0 -1
  344. package/dist/components/stream-viewer.js.map +0 -1
  345. package/dist/components/trace-viewer/components/map.js.map +0 -1
  346. package/dist/components/trace-viewer/components/markers.js.map +0 -1
  347. package/dist/components/trace-viewer/components/node.js.map +0 -1
  348. package/dist/components/trace-viewer/components/search-input.js.map +0 -1
  349. package/dist/components/trace-viewer/components/search.js.map +0 -1
  350. package/dist/components/trace-viewer/components/span-content.js.map +0 -1
  351. package/dist/components/trace-viewer/components/span-detail-panel.js.map +0 -1
  352. package/dist/components/trace-viewer/components/span-segments.js.map +0 -1
  353. package/dist/components/trace-viewer/components/span-strategies.js.map +0 -1
  354. package/dist/components/trace-viewer/components/ui.js.map +0 -1
  355. package/dist/components/trace-viewer/components/zoom-button.js.map +0 -1
  356. package/dist/components/trace-viewer/components/zoom-icons.js.map +0 -1
  357. package/dist/components/trace-viewer/context.js.map +0 -1
  358. package/dist/components/trace-viewer/index.js.map +0 -1
  359. package/dist/components/trace-viewer/trace-viewer.js.map +0 -1
  360. package/dist/components/trace-viewer/types.js.map +0 -1
  361. package/dist/components/trace-viewer/util/constants.js.map +0 -1
  362. package/dist/components/trace-viewer/util/scrollbar-width.js.map +0 -1
  363. package/dist/components/trace-viewer/util/timing.js.map +0 -1
  364. package/dist/components/trace-viewer/util/tree.js.map +0 -1
  365. package/dist/components/trace-viewer/util/use-immediate-style.js.map +0 -1
  366. package/dist/components/trace-viewer/util/use-streaming-spans.js.map +0 -1
  367. package/dist/components/trace-viewer/util/use-trackpad-zoom.js.map +0 -1
  368. package/dist/components/trace-viewer/worker.js.map +0 -1
  369. package/dist/components/trace-viewer-new.js.map +0 -1
  370. package/dist/components/ui/alert.js.map +0 -1
  371. package/dist/components/ui/card.js.map +0 -1
  372. package/dist/components/ui/data-inspector.js.map +0 -1
  373. package/dist/components/ui/decrypt-button.js.map +0 -1
  374. package/dist/components/ui/error-card.js.map +0 -1
  375. package/dist/components/ui/error-stack-block.js.map +0 -1
  376. package/dist/components/ui/inspector-theme.d.ts +0 -95
  377. package/dist/components/ui/inspector-theme.d.ts.map +0 -1
  378. package/dist/components/ui/inspector-theme.js +0 -82
  379. package/dist/components/ui/inspector-theme.js.map +0 -1
  380. package/dist/components/ui/load-more-button.js.map +0 -1
  381. package/dist/components/ui/menu-dropdown.js.map +0 -1
  382. package/dist/components/ui/skeleton.js.map +0 -1
  383. package/dist/components/ui/spinner.js.map +0 -1
  384. package/dist/components/ui/timestamp-tooltip.js.map +0 -1
  385. package/dist/components/workflow-trace-view.js.map +0 -1
  386. package/dist/components/workflow-traces/event-colors.js.map +0 -1
  387. package/dist/components/workflow-traces/trace-colors.js.map +0 -1
  388. package/dist/components/workflow-traces/trace-span-construction.js.map +0 -1
  389. package/dist/components/workflow-traces/trace-time-utils.js.map +0 -1
  390. package/dist/hooks/use-dark-mode.js.map +0 -1
  391. package/dist/index.js.map +0 -1
  392. package/dist/lib/event-analysis.js.map +0 -1
  393. package/dist/lib/event-materialization.js.map +0 -1
  394. package/dist/lib/hydration.js.map +0 -1
  395. package/dist/lib/stream-display.js.map +0 -1
  396. package/dist/lib/toast.js.map +0 -1
  397. package/dist/lib/trace-builder.js.map +0 -1
  398. package/dist/lib/utils.js.map +0 -1
  399. package/src/components/new-trace-viewer/detail-panel.tsx +0 -57
  400. package/src/components/new-trace-viewer/util/constants.ts +0 -0
  401. package/src/components/sidebar/detail-card.tsx +0 -65
  402. package/src/components/ui/inspector-theme.ts +0 -110
@@ -1 +1 @@
1
- {"version":3,"file":"attribute-panel.d.ts","sourceRoot":"","sources":["../../../src/components/sidebar/attribute-panel.tsx"],"names":[],"mappings":"AAwYA,eAAO,MAAM,oBAAoB,GAAI,OAAO,OAAO,KAAG,MAQrD,CAAC;AAoBF,UAAU,cAAc;IACtB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAmOD,eAAO,MAAM,cAAc,GAAI,mDAM5B;IACD,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,OAAO,CAAC;IACf,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,OAAO,CAAC,EAAE,cAAc,CAAC;CAC1B,mDAiEA,CAAC;AAEF,eAAO,MAAM,cAAc,GAAI,uHAW5B;IACD,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC9B,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,KAAK,CAAC,EAAE,KAAK,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,kDAAkD;IAClD,aAAa,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;IAC3C,+CAA+C;IAC/C,UAAU,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACrC,yEAAyE;IACzE,SAAS,CAAC,EAAE,MAAM,IAAI,CAAC;IACvB,kDAAkD;IAClD,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,oFAAoF;IACpF,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB,4CA2NA,CAAC"}
1
+ {"version":3,"file":"attribute-panel.d.ts","sourceRoot":"","sources":["../../../src/components/sidebar/attribute-panel.tsx"],"names":[],"mappings":"AA2WA,eAAO,MAAM,oBAAoB,GAAI,OAAO,OAAO,KAAG,MAOrD,CAAC;AAoBF,UAAU,cAAc;IACtB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,mBAAmB,CAAC,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;CAC/C;AAuSD,eAAO,MAAM,cAAc,GAAI,mDAM5B;IACD,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,OAAO,CAAC;IACf,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,OAAO,CAAC,EAAE,cAAc,CAAC;CAC1B,mDA4EA,CAAC;AAEF,eAAO,MAAM,cAAc,GAAI,wIAY5B;IACD,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC9B,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,KAAK,CAAC,EAAE,KAAK,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,kDAAkD;IAClD,aAAa,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;IAC3C,+CAA+C;IAC/C,UAAU,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACrC,yEAAyE;IACzE,SAAS,CAAC,EAAE,MAAM,IAAI,CAAC;IACvB,kDAAkD;IAClD,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,oFAAoF;IACpF,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB,4CAuKA,CAAC"}
@@ -1,20 +1,20 @@
1
1
  'use client';
2
2
  import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
3
3
  import { parseStepName, parseWorkflowName } from '@workflow/utils/parse-name';
4
- import { Lock } from 'lucide-react';
5
- import { useCallback, useContext, useMemo, useState } from 'react';
4
+ import { format } from 'date-fns';
5
+ import { useCallback, useContext, useMemo, useRef, useState } from 'react';
6
6
  import { isEncryptedMarker, isExpiredMarker } from '../../lib/hydration';
7
- import { useToast } from '../../lib/toast';
8
7
  import { extractConversation, isDoStreamStep } from '../../lib/utils';
8
+ import { Collapsible, CollapsibleContent, CollapsibleRoot, CollapsibleTrigger, } from '../ui/collapsible';
9
+ import { ContextCardProvider } from '../ui/context-card';
9
10
  import { DecryptClickContext, RunClickContext, StreamClickContext, } from '../ui/data-inspector';
10
11
  import { ErrorCard } from '../ui/error-card';
11
- import { ErrorStackBlock, isStructuredErrorWithStack, } from '../ui/error-stack-block';
12
+ import { ErrorStackBlock, isStructuredError } from '../ui/error-stack-block';
12
13
  import { Skeleton } from '../ui/skeleton';
13
- import { Spinner } from '../ui/spinner';
14
14
  import { TimestampTooltip } from '../ui/timestamp-tooltip';
15
+ import { DetailMonoKeyValueRow, RunAttributesCard, RunMetadataCard, } from './attributes-block';
15
16
  import { ConversationView } from './conversation-view';
16
- import { CopyableDataBlock } from './copyable-data-block';
17
- import { DetailCard } from './detail-card';
17
+ import { CopyableDataBlock, EncryptedDataBlock } from './copyable-data-block';
18
18
  /**
19
19
  * Tab button for conversation/JSON toggle
20
20
  */
@@ -64,9 +64,9 @@ const conversationTabs = [
64
64
  /**
65
65
  * Tabbed view for conversation and raw JSON
66
66
  */
67
- function ConversationWithTabs({ conversation, args, }) {
67
+ function ConversationWithTabs({ conversation, args, defaultOpen, onOpenChange, }) {
68
68
  const [activeTab, setActiveTab] = useState('conversation');
69
- return (_jsx(DetailCard, { summary: `Input (${conversation.length} messages)`, children: _jsx(TabbedContainer, { tabs: conversationTabs, activeTab: activeTab, onTabChange: setActiveTab, ariaLabel: "Conversation view", children: activeTab === 'conversation' ? (_jsx(ConversationView, { messages: conversation })) : (_jsx("div", { className: "p-3", children: Array.isArray(args)
69
+ return (_jsx(Collapsible, { label: "Input", defaultOpen: defaultOpen, onOpenChange: onOpenChange, children: _jsx(TabbedContainer, { tabs: conversationTabs, activeTab: activeTab, onTabChange: setActiveTab, ariaLabel: "Conversation view", children: activeTab === 'conversation' ? (_jsx(ConversationView, { messages: conversation })) : (_jsx("div", { className: "p-3", children: Array.isArray(args)
70
70
  ? args.map((v, i) => (_jsx("div", { className: "mt-2 first:mt-0", children: JsonBlock(v) }, i)))
71
71
  : JsonBlock(args) })) }) }));
72
72
  }
@@ -74,25 +74,8 @@ function ConversationWithTabs({ conversation, args, }) {
74
74
  * Render a value with the shared DataInspector (ObjectInspector with
75
75
  * custom theming, nodeRenderer for StreamRef/ClassInstanceRef, etc.)
76
76
  */
77
- /**
78
- * Inline display for an encrypted field — no expand, just a flat label
79
- * with the lucide Lock icon matching the title bar Decrypt button.
80
- */
81
77
  function EncryptedFieldBlock() {
82
- const ctx = useContext(DecryptClickContext);
83
- if (ctx) {
84
- return (_jsxs("button", { type: "button", onClick: ctx.onDecrypt, disabled: ctx.isDecrypting, className: "flex w-full items-center justify-center gap-1.5 rounded-md border px-3 py-2 text-xs cursor-pointer transition-colors", style: {
85
- borderColor: 'var(--ds-gray-400)',
86
- backgroundColor: 'var(--ds-gray-100)',
87
- color: 'var(--ds-gray-700)',
88
- opacity: ctx.isDecrypting ? 0.6 : 1,
89
- }, title: "Click to decrypt", children: [ctx.isDecrypting ? (_jsx(Spinner, { size: 12 })) : (_jsx(Lock, { className: "h-3 w-3" })), _jsx("span", { className: "font-medium", children: ctx.isDecrypting ? 'Decrypting…' : 'Decrypt' })] }));
90
- }
91
- return (_jsxs("div", { className: "flex w-full items-center justify-center gap-1.5 rounded-md border px-3 py-2 text-xs", style: {
92
- borderColor: 'var(--ds-gray-300)',
93
- backgroundColor: 'var(--ds-gray-100)',
94
- color: 'var(--ds-gray-700)',
95
- }, children: [_jsx(Lock, { className: "h-3 w-3" }), _jsx("span", { className: "font-medium", children: "Encrypted" })] }));
78
+ return _jsx(EncryptedDataBlock, {});
96
79
  }
97
80
  /**
98
81
  * Inline display for an expired field — flat label indicating data is no longer available.
@@ -141,6 +124,7 @@ const attributeOrder = [
141
124
  'projectId',
142
125
  'environment',
143
126
  'executionContext',
127
+ 'occurredAt',
144
128
  'createdAt',
145
129
  'startedAt',
146
130
  'updatedAt',
@@ -152,6 +136,7 @@ const attributeOrder = [
152
136
  'eventData',
153
137
  'input',
154
138
  'output',
139
+ 'attributes',
155
140
  'resumeAt',
156
141
  ];
157
142
  const sortByAttributeOrder = (a, b) => {
@@ -171,11 +156,14 @@ const attributeDisplayNames = {
171
156
  attempt: 'Attempts',
172
157
  eventId: 'Event ID',
173
158
  runId: 'Run ID',
159
+ token: 'Token',
174
160
  eventType: 'Event Type',
161
+ errorCode: 'Error Code',
175
162
  correlationId: 'Correlation ID',
176
163
  deploymentId: 'Deployment ID',
177
164
  specVersion: 'Spec Version',
178
165
  workflowCoreVersion: '@workflow/core version',
166
+ occurredAt: 'Occurred',
179
167
  createdAt: 'Created',
180
168
  startedAt: 'Started',
181
169
  updatedAt: 'Updated',
@@ -218,21 +206,12 @@ const parseDateValue = (value) => {
218
206
  const date = typeof value === 'number' ? new Date(value) : new Date(String(value));
219
207
  return Number.isNaN(date.getTime()) ? null : date;
220
208
  };
221
- const formatLocalMillisecondTime = (date) => date.toLocaleString(undefined, {
222
- year: 'numeric',
223
- month: 'numeric',
224
- day: 'numeric',
225
- hour: 'numeric',
226
- minute: 'numeric',
227
- second: 'numeric',
228
- fractionalSecondDigits: 3,
229
- });
209
+ const formatLocalMillisecondTime = (date) => format(date, 'MMM dd HH:mm:ss.SS OO').toUpperCase();
230
210
  export const localMillisecondTime = (value) => {
231
211
  const date = parseDateValue(value);
232
212
  if (!date) {
233
213
  return '-';
234
214
  }
235
- // e.g. 12/17/2025, 9:08:55.182 AM
236
215
  return formatLocalMillisecondTime(date);
237
216
  };
238
217
  const localMillisecondTimeOrNull = (value) => {
@@ -255,7 +234,7 @@ const attributeToDisplayFn = {
255
234
  stepName: (_value) => null,
256
235
  // IDs
257
236
  runId: (_value) => null,
258
- stepId: (_value) => null,
237
+ stepId: (value) => String(value),
259
238
  hookId: (value) => String(value),
260
239
  eventId: (value) => String(value),
261
240
  // Run/step details
@@ -264,6 +243,7 @@ const attributeToDisplayFn = {
264
243
  // Hook details
265
244
  token: (value) => String(value),
266
245
  isWebhook: (value) => String(value),
246
+ isSystem: (value) => String(value),
267
247
  receivedCount: (value) => String(value),
268
248
  lastReceivedAt: localMillisecondTimeOrNull,
269
249
  disposedAt: localMillisecondTimeOrNull,
@@ -279,7 +259,16 @@ const attributeToDisplayFn = {
279
259
  projectId: (_value) => null,
280
260
  environment: (_value) => null,
281
261
  executionContext: (_value) => null,
262
+ // Attributes — string-string metadata attached to the run.
263
+ // Rendered as key-value rows in its own collapsible section;
264
+ // if empty/missing, hidden by the hasDisplayContent gate.
265
+ attributes: (value) => {
266
+ if (!hasDisplayContent(value))
267
+ return null;
268
+ return _jsx(RunAttributesCard, { attributes: value });
269
+ },
282
270
  // Dates — wrapped with TimestampTooltip showing UTC/local + relative time
271
+ occurredAt: timestampWithTooltipOrNull,
283
272
  createdAt: timestampWithTooltipOrNull,
284
273
  startedAt: timestampWithTooltipOrNull,
285
274
  updatedAt: (_value) => null,
@@ -291,22 +280,23 @@ const attributeToDisplayFn = {
291
280
  metadata: (value) => {
292
281
  if (!hasDisplayContent(value))
293
282
  return null;
294
- if (isEncryptedMarker(value))
295
- return _jsx(EncryptedFieldBlock, {});
296
- if (isExpiredMarker(value))
297
- return _jsx(ExpiredFieldBlock, {});
298
- return JsonBlock(value);
283
+ if (isEncryptedMarker(value)) {
284
+ return (_jsx(Collapsible, { label: "Metadata", children: _jsx(EncryptedDataBlock, {}) }));
285
+ }
286
+ if (isExpiredMarker(value)) {
287
+ return (_jsx(Collapsible, { label: "Metadata", children: _jsx(ExpiredFieldBlock, {}) }));
288
+ }
289
+ return _jsx(RunMetadataCard, { metadata: value });
299
290
  },
300
291
  input: (value, context) => {
301
- if (isEncryptedMarker(value))
302
- return _jsx(EncryptedFieldBlock, {});
292
+ if (isEncryptedMarker(value)) {
293
+ return (_jsx(Collapsible, { label: "Input", defaultOpen: context?.sectionOpen, onOpenChange: context?.onSectionOpenChange, children: _jsx(EncryptedFieldBlock, {}) }));
294
+ }
303
295
  if (isExpiredMarker(value))
304
296
  return _jsx(ExpiredFieldBlock, {});
305
297
  // Check if input has args + closure vars structure
306
298
  if (value && typeof value === 'object' && 'args' in value) {
307
299
  const { args, closureVars, thisVal } = value;
308
- const argCount = Array.isArray(args) ? args.length : 0;
309
- const argLabel = argCount === 1 ? 'argument' : 'arguments';
310
300
  const hasClosureVars = hasDisplayContent(closureVars);
311
301
  const hasThisVal = hasDisplayContent(thisVal);
312
302
  const hasArgs = hasDisplayContent(args);
@@ -314,58 +304,64 @@ const attributeToDisplayFn = {
314
304
  if (context?.stepName && isDoStreamStep(context.stepName)) {
315
305
  const conversation = extractConversation(args);
316
306
  if (conversation && conversation.length > 0) {
317
- return (_jsxs(_Fragment, { children: [_jsx(ConversationWithTabs, { conversation: conversation, args: args }), hasClosureVars && (_jsx(DetailCard, { summary: "Closure Variables", children: JsonBlock(closureVars) })), hasThisVal && (_jsx(DetailCard, { summary: "This Value", children: JsonBlock(thisVal) }))] }));
307
+ return (_jsxs(_Fragment, { children: [_jsx(ConversationWithTabs, { conversation: conversation, args: args, defaultOpen: context?.sectionOpen, onOpenChange: context?.onSectionOpenChange }), hasClosureVars && (_jsx(Collapsible, { label: "Closure Variables", children: JsonBlock(closureVars) })), hasThisVal && (_jsx(Collapsible, { label: "This Value", children: JsonBlock(thisVal) }))] }));
318
308
  }
319
309
  }
320
310
  // Don't render an empty "Input (0 arguments)" card when no input exists.
321
311
  if (!hasArgs && !hasClosureVars && !hasThisVal) {
322
- return (_jsx(DetailCard, { summary: "Input (no data)", disabled: true, summaryClassName: "text-label-14 font-medium py-2" }));
312
+ return _jsx(Collapsible, { label: "Input (no data)", disabled: true });
323
313
  }
324
- return (_jsxs(_Fragment, { children: [_jsx(DetailCard, { summary: `Input (${argCount} ${argLabel})`, summaryClassName: "text-label-14 font-medium py-2", contentClassName: "mt-0", children: Array.isArray(args)
314
+ return (_jsxs(_Fragment, { children: [_jsx(Collapsible, { label: "Input", defaultOpen: context?.sectionOpen, onOpenChange: context?.onSectionOpenChange, children: Array.isArray(args)
325
315
  ? args.map((v, i) => (_jsx("div", { className: "mt-2 first:mt-0", children: JsonBlock(v) }, i)))
326
- : JsonBlock(args) }), hasClosureVars && (_jsx(DetailCard, { summary: "Closure Variables", children: JsonBlock(closureVars) })), hasThisVal && (_jsx(DetailCard, { summary: "this", children: JsonBlock(thisVal) }))] }));
316
+ : JsonBlock(args) }), hasClosureVars && (_jsx(Collapsible, { label: "Closure Variables", children: JsonBlock(closureVars) })), hasThisVal && (_jsx(Collapsible, { label: "Context", children: JsonBlock(thisVal) }))] }));
327
317
  }
328
318
  // Fallback: treat as plain array or object
329
- const argCount = Array.isArray(value) ? value.length : 0;
330
- const argLabel = argCount === 1 ? 'argument' : 'arguments';
331
319
  if (!hasDisplayContent(value)) {
332
- return (_jsx(DetailCard, { summary: "Input (no data)", disabled: true, summaryClassName: "text-label-14 font-medium py-2" }));
320
+ return _jsx(Collapsible, { label: "Input (no data)", disabled: true });
333
321
  }
334
- return (_jsx(DetailCard, { summary: `Input (${argCount} ${argLabel})`, summaryClassName: "text-label-14 font-medium py-2", contentClassName: "mt-0", children: Array.isArray(value)
322
+ return (_jsx(Collapsible, { label: "Input", defaultOpen: context?.sectionOpen, onOpenChange: context?.onSectionOpenChange, children: Array.isArray(value)
335
323
  ? value.map((v, i) => (_jsx("div", { className: "mt-2 first:mt-0", children: JsonBlock(v) }, i)))
336
324
  : JsonBlock(value) }));
337
325
  },
338
- output: (value) => {
326
+ output: (value, context) => {
327
+ if (isEncryptedMarker(value)) {
328
+ return (_jsx(Collapsible, { label: "Output", defaultOpen: context?.sectionOpen, onOpenChange: context?.onSectionOpenChange, children: _jsx(EncryptedFieldBlock, {}) }));
329
+ }
339
330
  if (!hasDisplayContent(value))
340
331
  return null;
341
- if (isEncryptedMarker(value))
342
- return _jsx(EncryptedFieldBlock, {});
343
332
  if (isExpiredMarker(value))
344
333
  return _jsx(ExpiredFieldBlock, {});
345
- return (_jsx(DetailCard, { summary: "Output", summaryClassName: "text-label-14 font-medium py-2", contentClassName: "mt-0", children: JsonBlock(value) }));
334
+ return (_jsx(Collapsible, { label: "Output", defaultOpen: context?.sectionOpen, onOpenChange: context?.onSectionOpenChange, children: JsonBlock(value) }));
346
335
  },
347
336
  error: (value) => {
348
- if (isEncryptedMarker(value))
349
- return _jsx(EncryptedFieldBlock, {});
337
+ if (isEncryptedMarker(value)) {
338
+ return (_jsx(Collapsible, { label: "Error", defaultOpen: true, children: _jsx(EncryptedFieldBlock, {}) }));
339
+ }
350
340
  if (isExpiredMarker(value))
351
341
  return _jsx(ExpiredFieldBlock, {});
352
342
  if (!hasDisplayContent(value))
353
343
  return null;
354
- // If the error object has a `stack` field, render it as readable
355
- // pre-formatted text. Otherwise fall back to the raw JSON viewer.
356
- if (isStructuredErrorWithStack(value)) {
357
- return (_jsx(DetailCard, { summary: "Error", summaryClassName: "text-label-14 font-medium py-2", contentClassName: "mt-0", children: _jsx(ErrorStackBlock, { value: value }) }));
344
+ // Structured workflow errors may be persisted as either `{ message }` or
345
+ // `{ message, stack }`. Render both with the dedicated error block.
346
+ if (isStructuredError(value)) {
347
+ return (_jsx(Collapsible, { label: "Error", defaultOpen: true, children: _jsx(ErrorStackBlock, { value: value }) }));
358
348
  }
359
- return (_jsx(DetailCard, { summary: "Error", summaryClassName: "text-label-14 font-medium py-2", contentClassName: "mt-0", children: JsonBlock(value) }));
349
+ return (_jsx(Collapsible, { label: "Error", defaultOpen: true, children: JsonBlock(value) }));
360
350
  },
361
351
  eventData: (value) => {
362
- if (isEncryptedMarker(value))
363
- return _jsx(EncryptedFieldBlock, {});
352
+ if (isEncryptedMarker(value)) {
353
+ return (_jsx(Collapsible, { label: "Event Data", defaultOpen: true, children: _jsx(EncryptedFieldBlock, {}) }));
354
+ }
364
355
  if (isExpiredMarker(value))
365
356
  return _jsx(ExpiredFieldBlock, {});
366
357
  if (!hasDisplayContent(value))
367
358
  return null;
368
- return _jsx(DetailCard, { summary: "Event Data", children: JsonBlock(value) });
359
+ return (_jsx(Collapsible, { label: "Event Data", defaultOpen: true, children: JsonBlock(value) }));
360
+ },
361
+ errorCode: (value) => {
362
+ if (typeof value !== 'string' || value.length === 0)
363
+ return null;
364
+ return String(value);
369
365
  },
370
366
  };
371
367
  const resolvableAttributes = [
@@ -373,33 +369,70 @@ const resolvableAttributes = [
373
369
  'output',
374
370
  'error',
375
371
  'metadata',
372
+ 'attributes',
376
373
  'eventData',
377
374
  ];
375
+ // Attributes whose displayFn renders its own section header via Collapsible,
376
+ // so the outer AttributeBlock should not duplicate the label.
377
+ const selfHeaderedAttributes = new Set([
378
+ 'input',
379
+ 'output',
380
+ 'error',
381
+ 'metadata',
382
+ 'attributes',
383
+ 'eventData',
384
+ ]);
378
385
  const ExpiredDataMessage = () => (_jsx("div", { className: "text-copy-12 rounded-md border p-4 my-2", style: {
379
386
  borderColor: 'var(--ds-gray-300)',
380
387
  backgroundColor: 'var(--ds-gray-100)',
381
388
  color: 'var(--ds-gray-700)',
382
389
  }, children: _jsx("span", { children: "The data for this run has expired and is no longer available." }) }));
390
+ const copyableBasicAttributes = new Set([
391
+ 'stepId',
392
+ 'hookId',
393
+ 'eventId',
394
+ 'deploymentId',
395
+ 'moduleSpecifier',
396
+ ]);
397
+ const loadingSectionLabels = {
398
+ input: 'Input',
399
+ output: 'Output',
400
+ eventData: 'Event Data',
401
+ };
383
402
  export const AttributeBlock = ({ attribute, value, isLoading, inline = false, context, }) => {
384
- const isExpandableLoadingTarget = attribute === 'input' || attribute === 'eventData';
385
- if (isLoading && isExpandableLoadingTarget && !hasDisplayContent(value)) {
386
- return (_jsxs("div", { className: `my-2 flex flex-col ${attribute === 'input' ? 'gap-2 my-3.5' : 'gap-0'}`, children: [_jsx("span", { className: "text-label-14 text-gray-1000 font-medium first-letter:uppercase", children: attribute }), _jsx(Skeleton, { className: "h-9 w-full rounded-md" })] }));
403
+ const decryptCtx = useContext(DecryptClickContext);
404
+ const sectionOpenRef = useRef(false);
405
+ const handleSectionOpenChange = useCallback((open) => {
406
+ sectionOpenRef.current = open;
407
+ }, []);
408
+ const label = loadingSectionLabels[attribute];
409
+ if (isLoading && label && !hasDisplayContent(value)) {
410
+ if (decryptCtx?.hasEncryptedData) {
411
+ return (_jsx(Collapsible, { label: label, defaultOpen: attribute === 'eventData' || sectionOpenRef.current, onOpenChange: handleSectionOpenChange, children: _jsx(EncryptedFieldBlock, {}) }));
412
+ }
413
+ return _jsx(Collapsible, { label: label });
387
414
  }
388
415
  const displayFn = attributeToDisplayFn[attribute];
389
416
  if (!displayFn) {
390
417
  return null;
391
418
  }
392
- const displayValue = displayFn(value, context);
419
+ const displayValue = displayFn(value, {
420
+ ...context,
421
+ sectionOpen: sectionOpenRef.current,
422
+ onSectionOpenChange: handleSectionOpenChange,
423
+ });
393
424
  if (!displayValue) {
394
425
  return null;
395
426
  }
396
427
  if (inline) {
397
428
  return (_jsxs("div", { className: "flex items-center gap-1.5", children: [_jsx("span", { className: "text-[11px] font-medium", style: { color: 'var(--ds-gray-700)' }, children: attribute }), _jsx("span", { className: "text-[11px]", style: { color: 'var(--ds-gray-1000)' }, children: displayValue })] }));
398
429
  }
399
- return (_jsxs("div", { className: "relative", children: [typeof isLoading === 'boolean' && isLoading && (_jsx("div", { className: "absolute top-9 right-4", children: _jsx("div", { className: "animate-spin rounded-full h-4 w-4 border-b-2", style: { borderColor: 'var(--ds-gray-900)' } }) })), _jsxs("div", { className: `my-2 flex flex-col ${attribute === 'input' || attribute === 'output' || attribute === 'error' ? 'gap-2 my-3.5' : 'gap-0'}`, children: [_jsx("span", { className: "text-label-14 text-gray-1000 font-medium first-letter:uppercase", children: attribute }), _jsx("span", { className: "text-xs", style: { color: 'var(--ds-gray-1000)' }, children: displayValue })] }, attribute)] }));
430
+ if (selfHeaderedAttributes.has(attribute)) {
431
+ return _jsx(_Fragment, { children: displayValue });
432
+ }
433
+ return (_jsxs("div", { className: "relative", children: [typeof isLoading === 'boolean' && isLoading && (_jsx("div", { className: "absolute top-9 right-4", children: _jsx("div", { className: "animate-spin rounded-full h-4 w-4 border-b-2", style: { borderColor: 'var(--ds-gray-900)' } }) })), _jsxs("div", { className: "my-2 flex flex-col gap-0", children: [_jsx("span", { className: "text-label-14 text-gray-1000 font-medium first-letter:uppercase", children: attribute }), _jsx("span", { className: "text-xs", style: { color: 'var(--ds-gray-1000)' }, children: displayValue })] }, attribute)] }));
400
434
  };
401
- export const AttributePanel = ({ data, moduleSpecifier, isLoading, error, expiredAt, onStreamClick, onRunClick, onDecrypt, isDecrypting = false, resource, }) => {
402
- const toast = useToast();
435
+ export const AttributePanel = ({ data, moduleSpecifier, moduleSourceUrl, isLoading, error, expiredAt, onStreamClick, onRunClick, onDecrypt, isDecrypting = false, resource, }) => {
403
436
  // Extract workflowCoreVersion from executionContext for display
404
437
  const displayData = useMemo(() => {
405
438
  const result = { ...data };
@@ -428,16 +461,16 @@ export const AttributePanel = ({ data, moduleSpecifier, isLoading, error, expire
428
461
  .sort(sortByAttributeOrder);
429
462
  if (!isLoading)
430
463
  return present;
431
- // During loading, ensure input appears so its skeleton renders
432
- // in the correct position (above the events section).
433
- const loadingDefaults = ['input'];
434
- for (const key of loadingDefaults) {
464
+ if (resource === 'sleep')
465
+ return present;
466
+ const loadingPlaceholders = ['input', 'output'];
467
+ for (const key of loadingPlaceholders) {
435
468
  if (!present.includes(key)) {
436
469
  present.push(key);
437
470
  }
438
471
  }
439
472
  return present.sort(sortByAttributeOrder);
440
- }, [displayData, isLoading]);
473
+ }, [displayData, isLoading, resource]);
441
474
  // Filter out attributes that return null
442
475
  const visibleBasicAttributes = basicAttributes.filter((attribute) => {
443
476
  const displayFn = attributeToDisplayFn[attribute];
@@ -471,36 +504,23 @@ export const AttributePanel = ({ data, moduleSpecifier, isLoading, error, expire
471
504
  const displayContext = useMemo(() => ({
472
505
  stepName: displayData.stepName,
473
506
  }), [displayData.stepName]);
474
- const handleCopyModuleSpecifier = useCallback((value) => {
475
- navigator.clipboard
476
- .writeText(value)
477
- .then(() => {
478
- toast.success('moduleSpecifier copied');
479
- })
480
- .catch(() => {
481
- toast.error('Failed to copy moduleSpecifier');
482
- });
483
- }, []);
484
- return (_jsx(RunClickContext.Provider, { value: onRunClick, children: _jsx(StreamClickContext.Provider, { value: onStreamClick, children: _jsx(DecryptClickContext.Provider, { value: onDecrypt ? { onDecrypt, isDecrypting } : undefined, children: _jsxs("div", { children: [visibleBasicAttributes.length > 0 && (_jsxs("div", { className: "mb-3 flex flex-col overflow-hidden rounded-md border", style: {
485
- borderColor: 'var(--ds-gray-300)',
486
- }, children: [orderedBasicAttributes.map((attribute, index) => {
487
- const displayValue = attributeToDisplayFn[attribute]?.(displayData[attribute]);
488
- const isModuleSpecifier = attribute === 'moduleSpecifier';
489
- const moduleSpecifierValue = typeof displayValue === 'string'
490
- ? displayValue
491
- : String(displayValue ?? displayData.moduleSpecifier ?? '');
492
- const shouldCapitalizeLabel = attribute !== 'workflowCoreVersion';
493
- const showResumeAtSkeleton = isLoading && resource === 'sleep' && !displayData.resumeAt;
494
- const showDivider = index < orderedBasicAttributes.length - 1 ||
495
- showResumeAtSkeleton;
496
- return (_jsxs("div", { className: "py-1", children: [_jsxs("div", { className: "flex min-h-[32px] items-center justify-between gap-4 rounded-sm px-2.5 py-1", children: [_jsx("span", { className: shouldCapitalizeLabel
497
- ? 'text-[14px] first-letter:uppercase'
498
- : 'text-[14px]', style: { color: 'var(--ds-gray-700)' }, children: getAttributeDisplayName(attribute) }), isModuleSpecifier ? (_jsx("button", { type: "button", className: "min-w-0 max-w-[70%] truncate text-right text-[13px] font-mono", style: {
499
- color: 'var(--ds-gray-1000)',
500
- background: 'transparent',
501
- border: 'none',
502
- padding: 0,
503
- }, title: moduleSpecifierValue, onClick: () => handleCopyModuleSpecifier(moduleSpecifierValue), children: moduleSpecifierValue })) : (_jsx("span", { className: "min-w-0 max-w-[70%] truncate text-right text-[13px] font-mono", style: { color: 'var(--ds-gray-1000)' }, children: displayValue }))] }), showDivider ? (_jsx("div", { className: "mx-2.5 border-b", style: { borderColor: 'var(--ds-gray-300)' } })) : null] }, attribute));
504
- }), isLoading && resource === 'sleep' && !displayData.resumeAt && (_jsx("div", { className: "py-1", children: _jsxs("div", { className: "flex min-h-[32px] items-center justify-between gap-4 rounded-sm px-2.5 py-1", children: [_jsx("span", { className: "text-[14px] first-letter:uppercase", style: { color: 'var(--ds-gray-700)' }, children: "resumeAt" }), _jsx(Skeleton, { className: "h-4 w-[55%]" })] }) }))] })), error ? (_jsx(ErrorCard, { title: "Failed to load resource details", details: error.message, className: "my-4" })) : hasExpired ? (_jsx(ExpiredDataMessage, {})) : (_jsx(_Fragment, { children: resolvedAttributes.map((attribute) => (_jsx(AttributeBlock, { isLoading: isLoading, attribute: attribute, value: displayData[attribute], context: displayContext }, attribute))) }))] }) }) }) }));
507
+ const outerDecryptCtx = useContext(DecryptClickContext);
508
+ const decryptValue = onDecrypt
509
+ ? {
510
+ onDecrypt,
511
+ isDecrypting,
512
+ hasEncryptedData: outerDecryptCtx?.hasEncryptedData,
513
+ }
514
+ : outerDecryptCtx;
515
+ return (_jsx(ContextCardProvider, { children: _jsx(RunClickContext.Provider, { value: onRunClick, children: _jsx(StreamClickContext.Provider, { value: onStreamClick, children: _jsxs(DecryptClickContext.Provider, { value: decryptValue, children: [visibleBasicAttributes.length > 0 && (_jsxs(CollapsibleRoot, { defaultOpen: true, children: [_jsx(CollapsibleTrigger, { children: "Metadata" }), _jsx(CollapsibleContent, { className: "mt-0 mb-2", children: _jsxs("div", { className: "flex flex-col", children: [orderedBasicAttributes.map((attribute) => {
516
+ const displayValue = attributeToDisplayFn[attribute]?.(displayData[attribute]);
517
+ const isCopyableBasicAttribute = copyableBasicAttributes.has(attribute) && typeof displayValue === 'string';
518
+ const label = getAttributeDisplayName(attribute);
519
+ return (_jsx(DetailMonoKeyValueRow, { label: label, value: displayValue, copyText: isCopyableBasicAttribute ? displayValue : undefined, href: attribute === 'moduleSpecifier'
520
+ ? moduleSourceUrl
521
+ : undefined }, attribute));
522
+ }), isLoading &&
523
+ resource === 'sleep' &&
524
+ !displayData.resumeAt && (_jsxs("div", { className: "flex items-center justify-between gap-3 py-0.5", children: [_jsx("span", { className: "text-label-13 text-gray-900", children: "Resume" }), _jsx(Skeleton, { className: "h-4 w-[55%]" })] }))] }) })] })), error ? (_jsx(ErrorCard, { title: "Failed to load resource details", details: error.message, className: "my-4" })) : hasExpired ? (_jsx(ExpiredDataMessage, {})) : resolvedAttributes.length > 0 ? (resolvedAttributes.map((attribute) => (_jsx(AttributeBlock, { isLoading: isLoading, attribute: attribute, value: displayData[attribute], context: displayContext }, attribute)))) : null] }) }) }) }));
505
525
  };
506
- //# sourceMappingURL=attribute-panel.js.map
526
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXR0cmlidXRlLXBhbmVsLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2NvbXBvbmVudHMvc2lkZWJhci9hdHRyaWJ1dGUtcGFuZWwudHN4Il0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLFlBQVksQ0FBQzs7QUFFYixPQUFPLEVBQUUsYUFBYSxFQUFFLGlCQUFpQixFQUFFLE1BQU0sNEJBQTRCLENBQUM7QUFHOUUsT0FBTyxFQUFFLE1BQU0sRUFBRSxNQUFNLFVBQVUsQ0FBQztBQUVsQyxPQUFPLEVBQUUsV0FBVyxFQUFFLFVBQVUsRUFBRSxPQUFPLEVBQUUsTUFBTSxFQUFFLFFBQVEsRUFBRSxNQUFNLE9BQU8sQ0FBQztBQUMzRSxPQUFPLEVBQUUsaUJBQWlCLEVBQUUsZUFBZSxFQUFFLE1BQU0scUJBQXFCLENBQUM7QUFDekUsT0FBTyxFQUFFLG1CQUFtQixFQUFFLGNBQWMsRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQ3RFLE9BQU8sRUFDTCxXQUFXLEVBQ1gsa0JBQWtCLEVBQ2xCLGVBQWUsRUFDZixrQkFBa0IsR0FDbkIsTUFBTSxtQkFBbUIsQ0FBQztBQUMzQixPQUFPLEVBQUUsbUJBQW1CLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQztBQUN6RCxPQUFPLEVBQ0wsbUJBQW1CLEVBQ25CLGVBQWUsRUFDZixrQkFBa0IsR0FDbkIsTUFBTSxzQkFBc0IsQ0FBQztBQUM5QixPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0sa0JBQWtCLENBQUM7QUFDN0MsT0FBTyxFQUFFLGVBQWUsRUFBRSxpQkFBaUIsRUFBRSxNQUFNLHlCQUF5QixDQUFDO0FBQzdFLE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUMxQyxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQUMzRCxPQUFPLEVBQ0wscUJBQXFCLEVBQ3JCLGlCQUFpQixFQUNqQixlQUFlLEdBQ2hCLE1BQU0sb0JBQW9CLENBQUM7QUFDNUIsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0scUJBQXFCLENBQUM7QUFDdkQsT0FBTyxFQUFFLGlCQUFpQixFQUFFLGtCQUFrQixFQUFFLE1BQU0sdUJBQXVCLENBQUM7QUFFOUU7O0dBRUc7QUFDSCxTQUFTLFNBQVMsQ0FBQyxFQUNqQixNQUFNLEVBQ04sT0FBTyxFQUNQLFFBQVEsR0FLVDtJQUNDLE9BQU8sQ0FDTCxpQkFDRSxJQUFJLEVBQUMsUUFBUSxFQUNiLElBQUksRUFBQyxLQUFLLG1CQUNLLE1BQU0sRUFDckIsUUFBUSxFQUFFLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFDekIsT0FBTyxFQUFFLE9BQU8sRUFDaEIsU0FBUyxFQUFDLDhEQUE4RCxFQUN4RSxLQUFLLEVBQUU7WUFDTCx3RUFBd0U7WUFDeEUsb0NBQW9DO1lBQ3BDLGVBQWUsRUFBRSxhQUFhO1lBQzlCLFNBQVMsRUFBRSxNQUFNO1lBQ2pCLFVBQVUsRUFBRSxNQUFNO1lBQ2xCLFdBQVcsRUFBRSxNQUFNO1lBQ25CLFlBQVksRUFBRSxhQUFhLE1BQU0sQ0FBQyxDQUFDLENBQUMsb0JBQW9CLENBQUMsQ0FBQyxDQUFDLGFBQWEsRUFBRTtZQUMxRSxZQUFZLEVBQUUsQ0FBQztZQUNmLE9BQU8sRUFBRSxNQUFNO1lBQ2YsU0FBUyxFQUFFLE1BQU07WUFDakIsTUFBTSxFQUFFLFNBQVM7WUFDakIsS0FBSyxFQUFFLE1BQU0sQ0FBQyxDQUFDLENBQUMscUJBQXFCLENBQUMsQ0FBQyxDQUFDLG9CQUFvQjtTQUM3RCxZQUVBLFFBQVEsR0FDRixDQUNWLENBQUM7QUFDSixDQUFDO0FBRUQ7OztHQUdHO0FBQ0gsU0FBUyxlQUFlLENBQW1CLEVBQ3pDLElBQUksRUFDSixTQUFTLEVBQ1QsV0FBVyxFQUNYLFNBQVMsRUFDVCxRQUFRLEdBT1Q7SUFDQyxNQUFNLGFBQWEsR0FBRyxXQUFXLENBQy9CLENBQUMsS0FBb0MsRUFBRSxFQUFFO1FBQ3ZDLElBQUksS0FBSyxDQUFDLEdBQUcsS0FBSyxZQUFZLElBQUksS0FBSyxDQUFDLEdBQUcsS0FBSyxXQUFXO1lBQUUsT0FBTztRQUNwRSxLQUFLLENBQUMsY0FBYyxFQUFFLENBQUM7UUFDdkIsTUFBTSxZQUFZLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLEVBQUUsS0FBSyxTQUFTLENBQUMsQ0FBQztRQUMvRCxNQUFNLFNBQVMsR0FDYixLQUFLLENBQUMsR0FBRyxLQUFLLFlBQVk7WUFDeEIsQ0FBQyxDQUFDLENBQUMsWUFBWSxHQUFHLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxNQUFNO1lBQ2xDLENBQUMsQ0FBQyxDQUFDLFlBQVksR0FBRyxDQUFDLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQyxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUM7UUFDckQsV0FBVyxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQztJQUNsQyxDQUFDLEVBQ0QsQ0FBQyxJQUFJLEVBQUUsU0FBUyxFQUFFLFdBQVcsQ0FBQyxDQUMvQixDQUFDO0lBRUYsT0FBTyxDQUNMLGVBQ0UsU0FBUyxFQUFDLG1CQUFtQixFQUM3QixLQUFLLEVBQUU7WUFDTCxXQUFXLEVBQUUsb0JBQW9CO1lBQ2pDLGVBQWUsRUFBRSxhQUFhO1NBQy9CLGFBRUQsY0FDRSxTQUFTLEVBQUMscUJBQXFCLEVBQy9CLElBQUksRUFBQyxTQUFTLGdCQUNGLFNBQVMsRUFDckIsU0FBUyxFQUFFLGFBQWEsRUFDeEIsS0FBSyxFQUFFO29CQUNMLFdBQVcsRUFBRSxvQkFBb0I7b0JBQ2pDLGVBQWUsRUFBRSxhQUFhO2lCQUMvQixZQUVBLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxHQUFHLEVBQUUsRUFBRSxDQUFDLENBQ2pCLEtBQUMsU0FBUyxJQUVSLE1BQU0sRUFBRSxTQUFTLEtBQUssR0FBRyxDQUFDLEVBQUUsRUFDNUIsT0FBTyxFQUFFLEdBQUcsRUFBRSxDQUFDLFdBQVcsQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLFlBRWpDLEdBQUcsQ0FBQyxLQUFLLElBSkwsR0FBRyxDQUFDLEVBQUUsQ0FLRCxDQUNiLENBQUMsR0FDRSxFQUVOLGNBQUssSUFBSSxFQUFDLFVBQVUsWUFBRSxRQUFRLEdBQU8sSUFDakMsQ0FDUCxDQUFDO0FBQ0osQ0FBQztBQUVELE1BQU0sZ0JBQWdCLEdBQUc7SUFDdkIsRUFBRSxFQUFFLEVBQUUsY0FBdUIsRUFBRSxLQUFLLEVBQUUsY0FBYyxFQUFFO0lBQ3RELEVBQUUsRUFBRSxFQUFFLE1BQWUsRUFBRSxLQUFLLEVBQUUsVUFBVSxFQUFFO0NBQzNDLENBQUM7QUFFRjs7R0FFRztBQUNILFNBQVMsb0JBQW9CLENBQUMsRUFDNUIsWUFBWSxFQUNaLElBQUksRUFDSixXQUFXLEVBQ1gsWUFBWSxHQU1iO0lBQ0MsTUFBTSxDQUFDLFNBQVMsRUFBRSxZQUFZLENBQUMsR0FBRyxRQUFRLENBQ3hDLGNBQWMsQ0FDZixDQUFDO0lBRUYsT0FBTyxDQUNMLEtBQUMsV0FBVyxJQUNWLEtBQUssRUFBQyxPQUFPLEVBQ2IsV0FBVyxFQUFFLFdBQVcsRUFDeEIsWUFBWSxFQUFFLFlBQVksWUFFMUIsS0FBQyxlQUFlLElBQ2QsSUFBSSxFQUFFLGdCQUFnQixFQUN0QixTQUFTLEVBQUUsU0FBUyxFQUNwQixXQUFXLEVBQUUsWUFBWSxFQUN6QixTQUFTLEVBQUMsbUJBQW1CLFlBRTVCLFNBQVMsS0FBSyxjQUFjLENBQUMsQ0FBQyxDQUFDLENBQzlCLEtBQUMsZ0JBQWdCLElBQUMsUUFBUSxFQUFFLFlBQVksR0FBSSxDQUM3QyxDQUFDLENBQUMsQ0FBQyxDQUNGLGNBQUssU0FBUyxFQUFDLEtBQUssWUFDakIsS0FBSyxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUM7b0JBQ2xCLENBQUMsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FDakIsY0FBSyxTQUFTLEVBQUMsaUJBQWlCLFlBQzdCLFNBQVMsQ0FBQyxDQUFDLENBQUMsSUFEdUIsQ0FBQyxDQUVqQyxDQUNQLENBQUM7b0JBQ0osQ0FBQyxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsR0FDZixDQUNQLEdBQ2UsR0FDTixDQUNmLENBQUM7QUFDSixDQUFDO0FBRUQ7OztHQUdHO0FBQ0gsU0FBUyxtQkFBbUI7SUFDMUIsT0FBTyxLQUFDLGtCQUFrQixLQUFHLENBQUM7QUFDaEMsQ0FBQztBQUVEOztHQUVHO0FBQ0gsU0FBUyxpQkFBaUI7SUFDeEIsT0FBTyxDQUNMLGNBQ0UsU0FBUyxFQUFDLCtEQUErRCxFQUN6RSxLQUFLLEVBQUU7WUFDTCxXQUFXLEVBQUUsb0JBQW9CO1lBQ2pDLGVBQWUsRUFBRSxvQkFBb0I7WUFDckMsS0FBSyxFQUFFLG9CQUFvQjtTQUM1QixZQUVELGVBQU0sU0FBUyxFQUFDLGFBQWEsNkJBQW9CLEdBQzdDLENBQ1AsQ0FBQztBQUNKLENBQUM7QUFFRCxTQUFTLFNBQVMsQ0FBQyxLQUFjO0lBQy9CLE9BQU8sS0FBQyxpQkFBaUIsSUFBQyxJQUFJLEVBQUUsS0FBSyxHQUFJLENBQUM7QUFDNUMsQ0FBQztBQUVELE1BQU0saUJBQWlCLEdBQUcsQ0FBQyxLQUFjLEVBQVcsRUFBRTtJQUNwRCxJQUFJLEtBQUssSUFBSSxJQUFJO1FBQUUsT0FBTyxLQUFLLENBQUM7SUFDaEMsSUFBSSxPQUFPLEtBQUssS0FBSyxRQUFRO1FBQUUsT0FBTyxLQUFLLENBQUMsSUFBSSxFQUFFLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FBQztJQUM5RCxJQUFJLEtBQUssQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDO1FBQUUsT0FBTyxLQUFLLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FBQztJQUNsRCxJQUFJLE9BQU8sS0FBSyxLQUFLLFFBQVE7UUFBRSxPQUFPLE1BQU0sQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FBQztJQUNwRSxPQUFPLElBQUksQ0FBQztBQUNkLENBQUMsQ0FBQztBQW1CRixNQUFNLGNBQWMsR0FBbUI7SUFDckMsY0FBYztJQUNkLGlCQUFpQjtJQUNqQixVQUFVO0lBQ1YsUUFBUTtJQUNSLFFBQVE7SUFDUixRQUFRO0lBQ1IsU0FBUztJQUNULE9BQU87SUFDUCxTQUFTO0lBQ1QsT0FBTztJQUNQLGVBQWU7SUFDZixnQkFBZ0I7SUFDaEIsWUFBWTtJQUNaLGVBQWU7SUFDZixXQUFXO0lBQ1gsY0FBYztJQUNkLGFBQWE7SUFDYixxQkFBcUI7SUFDckIsU0FBUztJQUNULFdBQVc7SUFDWCxhQUFhO0lBQ2Isa0JBQWtCO0lBQ2xCLFlBQVk7SUFDWixXQUFXO0lBQ1gsV0FBVztJQUNYLFdBQVc7SUFDWCxhQUFhO0lBQ2IsV0FBVztJQUNYLFlBQVk7SUFDWixPQUFPO0lBQ1AsVUFBVTtJQUNWLFdBQVc7SUFDWCxPQUFPO0lBQ1AsUUFBUTtJQUNSLFlBQVk7SUFDWixVQUFVO0NBQ1gsQ0FBQztBQUVGLE1BQU0sb0JBQW9CLEdBQUcsQ0FBQyxDQUFTLEVBQUUsQ0FBUyxFQUFVLEVBQUU7SUFDNUQsTUFBTSxNQUFNLEdBQUcsY0FBYyxDQUFDLE9BQU8sQ0FBQyxDQUFpQixDQUFDLElBQUksQ0FBQyxDQUFDO0lBQzlELE1BQU0sTUFBTSxHQUFHLGNBQWMsQ0FBQyxPQUFPLENBQUMsQ0FBaUIsQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUM5RCxPQUFPLE1BQU0sR0FBRyxNQUFNLENBQUM7QUFDekIsQ0FBQyxDQUFDO0FBRUY7O0dBRUc7QUFDSCxNQUFNLHFCQUFxQixHQUEwQztJQUNuRSxlQUFlLEVBQUUsUUFBUTtJQUN6QixZQUFZLEVBQUUsZUFBZTtJQUM3QixRQUFRLEVBQUUsV0FBVztJQUNyQixNQUFNLEVBQUUsU0FBUztJQUNqQixNQUFNLEVBQUUsU0FBUztJQUNqQixPQUFPLEVBQUUsVUFBVTtJQUNuQixPQUFPLEVBQUUsVUFBVTtJQUNuQixLQUFLLEVBQUUsUUFBUTtJQUNmLEtBQUssRUFBRSxPQUFPO0lBQ2QsU0FBUyxFQUFFLFlBQVk7SUFDdkIsU0FBUyxFQUFFLFlBQVk7SUFDdkIsYUFBYSxFQUFFLGdCQUFnQjtJQUMvQixZQUFZLEVBQUUsZUFBZTtJQUM3QixXQUFXLEVBQUUsY0FBYztJQUMzQixtQkFBbUIsRUFBRSx3QkFBd0I7SUFDN0MsVUFBVSxFQUFFLFVBQVU7SUFDdEIsU0FBUyxFQUFFLFNBQVM7SUFDcEIsU0FBUyxFQUFFLFNBQVM7SUFDcEIsU0FBUyxFQUFFLFNBQVM7SUFDcEIsV0FBVyxFQUFFLFdBQVc7SUFDeEIsU0FBUyxFQUFFLFNBQVM7SUFDcEIsVUFBVSxFQUFFLGFBQWE7SUFDekIsUUFBUSxFQUFFLFFBQVE7SUFDbEIsY0FBYyxFQUFFLGVBQWU7SUFDL0IsVUFBVSxFQUFFLFVBQVU7SUFDdEIsYUFBYSxFQUFFLGdCQUFnQjtDQUNoQyxDQUFDO0FBRUY7O0dBRUc7QUFDSCxNQUFNLHVCQUF1QixHQUFHLENBQUMsU0FBaUIsRUFBVSxFQUFFO0lBQzVELE9BQU8scUJBQXFCLENBQUMsU0FBeUIsQ0FBQyxJQUFJLFNBQVMsQ0FBQztBQUN2RSxDQUFDLENBQUM7QUFFRixNQUFNLDBCQUEwQixHQUFHLENBQUMsS0FBYyxFQUFVLEVBQUU7SUFDNUQsTUFBTSxHQUFHLEdBQUcsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDO0lBQzFCLE1BQU0sVUFBVSxHQUFHLGFBQWEsQ0FBQyxHQUFHLENBQUMsQ0FBQztJQUN0QyxJQUFJLFVBQVUsRUFBRSxDQUFDO1FBQ2YsT0FBTyxVQUFVLENBQUMsZUFBZSxDQUFDO0lBQ3BDLENBQUM7SUFDRCxNQUFNLGNBQWMsR0FBRyxpQkFBaUIsQ0FBQyxHQUFHLENBQUMsQ0FBQztJQUM5QyxJQUFJLGNBQWMsRUFBRSxDQUFDO1FBQ25CLE9BQU8sY0FBYyxDQUFDLGVBQWUsQ0FBQztJQUN4QyxDQUFDO0lBQ0QsT0FBTyxHQUFHLENBQUM7QUFDYixDQUFDLENBQUM7QUFFRixNQUFNLGNBQWMsR0FBRyxDQUFDLEtBQWMsRUFBZSxFQUFFO0lBQ3JELElBQUksS0FBSyxJQUFJLElBQUksRUFBRSxDQUFDO1FBQ2xCLE9BQU8sSUFBSSxDQUFDO0lBQ2QsQ0FBQztJQUNELElBQUksS0FBSyxZQUFZLElBQUksRUFBRSxDQUFDO1FBQzFCLE9BQU8sTUFBTSxDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUMsT0FBTyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUM7SUFDdEQsQ0FBQztJQUNELElBQUksT0FBTyxLQUFLLEtBQUssUUFBUSxJQUFJLEtBQUssQ0FBQyxJQUFJLEVBQUUsQ0FBQyxNQUFNLEtBQUssQ0FBQyxFQUFFLENBQUM7UUFDM0QsT0FBTyxJQUFJLENBQUM7SUFDZCxDQUFDO0lBRUQsTUFBTSxJQUFJLEdBQ1IsT0FBTyxLQUFLLEtBQUssUUFBUSxDQUFDLENBQUMsQ0FBQyxJQUFJLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxJQUFJLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUM7SUFDeEUsT0FBTyxNQUFNLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxPQUFPLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQztBQUNwRCxDQUFDLENBQUM7QUFFRixNQUFNLDBCQUEwQixHQUFHLENBQUMsSUFBVSxFQUFVLEVBQUUsQ0FDeEQsTUFBTSxDQUFDLElBQUksRUFBRSx1QkFBdUIsQ0FBQyxDQUFDLFdBQVcsRUFBRSxDQUFDO0FBRXRELE1BQU0sQ0FBQyxNQUFNLG9CQUFvQixHQUFHLENBQUMsS0FBYyxFQUFVLEVBQUU7SUFDN0QsTUFBTSxJQUFJLEdBQUcsY0FBYyxDQUFDLEtBQUssQ0FBQyxDQUFDO0lBQ25DLElBQUksQ0FBQyxJQUFJLEVBQUUsQ0FBQztRQUNWLE9BQU8sR0FBRyxDQUFDO0lBQ2IsQ0FBQztJQUVELE9BQU8sMEJBQTBCLENBQUMsSUFBSSxDQUFDLENBQUM7QUFDMUMsQ0FBQyxDQUFDO0FBRUYsTUFBTSwwQkFBMEIsR0FBRyxDQUFDLEtBQWMsRUFBaUIsRUFBRTtJQUNuRSxNQUFNLElBQUksR0FBRyxjQUFjLENBQUMsS0FBSyxDQUFDLENBQUM7SUFDbkMsSUFBSSxDQUFDLElBQUksRUFBRSxDQUFDO1FBQ1YsT0FBTyxJQUFJLENBQUM7SUFDZCxDQUFDO0lBQ0QsT0FBTywwQkFBMEIsQ0FBQyxJQUFJLENBQUMsQ0FBQztBQUMxQyxDQUFDLENBQUM7QUFFRixNQUFNLDBCQUEwQixHQUFHLENBQUMsS0FBYyxFQUFvQixFQUFFO0lBQ3RFLE1BQU0sSUFBSSxHQUFHLGNBQWMsQ0FBQyxLQUFLLENBQUMsQ0FBQztJQUNuQyxJQUFJLENBQUMsSUFBSTtRQUFFLE9BQU8sSUFBSSxDQUFDO0lBQ3ZCLE9BQU8sQ0FDTCxLQUFDLGdCQUFnQixJQUFDLElBQUksRUFBRSxJQUFJLFlBQzFCLHlCQUFPLDBCQUEwQixDQUFDLElBQUksQ0FBQyxHQUFRLEdBQzlCLENBQ3BCLENBQUM7QUFDSixDQUFDLENBQUM7QUFRRixNQUFNLG9CQUFvQixHQUd0QjtJQUNGLGtDQUFrQztJQUNsQyxZQUFZLEVBQUUsQ0FBQyxNQUFlLEVBQUUsRUFBRSxDQUFDLElBQUk7SUFDdkMsZUFBZSxFQUFFLENBQUMsS0FBYyxFQUFFLEVBQUUsQ0FBQywwQkFBMEIsQ0FBQyxLQUFLLENBQUM7SUFDdEUsUUFBUSxFQUFFLENBQUMsTUFBZSxFQUFFLEVBQUUsQ0FBQyxJQUFJO0lBQ25DLE1BQU07SUFDTixLQUFLLEVBQUUsQ0FBQyxNQUFlLEVBQUUsRUFBRSxDQUFDLElBQUk7SUFDaEMsTUFBTSxFQUFFLENBQUMsS0FBYyxFQUFFLEVBQUUsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDO0lBQ3pDLE1BQU0sRUFBRSxDQUFDLEtBQWMsRUFBRSxFQUFFLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQztJQUN6QyxPQUFPLEVBQUUsQ0FBQyxLQUFjLEVBQUUsRUFBRSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUM7SUFDMUMsbUJBQW1CO0lBQ25CLE1BQU0sRUFBRSxDQUFDLE1BQWUsRUFBRSxFQUFFLENBQUMsSUFBSTtJQUNqQyxPQUFPLEVBQUUsQ0FBQyxLQUFjLEVBQUUsRUFBRSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUM7SUFDMUMsZUFBZTtJQUNmLEtBQUssRUFBRSxDQUFDLEtBQWMsRUFBRSxFQUFFLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQztJQUN4QyxTQUFTLEVBQUUsQ0FBQyxLQUFjLEVBQUUsRUFBRSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUM7SUFDNUMsUUFBUSxFQUFFLENBQUMsS0FBYyxFQUFFLEVBQUUsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDO0lBQzNDLGFBQWEsRUFBRSxDQUFDLEtBQWMsRUFBRSxFQUFFLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQztJQUNoRCxjQUFjLEVBQUUsMEJBQTBCO0lBQzFDLFVBQVUsRUFBRSwwQkFBMEI7SUFDdEMsZ0JBQWdCO0lBQ2hCLFNBQVMsRUFBRSxDQUFDLEtBQWMsRUFBRSxFQUFFLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQztJQUM1QyxhQUFhLEVBQUUsQ0FBQyxLQUFjLEVBQUUsRUFBRSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUM7SUFDaEQsa0JBQWtCO0lBQ2xCLFlBQVksRUFBRSxDQUFDLEtBQWMsRUFBRSxFQUFFLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQztJQUMvQyxXQUFXLEVBQUUsQ0FBQyxLQUFjLEVBQUUsRUFBRSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUM7SUFDOUMsbUJBQW1CLEVBQUUsQ0FBQyxLQUFjLEVBQUUsRUFBRSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUM7SUFDdEQsZ0NBQWdDO0lBQ2hDLE9BQU8sRUFBRSxDQUFDLE1BQWUsRUFBRSxFQUFFLENBQUMsSUFBSTtJQUNsQyxTQUFTLEVBQUUsQ0FBQyxNQUFlLEVBQUUsRUFBRSxDQUFDLElBQUk7SUFDcEMsV0FBVyxFQUFFLENBQUMsTUFBZSxFQUFFLEVBQUUsQ0FBQyxJQUFJO0lBQ3RDLGdCQUFnQixFQUFFLENBQUMsTUFBZSxFQUFFLEVBQUUsQ0FBQyxJQUFJO0lBQzNDLDJEQUEyRDtJQUMzRCw2REFBNkQ7SUFDN0QsMERBQTBEO0lBQzFELFVBQVUsRUFBRSxDQUFDLEtBQWMsRUFBRSxFQUFFO1FBQzdCLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxLQUFLLENBQUM7WUFBRSxPQUFPLElBQUksQ0FBQztRQUMzQyxPQUFPLEtBQUMsaUJBQWlCLElBQUMsVUFBVSxFQUFFLEtBQStCLEdBQUksQ0FBQztJQUM1RSxDQUFDO0lBQ0QsMEVBQTBFO0lBQzFFLFVBQVUsRUFBRSwwQkFBMEI7SUFDdEMsU0FBUyxFQUFFLDBCQUEwQjtJQUNyQyxTQUFTLEVBQUUsMEJBQTBCO0lBQ3JDLFNBQVMsRUFBRSxDQUFDLE1BQWUsRUFBRSxFQUFFLENBQUMsSUFBSTtJQUNwQyxXQUFXLEVBQUUsMEJBQTBCO0lBQ3ZDLFNBQVMsRUFBRSxDQUFDLE1BQWUsRUFBRSxFQUFFLENBQUMsSUFBSTtJQUNwQyxVQUFVLEVBQUUsMEJBQTBCO0lBQ3RDLFFBQVEsRUFBRSwwQkFBMEI7SUFDcEMsd0RBQXdEO0lBQ3hELFFBQVEsRUFBRSxDQUFDLEtBQWMsRUFBRSxFQUFFO1FBQzNCLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxLQUFLLENBQUM7WUFBRSxPQUFPLElBQUksQ0FBQztRQUMzQyxJQUFJLGlCQUFpQixDQUFDLEtBQUssQ0FBQyxFQUFFLENBQUM7WUFDN0IsT0FBTyxDQUNMLEtBQUMsV0FBVyxJQUFDLEtBQUssRUFBQyxVQUFVLFlBQzNCLEtBQUMsa0JBQWtCLEtBQUcsR0FDVixDQUNmLENBQUM7UUFDSixDQUFDO1FBQ0QsSUFBSSxlQUFlLENBQUMsS0FBSyxDQUFDLEVBQUUsQ0FBQztZQUMzQixPQUFPLENBQ0wsS0FBQyxXQUFXLElBQUMsS0FBSyxFQUFDLFVBQVUsWUFDM0IsS0FBQyxpQkFBaUIsS0FBRyxHQUNULENBQ2YsQ0FBQztRQUNKLENBQUM7UUFDRCxPQUFPLEtBQUMsZUFBZSxJQUFDLFFBQVEsRUFBRSxLQUFLLEdBQUksQ0FBQztJQUM5QyxDQUFDO0lBQ0QsS0FBSyxFQUFFLENBQUMsS0FBYyxFQUFFLE9BQXdCLEVBQUUsRUFBRTtRQUNsRCxJQUFJLGlCQUFpQixDQUFDLEtBQUssQ0FBQyxFQUFFLENBQUM7WUFDN0IsT0FBTyxDQUNMLEtBQUMsV0FBVyxJQUNWLEtBQUssRUFBQyxPQUFPLEVBQ2IsV0FBVyxFQUFFLE9BQU8sRUFBRSxXQUFXLEVBQ2pDLFlBQVksRUFBRSxPQUFPLEVBQUUsbUJBQW1CLFlBRTFDLEtBQUMsbUJBQW1CLEtBQUcsR0FDWCxDQUNmLENBQUM7UUFDSixDQUFDO1FBQ0QsSUFBSSxlQUFlLENBQUMsS0FBSyxDQUFDO1lBQUUsT0FBTyxLQUFDLGlCQUFpQixLQUFHLENBQUM7UUFDekQsbURBQW1EO1FBQ25ELElBQUksS0FBSyxJQUFJLE9BQU8sS0FBSyxLQUFLLFFBQVEsSUFBSSxNQUFNLElBQUksS0FBSyxFQUFFLENBQUM7WUFDMUQsTUFBTSxFQUFFLElBQUksRUFBRSxXQUFXLEVBQUUsT0FBTyxFQUFFLEdBQUcsS0FJdEMsQ0FBQztZQUNGLE1BQU0sY0FBYyxHQUFHLGlCQUFpQixDQUFDLFdBQVcsQ0FBQyxDQUFDO1lBQ3RELE1BQU0sVUFBVSxHQUFHLGlCQUFpQixDQUFDLE9BQU8sQ0FBQyxDQUFDO1lBQzlDLE1BQU0sT0FBTyxHQUFHLGlCQUFpQixDQUFDLElBQUksQ0FBQyxDQUFDO1lBRXhDLHFFQUFxRTtZQUNyRSxJQUFJLE9BQU8sRUFBRSxRQUFRLElBQUksY0FBYyxDQUFDLE9BQU8sQ0FBQyxRQUFRLENBQUMsRUFBRSxDQUFDO2dCQUMxRCxNQUFNLFlBQVksR0FBRyxtQkFBbUIsQ0FBQyxJQUFJLENBQUMsQ0FBQztnQkFDL0MsSUFBSSxZQUFZLElBQUksWUFBWSxDQUFDLE1BQU0sR0FBRyxDQUFDLEVBQUUsQ0FBQztvQkFDNUMsT0FBTyxDQUNMLDhCQUNFLEtBQUMsb0JBQW9CLElBQ25CLFlBQVksRUFBRSxZQUFZLEVBQzFCLElBQUksRUFBRSxJQUFJLEVBQ1YsV0FBVyxFQUFFLE9BQU8sRUFBRSxXQUFXLEVBQ2pDLFlBQVksRUFBRSxPQUFPLEVBQUUsbUJBQW1CLEdBQzFDLEVBQ0QsY0FBYyxJQUFJLENBQ2pCLEtBQUMsV0FBVyxJQUFDLEtBQUssRUFBQyxtQkFBbUIsWUFDbkMsU0FBUyxDQUFDLFdBQVcsQ0FBQyxHQUNYLENBQ2YsRUFDQSxVQUFVLElBQUksQ0FDYixLQUFDLFdBQVcsSUFBQyxLQUFLLEVBQUMsWUFBWSxZQUM1QixTQUFTLENBQUMsT0FBTyxDQUFDLEdBQ1AsQ0FDZixJQUNBLENBQ0osQ0FBQztnQkFDSixDQUFDO1lBQ0gsQ0FBQztZQUVELHlFQUF5RTtZQUN6RSxJQUFJLENBQUMsT0FBTyxJQUFJLENBQUMsY0FBYyxJQUFJLENBQUMsVUFBVSxFQUFFLENBQUM7Z0JBQy9DLE9BQU8sS0FBQyxXQUFXLElBQUMsS0FBSyxFQUFDLGlCQUFpQixFQUFDLFFBQVEsU0FBRyxDQUFDO1lBQzFELENBQUM7WUFFRCxPQUFPLENBQ0wsOEJBQ0UsS0FBQyxXQUFXLElBQ1YsS0FBSyxFQUFDLE9BQU8sRUFDYixXQUFXLEVBQUUsT0FBTyxFQUFFLFdBQVcsRUFDakMsWUFBWSxFQUFFLE9BQU8sRUFBRSxtQkFBbUIsWUFFekMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUM7NEJBQ2xCLENBQUMsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FDakIsY0FBSyxTQUFTLEVBQUMsaUJBQWlCLFlBQzdCLFNBQVMsQ0FBQyxDQUFDLENBQUMsSUFEdUIsQ0FBQyxDQUVqQyxDQUNQLENBQUM7NEJBQ0osQ0FBQyxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsR0FDUCxFQUNiLGNBQWMsSUFBSSxDQUNqQixLQUFDLFdBQVcsSUFBQyxLQUFLLEVBQUMsbUJBQW1CLFlBQ25DLFNBQVMsQ0FBQyxXQUFXLENBQUMsR0FDWCxDQUNmLEVBQ0EsVUFBVSxJQUFJLENBQ2IsS0FBQyxXQUFXLElBQUMsS0FBSyxFQUFDLFNBQVMsWUFBRSxTQUFTLENBQUMsT0FBTyxDQUFDLEdBQWUsQ0FDaEUsSUFDQSxDQUNKLENBQUM7UUFDSixDQUFDO1FBRUQsMkNBQTJDO1FBQzNDLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDO1lBQzlCLE9BQU8sS0FBQyxXQUFXLElBQUMsS0FBSyxFQUFDLGlCQUFpQixFQUFDLFFBQVEsU0FBRyxDQUFDO1FBQzFELENBQUM7UUFDRCxPQUFPLENBQ0wsS0FBQyxXQUFXLElBQ1YsS0FBSyxFQUFDLE9BQU8sRUFDYixXQUFXLEVBQUUsT0FBTyxFQUFFLFdBQVcsRUFDakMsWUFBWSxFQUFFLE9BQU8sRUFBRSxtQkFBbUIsWUFFekMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUM7Z0JBQ25CLENBQUMsQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FDbEIsY0FBSyxTQUFTLEVBQUMsaUJBQWlCLFlBQzdCLFNBQVMsQ0FBQyxDQUFDLENBQUMsSUFEdUIsQ0FBQyxDQUVqQyxDQUNQLENBQUM7Z0JBQ0osQ0FBQyxDQUFDLFNBQVMsQ0FBQyxLQUFLLENBQUMsR0FDUixDQUNmLENBQUM7SUFDSixDQUFDO0lBQ0QsTUFBTSxFQUFFLENBQUMsS0FBYyxFQUFFLE9BQXdCLEVBQUUsRUFBRTtRQUNuRCxJQUFJLGlCQUFpQixDQUFDLEtBQUssQ0FBQyxFQUFFLENBQUM7WUFDN0IsT0FBTyxDQUNMLEtBQUMsV0FBVyxJQUNWLEtBQUssRUFBQyxRQUFRLEVBQ2QsV0FBVyxFQUFFLE9BQU8sRUFBRSxXQUFXLEVBQ2pDLFlBQVksRUFBRSxPQUFPLEVBQUUsbUJBQW1CLFlBRTFDLEtBQUMsbUJBQW1CLEtBQUcsR0FDWCxDQUNmLENBQUM7UUFDSixDQUFDO1FBQ0QsSUFBSSxDQUFDLGlCQUFpQixDQUFDLEtBQUssQ0FBQztZQUFFLE9BQU8sSUFBSSxDQUFDO1FBQzNDLElBQUksZUFBZSxDQUFDLEtBQUssQ0FBQztZQUFFLE9BQU8sS0FBQyxpQkFBaUIsS0FBRyxDQUFDO1FBQ3pELE9BQU8sQ0FDTCxLQUFDLFdBQVcsSUFDVixLQUFLLEVBQUMsUUFBUSxFQUNkLFdBQVcsRUFBRSxPQUFPLEVBQUUsV0FBVyxFQUNqQyxZQUFZLEVBQUUsT0FBTyxFQUFFLG1CQUFtQixZQUV6QyxTQUFTLENBQUMsS0FBSyxDQUFDLEdBQ0wsQ0FDZixDQUFDO0lBQ0osQ0FBQztJQUNELEtBQUssRUFBRSxDQUFDLEtBQWMsRUFBRSxFQUFFO1FBQ3hCLElBQUksaUJBQWlCLENBQUMsS0FBSyxDQUFDLEVBQUUsQ0FBQztZQUM3QixPQUFPLENBQ0wsS0FBQyxXQUFXLElBQUMsS0FBSyxFQUFDLE9BQU8sRUFBQyxXQUFXLGtCQUNwQyxLQUFDLG1CQUFtQixLQUFHLEdBQ1gsQ0FDZixDQUFDO1FBQ0osQ0FBQztRQUNELElBQUksZUFBZSxDQUFDLEtBQUssQ0FBQztZQUFFLE9BQU8sS0FBQyxpQkFBaUIsS0FBRyxDQUFDO1FBQ3pELElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxLQUFLLENBQUM7WUFBRSxPQUFPLElBQUksQ0FBQztRQUUzQyx5RUFBeUU7UUFDekUsb0VBQW9FO1FBQ3BFLElBQUksaUJBQWlCLENBQUMsS0FBSyxDQUFDLEVBQUUsQ0FBQztZQUM3QixPQUFPLENBQ0wsS0FBQyxXQUFXLElBQUMsS0FBSyxFQUFDLE9BQU8sRUFBQyxXQUFXLGtCQUNwQyxLQUFDLGVBQWUsSUFBQyxLQUFLLEVBQUUsS0FBSyxHQUFJLEdBQ3JCLENBQ2YsQ0FBQztRQUNKLENBQUM7UUFFRCxPQUFPLENBQ0wsS0FBQyxXQUFXLElBQUMsS0FBSyxFQUFDLE9BQU8sRUFBQyxXQUFXLGtCQUNuQyxTQUFTLENBQUMsS0FBSyxDQUFDLEdBQ0wsQ0FDZixDQUFDO0lBQ0osQ0FBQztJQUNELFNBQVMsRUFBRSxDQUFDLEtBQWMsRUFBRSxFQUFFO1FBQzVCLElBQUksaUJBQWlCLENBQUMsS0FBSyxDQUFDLEVBQUUsQ0FBQztZQUM3QixPQUFPLENBQ0wsS0FBQyxXQUFXLElBQUMsS0FBSyxFQUFDLFlBQVksRUFBQyxXQUFXLGtCQUN6QyxLQUFDLG1CQUFtQixLQUFHLEdBQ1gsQ0FDZixDQUFDO1FBQ0osQ0FBQztRQUNELElBQUksZUFBZSxDQUFDLEtBQUssQ0FBQztZQUFFLE9BQU8sS0FBQyxpQkFBaUIsS0FBRyxDQUFDO1FBQ3pELElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxLQUFLLENBQUM7WUFBRSxPQUFPLElBQUksQ0FBQztRQUMzQyxPQUFPLENBQ0wsS0FBQyxXQUFXLElBQUMsS0FBSyxFQUFDLFlBQVksRUFBQyxXQUFXLGtCQUN4QyxTQUFTLENBQUMsS0FBSyxDQUFDLEdBQ0wsQ0FDZixDQUFDO0lBQ0osQ0FBQztJQUNELFNBQVMsRUFBRSxDQUFDLEtBQWMsRUFBRSxFQUFFO1FBQzVCLElBQUksT0FBTyxLQUFLLEtBQUssUUFBUSxJQUFJLEtBQUssQ0FBQyxNQUFNLEtBQUssQ0FBQztZQUFFLE9BQU8sSUFBSSxDQUFDO1FBQ2pFLE9BQU8sTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDO0lBQ3ZCLENBQUM7Q0FDRixDQUFDO0FBRUYsTUFBTSxvQkFBb0IsR0FBRztJQUMzQixPQUFPO0lBQ1AsUUFBUTtJQUNSLE9BQU87SUFDUCxVQUFVO0lBQ1YsWUFBWTtJQUNaLFdBQVc7Q0FDWixDQUFDO0FBRUYsNkVBQTZFO0FBQzdFLDhEQUE4RDtBQUM5RCxNQUFNLHNCQUFzQixHQUFHLElBQUksR0FBRyxDQUFDO0lBQ3JDLE9BQU87SUFDUCxRQUFRO0lBQ1IsT0FBTztJQUNQLFVBQVU7SUFDVixZQUFZO0lBQ1osV0FBVztDQUNaLENBQUMsQ0FBQztBQUVILE1BQU0sa0JBQWtCLEdBQUcsR0FBRyxFQUFFLENBQUMsQ0FDL0IsY0FDRSxTQUFTLEVBQUMseUNBQXlDLEVBQ25ELEtBQUssRUFBRTtRQUNMLFdBQVcsRUFBRSxvQkFBb0I7UUFDakMsZUFBZSxFQUFFLG9CQUFvQjtRQUNyQyxLQUFLLEVBQUUsb0JBQW9CO0tBQzVCLFlBRUQsMkZBQTBFLEdBQ3RFLENBQ1AsQ0FBQztBQUVGLE1BQU0sdUJBQXVCLEdBQUcsSUFBSSxHQUFHLENBQWU7SUFDcEQsUUFBUTtJQUNSLFFBQVE7SUFDUixTQUFTO0lBQ1QsY0FBYztJQUNkLGlCQUFpQjtDQUNsQixDQUFDLENBQUM7QUFFSCxNQUFNLG9CQUFvQixHQUEwQztJQUNsRSxLQUFLLEVBQUUsT0FBTztJQUNkLE1BQU0sRUFBRSxRQUFRO0lBQ2hCLFNBQVMsRUFBRSxZQUFZO0NBQ3hCLENBQUM7QUFFRixNQUFNLENBQUMsTUFBTSxjQUFjLEdBQUcsQ0FBQyxFQUM3QixTQUFTLEVBQ1QsS0FBSyxFQUNMLFNBQVMsRUFDVCxNQUFNLEdBQUcsS0FBSyxFQUNkLE9BQU8sR0FPUixFQUFFLEVBQUU7SUFDSCxNQUFNLFVBQVUsR0FBRyxVQUFVLENBQUMsbUJBQW1CLENBQUMsQ0FBQztJQUNuRCxNQUFNLGNBQWMsR0FBRyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUM7SUFDckMsTUFBTSx1QkFBdUIsR0FBRyxXQUFXLENBQUMsQ0FBQyxJQUFhLEVBQUUsRUFBRTtRQUM1RCxjQUFjLENBQUMsT0FBTyxHQUFHLElBQUksQ0FBQztJQUNoQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUM7SUFDUCxNQUFNLEtBQUssR0FBRyxvQkFBb0IsQ0FBQyxTQUF5QixDQUFDLENBQUM7SUFDOUQsSUFBSSxTQUFTLElBQUksS0FBSyxJQUFJLENBQUMsaUJBQWlCLENBQUMsS0FBSyxDQUFDLEVBQUUsQ0FBQztRQUNwRCxJQUFJLFVBQVUsRUFBRSxnQkFBZ0IsRUFBRSxDQUFDO1lBQ2pDLE9BQU8sQ0FDTCxLQUFDLFdBQVcsSUFDVixLQUFLLEVBQUUsS0FBSyxFQUNaLFdBQVcsRUFBRSxTQUFTLEtBQUssV0FBVyxJQUFJLGNBQWMsQ0FBQyxPQUFPLEVBQ2hFLFlBQVksRUFBRSx1QkFBdUIsWUFFckMsS0FBQyxtQkFBbUIsS0FBRyxHQUNYLENBQ2YsQ0FBQztRQUNKLENBQUM7UUFDRCxPQUFPLEtBQUMsV0FBVyxJQUFDLEtBQUssRUFBRSxLQUFLLEdBQUksQ0FBQztJQUN2QyxDQUFDO0lBRUQsTUFBTSxTQUFTLEdBQ2Isb0JBQW9CLENBQUMsU0FBOEMsQ0FBQyxDQUFDO0lBQ3ZFLElBQUksQ0FBQyxTQUFTLEVBQUUsQ0FBQztRQUNmLE9BQU8sSUFBSSxDQUFDO0lBQ2QsQ0FBQztJQUNELE1BQU0sWUFBWSxHQUFHLFNBQVMsQ0FBQyxLQUFLLEVBQUU7UUFDcEMsR0FBRyxPQUFPO1FBQ1YsV0FBVyxFQUFFLGNBQWMsQ0FBQyxPQUFPO1FBQ25DLG1CQUFtQixFQUFFLHVCQUF1QjtLQUM3QyxDQUFDLENBQUM7SUFDSCxJQUFJLENBQUMsWUFBWSxFQUFFLENBQUM7UUFDbEIsT0FBTyxJQUFJLENBQUM7SUFDZCxDQUFDO0lBRUQsSUFBSSxNQUFNLEVBQUUsQ0FBQztRQUNYLE9BQU8sQ0FDTCxlQUFLLFNBQVMsRUFBQywyQkFBMkIsYUFDeEMsZUFDRSxTQUFTLEVBQUMseUJBQXlCLEVBQ25DLEtBQUssRUFBRSxFQUFFLEtBQUssRUFBRSxvQkFBb0IsRUFBRSxZQUVyQyxTQUFTLEdBQ0wsRUFDUCxlQUFNLFNBQVMsRUFBQyxhQUFhLEVBQUMsS0FBSyxFQUFFLEVBQUUsS0FBSyxFQUFFLHFCQUFxQixFQUFFLFlBQ2xFLFlBQVksR0FDUixJQUNILENBQ1AsQ0FBQztJQUNKLENBQUM7SUFFRCxJQUFJLHNCQUFzQixDQUFDLEdBQUcsQ0FBQyxTQUFTLENBQUMsRUFBRSxDQUFDO1FBQzFDLE9BQU8sNEJBQUcsWUFBWSxHQUFJLENBQUM7SUFDN0IsQ0FBQztJQUVELE9BQU8sQ0FDTCxlQUFLLFNBQVMsRUFBQyxVQUFVLGFBQ3RCLE9BQU8sU0FBUyxLQUFLLFNBQVMsSUFBSSxTQUFTLElBQUksQ0FDOUMsY0FBSyxTQUFTLEVBQUMsd0JBQXdCLFlBQ3JDLGNBQ0UsU0FBUyxFQUFDLDhDQUE4QyxFQUN4RCxLQUFLLEVBQUUsRUFBRSxXQUFXLEVBQUUsb0JBQW9CLEVBQUUsR0FDNUMsR0FDRSxDQUNQLEVBQ0QsZUFBcUIsU0FBUyxFQUFDLDBCQUEwQixhQUN2RCxlQUFNLFNBQVMsRUFBQyxpRUFBaUUsWUFDOUUsU0FBUyxHQUNMLEVBQ1AsZUFBTSxTQUFTLEVBQUMsU0FBUyxFQUFDLEtBQUssRUFBRSxFQUFFLEtBQUssRUFBRSxxQkFBcUIsRUFBRSxZQUM5RCxZQUFZLEdBQ1IsS0FOQyxTQUFTLENBT2IsSUFDRixDQUNQLENBQUM7QUFDSixDQUFDLENBQUM7QUFFRixNQUFNLENBQUMsTUFBTSxjQUFjLEdBQUcsQ0FBQyxFQUM3QixJQUFJLEVBQ0osZUFBZSxFQUNmLGVBQWUsRUFDZixTQUFTLEVBQ1QsS0FBSyxFQUNMLFNBQVMsRUFDVCxhQUFhLEVBQ2IsVUFBVSxFQUNWLFNBQVMsRUFDVCxZQUFZLEdBQUcsS0FBSyxFQUNwQixRQUFRLEdBa0JULEVBQUUsRUFBRTtJQUNILGdFQUFnRTtJQUNoRSxNQUFNLFdBQVcsR0FBRyxPQUFPLENBQUMsR0FBRyxFQUFFO1FBQy9CLE1BQU0sTUFBTSxHQUFHLEVBQUUsR0FBRyxJQUFJLEVBQUUsQ0FBQztRQUMzQixNQUFNLE9BQU8sR0FBRyxJQUFJLENBQUMsZ0JBRVIsQ0FBQztRQUNkLElBQUksT0FBTyxFQUFFLG1CQUFtQixFQUFFLENBQUM7WUFDakMsTUFBTSxDQUFDLG1CQUFtQixHQUFHLE9BQU8sQ0FBQyxtQkFBbUIsQ0FBQztRQUMzRCxDQUFDO1FBQ0QsSUFBSSxlQUFlLEVBQUUsQ0FBQztZQUNwQixNQUFNLENBQUMsZUFBZSxHQUFHLGVBQWUsQ0FBQztRQUMzQyxDQUFDO2FBQU0sSUFBSSxPQUFPLElBQUksQ0FBQyxRQUFRLEtBQUssUUFBUSxFQUFFLENBQUM7WUFDN0MsTUFBTSxDQUFDLGVBQWUsR0FBRyxJQUFJLENBQUMsUUFBUSxDQUFDO1FBQ3pDLENBQUM7YUFBTSxJQUFJLE9BQU8sSUFBSSxDQUFDLFlBQVksS0FBSyxRQUFRLEVBQUUsQ0FBQztZQUNqRCxNQUFNLENBQUMsZUFBZSxHQUFHLElBQUksQ0FBQyxZQUFZLENBQUM7UUFDN0MsQ0FBQztRQUNELE9BQU8sTUFBTSxDQUFDO0lBQ2hCLENBQUMsRUFBRSxDQUFDLElBQUksRUFBRSxlQUFlLENBQUMsQ0FBQyxDQUFDO0lBQzVCLE1BQU0sVUFBVSxHQUFHLFNBQVMsSUFBSSxJQUFJLElBQUksSUFBSSxJQUFJLENBQUMsU0FBUyxDQUFDLEdBQUcsSUFBSSxJQUFJLEVBQUUsQ0FBQztJQUN6RSxNQUFNLGVBQWUsR0FBRyxNQUFNLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQztTQUM3QyxNQUFNLENBQUMsQ0FBQyxHQUFHLEVBQUUsRUFBRSxDQUFDLENBQUMsb0JBQW9CLENBQUMsUUFBUSxDQUFDLEdBQUcsQ0FBQyxDQUFDO1NBQ3BELElBQUksQ0FBQyxvQkFBb0IsQ0FBQyxDQUFDO0lBQzlCLE1BQU0sa0JBQWtCLEdBQUcsT0FBTyxDQUFDLEdBQUcsRUFBRTtRQUN0QyxNQUFNLE9BQU8sR0FBRyxNQUFNLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQzthQUNyQyxNQUFNLENBQUMsQ0FBQyxHQUFHLEVBQUUsRUFBRSxDQUFDLG9CQUFvQixDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQUMsQ0FBQzthQUNuRCxJQUFJLENBQUMsb0JBQW9CLENBQUMsQ0FBQztRQUU5QixJQUFJLENBQUMsU0FBUztZQUFFLE9BQU8sT0FBTyxDQUFDO1FBRS9CLElBQUksUUFBUSxLQUFLLE9BQU87WUFBRSxPQUFPLE9BQU8sQ0FBQztRQUV6QyxNQUFNLG1CQUFtQixHQUFHLENBQUMsT0FBTyxFQUFFLFFBQVEsQ0FBQyxDQUFDO1FBQ2hELEtBQUssTUFBTSxHQUFHLElBQUksbUJBQW1CLEVBQUUsQ0FBQztZQUN0QyxJQUFJLENBQUMsT0FBTyxDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDO2dCQUMzQixPQUFPLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDO1lBQ3BCLENBQUM7UUFDSCxDQUFDO1FBQ0QsT0FBTyxPQUFPLENBQUMsSUFBSSxDQUFDLG9CQUFvQixDQUFDLENBQUM7SUFDNUMsQ0FBQyxFQUFFLENBQUMsV0FBVyxFQUFFLFNBQVMsRUFBRSxRQUFRLENBQUMsQ0FBQyxDQUFDO0lBRXZDLHlDQUF5QztJQUN6QyxNQUFNLHNCQUFzQixHQUFHLGVBQWUsQ0FBQyxNQUFNLENBQUMsQ0FBQyxTQUFTLEVBQUUsRUFBRTtRQUNsRSxNQUFNLFNBQVMsR0FDYixvQkFBb0IsQ0FBQyxTQUE4QyxDQUFDLENBQUM7UUFDdkUsSUFBSSxDQUFDLFNBQVM7WUFBRSxPQUFPLEtBQUssQ0FBQztRQUM3QixNQUFNLFlBQVksR0FBRyxTQUFTLENBQzVCLFdBQVcsQ0FBQyxTQUFxQyxDQUFDLENBQ25ELENBQUM7UUFDRixPQUFPLFlBQVksS0FBSyxJQUFJLENBQUM7SUFDL0IsQ0FBQyxDQUFDLENBQUM7SUFFSCx5RUFBeUU7SUFDekUsTUFBTSxzQkFBc0IsR0FBRyxPQUFPLENBQUMsR0FBRyxFQUFFO1FBQzFDLE1BQU0sVUFBVSxHQUFHLENBQUMsR0FBRyxzQkFBc0IsQ0FBQyxDQUFDO1FBQy9DLE1BQU0sb0JBQW9CLEdBQUcsVUFBVSxDQUFDLE9BQU8sQ0FBQyxpQkFBaUIsQ0FBQyxDQUFDO1FBQ25FLElBQUksb0JBQW9CLEtBQUssQ0FBQyxDQUFDLEVBQUUsQ0FBQztZQUNoQyxPQUFPLFVBQVUsQ0FBQztRQUNwQixDQUFDO1FBRUQsVUFBVSxDQUFDLE1BQU0sQ0FBQyxvQkFBb0IsRUFBRSxDQUFDLENBQUMsQ0FBQztRQUMzQyxNQUFNLGlCQUFpQixHQUFHLFVBQVUsQ0FBQyxPQUFPLENBQUMsY0FBYyxDQUFDLENBQUM7UUFDN0QsSUFBSSxpQkFBaUIsS0FBSyxDQUFDLENBQUMsRUFBRSxDQUFDO1lBQzdCLFVBQVUsQ0FBQyxNQUFNLENBQUMsaUJBQWlCLEdBQUcsQ0FBQyxFQUFFLENBQUMsRUFBRSxpQkFBaUIsQ0FBQyxDQUFDO1lBQy9ELE9BQU8sVUFBVSxDQUFDO1FBQ3BCLENBQUM7UUFFRCxNQUFNLGFBQWEsR0FBRyxVQUFVLENBQUMsT0FBTyxDQUFDLFVBQVUsQ0FBQyxDQUFDO1FBQ3JELElBQUksYUFBYSxLQUFLLENBQUMsQ0FBQyxFQUFFLENBQUM7WUFDekIsVUFBVSxDQUFDLE1BQU0sQ0FBQyxhQUFhLEdBQUcsQ0FBQyxFQUFFLENBQUMsRUFBRSxpQkFBaUIsQ0FBQyxDQUFDO1lBQzNELE9BQU8sVUFBVSxDQUFDO1FBQ3BCLENBQUM7UUFFRCxVQUFVLENBQUMsT0FBTyxDQUFDLGlCQUFpQixDQUFDLENBQUM7UUFDdEMsT0FBTyxVQUFVLENBQUM7SUFDcEIsQ0FBQyxFQUFFLENBQUMsc0JBQXNCLENBQUMsQ0FBQyxDQUFDO0lBRTdCLGtFQUFrRTtJQUNsRSxNQUFNLGNBQWMsR0FBRyxPQUFPLENBQzVCLEdBQUcsRUFBRSxDQUFDLENBQUM7UUFDTCxRQUFRLEVBQUUsV0FBVyxDQUFDLFFBQThCO0tBQ3JELENBQUMsRUFDRixDQUFDLFdBQVcsQ0FBQyxRQUFRLENBQUMsQ0FDdkIsQ0FBQztJQUNGLE1BQU0sZUFBZSxHQUFHLFVBQVUsQ0FBQyxtQkFBbUIsQ0FBQyxDQUFDO0lBQ3hELE1BQU0sWUFBWSxHQUFHLFNBQVM7UUFDNUIsQ0FBQyxDQUFDO1lBQ0UsU0FBUztZQUNULFlBQVk7WUFDWixnQkFBZ0IsRUFBRSxlQUFlLEVBQUUsZ0JBQWdCO1NBQ3BEO1FBQ0gsQ0FBQyxDQUFDLGVBQWUsQ0FBQztJQUVwQixPQUFPLENBQ0wsS0FBQyxtQkFBbUIsY0FDbEIsS0FBQyxlQUFlLENBQUMsUUFBUSxJQUFDLEtBQUssRUFBRSxVQUFVLFlBQ3pDLEtBQUMsa0JBQWtCLENBQUMsUUFBUSxJQUFDLEtBQUssRUFBRSxhQUFhLFlBQy9DLE1BQUMsbUJBQW1CLENBQUMsUUFBUSxJQUFDLEtBQUssRUFBRSxZQUFZLGFBQzlDLHNCQUFzQixDQUFDLE1BQU0sR0FBRyxDQUFDLElBQUksQ0FDcEMsTUFBQyxlQUFlLElBQUMsV0FBVyxtQkFDMUIsS0FBQyxrQkFBa0IsMkJBQThCLEVBQ2pELEtBQUMsa0JBQWtCLElBQUMsU0FBUyxFQUFDLFdBQVcsWUFDdkMsZUFBSyxTQUFTLEVBQUMsZUFBZSxhQUMzQixzQkFBc0IsQ0FBQyxHQUFHLENBQUMsQ0FBQyxTQUFTLEVBQUUsRUFBRTtnREFDeEMsTUFBTSxZQUFZLEdBQUcsb0JBQW9CLENBQ3ZDLFNBQThDLENBQy9DLEVBQUUsQ0FBQyxXQUFXLENBQUMsU0FBcUMsQ0FBQyxDQUFDLENBQUM7Z0RBQ3hELE1BQU0sd0JBQXdCLEdBQzVCLHVCQUF1QixDQUFDLEdBQUcsQ0FDekIsU0FBeUIsQ0FDMUIsSUFBSSxPQUFPLFlBQVksS0FBSyxRQUFRLENBQUM7Z0RBQ3hDLE1BQU0sS0FBSyxHQUFHLHVCQUF1QixDQUFDLFNBQVMsQ0FBQyxDQUFDO2dEQUVqRCxPQUFPLENBQ0wsS0FBQyxxQkFBcUIsSUFFcEIsS0FBSyxFQUFFLEtBQUssRUFDWixLQUFLLEVBQUUsWUFBWSxFQUNuQixRQUFRLEVBQ04sd0JBQXdCLENBQUMsQ0FBQyxDQUFDLFlBQVksQ0FBQyxDQUFDLENBQUMsU0FBUyxFQUVyRCxJQUFJLEVBQ0YsU0FBUyxLQUFLLGlCQUFpQjt3REFDN0IsQ0FBQyxDQUFDLGVBQWU7d0RBQ2pCLENBQUMsQ0FBQyxTQUFTLElBVFYsU0FBUyxDQVdkLENBQ0gsQ0FBQzs0Q0FDSixDQUFDLENBQUMsRUFDRCxTQUFTO2dEQUNSLFFBQVEsS0FBSyxPQUFPO2dEQUNwQixDQUFDLFdBQVcsQ0FBQyxRQUFRLElBQUksQ0FDdkIsZUFBSyxTQUFTLEVBQUMsZ0RBQWdELGFBQzdELGVBQU0sU0FBUyxFQUFDLDZCQUE2Qix1QkFFdEMsRUFDUCxLQUFDLFFBQVEsSUFBQyxTQUFTLEVBQUMsYUFBYSxHQUFHLElBQ2hDLENBQ1AsSUFDQyxHQUNhLElBQ0wsQ0FDbkIsRUFDQSxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQ1AsS0FBQyxTQUFTLElBQ1IsS0FBSyxFQUFDLGlDQUFpQyxFQUN2QyxPQUFPLEVBQUUsS0FBSyxDQUFDLE9BQU8sRUFDdEIsU0FBUyxFQUFDLE1BQU0sR0FDaEIsQ0FDSCxDQUFDLENBQUMsQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDLENBQ2YsS0FBQyxrQkFBa0IsS0FBRyxDQUN2QixDQUFDLENBQUMsQ0FBQyxrQkFBa0IsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUNsQyxrQkFBa0IsQ0FBQyxHQUFHLENBQUMsQ0FBQyxTQUFTLEVBQUUsRUFBRSxDQUFDLENBQ3BDLEtBQUMsY0FBYyxJQUNiLFNBQVMsRUFBRSxTQUFTLEVBRXBCLFNBQVMsRUFBRSxTQUFTLEVBQ3BCLEtBQUssRUFBRSxXQUFXLENBQUMsU0FBcUMsQ0FBQyxFQUN6RCxPQUFPLEVBQUUsY0FBYyxJQUhsQixTQUFTLENBSWQsQ0FDSCxDQUFDLENBQ0gsQ0FBQyxDQUFDLENBQUMsSUFBSSxJQUNxQixHQUNILEdBQ0wsR0FDUCxDQUN2QixDQUFDO0FBQ0osQ0FBQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBjbGllbnQnO1xuXG5pbXBvcnQgeyBwYXJzZVN0ZXBOYW1lLCBwYXJzZVdvcmtmbG93TmFtZSB9IGZyb20gJ0B3b3JrZmxvdy91dGlscy9wYXJzZS1uYW1lJztcbmltcG9ydCB0eXBlIHsgRXZlbnQsIEhvb2ssIFN0ZXAsIFdvcmtmbG93UnVuIH0gZnJvbSAnQHdvcmtmbG93L3dvcmxkJztcbmltcG9ydCB0eXBlIHsgTW9kZWxNZXNzYWdlIH0gZnJvbSAnYWknO1xuaW1wb3J0IHsgZm9ybWF0IH0gZnJvbSAnZGF0ZS1mbnMnO1xuaW1wb3J0IHR5cGUgeyBLZXlib2FyZEV2ZW50LCBSZWFjdE5vZGUgfSBmcm9tICdyZWFjdCc7XG5pbXBvcnQgeyB1c2VDYWxsYmFjaywgdXNlQ29udGV4dCwgdXNlTWVtbywgdXNlUmVmLCB1c2VTdGF0ZSB9IGZyb20gJ3JlYWN0JztcbmltcG9ydCB7IGlzRW5jcnlwdGVkTWFya2VyLCBpc0V4cGlyZWRNYXJrZXIgfSBmcm9tICcuLi8uLi9saWIvaHlkcmF0aW9uJztcbmltcG9ydCB7IGV4dHJhY3RDb252ZXJzYXRpb24sIGlzRG9TdHJlYW1TdGVwIH0gZnJvbSAnLi4vLi4vbGliL3V0aWxzJztcbmltcG9ydCB7XG4gIENvbGxhcHNpYmxlLFxuICBDb2xsYXBzaWJsZUNvbnRlbnQsXG4gIENvbGxhcHNpYmxlUm9vdCxcbiAgQ29sbGFwc2libGVUcmlnZ2VyLFxufSBmcm9tICcuLi91aS9jb2xsYXBzaWJsZSc7XG5pbXBvcnQgeyBDb250ZXh0Q2FyZFByb3ZpZGVyIH0gZnJvbSAnLi4vdWkvY29udGV4dC1jYXJkJztcbmltcG9ydCB7XG4gIERlY3J5cHRDbGlja0NvbnRleHQsXG4gIFJ1bkNsaWNrQ29udGV4dCxcbiAgU3RyZWFtQ2xpY2tDb250ZXh0LFxufSBmcm9tICcuLi91aS9kYXRhLWluc3BlY3Rvcic7XG5pbXBvcnQgeyBFcnJvckNhcmQgfSBmcm9tICcuLi91aS9lcnJvci1jYXJkJztcbmltcG9ydCB7IEVycm9yU3RhY2tCbG9jaywgaXNTdHJ1Y3R1cmVkRXJyb3IgfSBmcm9tICcuLi91aS9lcnJvci1zdGFjay1ibG9jayc7XG5pbXBvcnQgeyBTa2VsZXRvbiB9IGZyb20gJy4uL3VpL3NrZWxldG9uJztcbmltcG9ydCB7IFRpbWVzdGFtcFRvb2x0aXAgfSBmcm9tICcuLi91aS90aW1lc3RhbXAtdG9vbHRpcCc7XG5pbXBvcnQge1xuICBEZXRhaWxNb25vS2V5VmFsdWVSb3csXG4gIFJ1bkF0dHJpYnV0ZXNDYXJkLFxuICBSdW5NZXRhZGF0YUNhcmQsXG59IGZyb20gJy4vYXR0cmlidXRlcy1ibG9jayc7XG5pbXBvcnQgeyBDb252ZXJzYXRpb25WaWV3IH0gZnJvbSAnLi9jb252ZXJzYXRpb24tdmlldyc7XG5pbXBvcnQgeyBDb3B5YWJsZURhdGFCbG9jaywgRW5jcnlwdGVkRGF0YUJsb2NrIH0gZnJvbSAnLi9jb3B5YWJsZS1kYXRhLWJsb2NrJztcblxuLyoqXG4gKiBUYWIgYnV0dG9uIGZvciBjb252ZXJzYXRpb24vSlNPTiB0b2dnbGVcbiAqL1xuZnVuY3Rpb24gVGFiQnV0dG9uKHtcbiAgYWN0aXZlLFxuICBvbkNsaWNrLFxuICBjaGlsZHJlbixcbn06IHtcbiAgYWN0aXZlOiBib29sZWFuO1xuICBvbkNsaWNrOiAoKSA9PiB2b2lkO1xuICBjaGlsZHJlbjogUmVhY3ROb2RlO1xufSkge1xuICByZXR1cm4gKFxuICAgIDxidXR0b25cbiAgICAgIHR5cGU9XCJidXR0b25cIlxuICAgICAgcm9sZT1cInRhYlwiXG4gICAgICBhcmlhLXNlbGVjdGVkPXthY3RpdmV9XG4gICAgICB0YWJJbmRleD17YWN0aXZlID8gMCA6IC0xfVxuICAgICAgb25DbGljaz17b25DbGlja31cbiAgICAgIGNsYXNzTmFtZT1cInB4LTMgcHktMS41IHRleHQtWzExcHhdIGZvbnQtbWVkaXVtIHRyYW5zaXRpb24tY29sb3JzIC1tYi1weFwiXG4gICAgICBzdHlsZT17e1xuICAgICAgICAvLyBFeHBsaWNpdCBzdHlsZXMgdG8gcHJldmVudCBhcHAtbGV2ZWwgYnV0dG9uIG92ZXJyaWRlcyB3aGVuIHdlYi1zaGFyZWRcbiAgICAgICAgLy8gaXMgZW1iZWRkZWQgaW4gYSBzZWxmLWhvc3RlZCBhcHAuXG4gICAgICAgIGJhY2tncm91bmRDb2xvcjogJ3RyYW5zcGFyZW50JyxcbiAgICAgICAgYm9yZGVyVG9wOiAnbm9uZScsXG4gICAgICAgIGJvcmRlckxlZnQ6ICdub25lJyxcbiAgICAgICAgYm9yZGVyUmlnaHQ6ICdub25lJyxcbiAgICAgICAgYm9yZGVyQm90dG9tOiBgMnB4IHNvbGlkICR7YWN0aXZlID8gJ3ZhcigtLWRzLWJsdWUtNjAwKScgOiAndHJhbnNwYXJlbnQnfWAsXG4gICAgICAgIGJvcmRlclJhZGl1czogMCxcbiAgICAgICAgb3V0bGluZTogJ25vbmUnLFxuICAgICAgICBib3hTaGFkb3c6ICdub25lJyxcbiAgICAgICAgY3Vyc29yOiAncG9pbnRlcicsXG4gICAgICAgIGNvbG9yOiBhY3RpdmUgPyAndmFyKC0tZHMtZ3JheS0xMDAwKScgOiAndmFyKC0tZHMtZ3JheS02MDApJyxcbiAgICAgIH19XG4gICAgPlxuICAgICAge2NoaWxkcmVufVxuICAgIDwvYnV0dG9uPlxuICApO1xufVxuXG4vKipcbiAqIFNoYXJlZCB0YWJiZWQgY29udGFpbmVyIHdpdGggYWNjZXNzaWJsZSBBUklBIHJvbGVzIGFuZCBrZXlib2FyZCBuYXZpZ2F0aW9uLlxuICogVXNlZCBieSBDb252ZXJzYXRpb25XaXRoVGFicyBmb3IgdGhlIGNvbnZlcnNhdGlvbi9KU09OIHRvZ2dsZS5cbiAqL1xuZnVuY3Rpb24gVGFiYmVkQ29udGFpbmVyPFQgZXh0ZW5kcyBzdHJpbmc+KHtcbiAgdGFicyxcbiAgYWN0aXZlVGFiLFxuICBvblRhYkNoYW5nZSxcbiAgYXJpYUxhYmVsLFxuICBjaGlsZHJlbixcbn06IHtcbiAgdGFiczogeyBpZDogVDsgbGFiZWw6IHN0cmluZyB9W107XG4gIGFjdGl2ZVRhYjogVDtcbiAgb25UYWJDaGFuZ2U6ICh0YWI6IFQpID0+IHZvaWQ7XG4gIGFyaWFMYWJlbDogc3RyaW5nO1xuICBjaGlsZHJlbjogUmVhY3ROb2RlO1xufSkge1xuICBjb25zdCBoYW5kbGVLZXlEb3duID0gdXNlQ2FsbGJhY2soXG4gICAgKGV2ZW50OiBLZXlib2FyZEV2ZW50PEhUTUxEaXZFbGVtZW50PikgPT4ge1xuICAgICAgaWYgKGV2ZW50LmtleSAhPT0gJ0Fycm93UmlnaHQnICYmIGV2ZW50LmtleSAhPT0gJ0Fycm93TGVmdCcpIHJldHVybjtcbiAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgICBjb25zdCBjdXJyZW50SW5kZXggPSB0YWJzLmZpbmRJbmRleCgodCkgPT4gdC5pZCA9PT0gYWN0aXZlVGFiKTtcbiAgICAgIGNvbnN0IG5leHRJbmRleCA9XG4gICAgICAgIGV2ZW50LmtleSA9PT0gJ0Fycm93UmlnaHQnXG4gICAgICAgICAgPyAoY3VycmVudEluZGV4ICsgMSkgJSB0YWJzLmxlbmd0aFxuICAgICAgICAgIDogKGN1cnJlbnRJbmRleCAtIDEgKyB0YWJzLmxlbmd0aCkgJSB0YWJzLmxlbmd0aDtcbiAgICAgIG9uVGFiQ2hhbmdlKHRhYnNbbmV4dEluZGV4XS5pZCk7XG4gICAgfSxcbiAgICBbdGFicywgYWN0aXZlVGFiLCBvblRhYkNoYW5nZV1cbiAgKTtcblxuICByZXR1cm4gKFxuICAgIDxkaXZcbiAgICAgIGNsYXNzTmFtZT1cInJvdW5kZWQtbWQgYm9yZGVyXCJcbiAgICAgIHN0eWxlPXt7XG4gICAgICAgIGJvcmRlckNvbG9yOiAndmFyKC0tZHMtZ3JheS0zMDApJyxcbiAgICAgICAgYmFja2dyb3VuZENvbG9yOiAndHJhbnNwYXJlbnQnLFxuICAgICAgfX1cbiAgICA+XG4gICAgICA8ZGl2XG4gICAgICAgIGNsYXNzTmFtZT1cImZsZXggZ2FwLTEgYm9yZGVyLWJcIlxuICAgICAgICByb2xlPVwidGFibGlzdFwiXG4gICAgICAgIGFyaWEtbGFiZWw9e2FyaWFMYWJlbH1cbiAgICAgICAgb25LZXlEb3duPXtoYW5kbGVLZXlEb3dufVxuICAgICAgICBzdHlsZT17e1xuICAgICAgICAgIGJvcmRlckNvbG9yOiAndmFyKC0tZHMtZ3JheS0zMDApJyxcbiAgICAgICAgICBiYWNrZ3JvdW5kQ29sb3I6ICd0cmFuc3BhcmVudCcsXG4gICAgICAgIH19XG4gICAgICA+XG4gICAgICAgIHt0YWJzLm1hcCgodGFiKSA9PiAoXG4gICAgICAgICAgPFRhYkJ1dHRvblxuICAgICAgICAgICAga2V5PXt0YWIuaWR9XG4gICAgICAgICAgICBhY3RpdmU9e2FjdGl2ZVRhYiA9PT0gdGFiLmlkfVxuICAgICAgICAgICAgb25DbGljaz17KCkgPT4gb25UYWJDaGFuZ2UodGFiLmlkKX1cbiAgICAgICAgICA+XG4gICAgICAgICAgICB7dGFiLmxhYmVsfVxuICAgICAgICAgIDwvVGFiQnV0dG9uPlxuICAgICAgICApKX1cbiAgICAgIDwvZGl2PlxuXG4gICAgICA8ZGl2IHJvbGU9XCJ0YWJwYW5lbFwiPntjaGlsZHJlbn08L2Rpdj5cbiAgICA8L2Rpdj5cbiAgKTtcbn1cblxuY29uc3QgY29udmVyc2F0aW9uVGFicyA9IFtcbiAgeyBpZDogJ2NvbnZlcnNhdGlvbicgYXMgY29uc3QsIGxhYmVsOiAnQ29udmVyc2F0aW9uJyB9LFxuICB7IGlkOiAnanNvbicgYXMgY29uc3QsIGxhYmVsOiAnUmF3IEpTT04nIH0sXG5dO1xuXG4vKipcbiAqIFRhYmJlZCB2aWV3IGZvciBjb252ZXJzYXRpb24gYW5kIHJhdyBKU09OXG4gKi9cbmZ1bmN0aW9uIENvbnZlcnNhdGlvbldpdGhUYWJzKHtcbiAgY29udmVyc2F0aW9uLFxuICBhcmdzLFxuICBkZWZhdWx0T3BlbixcbiAgb25PcGVuQ2hhbmdlLFxufToge1xuICBjb252ZXJzYXRpb246IE1vZGVsTWVzc2FnZVtdO1xuICBhcmdzOiB1bmtub3duW107XG4gIGRlZmF1bHRPcGVuPzogYm9vbGVhbjtcbiAgb25PcGVuQ2hhbmdlPzogKG9wZW46IGJvb2xlYW4pID0+IHZvaWQ7XG59KSB7XG4gIGNvbnN0IFthY3RpdmVUYWIsIHNldEFjdGl2ZVRhYl0gPSB1c2VTdGF0ZTwnY29udmVyc2F0aW9uJyB8ICdqc29uJz4oXG4gICAgJ2NvbnZlcnNhdGlvbidcbiAgKTtcblxuICByZXR1cm4gKFxuICAgIDxDb2xsYXBzaWJsZVxuICAgICAgbGFiZWw9XCJJbnB1dFwiXG4gICAgICBkZWZhdWx0T3Blbj17ZGVmYXVsdE9wZW59XG4gICAgICBvbk9wZW5DaGFuZ2U9e29uT3BlbkNoYW5nZX1cbiAgICA+XG4gICAgICA8VGFiYmVkQ29udGFpbmVyXG4gICAgICAgIHRhYnM9e2NvbnZlcnNhdGlvblRhYnN9XG4gICAgICAgIGFjdGl2ZVRhYj17YWN0aXZlVGFifVxuICAgICAgICBvblRhYkNoYW5nZT17c2V0QWN0aXZlVGFifVxuICAgICAgICBhcmlhTGFiZWw9XCJDb252ZXJzYXRpb24gdmlld1wiXG4gICAgICA+XG4gICAgICAgIHthY3RpdmVUYWIgPT09ICdjb252ZXJzYXRpb24nID8gKFxuICAgICAgICAgIDxDb252ZXJzYXRpb25WaWV3IG1lc3NhZ2VzPXtjb252ZXJzYXRpb259IC8+XG4gICAgICAgICkgOiAoXG4gICAgICAgICAgPGRpdiBjbGFzc05hbWU9XCJwLTNcIj5cbiAgICAgICAgICAgIHtBcnJheS5pc0FycmF5KGFyZ3MpXG4gICAgICAgICAgICAgID8gYXJncy5tYXAoKHYsIGkpID0+IChcbiAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3NOYW1lPVwibXQtMiBmaXJzdDptdC0wXCIga2V5PXtpfT5cbiAgICAgICAgICAgICAgICAgICAge0pzb25CbG9jayh2KX1cbiAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICkpXG4gICAgICAgICAgICAgIDogSnNvbkJsb2NrKGFyZ3MpfVxuICAgICAgICAgIDwvZGl2PlxuICAgICAgICApfVxuICAgICAgPC9UYWJiZWRDb250YWluZXI+XG4gICAgPC9Db2xsYXBzaWJsZT5cbiAgKTtcbn1cblxuLyoqXG4gKiBSZW5kZXIgYSB2YWx1ZSB3aXRoIHRoZSBzaGFyZWQgRGF0YUluc3BlY3RvciAoT2JqZWN0SW5zcGVjdG9yIHdpdGhcbiAqIGN1c3RvbSB0aGVtaW5nLCBub2RlUmVuZGVyZXIgZm9yIFN0cmVhbVJlZi9DbGFzc0luc3RhbmNlUmVmLCBldGMuKVxuICovXG5mdW5jdGlvbiBFbmNyeXB0ZWRGaWVsZEJsb2NrKCkge1xuICByZXR1cm4gPEVuY3J5cHRlZERhdGFCbG9jayAvPjtcbn1cblxuLyoqXG4gKiBJbmxpbmUgZGlzcGxheSBmb3IgYW4gZXhwaXJlZCBmaWVsZCDigJQgZmxhdCBsYWJlbCBpbmRpY2F0aW5nIGRhdGEgaXMgbm8gbG9uZ2VyIGF2YWlsYWJsZS5cbiAqL1xuZnVuY3Rpb24gRXhwaXJlZEZpZWxkQmxvY2soKSB7XG4gIHJldHVybiAoXG4gICAgPGRpdlxuICAgICAgY2xhc3NOYW1lPVwiZmxleCBpdGVtcy1jZW50ZXIgZ2FwLTEuNSByb3VuZGVkLW1kIGJvcmRlciBweC0zIHB5LTIgdGV4dC14c1wiXG4gICAgICBzdHlsZT17e1xuICAgICAgICBib3JkZXJDb2xvcjogJ3ZhcigtLWRzLWdyYXktMzAwKScsXG4gICAgICAgIGJhY2tncm91bmRDb2xvcjogJ3ZhcigtLWRzLWdyYXktMTAwKScsXG4gICAgICAgIGNvbG9yOiAndmFyKC0tZHMtZ3JheS03MDApJyxcbiAgICAgIH19XG4gICAgPlxuICAgICAgPHNwYW4gY2xhc3NOYW1lPVwiZm9udC1tZWRpdW1cIj5EYXRhIGV4cGlyZWQ8L3NwYW4+XG4gICAgPC9kaXY+XG4gICk7XG59XG5cbmZ1bmN0aW9uIEpzb25CbG9jayh2YWx1ZTogdW5rbm93bikge1xuICByZXR1cm4gPENvcHlhYmxlRGF0YUJsb2NrIGRhdGE9e3ZhbHVlfSAvPjtcbn1cblxuY29uc3QgaGFzRGlzcGxheUNvbnRlbnQgPSAodmFsdWU6IHVua25vd24pOiBib29sZWFuID0+IHtcbiAgaWYgKHZhbHVlID09IG51bGwpIHJldHVybiBmYWxzZTtcbiAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ3N0cmluZycpIHJldHVybiB2YWx1ZS50cmltKCkubGVuZ3RoID4gMDtcbiAgaWYgKEFycmF5LmlzQXJyYXkodmFsdWUpKSByZXR1cm4gdmFsdWUubGVuZ3RoID4gMDtcbiAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ29iamVjdCcpIHJldHVybiBPYmplY3Qua2V5cyh2YWx1ZSkubGVuZ3RoID4gMDtcbiAgcmV0dXJuIHRydWU7XG59O1xuXG50eXBlIEF0dHJpYnV0ZUtleSA9XG4gIHwga2V5b2YgU3RlcFxuICB8IGtleW9mIFdvcmtmbG93UnVuXG4gIHwga2V5b2YgSG9va1xuICB8IGtleW9mIEV2ZW50XG4gIHwgJ29jY3VycmVkQXQnXG4gIHwgJ21vZHVsZVNwZWNpZmllcidcbiAgfCAnZXZlbnREYXRhJ1xuICB8ICdyZXN1bWVBdCdcbiAgfCAnZXhwaXJlZEF0J1xuICB8ICd3b3JrZmxvd0NvcmVWZXJzaW9uJ1xuICB8ICdyZWNlaXZlZENvdW50J1xuICB8ICdsYXN0UmVjZWl2ZWRBdCdcbiAgfCAnZGlzcG9zZWRBdCdcbiAgfCAnaXNTeXN0ZW0nXG4gIHwgJ2Vycm9yQ29kZSc7XG5cbmNvbnN0IGF0dHJpYnV0ZU9yZGVyOiBBdHRyaWJ1dGVLZXlbXSA9IFtcbiAgJ3dvcmtmbG93TmFtZScsXG4gICdtb2R1bGVTcGVjaWZpZXInLFxuICAnc3RlcE5hbWUnLFxuICAnc3RhdHVzJyxcbiAgJ3N0ZXBJZCcsXG4gICdob29rSWQnLFxuICAnZXZlbnRJZCcsXG4gICdydW5JZCcsXG4gICdhdHRlbXB0JyxcbiAgJ3Rva2VuJyxcbiAgJ3JlY2VpdmVkQ291bnQnLFxuICAnbGFzdFJlY2VpdmVkQXQnLFxuICAnZGlzcG9zZWRBdCcsXG4gICdjb3JyZWxhdGlvbklkJyxcbiAgJ2V2ZW50VHlwZScsXG4gICdkZXBsb3ltZW50SWQnLFxuICAnc3BlY1ZlcnNpb24nLFxuICAnd29ya2Zsb3dDb3JlVmVyc2lvbicsXG4gICdvd25lcklkJyxcbiAgJ3Byb2plY3RJZCcsXG4gICdlbnZpcm9ubWVudCcsXG4gICdleGVjdXRpb25Db250ZXh0JyxcbiAgJ29jY3VycmVkQXQnLFxuICAnY3JlYXRlZEF0JyxcbiAgJ3N0YXJ0ZWRBdCcsXG4gICd1cGRhdGVkQXQnLFxuICAnY29tcGxldGVkQXQnLFxuICAnZXhwaXJlZEF0JyxcbiAgJ3JldHJ5QWZ0ZXInLFxuICAnZXJyb3InLFxuICAnbWV0YWRhdGEnLFxuICAnZXZlbnREYXRhJyxcbiAgJ2lucHV0JyxcbiAgJ291dHB1dCcsXG4gICdhdHRyaWJ1dGVzJyxcbiAgJ3Jlc3VtZUF0Jyxcbl07XG5cbmNvbnN0IHNvcnRCeUF0dHJpYnV0ZU9yZGVyID0gKGE6IHN0cmluZywgYjogc3RyaW5nKTogbnVtYmVyID0+IHtcbiAgY29uc3QgYUluZGV4ID0gYXR0cmlidXRlT3JkZXIuaW5kZXhPZihhIGFzIEF0dHJpYnV0ZUtleSkgfHwgMDtcbiAgY29uc3QgYkluZGV4ID0gYXR0cmlidXRlT3JkZXIuaW5kZXhPZihiIGFzIEF0dHJpYnV0ZUtleSkgfHwgMDtcbiAgcmV0dXJuIGFJbmRleCAtIGJJbmRleDtcbn07XG5cbi8qKlxuICogRGlzcGxheSBuYW1lcyBmb3IgYXR0cmlidXRlcyB0aGF0IHNob3VsZCByZW5kZXIgZGlmZmVyZW50bHkgZnJvbSB0aGVpciBrZXkuXG4gKi9cbmNvbnN0IGF0dHJpYnV0ZURpc3BsYXlOYW1lczogUGFydGlhbDxSZWNvcmQ8QXR0cmlidXRlS2V5LCBzdHJpbmc+PiA9IHtcbiAgbW9kdWxlU3BlY2lmaWVyOiAnTW9kdWxlJyxcbiAgd29ya2Zsb3dOYW1lOiAnV29ya2Zsb3cgTmFtZScsXG4gIHN0ZXBOYW1lOiAnU3RlcCBOYW1lJyxcbiAgc3RlcElkOiAnU3RlcCBJRCcsXG4gIGhvb2tJZDogJ0hvb2sgSUQnLFxuICBhdHRlbXB0OiAnQXR0ZW1wdHMnLFxuICBldmVudElkOiAnRXZlbnQgSUQnLFxuICBydW5JZDogJ1J1biBJRCcsXG4gIHRva2VuOiAnVG9rZW4nLFxuICBldmVudFR5cGU6ICdFdmVudCBUeXBlJyxcbiAgZXJyb3JDb2RlOiAnRXJyb3IgQ29kZScsXG4gIGNvcnJlbGF0aW9uSWQ6ICdDb3JyZWxhdGlvbiBJRCcsXG4gIGRlcGxveW1lbnRJZDogJ0RlcGxveW1lbnQgSUQnLFxuICBzcGVjVmVyc2lvbjogJ1NwZWMgVmVyc2lvbicsXG4gIHdvcmtmbG93Q29yZVZlcnNpb246ICdAd29ya2Zsb3cvY29yZSB2ZXJzaW9uJyxcbiAgb2NjdXJyZWRBdDogJ09jY3VycmVkJyxcbiAgY3JlYXRlZEF0OiAnQ3JlYXRlZCcsXG4gIHN0YXJ0ZWRBdDogJ1N0YXJ0ZWQnLFxuICB1cGRhdGVkQXQ6ICdVcGRhdGVkJyxcbiAgY29tcGxldGVkQXQ6ICdDb21wbGV0ZWQnLFxuICBleHBpcmVkQXQ6ICdFeHBpcmVkJyxcbiAgcmV0cnlBZnRlcjogJ1JldHJ5IEFmdGVyJyxcbiAgcmVzdW1lQXQ6ICdSZXN1bWUnLFxuICBsYXN0UmVjZWl2ZWRBdDogJ0xhc3QgUmVjZWl2ZWQnLFxuICBkaXNwb3NlZEF0OiAnRGlzcG9zZWQnLFxuICByZWNlaXZlZENvdW50OiAnVGltZXMgUmVzb2x2ZWQnLFxufTtcblxuLyoqXG4gKiBHZXQgdGhlIGRpc3BsYXkgbmFtZSBmb3IgYW4gYXR0cmlidXRlIGtleS5cbiAqL1xuY29uc3QgZ2V0QXR0cmlidXRlRGlzcGxheU5hbWUgPSAoYXR0cmlidXRlOiBzdHJpbmcpOiBzdHJpbmcgPT4ge1xuICByZXR1cm4gYXR0cmlidXRlRGlzcGxheU5hbWVzW2F0dHJpYnV0ZSBhcyBBdHRyaWJ1dGVLZXldID8/IGF0dHJpYnV0ZTtcbn07XG5cbmNvbnN0IGdldE1vZHVsZVNwZWNpZmllckZyb21OYW1lID0gKHZhbHVlOiB1bmtub3duKTogc3RyaW5nID0+IHtcbiAgY29uc3QgcmF3ID0gU3RyaW5nKHZhbHVlKTtcbiAgY29uc3QgcGFyc2VkU3RlcCA9IHBhcnNlU3RlcE5hbWUocmF3KTtcbiAgaWYgKHBhcnNlZFN0ZXApIHtcbiAgICByZXR1cm4gcGFyc2VkU3RlcC5tb2R1bGVTcGVjaWZpZXI7XG4gIH1cbiAgY29uc3QgcGFyc2VkV29ya2Zsb3cgPSBwYXJzZVdvcmtmbG93TmFtZShyYXcpO1xuICBpZiAocGFyc2VkV29ya2Zsb3cpIHtcbiAgICByZXR1cm4gcGFyc2VkV29ya2Zsb3cubW9kdWxlU3BlY2lmaWVyO1xuICB9XG4gIHJldHVybiByYXc7XG59O1xuXG5jb25zdCBwYXJzZURhdGVWYWx1ZSA9ICh2YWx1ZTogdW5rbm93bik6IERhdGUgfCBudWxsID0+IHtcbiAgaWYgKHZhbHVlID09IG51bGwpIHtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuICBpZiAodmFsdWUgaW5zdGFuY2VvZiBEYXRlKSB7XG4gICAgcmV0dXJuIE51bWJlci5pc05hTih2YWx1ZS5nZXRUaW1lKCkpID8gbnVsbCA6IHZhbHVlO1xuICB9XG4gIGlmICh0eXBlb2YgdmFsdWUgPT09ICdzdHJpbmcnICYmIHZhbHVlLnRyaW0oKS5sZW5ndGggPT09IDApIHtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIGNvbnN0IGRhdGUgPVxuICAgIHR5cGVvZiB2YWx1ZSA9PT0gJ251bWJlcicgPyBuZXcgRGF0ZSh2YWx1ZSkgOiBuZXcgRGF0ZShTdHJpbmcodmFsdWUpKTtcbiAgcmV0dXJuIE51bWJlci5pc05hTihkYXRlLmdldFRpbWUoKSkgPyBudWxsIDogZGF0ZTtcbn07XG5cbmNvbnN0IGZvcm1hdExvY2FsTWlsbGlzZWNvbmRUaW1lID0gKGRhdGU6IERhdGUpOiBzdHJpbmcgPT5cbiAgZm9ybWF0KGRhdGUsICdNTU0gZGQgSEg6bW06c3MuU1MgT08nKS50b1VwcGVyQ2FzZSgpO1xuXG5leHBvcnQgY29uc3QgbG9jYWxNaWxsaXNlY29uZFRpbWUgPSAodmFsdWU6IHVua25vd24pOiBzdHJpbmcgPT4ge1xuICBjb25zdCBkYXRlID0gcGFyc2VEYXRlVmFsdWUodmFsdWUpO1xuICBpZiAoIWRhdGUpIHtcbiAgICByZXR1cm4gJy0nO1xuICB9XG5cbiAgcmV0dXJuIGZvcm1hdExvY2FsTWlsbGlzZWNvbmRUaW1lKGRhdGUpO1xufTtcblxuY29uc3QgbG9jYWxNaWxsaXNlY29uZFRpbWVPck51bGwgPSAodmFsdWU6IHVua25vd24pOiBzdHJpbmcgfCBudWxsID0+IHtcbiAgY29uc3QgZGF0ZSA9IHBhcnNlRGF0ZVZhbHVlKHZhbHVlKTtcbiAgaWYgKCFkYXRlKSB7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cbiAgcmV0dXJuIGZvcm1hdExvY2FsTWlsbGlzZWNvbmRUaW1lKGRhdGUpO1xufTtcblxuY29uc3QgdGltZXN0YW1wV2l0aFRvb2x0aXBPck51bGwgPSAodmFsdWU6IHVua25vd24pOiBSZWFjdE5vZGUgfCBudWxsID0+IHtcbiAgY29uc3QgZGF0ZSA9IHBhcnNlRGF0ZVZhbHVlKHZhbHVlKTtcbiAgaWYgKCFkYXRlKSByZXR1cm4gbnVsbDtcbiAgcmV0dXJuIChcbiAgICA8VGltZXN0YW1wVG9vbHRpcCBkYXRlPXtkYXRlfT5cbiAgICAgIDxzcGFuPntmb3JtYXRMb2NhbE1pbGxpc2Vjb25kVGltZShkYXRlKX08L3NwYW4+XG4gICAgPC9UaW1lc3RhbXBUb29sdGlwPlxuICApO1xufTtcblxuaW50ZXJmYWNlIERpc3BsYXlDb250ZXh0IHtcbiAgc3RlcE5hbWU/OiBzdHJpbmc7XG4gIHNlY3Rpb25PcGVuPzogYm9vbGVhbjtcbiAgb25TZWN0aW9uT3BlbkNoYW5nZT86IChvcGVuOiBib29sZWFuKSA9PiB2b2lkO1xufVxuXG5jb25zdCBhdHRyaWJ1dGVUb0Rpc3BsYXlGbjogUmVjb3JkPFxuICBBdHRyaWJ1dGVLZXksXG4gICh2YWx1ZTogdW5rbm93biwgY29udGV4dD86IERpc3BsYXlDb250ZXh0KSA9PiBudWxsIHwgc3RyaW5nIHwgUmVhY3ROb2RlXG4+ID0ge1xuICAvLyBOYW1lcyB0aGF0IG5lZWQgcHJldHR5LXByaW50aW5nXG4gIHdvcmtmbG93TmFtZTogKF92YWx1ZTogdW5rbm93bikgPT4gbnVsbCxcbiAgbW9kdWxlU3BlY2lmaWVyOiAodmFsdWU6IHVua25vd24pID0+IGdldE1vZHVsZVNwZWNpZmllckZyb21OYW1lKHZhbHVlKSxcbiAgc3RlcE5hbWU6IChfdmFsdWU6IHVua25vd24pID0+IG51bGwsXG4gIC8vIElEc1xuICBydW5JZDogKF92YWx1ZTogdW5rbm93bikgPT4gbnVsbCxcbiAgc3RlcElkOiAodmFsdWU6IHVua25vd24pID0+IFN0cmluZyh2YWx1ZSksXG4gIGhvb2tJZDogKHZhbHVlOiB1bmtub3duKSA9PiBTdHJpbmcodmFsdWUpLFxuICBldmVudElkOiAodmFsdWU6IHVua25vd24pID0+IFN0cmluZyh2YWx1ZSksXG4gIC8vIFJ1bi9zdGVwIGRldGFpbHNcbiAgc3RhdHVzOiAoX3ZhbHVlOiB1bmtub3duKSA9PiBudWxsLFxuICBhdHRlbXB0OiAodmFsdWU6IHVua25vd24pID0+IFN0cmluZyh2YWx1ZSksXG4gIC8vIEhvb2sgZGV0YWlsc1xuICB0b2tlbjogKHZhbHVlOiB1bmtub3duKSA9PiBTdHJpbmcodmFsdWUpLFxuICBpc1dlYmhvb2s6ICh2YWx1ZTogdW5rbm93bikgPT4gU3RyaW5nKHZhbHVlKSxcbiAgaXNTeXN0ZW06ICh2YWx1ZTogdW5rbm93bikgPT4gU3RyaW5nKHZhbHVlKSxcbiAgcmVjZWl2ZWRDb3VudDogKHZhbHVlOiB1bmtub3duKSA9PiBTdHJpbmcodmFsdWUpLFxuICBsYXN0UmVjZWl2ZWRBdDogbG9jYWxNaWxsaXNlY29uZFRpbWVPck51bGwsXG4gIGRpc3Bvc2VkQXQ6IGxvY2FsTWlsbGlzZWNvbmRUaW1lT3JOdWxsLFxuICAvLyBFdmVudCBkZXRhaWxzXG4gIGV2ZW50VHlwZTogKHZhbHVlOiB1bmtub3duKSA9PiBTdHJpbmcodmFsdWUpLFxuICBjb3JyZWxhdGlvbklkOiAodmFsdWU6IHVua25vd24pID0+IFN0cmluZyh2YWx1ZSksXG4gIC8vIFByb2plY3QgZGV0YWlsc1xuICBkZXBsb3ltZW50SWQ6ICh2YWx1ZTogdW5rbm93bikgPT4gU3RyaW5nKHZhbHVlKSxcbiAgc3BlY1ZlcnNpb246ICh2YWx1ZTogdW5rbm93bikgPT4gU3RyaW5nKHZhbHVlKSxcbiAgd29ya2Zsb3dDb3JlVmVyc2lvbjogKHZhbHVlOiB1bmtub3duKSA9PiBTdHJpbmcodmFsdWUpLFxuICAvLyBUZW5hbmN5ICh3ZSBkb24ndCBzaG93IHRoZXNlKVxuICBvd25lcklkOiAoX3ZhbHVlOiB1bmtub3duKSA9PiBudWxsLFxuICBwcm9qZWN0SWQ6IChfdmFsdWU6IHVua25vd24pID0+IG51bGwsXG4gIGVudmlyb25tZW50OiAoX3ZhbHVlOiB1bmtub3duKSA9PiBudWxsLFxuICBleGVjdXRpb25Db250ZXh0OiAoX3ZhbHVlOiB1bmtub3duKSA9PiBudWxsLFxuICAvLyBBdHRyaWJ1dGVzIOKAlCBzdHJpbmctc3RyaW5nIG1ldGFkYXRhIGF0dGFjaGVkIHRvIHRoZSBydW4uXG4gIC8vIFJlbmRlcmVkIGFzIGtleS12YWx1ZSByb3dzIGluIGl0cyBvd24gY29sbGFwc2libGUgc2VjdGlvbjtcbiAgLy8gaWYgZW1wdHkvbWlzc2luZywgaGlkZGVuIGJ5IHRoZSBoYXNEaXNwbGF5Q29udGVudCBnYXRlLlxuICBhdHRyaWJ1dGVzOiAodmFsdWU6IHVua25vd24pID0+IHtcbiAgICBpZiAoIWhhc0Rpc3BsYXlDb250ZW50KHZhbHVlKSkgcmV0dXJuIG51bGw7XG4gICAgcmV0dXJuIDxSdW5BdHRyaWJ1dGVzQ2FyZCBhdHRyaWJ1dGVzPXt2YWx1ZSBhcyBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+fSAvPjtcbiAgfSxcbiAgLy8gRGF0ZXMg4oCUIHdyYXBwZWQgd2l0aCBUaW1lc3RhbXBUb29sdGlwIHNob3dpbmcgVVRDL2xvY2FsICsgcmVsYXRpdmUgdGltZVxuICBvY2N1cnJlZEF0OiB0aW1lc3RhbXBXaXRoVG9vbHRpcE9yTnVsbCxcbiAgY3JlYXRlZEF0OiB0aW1lc3RhbXBXaXRoVG9vbHRpcE9yTnVsbCxcbiAgc3RhcnRlZEF0OiB0aW1lc3RhbXBXaXRoVG9vbHRpcE9yTnVsbCxcbiAgdXBkYXRlZEF0OiAoX3ZhbHVlOiB1bmtub3duKSA9PiBudWxsLFxuICBjb21wbGV0ZWRBdDogdGltZXN0YW1wV2l0aFRvb2x0aXBPck51bGwsXG4gIGV4cGlyZWRBdDogKF92YWx1ZTogdW5rbm93bikgPT4gbnVsbCxcbiAgcmV0cnlBZnRlcjogdGltZXN0YW1wV2l0aFRvb2x0aXBPck51bGwsXG4gIHJlc3VtZUF0OiB0aW1lc3RhbXBXaXRoVG9vbHRpcE9yTnVsbCxcbiAgLy8gUmVzb2x2ZWQgYXR0cmlidXRlcywgd29uJ3QgYWN0dWFsbHkgdXNlIHRoaXMgZnVuY3Rpb25cbiAgbWV0YWRhdGE6ICh2YWx1ZTogdW5rbm93bikgPT4ge1xuICAgIGlmICghaGFzRGlzcGxheUNvbnRlbnQodmFsdWUpKSByZXR1cm4gbnVsbDtcbiAgICBpZiAoaXNFbmNyeXB0ZWRNYXJrZXIodmFsdWUpKSB7XG4gICAgICByZXR1cm4gKFxuICAgICAgICA8Q29sbGFwc2libGUgbGFiZWw9XCJNZXRhZGF0YVwiPlxuICAgICAgICAgIDxFbmNyeXB0ZWREYXRhQmxvY2sgLz5cbiAgICAgICAgPC9Db2xsYXBzaWJsZT5cbiAgICAgICk7XG4gICAgfVxuICAgIGlmIChpc0V4cGlyZWRNYXJrZXIodmFsdWUpKSB7XG4gICAgICByZXR1cm4gKFxuICAgICAgICA8Q29sbGFwc2libGUgbGFiZWw9XCJNZXRhZGF0YVwiPlxuICAgICAgICAgIDxFeHBpcmVkRmllbGRCbG9jayAvPlxuICAgICAgICA8L0NvbGxhcHNpYmxlPlxuICAgICAgKTtcbiAgICB9XG4gICAgcmV0dXJuIDxSdW5NZXRhZGF0YUNhcmQgbWV0YWRhdGE9e3ZhbHVlfSAvPjtcbiAgfSxcbiAgaW5wdXQ6ICh2YWx1ZTogdW5rbm93biwgY29udGV4dD86IERpc3BsYXlDb250ZXh0KSA9PiB7XG4gICAgaWYgKGlzRW5jcnlwdGVkTWFya2VyKHZhbHVlKSkge1xuICAgICAgcmV0dXJuIChcbiAgICAgICAgPENvbGxhcHNpYmxlXG4gICAgICAgICAgbGFiZWw9XCJJbnB1dFwiXG4gICAgICAgICAgZGVmYXVsdE9wZW49e2NvbnRleHQ/LnNlY3Rpb25PcGVufVxuICAgICAgICAgIG9uT3BlbkNoYW5nZT17Y29udGV4dD8ub25TZWN0aW9uT3BlbkNoYW5nZX1cbiAgICAgICAgPlxuICAgICAgICAgIDxFbmNyeXB0ZWRGaWVsZEJsb2NrIC8+XG4gICAgICAgIDwvQ29sbGFwc2libGU+XG4gICAgICApO1xuICAgIH1cbiAgICBpZiAoaXNFeHBpcmVkTWFya2VyKHZhbHVlKSkgcmV0dXJuIDxFeHBpcmVkRmllbGRCbG9jayAvPjtcbiAgICAvLyBDaGVjayBpZiBpbnB1dCBoYXMgYXJncyArIGNsb3N1cmUgdmFycyBzdHJ1Y3R1cmVcbiAgICBpZiAodmFsdWUgJiYgdHlwZW9mIHZhbHVlID09PSAnb2JqZWN0JyAmJiAnYXJncycgaW4gdmFsdWUpIHtcbiAgICAgIGNvbnN0IHsgYXJncywgY2xvc3VyZVZhcnMsIHRoaXNWYWwgfSA9IHZhbHVlIGFzIHtcbiAgICAgICAgYXJnczogdW5rbm93bltdO1xuICAgICAgICBjbG9zdXJlVmFycz86IFJlY29yZDxzdHJpbmcsIHVua25vd24+O1xuICAgICAgICB0aGlzVmFsPzogdW5rbm93bjtcbiAgICAgIH07XG4gICAgICBjb25zdCBoYXNDbG9zdXJlVmFycyA9IGhhc0Rpc3BsYXlDb250ZW50KGNsb3N1cmVWYXJzKTtcbiAgICAgIGNvbnN0IGhhc1RoaXNWYWwgPSBoYXNEaXNwbGF5Q29udGVudCh0aGlzVmFsKTtcbiAgICAgIGNvbnN0IGhhc0FyZ3MgPSBoYXNEaXNwbGF5Q29udGVudChhcmdzKTtcblxuICAgICAgLy8gQ2hlY2sgaWYgdGhpcyBpcyBhIGRvU3RyZWFtU3RlcCAtIHNob3cgY29udmVyc2F0aW9uIHZpZXcgd2l0aCB0YWJzXG4gICAgICBpZiAoY29udGV4dD8uc3RlcE5hbWUgJiYgaXNEb1N0cmVhbVN0ZXAoY29udGV4dC5zdGVwTmFtZSkpIHtcbiAgICAgICAgY29uc3QgY29udmVyc2F0aW9uID0gZXh0cmFjdENvbnZlcnNhdGlvbihhcmdzKTtcbiAgICAgICAgaWYgKGNvbnZlcnNhdGlvbiAmJiBjb252ZXJzYXRpb24ubGVuZ3RoID4gMCkge1xuICAgICAgICAgIHJldHVybiAoXG4gICAgICAgICAgICA8PlxuICAgICAgICAgICAgICA8Q29udmVyc2F0aW9uV2l0aFRhYnNcbiAgICAgICAgICAgICAgICBjb252ZXJzYXRpb249e2NvbnZlcnNhdGlvbn1cbiAgICAgICAgICAgICAgICBhcmdzPXthcmdzfVxuICAgICAgICAgICAgICAgIGRlZmF1bHRPcGVuPXtjb250ZXh0Py5zZWN0aW9uT3Blbn1cbiAgICAgICAgICAgICAgICBvbk9wZW5DaGFuZ2U9e2NvbnRleHQ/Lm9uU2VjdGlvbk9wZW5DaGFuZ2V9XG4gICAgICAgICAgICAgIC8+XG4gICAgICAgICAgICAgIHtoYXNDbG9zdXJlVmFycyAmJiAoXG4gICAgICAgICAgICAgICAgPENvbGxhcHNpYmxlIGxhYmVsPVwiQ2xvc3VyZSBWYXJpYWJsZXNcIj5cbiAgICAgICAgICAgICAgICAgIHtKc29uQmxvY2soY2xvc3VyZVZhcnMpfVxuICAgICAgICAgICAgICAgIDwvQ29sbGFwc2libGU+XG4gICAgICAgICAgICAgICl9XG4gICAgICAgICAgICAgIHtoYXNUaGlzVmFsICYmIChcbiAgICAgICAgICAgICAgICA8Q29sbGFwc2libGUgbGFiZWw9XCJUaGlzIFZhbHVlXCI+XG4gICAgICAgICAgICAgICAgICB7SnNvbkJsb2NrKHRoaXNWYWwpfVxuICAgICAgICAgICAgICAgIDwvQ29sbGFwc2libGU+XG4gICAgICAgICAgICAgICl9XG4gICAgICAgICAgICA8Lz5cbiAgICAgICAgICApO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIC8vIERvbid0IHJlbmRlciBhbiBlbXB0eSBcIklucHV0ICgwIGFyZ3VtZW50cylcIiBjYXJkIHdoZW4gbm8gaW5wdXQgZXhpc3RzLlxuICAgICAgaWYgKCFoYXNBcmdzICYmICFoYXNDbG9zdXJlVmFycyAmJiAhaGFzVGhpc1ZhbCkge1xuICAgICAgICByZXR1cm4gPENvbGxhcHNpYmxlIGxhYmVsPVwiSW5wdXQgKG5vIGRhdGEpXCIgZGlzYWJsZWQgLz47XG4gICAgICB9XG5cbiAgICAgIHJldHVybiAoXG4gICAgICAgIDw+XG4gICAgICAgICAgPENvbGxhcHNpYmxlXG4gICAgICAgICAgICBsYWJlbD1cIklucHV0XCJcbiAgICAgICAgICAgIGRlZmF1bHRPcGVuPXtjb250ZXh0Py5zZWN0aW9uT3Blbn1cbiAgICAgICAgICAgIG9uT3BlbkNoYW5nZT17Y29udGV4dD8ub25TZWN0aW9uT3BlbkNoYW5nZX1cbiAgICAgICAgICA+XG4gICAgICAgICAgICB7QXJyYXkuaXNBcnJheShhcmdzKVxuICAgICAgICAgICAgICA/IGFyZ3MubWFwKCh2LCBpKSA9PiAoXG4gICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzTmFtZT1cIm10LTIgZmlyc3Q6bXQtMFwiIGtleT17aX0+XG4gICAgICAgICAgICAgICAgICAgIHtKc29uQmxvY2sodil9XG4gICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICApKVxuICAgICAgICAgICAgICA6IEpzb25CbG9jayhhcmdzKX1cbiAgICAgICAgICA8L0NvbGxhcHNpYmxlPlxuICAgICAgICAgIHtoYXNDbG9zdXJlVmFycyAmJiAoXG4gICAgICAgICAgICA8Q29sbGFwc2libGUgbGFiZWw9XCJDbG9zdXJlIFZhcmlhYmxlc1wiPlxuICAgICAgICAgICAgICB7SnNvbkJsb2NrKGNsb3N1cmVWYXJzKX1cbiAgICAgICAgICAgIDwvQ29sbGFwc2libGU+XG4gICAgICAgICAgKX1cbiAgICAgICAgICB7aGFzVGhpc1ZhbCAmJiAoXG4gICAgICAgICAgICA8Q29sbGFwc2libGUgbGFiZWw9XCJDb250ZXh0XCI+e0pzb25CbG9jayh0aGlzVmFsKX08L0NvbGxhcHNpYmxlPlxuICAgICAgICAgICl9XG4gICAgICAgIDwvPlxuICAgICAgKTtcbiAgICB9XG5cbiAgICAvLyBGYWxsYmFjazogdHJlYXQgYXMgcGxhaW4gYXJyYXkgb3Igb2JqZWN0XG4gICAgaWYgKCFoYXNEaXNwbGF5Q29udGVudCh2YWx1ZSkpIHtcbiAgICAgIHJldHVybiA8Q29sbGFwc2libGUgbGFiZWw9XCJJbnB1dCAobm8gZGF0YSlcIiBkaXNhYmxlZCAvPjtcbiAgICB9XG4gICAgcmV0dXJuIChcbiAgICAgIDxDb2xsYXBzaWJsZVxuICAgICAgICBsYWJlbD1cIklucHV0XCJcbiAgICAgICAgZGVmYXVsdE9wZW49e2NvbnRleHQ/LnNlY3Rpb25PcGVufVxuICAgICAgICBvbk9wZW5DaGFuZ2U9e2NvbnRleHQ/Lm9uU2VjdGlvbk9wZW5DaGFuZ2V9XG4gICAgICA+XG4gICAgICAgIHtBcnJheS5pc0FycmF5KHZhbHVlKVxuICAgICAgICAgID8gdmFsdWUubWFwKCh2LCBpKSA9PiAoXG4gICAgICAgICAgICAgIDxkaXYgY2xhc3NOYW1lPVwibXQtMiBmaXJzdDptdC0wXCIga2V5PXtpfT5cbiAgICAgICAgICAgICAgICB7SnNvbkJsb2NrKHYpfVxuICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICkpXG4gICAgICAgICAgOiBKc29uQmxvY2sodmFsdWUpfVxuICAgICAgPC9Db2xsYXBzaWJsZT5cbiAgICApO1xuICB9LFxuICBvdXRwdXQ6ICh2YWx1ZTogdW5rbm93biwgY29udGV4dD86IERpc3BsYXlDb250ZXh0KSA9PiB7XG4gICAgaWYgKGlzRW5jcnlwdGVkTWFya2VyKHZhbHVlKSkge1xuICAgICAgcmV0dXJuIChcbiAgICAgICAgPENvbGxhcHNpYmxlXG4gICAgICAgICAgbGFiZWw9XCJPdXRwdXRcIlxuICAgICAgICAgIGRlZmF1bHRPcGVuPXtjb250ZXh0Py5zZWN0aW9uT3Blbn1cbiAgICAgICAgICBvbk9wZW5DaGFuZ2U9e2NvbnRleHQ/Lm9uU2VjdGlvbk9wZW5DaGFuZ2V9XG4gICAgICAgID5cbiAgICAgICAgICA8RW5jcnlwdGVkRmllbGRCbG9jayAvPlxuICAgICAgICA8L0NvbGxhcHNpYmxlPlxuICAgICAgKTtcbiAgICB9XG4gICAgaWYgKCFoYXNEaXNwbGF5Q29udGVudCh2YWx1ZSkpIHJldHVybiBudWxsO1xuICAgIGlmIChpc0V4cGlyZWRNYXJrZXIodmFsdWUpKSByZXR1cm4gPEV4cGlyZWRGaWVsZEJsb2NrIC8+O1xuICAgIHJldHVybiAoXG4gICAgICA8Q29sbGFwc2libGVcbiAgICAgICAgbGFiZWw9XCJPdXRwdXRcIlxuICAgICAgICBkZWZhdWx0T3Blbj17Y29udGV4dD8uc2VjdGlvbk9wZW59XG4gICAgICAgIG9uT3BlbkNoYW5nZT17Y29udGV4dD8ub25TZWN0aW9uT3BlbkNoYW5nZX1cbiAgICAgID5cbiAgICAgICAge0pzb25CbG9jayh2YWx1ZSl9XG4gICAgICA8L0NvbGxhcHNpYmxlPlxuICAgICk7XG4gIH0sXG4gIGVycm9yOiAodmFsdWU6IHVua25vd24pID0+IHtcbiAgICBpZiAoaXNFbmNyeXB0ZWRNYXJrZXIodmFsdWUpKSB7XG4gICAgICByZXR1cm4gKFxuICAgICAgICA8Q29sbGFwc2libGUgbGFiZWw9XCJFcnJvclwiIGRlZmF1bHRPcGVuPlxuICAgICAgICAgIDxFbmNyeXB0ZWRGaWVsZEJsb2NrIC8+XG4gICAgICAgIDwvQ29sbGFwc2libGU+XG4gICAgICApO1xuICAgIH1cbiAgICBpZiAoaXNFeHBpcmVkTWFya2VyKHZhbHVlKSkgcmV0dXJuIDxFeHBpcmVkRmllbGRCbG9jayAvPjtcbiAgICBpZiAoIWhhc0Rpc3BsYXlDb250ZW50KHZhbHVlKSkgcmV0dXJuIG51bGw7XG5cbiAgICAvLyBTdHJ1Y3R1cmVkIHdvcmtmbG93IGVycm9ycyBtYXkgYmUgcGVyc2lzdGVkIGFzIGVpdGhlciBgeyBtZXNzYWdlIH1gIG9yXG4gICAgLy8gYHsgbWVzc2FnZSwgc3RhY2sgfWAuIFJlbmRlciBib3RoIHdpdGggdGhlIGRlZGljYXRlZCBlcnJvciBibG9jay5cbiAgICBpZiAoaXNTdHJ1Y3R1cmVkRXJyb3IodmFsdWUpKSB7XG4gICAgICByZXR1cm4gKFxuICAgICAgICA8Q29sbGFwc2libGUgbGFiZWw9XCJFcnJvclwiIGRlZmF1bHRPcGVuPlxuICAgICAgICAgIDxFcnJvclN0YWNrQmxvY2sgdmFsdWU9e3ZhbHVlfSAvPlxuICAgICAgICA8L0NvbGxhcHNpYmxlPlxuICAgICAgKTtcbiAgICB9XG5cbiAgICByZXR1cm4gKFxuICAgICAgPENvbGxhcHNpYmxlIGxhYmVsPVwiRXJyb3JcIiBkZWZhdWx0T3Blbj5cbiAgICAgICAge0pzb25CbG9jayh2YWx1ZSl9XG4gICAgICA8L0NvbGxhcHNpYmxlPlxuICAgICk7XG4gIH0sXG4gIGV2ZW50RGF0YTogKHZhbHVlOiB1bmtub3duKSA9PiB7XG4gICAgaWYgKGlzRW5jcnlwdGVkTWFya2VyKHZhbHVlKSkge1xuICAgICAgcmV0dXJuIChcbiAgICAgICAgPENvbGxhcHNpYmxlIGxhYmVsPVwiRXZlbnQgRGF0YVwiIGRlZmF1bHRPcGVuPlxuICAgICAgICAgIDxFbmNyeXB0ZWRGaWVsZEJsb2NrIC8+XG4gICAgICAgIDwvQ29sbGFwc2libGU+XG4gICAgICApO1xuICAgIH1cbiAgICBpZiAoaXNFeHBpcmVkTWFya2VyKHZhbHVlKSkgcmV0dXJuIDxFeHBpcmVkRmllbGRCbG9jayAvPjtcbiAgICBpZiAoIWhhc0Rpc3BsYXlDb250ZW50KHZhbHVlKSkgcmV0dXJuIG51bGw7XG4gICAgcmV0dXJuIChcbiAgICAgIDxDb2xsYXBzaWJsZSBsYWJlbD1cIkV2ZW50IERhdGFcIiBkZWZhdWx0T3Blbj5cbiAgICAgICAge0pzb25CbG9jayh2YWx1ZSl9XG4gICAgICA8L0NvbGxhcHNpYmxlPlxuICAgICk7XG4gIH0sXG4gIGVycm9yQ29kZTogKHZhbHVlOiB1bmtub3duKSA9PiB7XG4gICAgaWYgKHR5cGVvZiB2YWx1ZSAhPT0gJ3N0cmluZycgfHwgdmFsdWUubGVuZ3RoID09PSAwKSByZXR1cm4gbnVsbDtcbiAgICByZXR1cm4gU3RyaW5nKHZhbHVlKTtcbiAgfSxcbn07XG5cbmNvbnN0IHJlc29sdmFibGVBdHRyaWJ1dGVzID0gW1xuICAnaW5wdXQnLFxuICAnb3V0cHV0JyxcbiAgJ2Vycm9yJyxcbiAgJ21ldGFkYXRhJyxcbiAgJ2F0dHJpYnV0ZXMnLFxuICAnZXZlbnREYXRhJyxcbl07XG5cbi8vIEF0dHJpYnV0ZXMgd2hvc2UgZGlzcGxheUZuIHJlbmRlcnMgaXRzIG93biBzZWN0aW9uIGhlYWRlciB2aWEgQ29sbGFwc2libGUsXG4vLyBzbyB0aGUgb3V0ZXIgQXR0cmlidXRlQmxvY2sgc2hvdWxkIG5vdCBkdXBsaWNhdGUgdGhlIGxhYmVsLlxuY29uc3Qgc2VsZkhlYWRlcmVkQXR0cmlidXRlcyA9IG5ldyBTZXQoW1xuICAnaW5wdXQnLFxuICAnb3V0cHV0JyxcbiAgJ2Vycm9yJyxcbiAgJ21ldGFkYXRhJyxcbiAgJ2F0dHJpYnV0ZXMnLFxuICAnZXZlbnREYXRhJyxcbl0pO1xuXG5jb25zdCBFeHBpcmVkRGF0YU1lc3NhZ2UgPSAoKSA9PiAoXG4gIDxkaXZcbiAgICBjbGFzc05hbWU9XCJ0ZXh0LWNvcHktMTIgcm91bmRlZC1tZCBib3JkZXIgcC00IG15LTJcIlxuICAgIHN0eWxlPXt7XG4gICAgICBib3JkZXJDb2xvcjogJ3ZhcigtLWRzLWdyYXktMzAwKScsXG4gICAgICBiYWNrZ3JvdW5kQ29sb3I6ICd2YXIoLS1kcy1ncmF5LTEwMCknLFxuICAgICAgY29sb3I6ICd2YXIoLS1kcy1ncmF5LTcwMCknLFxuICAgIH19XG4gID5cbiAgICA8c3Bhbj5UaGUgZGF0YSBmb3IgdGhpcyBydW4gaGFzIGV4cGlyZWQgYW5kIGlzIG5vIGxvbmdlciBhdmFpbGFibGUuPC9zcGFuPlxuICA8L2Rpdj5cbik7XG5cbmNvbnN0IGNvcHlhYmxlQmFzaWNBdHRyaWJ1dGVzID0gbmV3IFNldDxBdHRyaWJ1dGVLZXk+KFtcbiAgJ3N0ZXBJZCcsXG4gICdob29rSWQnLFxuICAnZXZlbnRJZCcsXG4gICdkZXBsb3ltZW50SWQnLFxuICAnbW9kdWxlU3BlY2lmaWVyJyxcbl0pO1xuXG5jb25zdCBsb2FkaW5nU2VjdGlvbkxhYmVsczogUGFydGlhbDxSZWNvcmQ8QXR0cmlidXRlS2V5LCBzdHJpbmc+PiA9IHtcbiAgaW5wdXQ6ICdJbnB1dCcsXG4gIG91dHB1dDogJ091dHB1dCcsXG4gIGV2ZW50RGF0YTogJ0V2ZW50IERhdGEnLFxufTtcblxuZXhwb3J0IGNvbnN0IEF0dHJpYnV0ZUJsb2NrID0gKHtcbiAgYXR0cmlidXRlLFxuICB2YWx1ZSxcbiAgaXNMb2FkaW5nLFxuICBpbmxpbmUgPSBmYWxzZSxcbiAgY29udGV4dCxcbn06IHtcbiAgYXR0cmlidXRlOiBzdHJpbmc7XG4gIHZhbHVlOiB1bmtub3duO1xuICBpc0xvYWRpbmc/OiBib29sZWFuO1xuICBpbmxpbmU/OiBib29sZWFuO1xuICBjb250ZXh0PzogRGlzcGxheUNvbnRleHQ7XG59KSA9PiB7XG4gIGNvbnN0IGRlY3J5cHRDdHggPSB1c2VDb250ZXh0KERlY3J5cHRDbGlja0NvbnRleHQpO1xuICBjb25zdCBzZWN0aW9uT3BlblJlZiA9IHVzZVJlZihmYWxzZSk7XG4gIGNvbnN0IGhhbmRsZVNlY3Rpb25PcGVuQ2hhbmdlID0gdXNlQ2FsbGJhY2soKG9wZW46IGJvb2xlYW4pID0+IHtcbiAgICBzZWN0aW9uT3BlblJlZi5jdXJyZW50ID0gb3BlbjtcbiAgfSwgW10pO1xuICBjb25zdCBsYWJlbCA9IGxvYWRpbmdTZWN0aW9uTGFiZWxzW2F0dHJpYnV0ZSBhcyBBdHRyaWJ1dGVLZXldO1xuICBpZiAoaXNMb2FkaW5nICYmIGxhYmVsICYmICFoYXNEaXNwbGF5Q29udGVudCh2YWx1ZSkpIHtcbiAgICBpZiAoZGVjcnlwdEN0eD8uaGFzRW5jcnlwdGVkRGF0YSkge1xuICAgICAgcmV0dXJuIChcbiAgICAgICAgPENvbGxhcHNpYmxlXG4gICAgICAgICAgbGFiZWw9e2xhYmVsfVxuICAgICAgICAgIGRlZmF1bHRPcGVuPXthdHRyaWJ1dGUgPT09ICdldmVudERhdGEnIHx8IHNlY3Rpb25PcGVuUmVmLmN1cnJlbnR9XG4gICAgICAgICAgb25PcGVuQ2hhbmdlPXtoYW5kbGVTZWN0aW9uT3BlbkNoYW5nZX1cbiAgICAgICAgPlxuICAgICAgICAgIDxFbmNyeXB0ZWRGaWVsZEJsb2NrIC8+XG4gICAgICAgIDwvQ29sbGFwc2libGU+XG4gICAgICApO1xuICAgIH1cbiAgICByZXR1cm4gPENvbGxhcHNpYmxlIGxhYmVsPXtsYWJlbH0gLz47XG4gIH1cblxuICBjb25zdCBkaXNwbGF5Rm4gPVxuICAgIGF0dHJpYnV0ZVRvRGlzcGxheUZuW2F0dHJpYnV0ZSBhcyBrZXlvZiB0eXBlb2YgYXR0cmlidXRlVG9EaXNwbGF5Rm5dO1xuICBpZiAoIWRpc3BsYXlGbikge1xuICAgIHJldHVybiBudWxsO1xuICB9XG4gIGNvbnN0IGRpc3BsYXlWYWx1ZSA9IGRpc3BsYXlGbih2YWx1ZSwge1xuICAgIC4uLmNvbnRleHQsXG4gICAgc2VjdGlvbk9wZW46IHNlY3Rpb25PcGVuUmVmLmN1cnJlbnQsXG4gICAgb25TZWN0aW9uT3BlbkNoYW5nZTogaGFuZGxlU2VjdGlvbk9wZW5DaGFuZ2UsXG4gIH0pO1xuICBpZiAoIWRpc3BsYXlWYWx1ZSkge1xuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgaWYgKGlubGluZSkge1xuICAgIHJldHVybiAoXG4gICAgICA8ZGl2IGNsYXNzTmFtZT1cImZsZXggaXRlbXMtY2VudGVyIGdhcC0xLjVcIj5cbiAgICAgICAgPHNwYW5cbiAgICAgICAgICBjbGFzc05hbWU9XCJ0ZXh0LVsxMXB4XSBmb250LW1lZGl1bVwiXG4gICAgICAgICAgc3R5bGU9e3sgY29sb3I6ICd2YXIoLS1kcy1ncmF5LTcwMCknIH19XG4gICAgICAgID5cbiAgICAgICAgICB7YXR0cmlidXRlfVxuICAgICAgICA8L3NwYW4+XG4gICAgICAgIDxzcGFuIGNsYXNzTmFtZT1cInRleHQtWzExcHhdXCIgc3R5bGU9e3sgY29sb3I6ICd2YXIoLS1kcy1ncmF5LTEwMDApJyB9fT5cbiAgICAgICAgICB7ZGlzcGxheVZhbHVlfVxuICAgICAgICA8L3NwYW4+XG4gICAgICA8L2Rpdj5cbiAgICApO1xuICB9XG5cbiAgaWYgKHNlbGZIZWFkZXJlZEF0dHJpYnV0ZXMuaGFzKGF0dHJpYnV0ZSkpIHtcbiAgICByZXR1cm4gPD57ZGlzcGxheVZhbHVlfTwvPjtcbiAgfVxuXG4gIHJldHVybiAoXG4gICAgPGRpdiBjbGFzc05hbWU9XCJyZWxhdGl2ZVwiPlxuICAgICAge3R5cGVvZiBpc0xvYWRpbmcgPT09ICdib29sZWFuJyAmJiBpc0xvYWRpbmcgJiYgKFxuICAgICAgICA8ZGl2IGNsYXNzTmFtZT1cImFic29sdXRlIHRvcC05IHJpZ2h0LTRcIj5cbiAgICAgICAgICA8ZGl2XG4gICAgICAgICAgICBjbGFzc05hbWU9XCJhbmltYXRlLXNwaW4gcm91bmRlZC1mdWxsIGgtNCB3LTQgYm9yZGVyLWItMlwiXG4gICAgICAgICAgICBzdHlsZT17eyBib3JkZXJDb2xvcjogJ3ZhcigtLWRzLWdyYXktOTAwKScgfX1cbiAgICAgICAgICAvPlxuICAgICAgICA8L2Rpdj5cbiAgICAgICl9XG4gICAgICA8ZGl2IGtleT17YXR0cmlidXRlfSBjbGFzc05hbWU9XCJteS0yIGZsZXggZmxleC1jb2wgZ2FwLTBcIj5cbiAgICAgICAgPHNwYW4gY2xhc3NOYW1lPVwidGV4dC1sYWJlbC0xNCB0ZXh0LWdyYXktMTAwMCBmb250LW1lZGl1bSBmaXJzdC1sZXR0ZXI6dXBwZXJjYXNlXCI+XG4gICAgICAgICAge2F0dHJpYnV0ZX1cbiAgICAgICAgPC9zcGFuPlxuICAgICAgICA8c3BhbiBjbGFzc05hbWU9XCJ0ZXh0LXhzXCIgc3R5bGU9e3sgY29sb3I6ICd2YXIoLS1kcy1ncmF5LTEwMDApJyB9fT5cbiAgICAgICAgICB7ZGlzcGxheVZhbHVlfVxuICAgICAgICA8L3NwYW4+XG4gICAgICA8L2Rpdj5cbiAgICA8L2Rpdj5cbiAgKTtcbn07XG5cbmV4cG9ydCBjb25zdCBBdHRyaWJ1dGVQYW5lbCA9ICh7XG4gIGRhdGEsXG4gIG1vZHVsZVNwZWNpZmllcixcbiAgbW9kdWxlU291cmNlVXJsLFxuICBpc0xvYWRpbmcsXG4gIGVycm9yLFxuICBleHBpcmVkQXQsXG4gIG9uU3RyZWFtQ2xpY2ssXG4gIG9uUnVuQ2xpY2ssXG4gIG9uRGVjcnlwdCxcbiAgaXNEZWNyeXB0aW5nID0gZmFsc2UsXG4gIHJlc291cmNlLFxufToge1xuICBkYXRhOiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPjtcbiAgbW9kdWxlU3BlY2lmaWVyPzogc3RyaW5nO1xuICBtb2R1bGVTb3VyY2VVcmw/OiBzdHJpbmc7XG4gIGlzTG9hZGluZz86IGJvb2xlYW47XG4gIGVycm9yPzogRXJyb3I7XG4gIGV4cGlyZWRBdD86IHN0cmluZyB8IERhdGU7XG4gIC8qKiBDYWxsYmFjayB3aGVuIGEgc3RyZWFtIHJlZmVyZW5jZSBpcyBjbGlja2VkICovXG4gIG9uU3RyZWFtQ2xpY2s/OiAoc3RyZWFtSWQ6IHN0cmluZykgPT4gdm9pZDtcbiAgLyoqIENhbGxiYWNrIHdoZW4gYSBydW4gcmVmZXJlbmNlIGlzIGNsaWNrZWQgKi9cbiAgb25SdW5DbGljaz86IChydW5JZDogc3RyaW5nKSA9PiB2b2lkO1xuICAvKiogQ2FsbGJhY2sgd2hlbiBhbiBlbmNyeXB0ZWQgbWFya2VyIGlzIGNsaWNrZWQgKHRyaWdnZXJzIGRlY3J5cHRpb24pICovXG4gIG9uRGVjcnlwdD86ICgpID0+IHZvaWQ7XG4gIC8qKiBXaGV0aGVyIGRlY3J5cHRpb24gaXMgY3VycmVudGx5IGluIHByb2dyZXNzICovXG4gIGlzRGVjcnlwdGluZz86IGJvb2xlYW47XG4gIC8qKiBSZXNvdXJjZSB0eXBlIG9mIHRoZSBzZWxlY3RlZCBzcGFuIOKAlCB1c2VkIHRvIHNob3cgdGFyZ2V0ZWQgbG9hZGluZyBza2VsZXRvbnMuICovXG4gIHJlc291cmNlPzogc3RyaW5nO1xufSkgPT4ge1xuICAvLyBFeHRyYWN0IHdvcmtmbG93Q29yZVZlcnNpb24gZnJvbSBleGVjdXRpb25Db250ZXh0IGZvciBkaXNwbGF5XG4gIGNvbnN0IGRpc3BsYXlEYXRhID0gdXNlTWVtbygoKSA9PiB7XG4gICAgY29uc3QgcmVzdWx0ID0geyAuLi5kYXRhIH07XG4gICAgY29uc3QgZXhlY0N0eCA9IGRhdGEuZXhlY3V0aW9uQ29udGV4dCBhc1xuICAgICAgfCBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPlxuICAgICAgfCB1bmRlZmluZWQ7XG4gICAgaWYgKGV4ZWNDdHg/LndvcmtmbG93Q29yZVZlcnNpb24pIHtcbiAgICAgIHJlc3VsdC53b3JrZmxvd0NvcmVWZXJzaW9uID0gZXhlY0N0eC53b3JrZmxvd0NvcmVWZXJzaW9uO1xuICAgIH1cbiAgICBpZiAobW9kdWxlU3BlY2lmaWVyKSB7XG4gICAgICByZXN1bHQubW9kdWxlU3BlY2lmaWVyID0gbW9kdWxlU3BlY2lmaWVyO1xuICAgIH0gZWxzZSBpZiAodHlwZW9mIGRhdGEuc3RlcE5hbWUgPT09ICdzdHJpbmcnKSB7XG4gICAgICByZXN1bHQubW9kdWxlU3BlY2lmaWVyID0gZGF0YS5zdGVwTmFtZTtcbiAgICB9IGVsc2UgaWYgKHR5cGVvZiBkYXRhLndvcmtmbG93TmFtZSA9PT0gJ3N0cmluZycpIHtcbiAgICAgIHJlc3VsdC5tb2R1bGVTcGVjaWZpZXIgPSBkYXRhLndvcmtmbG93TmFtZTtcbiAgICB9XG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfSwgW2RhdGEsIG1vZHVsZVNwZWNpZmllcl0pO1xuICBjb25zdCBoYXNFeHBpcmVkID0gZXhwaXJlZEF0ICE9IG51bGwgJiYgbmV3IERhdGUoZXhwaXJlZEF0KSA8IG5ldyBEYXRlKCk7XG4gIGNvbnN0IGJhc2ljQXR0cmlidXRlcyA9IE9iamVjdC5rZXlzKGRpc3BsYXlEYXRhKVxuICAgIC5maWx0ZXIoKGtleSkgPT4gIXJlc29sdmFibGVBdHRyaWJ1dGVzLmluY2x1ZGVzKGtleSkpXG4gICAgLnNvcnQoc29ydEJ5QXR0cmlidXRlT3JkZXIpO1xuICBjb25zdCByZXNvbHZlZEF0dHJpYnV0ZXMgPSB1c2VNZW1vKCgpID0+IHtcbiAgICBjb25zdCBwcmVzZW50ID0gT2JqZWN0LmtleXMoZGlzcGxheURhdGEpXG4gICAgICAuZmlsdGVyKChrZXkpID0+IHJlc29sdmFibGVBdHRyaWJ1dGVzLmluY2x1ZGVzKGtleSkpXG4gICAgICAuc29ydChzb3J0QnlBdHRyaWJ1dGVPcmRlcik7XG5cbiAgICBpZiAoIWlzTG9hZGluZykgcmV0dXJuIHByZXNlbnQ7XG5cbiAgICBpZiAocmVzb3VyY2UgPT09ICdzbGVlcCcpIHJldHVybiBwcmVzZW50O1xuXG4gICAgY29uc3QgbG9hZGluZ1BsYWNlaG9sZGVycyA9IFsnaW5wdXQnLCAnb3V0cHV0J107XG4gICAgZm9yIChjb25zdCBrZXkgb2YgbG9hZGluZ1BsYWNlaG9sZGVycykge1xuICAgICAgaWYgKCFwcmVzZW50LmluY2x1ZGVzKGtleSkpIHtcbiAgICAgICAgcHJlc2VudC5wdXNoKGtleSk7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBwcmVzZW50LnNvcnQoc29ydEJ5QXR0cmlidXRlT3JkZXIpO1xuICB9LCBbZGlzcGxheURhdGEsIGlzTG9hZGluZywgcmVzb3VyY2VdKTtcblxuICAvLyBGaWx0ZXIgb3V0IGF0dHJpYnV0ZXMgdGhhdCByZXR1cm4gbnVsbFxuICBjb25zdCB2aXNpYmxlQmFzaWNBdHRyaWJ1dGVzID0gYmFzaWNBdHRyaWJ1dGVzLmZpbHRlcigoYXR0cmlidXRlKSA9PiB7XG4gICAgY29uc3QgZGlzcGxheUZuID1cbiAgICAgIGF0dHJpYnV0ZVRvRGlzcGxheUZuW2F0dHJpYnV0ZSBhcyBrZXlvZiB0eXBlb2YgYXR0cmlidXRlVG9EaXNwbGF5Rm5dO1xuICAgIGlmICghZGlzcGxheUZuKSByZXR1cm4gZmFsc2U7XG4gICAgY29uc3QgZGlzcGxheVZhbHVlID0gZGlzcGxheUZuKFxuICAgICAgZGlzcGxheURhdGFbYXR0cmlidXRlIGFzIGtleW9mIHR5cGVvZiBkaXNwbGF5RGF0YV1cbiAgICApO1xuICAgIHJldHVybiBkaXNwbGF5VmFsdWUgIT09IG51bGw7XG4gIH0pO1xuXG4gIC8vIEtlZXAgYG1vZHVsZVNwZWNpZmllcmAgaW1tZWRpYXRlbHkgYWZ0ZXIgYHdvcmtmbG93TmFtZWAgb3IgYHN0ZXBOYW1lYC5cbiAgY29uc3Qgb3JkZXJlZEJhc2ljQXR0cmlidXRlcyA9IHVzZU1lbW8oKCkgPT4ge1xuICAgIGNvbnN0IGF0dHJpYnV0ZXMgPSBbLi4udmlzaWJsZUJhc2ljQXR0cmlidXRlc107XG4gICAgY29uc3QgbW9kdWxlU3BlY2lmaWVySW5kZXggPSBhdHRyaWJ1dGVzLmluZGV4T2YoJ21vZHVsZVNwZWNpZmllcicpO1xuICAgIGlmIChtb2R1bGVTcGVjaWZpZXJJbmRleCA9PT0gLTEpIHtcbiAgICAgIHJldHVybiBhdHRyaWJ1dGVzO1xuICAgIH1cblxuICAgIGF0dHJpYnV0ZXMuc3BsaWNlKG1vZHVsZVNwZWNpZmllckluZGV4LCAxKTtcbiAgICBjb25zdCB3b3JrZmxvd05hbWVJbmRleCA9IGF0dHJpYnV0ZXMuaW5kZXhPZignd29ya2Zsb3dOYW1lJyk7XG4gICAgaWYgKHdvcmtmbG93TmFtZUluZGV4ICE9PSAtMSkge1xuICAgICAgYXR0cmlidXRlcy5zcGxpY2Uod29ya2Zsb3dOYW1lSW5kZXggKyAxLCAwLCAnbW9kdWxlU3BlY2lmaWVyJyk7XG4gICAgICByZXR1cm4gYXR0cmlidXRlcztcbiAgICB9XG5cbiAgICBjb25zdCBzdGVwTmFtZUluZGV4ID0gYXR0cmlidXRlcy5pbmRleE9mKCdzdGVwTmFtZScpO1xuICAgIGlmIChzdGVwTmFtZUluZGV4ICE9PSAtMSkge1xuICAgICAgYXR0cmlidXRlcy5zcGxpY2Uoc3RlcE5hbWVJbmRleCArIDEsIDAsICdtb2R1bGVTcGVjaWZpZXInKTtcbiAgICAgIHJldHVybiBhdHRyaWJ1dGVzO1xuICAgIH1cblxuICAgIGF0dHJpYnV0ZXMudW5zaGlmdCgnbW9kdWxlU3BlY2lmaWVyJyk7XG4gICAgcmV0dXJuIGF0dHJpYnV0ZXM7XG4gIH0sIFt2aXNpYmxlQmFzaWNBdHRyaWJ1dGVzXSk7XG5cbiAgLy8gTWVtb2l6ZSBjb250ZXh0IG9iamVjdCB0byBhdm9pZCBvYmplY3QgcmVjb25zdHJ1Y3Rpb24gb24gcmVuZGVyXG4gIGNvbnN0IGRpc3BsYXlDb250ZXh0ID0gdXNlTWVtbyhcbiAgICAoKSA9PiAoe1xuICAgICAgc3RlcE5hbWU6IGRpc3BsYXlEYXRhLnN0ZXBOYW1lIGFzIHN0cmluZyB8IHVuZGVmaW5lZCxcbiAgICB9KSxcbiAgICBbZGlzcGxheURhdGEuc3RlcE5hbWVdXG4gICk7XG4gIGNvbnN0IG91dGVyRGVjcnlwdEN0eCA9IHVzZUNvbnRleHQoRGVjcnlwdENsaWNrQ29udGV4dCk7XG4gIGNvbnN0IGRlY3J5cHRWYWx1ZSA9IG9uRGVjcnlwdFxuICAgID8ge1xuICAgICAgICBvbkRlY3J5cHQsXG4gICAgICAgIGlzRGVjcnlwdGluZyxcbiAgICAgICAgaGFzRW5jcnlwdGVkRGF0YTogb3V0ZXJEZWNyeXB0Q3R4Py5oYXNFbmNyeXB0ZWREYXRhLFxuICAgICAgfVxuICAgIDogb3V0ZXJEZWNyeXB0Q3R4O1xuXG4gIHJldHVybiAoXG4gICAgPENvbnRleHRDYXJkUHJvdmlkZXI+XG4gICAgICA8UnVuQ2xpY2tDb250ZXh0LlByb3ZpZGVyIHZhbHVlPXtvblJ1bkNsaWNrfT5cbiAgICAgICAgPFN0cmVhbUNsaWNrQ29udGV4dC5Qcm92aWRlciB2YWx1ZT17b25TdHJlYW1DbGlja30+XG4gICAgICAgICAgPERlY3J5cHRDbGlja0NvbnRleHQuUHJvdmlkZXIgdmFsdWU9e2RlY3J5cHRWYWx1ZX0+XG4gICAgICAgICAgICB7dmlzaWJsZUJhc2ljQXR0cmlidXRlcy5sZW5ndGggPiAwICYmIChcbiAgICAgICAgICAgICAgPENvbGxhcHNpYmxlUm9vdCBkZWZhdWx0T3Blbj5cbiAgICAgICAgICAgICAgICA8Q29sbGFwc2libGVUcmlnZ2VyPk1ldGFkYXRhPC9Db2xsYXBzaWJsZVRyaWdnZXI+XG4gICAgICAgICAgICAgICAgPENvbGxhcHNpYmxlQ29udGVudCBjbGFzc05hbWU9XCJtdC0wIG1iLTJcIj5cbiAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3NOYW1lPVwiZmxleCBmbGV4LWNvbFwiPlxuICAgICAgICAgICAgICAgICAgICB7b3JkZXJlZEJhc2ljQXR0cmlidXRlcy5tYXAoKGF0dHJpYnV0ZSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGRpc3BsYXlWYWx1ZSA9IGF0dHJpYnV0ZVRvRGlzcGxheUZuW1xuICAgICAgICAgICAgICAgICAgICAgICAgYXR0cmlidXRlIGFzIGtleW9mIHR5cGVvZiBhdHRyaWJ1dGVUb0Rpc3BsYXlGblxuICAgICAgICAgICAgICAgICAgICAgIF0/LihkaXNwbGF5RGF0YVthdHRyaWJ1dGUgYXMga2V5b2YgdHlwZW9mIGRpc3BsYXlEYXRhXSk7XG4gICAgICAgICAgICAgICAgICAgICAgY29uc3QgaXNDb3B5YWJsZUJhc2ljQXR0cmlidXRlID1cbiAgICAgICAgICAgICAgICAgICAgICAgIGNvcHlhYmxlQmFzaWNBdHRyaWJ1dGVzLmhhcyhcbiAgICAgICAgICAgICAgICAgICAgICAgICAgYXR0cmlidXRlIGFzIEF0dHJpYnV0ZUtleVxuICAgICAgICAgICAgICAgICAgICAgICAgKSAmJiB0eXBlb2YgZGlzcGxheVZhbHVlID09PSAnc3RyaW5nJztcbiAgICAgICAgICAgICAgICAgICAgICBjb25zdCBsYWJlbCA9IGdldEF0dHJpYnV0ZURpc3BsYXlOYW1lKGF0dHJpYnV0ZSk7XG5cbiAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gKFxuICAgICAgICAgICAgICAgICAgICAgICAgPERldGFpbE1vbm9LZXlWYWx1ZVJvd1xuICAgICAgICAgICAgICAgICAgICAgICAgICBrZXk9e2F0dHJpYnV0ZX1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgbGFiZWw9e2xhYmVsfVxuICAgICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZT17ZGlzcGxheVZhbHVlfVxuICAgICAgICAgICAgICAgICAgICAgICAgICBjb3B5VGV4dD17XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaXNDb3B5YWJsZUJhc2ljQXR0cmlidXRlID8gZGlzcGxheVZhbHVlIDogdW5kZWZpbmVkXG4gICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgaHJlZj17XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYXR0cmlidXRlID09PSAnbW9kdWxlU3BlY2lmaWVyJ1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPyBtb2R1bGVTb3VyY2VVcmxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDogdW5kZWZpbmVkXG4gICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIC8+XG4gICAgICAgICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICAgICAgfSl9XG4gICAgICAgICAgICAgICAgICAgIHtpc0xvYWRpbmcgJiZcbiAgICAgICAgICAgICAgICAgICAgICByZXNvdXJjZSA9PT0gJ3NsZWVwJyAmJlxuICAgICAgICAgICAgICAgICAgICAgICFkaXNwbGF5RGF0YS5yZXN1bWVBdCAmJiAoXG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzTmFtZT1cImZsZXggaXRlbXMtY2VudGVyIGp1c3RpZnktYmV0d2VlbiBnYXAtMyBweS0wLjVcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3NOYW1lPVwidGV4dC1sYWJlbC0xMyB0ZXh0LWdyYXktOTAwXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgUmVzdW1lXG4gICAgICAgICAgICAgICAgICAgICAgICAgIDwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgPFNrZWxldG9uIGNsYXNzTmFtZT1cImgtNCB3LVs1NSVdXCIgLz5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICl9XG4gICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICA8L0NvbGxhcHNpYmxlQ29udGVudD5cbiAgICAgICAgICAgICAgPC9Db2xsYXBzaWJsZVJvb3Q+XG4gICAgICAgICAgICApfVxuICAgICAgICAgICAge2Vycm9yID8gKFxuICAgICAgICAgICAgICA8RXJyb3JDYXJkXG4gICAgICAgICAgICAgICAgdGl0bGU9XCJGYWlsZWQgdG8gbG9hZCByZXNvdXJjZSBkZXRhaWxzXCJcbiAgICAgICAgICAgICAgICBkZXRhaWxzPXtlcnJvci5tZXNzYWdlfVxuICAgICAgICAgICAgICAgIGNsYXNzTmFtZT1cIm15LTRcIlxuICAgICAgICAgICAgICAvPlxuICAgICAgICAgICAgKSA6IGhhc0V4cGlyZWQgPyAoXG4gICAgICAgICAgICAgIDxFeHBpcmVkRGF0YU1lc3NhZ2UgLz5cbiAgICAgICAgICAgICkgOiByZXNvbHZlZEF0dHJpYnV0ZXMubGVuZ3RoID4gMCA/IChcbiAgICAgICAgICAgICAgcmVzb2x2ZWRBdHRyaWJ1dGVzLm1hcCgoYXR0cmlidXRlKSA9PiAoXG4gICAgICAgICAgICAgICAgPEF0dHJpYnV0ZUJsb2NrXG4gICAgICAgICAgICAgICAgICBpc0xvYWRpbmc9e2lzTG9hZGluZ31cbiAgICAgICAgICAgICAgICAgIGtleT17YXR0cmlidXRlfVxuICAgICAgICAgICAgICAgICAgYXR0cmlidXRlPXthdHRyaWJ1dGV9XG4gICAgICAgICAgICAgICAgICB2YWx1ZT17ZGlzcGxheURhdGFbYXR0cmlidXRlIGFzIGtleW9mIHR5cGVvZiBkaXNwbGF5RGF0YV19XG4gICAgICAgICAgICAgICAgICBjb250ZXh0PXtkaXNwbGF5Q29udGV4dH1cbiAgICAgICAgICAgICAgICAvPlxuICAgICAgICAgICAgICApKVxuICAgICAgICAgICAgKSA6IG51bGx9XG4gICAgICAgICAgPC9EZWNyeXB0Q2xpY2tDb250ZXh0LlByb3ZpZGVyPlxuICAgICAgICA8L1N0cmVhbUNsaWNrQ29udGV4dC5Qcm92aWRlcj5cbiAgICAgIDwvUnVuQ2xpY2tDb250ZXh0LlByb3ZpZGVyPlxuICAgIDwvQ29udGV4dENhcmRQcm92aWRlcj5cbiAgKTtcbn07XG4iXX0=