@rivet-health/design-system 40.44.0 → 40.44.2

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 (321) hide show
  1. package/{esm2020 → esm2022}/lib/accessibility/sr-only/sr-only.component.mjs +4 -4
  2. package/esm2022/lib/download/download.service.mjs +47 -0
  3. package/{esm2020 → esm2022}/lib/format/pipes/common.mjs +5 -5
  4. package/{esm2020 → esm2022}/lib/format/pipes/date.pipe.mjs +4 -4
  5. package/{esm2020 → esm2022}/lib/format/pipes/days.pipe.mjs +4 -4
  6. package/{esm2020 → esm2022}/lib/format/pipes/dollars.pipe.mjs +4 -4
  7. package/{esm2020 → esm2022}/lib/format/pipes/number.pipe.mjs +4 -4
  8. package/{esm2020 → esm2022}/lib/format/pipes/percentage.pipe.mjs +4 -4
  9. package/esm2022/lib/format/pipes/sentence-case.pipe.mjs +61 -0
  10. package/esm2022/lib/format/pipes/small-currency.pipe.mjs +24 -0
  11. package/esm2022/lib/format/pipes/small-number.pipe.mjs +29 -0
  12. package/esm2022/lib/format/svg-text-truncate/svg-text-truncate.directive.mjs +62 -0
  13. package/esm2022/lib/format/truncate/truncate.component.mjs +51 -0
  14. package/esm2022/lib/icon/dom-cache.mjs +32 -0
  15. package/esm2022/lib/icon/icon.component.mjs +86 -0
  16. package/{esm2020 → esm2022}/lib/icon/icons.mjs +1 -1
  17. package/{esm2020 → esm2022}/lib/input/alphabetic-field/alphabetic-field.component.mjs +4 -4
  18. package/esm2022/lib/input/auto-focus/auto-focus.directive.mjs +48 -0
  19. package/esm2022/lib/input/button/button.component.mjs +139 -0
  20. package/esm2022/lib/input/button-group/button-group.component.mjs +39 -0
  21. package/{esm2020 → esm2022}/lib/input/calendar/calendar.component.mjs +4 -4
  22. package/{esm2020 → esm2022}/lib/input/card-checkbox/card-checkbox.component.mjs +4 -4
  23. package/{esm2020 → esm2022}/lib/input/checkbox/checkbox.component.mjs +4 -4
  24. package/{esm2020 → esm2022}/lib/input/currency-field/currency-field.component.mjs +4 -4
  25. package/esm2022/lib/input/date/date.component.mjs +279 -0
  26. package/esm2022/lib/input/date-range/date-range.component.mjs +477 -0
  27. package/esm2022/lib/input/filter-chip/filter-chip.component.mjs +47 -0
  28. package/{esm2020 → esm2022}/lib/input/filter-dropdown/filter-dropdown.component.mjs +5 -5
  29. package/{esm2020 → esm2022}/lib/input/input-label/input-label.component.mjs +4 -4
  30. package/esm2022/lib/input/mentions-input/mentions-input.component.mjs +745 -0
  31. package/esm2022/lib/input/number-field/number-field.component.mjs +125 -0
  32. package/{esm2020 → esm2022}/lib/input/percentage-field/percentage-field.component.mjs +4 -4
  33. package/esm2022/lib/input/phone-field/phone-field.component.mjs +74 -0
  34. package/{esm2020 → esm2022}/lib/input/radio/radio.component.mjs +4 -4
  35. package/{esm2020 → esm2022}/lib/input/search/search.component.mjs +4 -4
  36. package/esm2022/lib/input/search-select/search-select.component.mjs +189 -0
  37. package/esm2022/lib/input/select/select/select.component.mjs +178 -0
  38. package/{esm2020 → esm2022}/lib/input/select/select-node/select-node.component.mjs +4 -4
  39. package/esm2022/lib/input/select/state.mjs +882 -0
  40. package/{esm2020 → esm2022}/lib/input/simple-select/option-group.pipe.mjs +4 -4
  41. package/esm2022/lib/input/simple-select/simple-select.component.mjs +178 -0
  42. package/esm2022/lib/input/switch-checkbox/switch-checkbox.component.mjs +33 -0
  43. package/esm2022/lib/input/text-field/text-field.component.mjs +115 -0
  44. package/{esm2020 → esm2022}/lib/input/textarea-field/textarea-field.component.mjs +4 -4
  45. package/{esm2020 → esm2022}/lib/input/validation-message/validation-message.component.mjs +4 -4
  46. package/{esm2020 → esm2022}/lib/layout/card/card-actions.component.mjs +4 -4
  47. package/esm2022/lib/layout/card/card-content.component.mjs +64 -0
  48. package/esm2022/lib/layout/card/card-header.component.mjs +201 -0
  49. package/{esm2020 → esm2022}/lib/layout/card/card-link.component.mjs +5 -5
  50. package/{esm2020 → esm2022}/lib/layout/card/card-media.component.mjs +4 -4
  51. package/esm2022/lib/layout/card/card.component.mjs +291 -0
  52. package/{esm2020 → esm2022}/lib/layout/setting-row/setting-row.component.mjs +4 -4
  53. package/esm2022/lib/load/loading/loading.component.mjs +43 -0
  54. package/{esm2020 → esm2022}/lib/load/loading-cover/loading-cover.component.mjs +4 -4
  55. package/esm2022/lib/navigation/editable-heading/editable-heading.component.mjs +243 -0
  56. package/{esm2020 → esm2022}/lib/navigation/link/link.component.mjs +6 -6
  57. package/{esm2020 → esm2022}/lib/navigation/page-header/page-header.component.mjs +4 -4
  58. package/{esm2020 → esm2022}/lib/navigation/simple-tabs/simple-tab/simple-tab.component.mjs +4 -4
  59. package/{esm2020 → esm2022}/lib/navigation/simple-tabs/simple-tabs/simple-tabs.component.mjs +4 -4
  60. package/{esm2020 → esm2022}/lib/navigation/tabs/tab/tab.component.mjs +4 -4
  61. package/{esm2020 → esm2022}/lib/navigation/tabs/tabs/tabs.component.mjs +4 -4
  62. package/{esm2020 → esm2022}/lib/navigation/views/all-views-modal/all-views-modal.component.mjs +4 -4
  63. package/{esm2020 → esm2022}/lib/navigation/views/edit-view/edit-view.component.mjs +9 -9
  64. package/esm2022/lib/navigation/views/permission-picker/permission-picker.component.mjs +151 -0
  65. package/esm2022/lib/navigation/views/state.mjs +456 -0
  66. package/{esm2020 → esm2022}/lib/navigation/views/view-menu/view-menu.component.mjs +5 -5
  67. package/esm2022/lib/navigation/views/views/views.component.mjs +90 -0
  68. package/{esm2020 → esm2022}/lib/notification/badge/badge.component.mjs +4 -4
  69. package/esm2022/lib/notification/banner/banner-action.component.mjs +48 -0
  70. package/esm2022/lib/notification/banner/banner.component.mjs +61 -0
  71. package/esm2022/lib/notification/map-indicator/map-indicator.component.mjs +50 -0
  72. package/esm2022/lib/notification/map-indicator/map-indicators.mjs +15 -0
  73. package/{esm2020 → esm2022}/lib/notification/notification-badge/notification-badge.component.mjs +4 -4
  74. package/esm2022/lib/overlay/callout/callout.component.mjs +130 -0
  75. package/esm2022/lib/overlay/callout/callout.helpers.mjs +113 -0
  76. package/{esm2020 → esm2022}/lib/overlay/callout/help/help.component.mjs +4 -4
  77. package/esm2022/lib/overlay/callout/lock-scroll.directive.mjs +69 -0
  78. package/{esm2020 → esm2022}/lib/overlay/callout/menu/menu-item/menu-item.component.mjs +5 -5
  79. package/{esm2020 → esm2022}/lib/overlay/callout/menu/menu.component.mjs +4 -4
  80. package/esm2022/lib/overlay/callout/tooltip/locked-tooltip.directive.mjs +30 -0
  81. package/{esm2020 → esm2022}/lib/overlay/callout/tooltip/tooltip.component.mjs +4 -4
  82. package/esm2022/lib/overlay/callout/tooltip/tooltip.directive.mjs +138 -0
  83. package/esm2022/lib/overlay/modal/dialog/dialog.component.mjs +47 -0
  84. package/{esm2020 → esm2022}/lib/overlay/modal/dialog-stack.service.mjs +4 -4
  85. package/esm2022/lib/overlay/modal/form-dialog/form-dialog.component.mjs +146 -0
  86. package/esm2022/lib/overlay/modal/modal.component.mjs +31 -0
  87. package/{esm2020 → esm2022}/lib/overlay/modal/side-sheet/side-sheet.component.mjs +4 -4
  88. package/esm2022/lib/overlay/overlay-outlet.component.mjs +98 -0
  89. package/{esm2020 → esm2022}/lib/overlay/overlay.directive.mjs +5 -5
  90. package/{esm2020 → esm2022}/lib/overlay/overlay.service.mjs +5 -5
  91. package/{esm2020 → esm2022}/lib/overlay/toast/toast-action.component.mjs +4 -4
  92. package/esm2022/lib/overlay/toast/toast.component.mjs +41 -0
  93. package/{esm2020 → esm2022}/lib/riv.module.mjs +227 -227
  94. package/esm2022/lib/size/size.directive.mjs +33 -0
  95. package/esm2022/lib/table/simple-table/coordinate-helper.mjs +61 -0
  96. package/esm2022/lib/table/simple-table/simple-table-cell.component.mjs +36 -0
  97. package/esm2022/lib/table/simple-table/simple-table-header-cell.component.mjs +37 -0
  98. package/{esm2020 → esm2022}/lib/table/simple-table/simple-table-row.component.mjs +4 -4
  99. package/esm2022/lib/table/simple-table/simple-table.component.mjs +104 -0
  100. package/esm2022/lib/table/table/clipboard.mjs +182 -0
  101. package/esm2022/lib/table/table/state-helpers/collapse-helpers.mjs +116 -0
  102. package/esm2022/lib/table/table/state-helpers/column-helpers.mjs +383 -0
  103. package/{esm2020 → esm2022}/lib/table/table/state-helpers/display-helpers.mjs +1 -1
  104. package/esm2022/lib/table/table/state-helpers/nesting-helpers.mjs +123 -0
  105. package/esm2022/lib/table/table/state-helpers/order-helpers.mjs +164 -0
  106. package/esm2022/lib/table/table/state-helpers/pagination-helpers.mjs +139 -0
  107. package/esm2022/lib/table/table/state-helpers/result-helpers.mjs +70 -0
  108. package/esm2022/lib/table/table/state-helpers/search-helpers.mjs +72 -0
  109. package/esm2022/lib/table/table/state-helpers/selection-helpers.mjs +180 -0
  110. package/esm2022/lib/table/table/state.mjs +1035 -0
  111. package/esm2022/lib/table/table/table/table.component.mjs +367 -0
  112. package/{esm2020 → esm2022}/lib/table/table/table-collapse-all/table-collapse-all.component.mjs +5 -5
  113. package/esm2022/lib/table/table/table-column-settings/table-column-settings-side-sheet.component.mjs +227 -0
  114. package/esm2022/lib/table/table/table-column-settings/table-column-settings.component.mjs +134 -0
  115. package/esm2022/lib/table/table/table-csv-export/table-csv-export.component.mjs +35 -0
  116. package/{esm2020 → esm2022}/lib/table/table/table-header-resize-handle/table-header-resize-handle.component.mjs +6 -6
  117. package/esm2022/lib/table/table/table-search/table-search.component.mjs +71 -0
  118. package/{esm2020 → esm2022}/lib/table/table/table-search-columns/table-search-columns.component.mjs +4 -4
  119. package/esm2022/lib/visibility/visibility.directive.mjs +34 -0
  120. package/esm2022/lib/visualization/chart/chart-scaling.mjs +380 -0
  121. package/esm2022/lib/visualization/chart/chart.component.mjs +626 -0
  122. package/esm2022/lib/visualization/chart/chart.mjs +3768 -0
  123. package/{esm2020 → esm2022}/lib/visualization/data-table/data-table-cell.component.mjs +5 -5
  124. package/{esm2020 → esm2022}/lib/visualization/data-table/data-table-header-cell.component.mjs +4 -4
  125. package/{esm2020 → esm2022}/lib/visualization/data-table/data-table-row.component.mjs +4 -4
  126. package/{esm2020 → esm2022}/lib/visualization/data-table/data-table.component.mjs +4 -4
  127. package/{esm2020 → esm2022}/lib/visualization/donut/donut.component.mjs +4 -4
  128. package/{esm2020 → esm2022}/lib/visualization/funnel-chart/funnel-chart.component.mjs +5 -5
  129. package/esm2022/lib/visualization/funnel-chart/funnel-chart.helpers.mjs +33 -0
  130. package/{esm2020 → esm2022}/lib/visualization/highlight/highlight.component.mjs +4 -4
  131. package/esm2022/lib/visualization/highlight/highlight.helpers.mjs +20 -0
  132. package/esm2022/lib/visualization/intervals.mjs +63 -0
  133. package/{esm2020 → esm2022}/lib/visualization/issue/issue.component.mjs +4 -4
  134. package/{esm2020 → esm2022}/lib/visualization/legend-item/legend-item.component.mjs +4 -4
  135. package/{esm2020 → esm2022}/lib/visualization/metric/metric.component.mjs +4 -4
  136. package/{esm2020 → esm2022}/lib/visualization/mini-pie/mini-pie.component.mjs +4 -4
  137. package/{esm2020 → esm2022}/lib/visualization/progress/progress.component.mjs +5 -5
  138. package/esm2022/lib/visualization/stacked-column/stacked-column.component.mjs +377 -0
  139. package/esm2022/lib/visualization/stacked-column/stacked-column.helpers.mjs +18 -0
  140. package/esm2022/lib/visualization/stacked-row/stacked-row.component.mjs +270 -0
  141. package/esm2022/lib/visualization/stacked-row/stacked-row.helpers.mjs +74 -0
  142. package/esm2022/lib/visualization/time-series/time-series.component.mjs +374 -0
  143. package/esm2022/lib/visualization/time-series/time-series.helpers.mjs +15 -0
  144. package/esm2022/lib/visualization/trend/trend.component.mjs +51 -0
  145. package/{esm2020 → esm2022}/lib/visualization/zero-state/zero-state.component.mjs +4 -4
  146. package/{fesm2020 → fesm2022}/rivet-health-design-system.mjs +670 -670
  147. package/{fesm2020 → fesm2022}/rivet-health-design-system.mjs.map +1 -1
  148. package/lib/format/svg-text-truncate/svg-text-truncate.directive.d.ts +1 -1
  149. package/lib/format/truncate/truncate.component.d.ts +1 -1
  150. package/lib/icon/icon.component.d.ts +1 -1
  151. package/lib/input/auto-focus/auto-focus.directive.d.ts +1 -1
  152. package/lib/input/button/button.component.d.ts +1 -1
  153. package/lib/input/calendar/calendar.component.d.ts +1 -1
  154. package/lib/input/checkbox/checkbox.component.d.ts +1 -1
  155. package/lib/input/currency-field/currency-field.component.d.ts +1 -1
  156. package/lib/input/date/date.component.d.ts +1 -1
  157. package/lib/input/date-range/date-range.component.d.ts +1 -1
  158. package/lib/input/filter-chip/filter-chip.component.d.ts +1 -1
  159. package/lib/input/filter-dropdown/filter-dropdown.component.d.ts +1 -1
  160. package/lib/input/input-label/input-label.component.d.ts +1 -1
  161. package/lib/input/mentions-input/mentions-input.component.d.ts +1 -1
  162. package/lib/input/number-field/number-field.component.d.ts +1 -1
  163. package/lib/input/percentage-field/percentage-field.component.d.ts +1 -1
  164. package/lib/input/phone-field/phone-field.component.d.ts +1 -1
  165. package/lib/input/radio/radio.component.d.ts +1 -1
  166. package/lib/input/search/search.component.d.ts +1 -1
  167. package/lib/input/search-select/search-select.component.d.ts +1 -1
  168. package/lib/input/select/select/select.component.d.ts +1 -1
  169. package/lib/input/select/select-node/select-node.component.d.ts +1 -1
  170. package/lib/input/simple-select/simple-select.component.d.ts +1 -1
  171. package/lib/input/switch-checkbox/switch-checkbox.component.d.ts +1 -1
  172. package/lib/input/text-field/text-field.component.d.ts +1 -1
  173. package/lib/input/textarea-field/textarea-field.component.d.ts +1 -1
  174. package/lib/input/validation-message/validation-message.component.d.ts +1 -1
  175. package/lib/layout/card/card-actions.component.d.ts +1 -1
  176. package/lib/layout/card/card-content.component.d.ts +1 -1
  177. package/lib/layout/card/card-header.component.d.ts +1 -1
  178. package/lib/layout/card/card-link.component.d.ts +1 -1
  179. package/lib/layout/card/card-media.component.d.ts +1 -1
  180. package/lib/layout/card/card.component.d.ts +1 -1
  181. package/lib/layout/setting-row/setting-row.component.d.ts +1 -1
  182. package/lib/load/loading/loading.component.d.ts +1 -1
  183. package/lib/load/loading-cover/loading-cover.component.d.ts +1 -1
  184. package/lib/navigation/editable-heading/editable-heading.component.d.ts +1 -1
  185. package/lib/navigation/link/link.component.d.ts +1 -1
  186. package/lib/navigation/page-header/page-header.component.d.ts +1 -1
  187. package/lib/navigation/simple-tabs/simple-tab/simple-tab.component.d.ts +1 -1
  188. package/lib/navigation/tabs/tab/tab.component.d.ts +1 -1
  189. package/lib/navigation/views/all-views-modal/all-views-modal.component.d.ts +1 -1
  190. package/lib/navigation/views/edit-view/edit-view.component.d.ts +1 -1
  191. package/lib/navigation/views/permission-picker/permission-picker.component.d.ts +3 -3
  192. package/lib/navigation/views/view-menu/view-menu.component.d.ts +1 -1
  193. package/lib/navigation/views/views/views.component.d.ts +1 -1
  194. package/lib/notification/badge/badge.component.d.ts +1 -1
  195. package/lib/notification/banner/banner-action.component.d.ts +1 -1
  196. package/lib/notification/banner/banner.component.d.ts +1 -1
  197. package/lib/notification/map-indicator/map-indicator.component.d.ts +1 -1
  198. package/lib/notification/notification-badge/notification-badge.component.d.ts +1 -1
  199. package/lib/overlay/callout/callout.component.d.ts +1 -1
  200. package/lib/overlay/callout/help/help.component.d.ts +1 -1
  201. package/lib/overlay/callout/lock-scroll.directive.d.ts +1 -1
  202. package/lib/overlay/callout/menu/menu-item/menu-item.component.d.ts +1 -1
  203. package/lib/overlay/callout/menu/menu.component.d.ts +1 -1
  204. package/lib/overlay/callout/tooltip/locked-tooltip.directive.d.ts +1 -1
  205. package/lib/overlay/callout/tooltip/tooltip.component.d.ts +1 -1
  206. package/lib/overlay/callout/tooltip/tooltip.directive.d.ts +1 -1
  207. package/lib/overlay/modal/dialog/dialog.component.d.ts +1 -1
  208. package/lib/overlay/modal/form-dialog/form-dialog.component.d.ts +1 -1
  209. package/lib/overlay/modal/modal.component.d.ts +1 -1
  210. package/lib/overlay/modal/side-sheet/side-sheet.component.d.ts +1 -1
  211. package/lib/overlay/toast/toast.component.d.ts +1 -1
  212. package/lib/table/simple-table/simple-table-header-cell.component.d.ts +1 -1
  213. package/lib/table/simple-table/simple-table-row.component.d.ts +1 -1
  214. package/lib/table/table/table/table.component.d.ts +1 -1
  215. package/lib/table/table/table-collapse-all/table-collapse-all.component.d.ts +1 -1
  216. package/lib/table/table/table-column-settings/table-column-settings-side-sheet.component.d.ts +1 -1
  217. package/lib/table/table/table-column-settings/table-column-settings.component.d.ts +1 -1
  218. package/lib/table/table/table-csv-export/table-csv-export.component.d.ts +1 -1
  219. package/lib/table/table/table-search/table-search.component.d.ts +1 -1
  220. package/lib/table/table/table-search-columns/table-search-columns.component.d.ts +1 -1
  221. package/lib/visualization/chart/chart.component.d.ts +1 -1
  222. package/lib/visualization/data-table/data-table-row.component.d.ts +1 -1
  223. package/lib/visualization/donut/donut.component.d.ts +1 -1
  224. package/lib/visualization/funnel-chart/funnel-chart.component.d.ts +1 -1
  225. package/lib/visualization/highlight/highlight.component.d.ts +1 -1
  226. package/lib/visualization/issue/issue.component.d.ts +1 -1
  227. package/lib/visualization/legend-item/legend-item.component.d.ts +1 -1
  228. package/lib/visualization/metric/metric.component.d.ts +1 -1
  229. package/lib/visualization/mini-pie/mini-pie.component.d.ts +1 -1
  230. package/lib/visualization/progress/progress.component.d.ts +1 -1
  231. package/lib/visualization/stacked-column/stacked-column.component.d.ts +3 -3
  232. package/lib/visualization/stacked-row/stacked-row.component.d.ts +1 -1
  233. package/lib/visualization/time-series/time-series.component.d.ts +3 -3
  234. package/lib/visualization/trend/trend.component.d.ts +1 -1
  235. package/lib/visualization/zero-state/zero-state.component.d.ts +1 -1
  236. package/package.json +5 -11
  237. package/esm2020/lib/download/download.service.mjs +0 -47
  238. package/esm2020/lib/format/pipes/sentence-case.pipe.mjs +0 -61
  239. package/esm2020/lib/format/pipes/small-currency.pipe.mjs +0 -24
  240. package/esm2020/lib/format/pipes/small-number.pipe.mjs +0 -29
  241. package/esm2020/lib/format/svg-text-truncate/svg-text-truncate.directive.mjs +0 -62
  242. package/esm2020/lib/format/truncate/truncate.component.mjs +0 -51
  243. package/esm2020/lib/icon/dom-cache.mjs +0 -32
  244. package/esm2020/lib/icon/icon.component.mjs +0 -86
  245. package/esm2020/lib/input/auto-focus/auto-focus.directive.mjs +0 -48
  246. package/esm2020/lib/input/button/button.component.mjs +0 -139
  247. package/esm2020/lib/input/button-group/button-group.component.mjs +0 -39
  248. package/esm2020/lib/input/date/date.component.mjs +0 -279
  249. package/esm2020/lib/input/date-range/date-range.component.mjs +0 -477
  250. package/esm2020/lib/input/filter-chip/filter-chip.component.mjs +0 -47
  251. package/esm2020/lib/input/mentions-input/mentions-input.component.mjs +0 -745
  252. package/esm2020/lib/input/number-field/number-field.component.mjs +0 -125
  253. package/esm2020/lib/input/phone-field/phone-field.component.mjs +0 -74
  254. package/esm2020/lib/input/search-select/search-select.component.mjs +0 -189
  255. package/esm2020/lib/input/select/select/select.component.mjs +0 -178
  256. package/esm2020/lib/input/select/state.mjs +0 -882
  257. package/esm2020/lib/input/simple-select/simple-select.component.mjs +0 -178
  258. package/esm2020/lib/input/switch-checkbox/switch-checkbox.component.mjs +0 -33
  259. package/esm2020/lib/input/text-field/text-field.component.mjs +0 -115
  260. package/esm2020/lib/layout/card/card-content.component.mjs +0 -64
  261. package/esm2020/lib/layout/card/card-header.component.mjs +0 -201
  262. package/esm2020/lib/layout/card/card.component.mjs +0 -291
  263. package/esm2020/lib/load/loading/loading.component.mjs +0 -43
  264. package/esm2020/lib/navigation/editable-heading/editable-heading.component.mjs +0 -243
  265. package/esm2020/lib/navigation/views/permission-picker/permission-picker.component.mjs +0 -151
  266. package/esm2020/lib/navigation/views/state.mjs +0 -456
  267. package/esm2020/lib/navigation/views/views/views.component.mjs +0 -90
  268. package/esm2020/lib/notification/banner/banner-action.component.mjs +0 -48
  269. package/esm2020/lib/notification/banner/banner.component.mjs +0 -61
  270. package/esm2020/lib/notification/map-indicator/map-indicator.component.mjs +0 -50
  271. package/esm2020/lib/notification/map-indicator/map-indicators.mjs +0 -15
  272. package/esm2020/lib/overlay/callout/callout.component.mjs +0 -130
  273. package/esm2020/lib/overlay/callout/callout.helpers.mjs +0 -113
  274. package/esm2020/lib/overlay/callout/lock-scroll.directive.mjs +0 -69
  275. package/esm2020/lib/overlay/callout/tooltip/locked-tooltip.directive.mjs +0 -30
  276. package/esm2020/lib/overlay/callout/tooltip/tooltip.directive.mjs +0 -138
  277. package/esm2020/lib/overlay/modal/dialog/dialog.component.mjs +0 -47
  278. package/esm2020/lib/overlay/modal/form-dialog/form-dialog.component.mjs +0 -146
  279. package/esm2020/lib/overlay/modal/modal.component.mjs +0 -31
  280. package/esm2020/lib/overlay/overlay-outlet.component.mjs +0 -98
  281. package/esm2020/lib/overlay/toast/toast.component.mjs +0 -41
  282. package/esm2020/lib/size/size.directive.mjs +0 -33
  283. package/esm2020/lib/table/simple-table/coordinate-helper.mjs +0 -61
  284. package/esm2020/lib/table/simple-table/simple-table-cell.component.mjs +0 -36
  285. package/esm2020/lib/table/simple-table/simple-table-header-cell.component.mjs +0 -37
  286. package/esm2020/lib/table/simple-table/simple-table.component.mjs +0 -104
  287. package/esm2020/lib/table/table/clipboard.mjs +0 -182
  288. package/esm2020/lib/table/table/state-helpers/collapse-helpers.mjs +0 -116
  289. package/esm2020/lib/table/table/state-helpers/column-helpers.mjs +0 -383
  290. package/esm2020/lib/table/table/state-helpers/nesting-helpers.mjs +0 -123
  291. package/esm2020/lib/table/table/state-helpers/order-helpers.mjs +0 -164
  292. package/esm2020/lib/table/table/state-helpers/pagination-helpers.mjs +0 -139
  293. package/esm2020/lib/table/table/state-helpers/result-helpers.mjs +0 -70
  294. package/esm2020/lib/table/table/state-helpers/search-helpers.mjs +0 -72
  295. package/esm2020/lib/table/table/state-helpers/selection-helpers.mjs +0 -180
  296. package/esm2020/lib/table/table/state.mjs +0 -1035
  297. package/esm2020/lib/table/table/table/table.component.mjs +0 -367
  298. package/esm2020/lib/table/table/table-column-settings/table-column-settings-side-sheet.component.mjs +0 -227
  299. package/esm2020/lib/table/table/table-column-settings/table-column-settings.component.mjs +0 -134
  300. package/esm2020/lib/table/table/table-csv-export/table-csv-export.component.mjs +0 -35
  301. package/esm2020/lib/table/table/table-search/table-search.component.mjs +0 -71
  302. package/esm2020/lib/visibility/visibility.directive.mjs +0 -34
  303. package/esm2020/lib/visualization/chart/chart-scaling.mjs +0 -380
  304. package/esm2020/lib/visualization/chart/chart.component.mjs +0 -626
  305. package/esm2020/lib/visualization/chart/chart.mjs +0 -3768
  306. package/esm2020/lib/visualization/funnel-chart/funnel-chart.helpers.mjs +0 -33
  307. package/esm2020/lib/visualization/highlight/highlight.helpers.mjs +0 -20
  308. package/esm2020/lib/visualization/intervals.mjs +0 -63
  309. package/esm2020/lib/visualization/stacked-column/stacked-column.component.mjs +0 -377
  310. package/esm2020/lib/visualization/stacked-column/stacked-column.helpers.mjs +0 -18
  311. package/esm2020/lib/visualization/stacked-row/stacked-row.component.mjs +0 -270
  312. package/esm2020/lib/visualization/stacked-row/stacked-row.helpers.mjs +0 -74
  313. package/esm2020/lib/visualization/time-series/time-series.component.mjs +0 -374
  314. package/esm2020/lib/visualization/time-series/time-series.helpers.mjs +0 -15
  315. package/esm2020/lib/visualization/trend/trend.component.mjs +0 -51
  316. package/fesm2015/rivet-health-design-system.mjs +0 -18370
  317. package/fesm2015/rivet-health-design-system.mjs.map +0 -1
  318. /package/{esm2020 → esm2022}/lib/overlay/callout/select-callout-defaults.mjs +0 -0
  319. /package/{esm2020 → esm2022}/lib/util/local-storage.mjs +0 -0
  320. /package/{esm2020 → esm2022}/public-api.mjs +0 -0
  321. /package/{esm2020 → esm2022}/rivet-health-design-system.mjs +0 -0
@@ -1,745 +0,0 @@
1
- import { ChangeDetectionStrategy, Component, EventEmitter, Input, Output, ViewChild, ViewEncapsulation, } from '@angular/core';
2
- import * as i0 from "@angular/core";
3
- import * as i1 from "@angular/common";
4
- import * as i2 from "../../overlay/callout/callout.component";
5
- const ZWS = '​';
6
- const ZWS_REGEX = /​/g;
7
- /**
8
- * A rich text input that supports `@`-mentions inside a `contenteditable` div.
9
- *
10
- * ## Data Model
11
- * - **Input/Output**: `ContentItem[]` (mentions, text, newlines)
12
- *
13
- * ## DOM Invariant
14
- * Every mention `<span data-type="mention" contenteditable="false">` is wrapped
15
- * by exactly one zero-width-space (ZWS) text node before and after it. ZWS gives
16
- * the cursor a valid landing spot adjacent to a non-editable element. The
17
- * invariant is established at render time and re-established by
18
- * `normalizeMentionPadding()` after any DOM-mutating operation.
19
- *
20
- * ## Copy/Paste
21
- * - **Copy**: `range.cloneContents()` preserves `data-*` attributes (only the
22
- * browser's default copy path strips them). We override copy, serialize the
23
- * clone ourselves, and strip ZWS from the output.
24
- * - **Paste**: HTML paths look for `data-type="mention"` spans and rebuild
25
- * them; otherwise plaintext fallback.
26
- */
27
- export class MentionsInputComponent {
28
- constructor(cdr) {
29
- this.cdr = cdr;
30
- this.content = [];
31
- this.users = [];
32
- this.readonly = false;
33
- this.placeholder = 'Add a comment';
34
- this.contentChange = new EventEmitter();
35
- this.mentionsVisible = false;
36
- this.mentionSearchText = '';
37
- this.mentionAnchor = null;
38
- this.selectedUserIndex = 0;
39
- this.savedRange = null;
40
- }
41
- ngAfterViewInit() {
42
- this.renderContent();
43
- }
44
- //DAHNE NOTE - ngOnChanges is called whenever any @Input() property changes, where the changed input contains information about those changes
45
- //So if @Input() content changes and it's not the first change (the first render is handled by ngAfterViewInit()), we render the content
46
- ngOnChanges(changes) {
47
- if (changes['content'] && !changes['content'].firstChange) {
48
- this.renderContent();
49
- }
50
- }
51
- renderContent() {
52
- //This is necessary because the @ViewChild reference isn't available until after the view initializes
53
- if (!this.inputElement?.nativeElement) {
54
- return;
55
- }
56
- const html = this.content
57
- .map(item => {
58
- const itemHtml = MentionsInputComponent.contentItemToHtml(item, this.readonly);
59
- return item.type === 'mention' ? `${ZWS}${itemHtml}${ZWS}` : itemHtml;
60
- })
61
- .join('');
62
- this.inputElement.nativeElement.innerHTML = html;
63
- }
64
- static contentItemToHtml(item, readonly) {
65
- switch (item.type) {
66
- //DAHNE TODO - maybe we escape HTML here too? Although I don't think it will be possible for users to input an XSS attack in item.name
67
- case 'mention':
68
- return `<span class="${readonly ? 'readonly-mention' : 'mention'}" data-id="${item.id}" data-type="mention" contenteditable="false">@${MentionsInputComponent.escapeHtml(item.name)}</span>`;
69
- case 'text':
70
- return MentionsInputComponent.escapeHtml(item.text);
71
- case 'newline':
72
- return '<br>';
73
- }
74
- }
75
- static escapeHtml(text) {
76
- const div = document.createElement('div');
77
- div.textContent = text;
78
- return div.innerHTML;
79
- }
80
- // ─── Event handlers ───────────────────────────────────────────────────
81
- onInput() {
82
- this.normalizeMentionPadding();
83
- this.checkForMentionTrigger();
84
- this.emitContentChange();
85
- }
86
- onKeyDown(event) {
87
- if (this.mentionsVisible) {
88
- this.handleMentionsDropdownNav(event);
89
- return;
90
- }
91
- // Word/line jump: native behavior.
92
- if (event.metaKey || event.ctrlKey) {
93
- return;
94
- }
95
- if (event.key === 'ArrowLeft' || event.key === 'ArrowRight') {
96
- const direction = event.key === 'ArrowLeft' ? 'before' : 'after';
97
- const mention = this.findMentionAdjacentToCursor(direction);
98
- if (mention) {
99
- event.preventDefault();
100
- if (event.shiftKey) {
101
- this.extendSelectionAcrossMention(mention, direction);
102
- }
103
- else {
104
- this.placeCursorAdjacentToMention(mention, direction);
105
- }
106
- }
107
- return;
108
- }
109
- if (event.key === 'Backspace' || event.key === 'Delete') {
110
- const direction = event.key === 'Backspace' ? 'before' : 'after';
111
- const mention = this.findMentionAdjacentToCursor(direction);
112
- if (mention) {
113
- event.preventDefault();
114
- this.removeMention(mention);
115
- this.emitContentChange();
116
- return;
117
- }
118
- if (event.key === 'Backspace') {
119
- const br = this.findBrAdjacentToCursor();
120
- if (br) {
121
- event.preventDefault();
122
- br.remove();
123
- this.emitContentChange();
124
- }
125
- }
126
- return;
127
- }
128
- //Handle newlines when mentions aren't visible
129
- if (event.key === 'Enter') {
130
- event.preventDefault();
131
- this.insertLineBreak();
132
- this.emitContentChange();
133
- }
134
- }
135
- onPaste(event) {
136
- event.preventDefault();
137
- if (!event.clipboardData) {
138
- return;
139
- }
140
- //Look for HTML first
141
- const html = event.clipboardData.getData('text/html');
142
- const plainText = event.clipboardData.getData('text/plain');
143
- const nodes = html && html.includes('data-type="mention"')
144
- ? this.parsePastedHtml(html)
145
- : this.plainTextToNodes(plainText);
146
- this.insertNodesAtCursor(nodes);
147
- this.normalizeMentionPadding();
148
- this.emitContentChange();
149
- }
150
- // The browser strips data-* attributes during default copy serialization, but
151
- // range.cloneContents() preserves them. We serialize the clone ourselves and
152
- // strip ZWS so it doesn't leak into the clipboard.
153
- onCopy(event) {
154
- const selection = window.getSelection();
155
- if (!selection?.rangeCount) {
156
- return;
157
- }
158
- event.preventDefault();
159
- const div = document.createElement('div');
160
- div.appendChild(selection.getRangeAt(0).cloneContents());
161
- const html = div.innerHTML.replace(ZWS_REGEX, '');
162
- const text = (div.textContent || '').replace(ZWS_REGEX, '');
163
- event.clipboardData?.setData('text/html', html);
164
- event.clipboardData?.setData('text/plain', text);
165
- }
166
- onCut(event) {
167
- this.onCopy(event);
168
- const selection = window.getSelection();
169
- if (!selection?.rangeCount) {
170
- return;
171
- }
172
- selection.getRangeAt(0).deleteContents();
173
- this.normalizeMentionPadding();
174
- this.emitContentChange();
175
- }
176
- // ─── Mention helpers ───────────────────────────────────────────────────
177
- static isMention(node) {
178
- return (!!node &&
179
- node.nodeType === Node.ELEMENT_NODE &&
180
- node.getAttribute('data-type') === 'mention');
181
- }
182
- static isZws(node) {
183
- return (!!node &&
184
- node.nodeType === Node.TEXT_NODE &&
185
- (node.textContent || '').replace(ZWS_REGEX, '') === '');
186
- }
187
- // Resolve the node logically adjacent to (container, offset) in the given
188
- // direction, transparently skipping any ZWS-only text nodes in between.
189
- resolveAdjacentNode(container, offset, direction) {
190
- let candidate = null;
191
- if (container.nodeType === Node.TEXT_NODE) {
192
- const length = (container.textContent || '').length;
193
- const atBoundary = MentionsInputComponent.isZws(container) ||
194
- (direction === 'before' ? offset === 0 : offset === length);
195
- if (!atBoundary) {
196
- return null;
197
- }
198
- candidate =
199
- direction === 'before'
200
- ? container.previousSibling
201
- : container.nextSibling;
202
- }
203
- else if (container.nodeType === Node.ELEMENT_NODE) {
204
- const children = container.childNodes;
205
- candidate =
206
- direction === 'before' ? children[offset - 1] : children[offset];
207
- }
208
- while (candidate && MentionsInputComponent.isZws(candidate)) {
209
- candidate =
210
- direction === 'before'
211
- ? candidate.previousSibling
212
- : candidate.nextSibling;
213
- }
214
- return candidate;
215
- }
216
- findMentionAdjacentToCursor(direction) {
217
- const selection = window.getSelection();
218
- if (!selection?.isCollapsed || !selection.rangeCount) {
219
- return null;
220
- }
221
- const range = selection.getRangeAt(0);
222
- const node = this.resolveAdjacentNode(range.startContainer, range.startOffset, direction);
223
- return MentionsInputComponent.isMention(node) ? node : null;
224
- }
225
- findBrAdjacentToCursor() {
226
- const selection = window.getSelection();
227
- if (!selection?.isCollapsed || !selection.rangeCount) {
228
- return null;
229
- }
230
- const range = selection.getRangeAt(0);
231
- const node = this.resolveAdjacentNode(range.startContainer, range.startOffset, 'before');
232
- return node?.nodeName === 'BR' ? node : null;
233
- }
234
- extendSelectionAcrossMention(mention, direction) {
235
- const selection = window.getSelection();
236
- const parent = mention.parentNode;
237
- if (!selection || !parent) {
238
- return;
239
- }
240
- const index = Array.from(parent.childNodes).indexOf(mention);
241
- selection.extend(parent, direction === 'before' ? index : index + 1);
242
- }
243
- placeCursorAdjacentToMention(mention, side) {
244
- const parent = mention.parentNode;
245
- if (!parent) {
246
- return;
247
- }
248
- const sibling = side === 'before' ? mention.previousSibling : mention.nextSibling;
249
- let zws;
250
- if (sibling && MentionsInputComponent.isZws(sibling)) {
251
- zws = sibling;
252
- }
253
- else {
254
- zws = document.createTextNode(ZWS);
255
- parent.insertBefore(zws, side === 'before' ? mention : mention.nextSibling);
256
- }
257
- const range = document.createRange();
258
- range.setStart(zws, side === 'before' ? (zws.textContent || '').length : 0);
259
- range.collapse(true);
260
- const selection = window.getSelection();
261
- selection?.removeAllRanges();
262
- selection?.addRange(range);
263
- }
264
- removeMention(mention) {
265
- const parent = mention.parentNode;
266
- if (!parent) {
267
- return;
268
- }
269
- // Empty text-node anchor preserves cursor position through the removal.
270
- const anchor = document.createTextNode('');
271
- parent.insertBefore(anchor, mention);
272
- const prev = mention.previousSibling;
273
- const next = mention.nextSibling;
274
- if (prev && MentionsInputComponent.isZws(prev)) {
275
- prev.remove();
276
- }
277
- if (next && MentionsInputComponent.isZws(next)) {
278
- next.remove();
279
- }
280
- mention.remove();
281
- const range = document.createRange();
282
- range.setStart(anchor, 0);
283
- range.collapse(true);
284
- const selection = window.getSelection();
285
- selection?.removeAllRanges();
286
- selection?.addRange(range);
287
- }
288
- // Re-establishes the invariant: every mention has exactly one ZWS text
289
- // node immediately before and after it, and there are no orphan ZWS-only
290
- // text nodes anywhere else. Run after any operation that may disturb the
291
- // tree (typing, paste, cut, delete) so cruft doesn't accumulate across
292
- // repeated copy/paste cycles.
293
- normalizeMentionPadding() {
294
- const root = this.inputElement?.nativeElement;
295
- if (!root) {
296
- return;
297
- }
298
- // 1. Ensure each mention has a ZWS pad on both sides.
299
- const mentions = Array.from(root.querySelectorAll('span[data-type="mention"]'));
300
- for (const m of mentions) {
301
- const parent = m.parentNode;
302
- if (!parent) {
303
- continue;
304
- }
305
- if (!m.previousSibling ||
306
- !MentionsInputComponent.isZws(m.previousSibling)) {
307
- parent.insertBefore(document.createTextNode(ZWS), m);
308
- }
309
- if (!m.nextSibling || !MentionsInputComponent.isZws(m.nextSibling)) {
310
- parent.insertBefore(document.createTextNode(ZWS), m.nextSibling);
311
- }
312
- }
313
- // 2. Remove any ZWS-only text node that isn't directly adjacent to a
314
- // mention (orphans from line-break pads, leftover splits from previous
315
- // paste insertions, duplicate pads from accumulated copy/paste cycles).
316
- // Skip a node if the cursor currently lives in it — preserves caret
317
- // position without needing manual restoration.
318
- const selection = window.getSelection();
319
- const cursorNode = selection?.rangeCount &&
320
- root.contains(selection.getRangeAt(0).startContainer)
321
- ? selection.getRangeAt(0).startContainer
322
- : null;
323
- const walker = document.createTreeWalker(root, NodeFilter.SHOW_TEXT, null);
324
- const orphans = [];
325
- while (walker.nextNode()) {
326
- const node = walker.currentNode;
327
- if (!MentionsInputComponent.isZws(node) || node === cursorNode) {
328
- continue;
329
- }
330
- const adjacentToMention = MentionsInputComponent.isMention(node.previousSibling) ||
331
- MentionsInputComponent.isMention(node.nextSibling);
332
- if (!adjacentToMention) {
333
- orphans.push(node);
334
- }
335
- }
336
- for (const node of orphans) {
337
- node.remove();
338
- }
339
- }
340
- handleMentionsDropdownNav(event) {
341
- const filteredUsers = this.getFilteredUsers();
342
- if (filteredUsers.length === 0) {
343
- this.closeMentions();
344
- return;
345
- }
346
- switch (event.key) {
347
- case 'ArrowDown':
348
- event.preventDefault();
349
- this.selectedUserIndex = Math.min(this.selectedUserIndex + 1, filteredUsers.length - 1);
350
- this.cdr.markForCheck();
351
- break;
352
- case 'ArrowUp':
353
- event.preventDefault();
354
- this.selectedUserIndex = Math.max(this.selectedUserIndex - 1, 0);
355
- this.cdr.markForCheck();
356
- break;
357
- case 'Enter':
358
- case 'Tab':
359
- event.preventDefault();
360
- if (filteredUsers[this.selectedUserIndex]) {
361
- this.selectUser(filteredUsers[this.selectedUserIndex]);
362
- }
363
- break;
364
- case 'Escape':
365
- event.preventDefault();
366
- this.closeMentions();
367
- break;
368
- }
369
- }
370
- // ─── Insertion ─────────────────────────────────────────────────────────
371
- plainTextToNodes(text) {
372
- const nodes = [];
373
- const lines = text.split('\n');
374
- lines.forEach((line, index) => {
375
- if (line) {
376
- nodes.push(document.createTextNode(line));
377
- }
378
- if (index < lines.length - 1) {
379
- nodes.push(document.createElement('br'));
380
- }
381
- });
382
- return nodes;
383
- }
384
- // Create a temporary container to parse the HTML
385
- parsePastedHtml(html) {
386
- // Create a temporary container to parse the HTML
387
- const tempContainer = document.createElement('div');
388
- tempContainer.innerHTML = html;
389
- const nodes = [];
390
- const walk = (node) => {
391
- if (node.nodeType === Node.ELEMENT_NODE) {
392
- const el = node;
393
- // DAHNE NOTE - we only want mention spans, br elements, and text
394
- if (el.tagName === 'SPAN' &&
395
- el.getAttribute('data-type') === 'mention' &&
396
- el.hasAttribute('data-id')) {
397
- //Create mention to ultimately insert into the DOM
398
- const span = document.createElement('span');
399
- span.className = this.readonly ? 'readonly-mention' : 'mention';
400
- span.setAttribute('data-id', el.getAttribute('data-id') || '');
401
- span.setAttribute('data-type', 'mention');
402
- span.setAttribute('contenteditable', 'false');
403
- const raw = el.textContent || '';
404
- span.textContent = raw.startsWith('@') ? raw : `@${raw}`;
405
- nodes.push(span);
406
- }
407
- else if (el.tagName === 'BR') {
408
- // Preserve line breaks
409
- nodes.push(document.createElement('br'));
410
- }
411
- else {
412
- //Recursively look for nested children
413
- for (const child of Array.from(el.childNodes)) {
414
- walk(child);
415
- }
416
- }
417
- }
418
- else if (node.nodeType === Node.TEXT_NODE) {
419
- const text = (node.textContent || '').replace(ZWS_REGEX, '');
420
- if (text) {
421
- nodes.push(document.createTextNode(text));
422
- }
423
- }
424
- };
425
- for (const child of Array.from(tempContainer.childNodes)) {
426
- walk(child);
427
- }
428
- //DAHNE NOTE - the result here should be an array of text/span-mention/br nodes
429
- return nodes;
430
- }
431
- insertNodesAtCursor(nodes) {
432
- //Get selection object, representing user cursor position/selection
433
- //Get Range object at start of selection, which should represent cursor position
434
- //If there is a selection, delete it
435
- //Insert the parsed nodes from above, move range ends to after node
436
- //Then remove the range and reset it to move the cursor position to the end
437
- const selection = window.getSelection();
438
- if (!selection?.rangeCount) {
439
- return;
440
- }
441
- const range = selection.getRangeAt(0);
442
- range.deleteContents();
443
- let cursorTarget = null;
444
- for (const node of nodes) {
445
- if (MentionsInputComponent.isMention(node)) {
446
- const before = document.createTextNode(ZWS);
447
- const after = document.createTextNode(ZWS);
448
- range.insertNode(before);
449
- range.setStartAfter(before);
450
- range.insertNode(node);
451
- range.setStartAfter(node);
452
- range.insertNode(after);
453
- range.setStartAfter(after);
454
- cursorTarget = after;
455
- }
456
- else {
457
- range.insertNode(node);
458
- range.setStartAfter(node);
459
- cursorTarget = node;
460
- }
461
- range.collapse(true);
462
- }
463
- // After a mention, leave the cursor inside the trailing ZWS so ArrowLeft
464
- // can step back to before-the-mention naturally.
465
- if (cursorTarget && MentionsInputComponent.isZws(cursorTarget)) {
466
- range.setStart(cursorTarget, 0);
467
- range.collapse(true);
468
- }
469
- selection.removeAllRanges();
470
- selection.addRange(range);
471
- }
472
- insertLineBreak() {
473
- const selection = window.getSelection();
474
- if (!selection?.rangeCount || !this.inputElement?.nativeElement) {
475
- return;
476
- }
477
- const range = selection.getRangeAt(0);
478
- range.deleteContents();
479
- const br = document.createElement('br');
480
- range.insertNode(br);
481
- range.setStartAfter(br);
482
- range.collapse(true);
483
- // A trailing <br> alone doesn't render an empty line in contenteditable —
484
- // a ZWS gives the caret a place to land.
485
- if (!br.nextSibling) {
486
- const zws = document.createTextNode(ZWS);
487
- range.insertNode(zws);
488
- range.setStart(zws, 0);
489
- range.collapse(true);
490
- }
491
- selection.removeAllRanges();
492
- selection.addRange(range);
493
- }
494
- // ─── Mention trigger / dropdown ────────────────────────────────────────
495
- checkForMentionTrigger() {
496
- const selection = window.getSelection();
497
- if (!selection || !selection.rangeCount || !this.inputElement) {
498
- return;
499
- }
500
- const range = selection.getRangeAt(0);
501
- const textBeforeCursor = this.getTextBeforeCursor(range);
502
- const lastAtIndex = textBeforeCursor.lastIndexOf('@');
503
- if (lastAtIndex === -1) {
504
- this.closeMentions();
505
- return;
506
- }
507
- //If we allow for a single space, we need to check to make sure that this logic won't pick up previous
508
- //'@' mentions and keep the mention dropdown open
509
- const atPosition = this.findDomPositionAtCharIndex(lastAtIndex);
510
- if (atPosition && this.isInsideMentionSpan(atPosition.node)) {
511
- this.closeMentions();
512
- return;
513
- }
514
- const textAfterAt = textBeforeCursor.substring(lastAtIndex + 1);
515
- const char1 = textAfterAt.charCodeAt(0);
516
- const charN = textAfterAt.charCodeAt(textAfterAt.length - 1);
517
- const charN_1 = textAfterAt.charCodeAt(textAfterAt.length - 2);
518
- //These are the Unicode representations of normal space and non-breaking space
519
- const unicodeSpaceChars = [32, 160];
520
- // Close mentions if:
521
- // - There's a double space (allows single spaces in the middle of search)
522
- // - The text starts with a space (typing "@ " should not trigger mentions)
523
- if (textAfterAt.includes(' ') ||
524
- textAfterAt.startsWith(' ') ||
525
- char1 == 160 ||
526
- (unicodeSpaceChars.includes(charN) && unicodeSpaceChars.includes(charN_1))) {
527
- this.closeMentions();
528
- return;
529
- }
530
- // Trim trailing/leading spaces from search text while preserving spaces in the middle
531
- this.mentionSearchText = textAfterAt.trim();
532
- // Only show mentions if there are filtered users
533
- const filteredUsers = this.getFilteredUsers();
534
- if (filteredUsers.length === 0) {
535
- this.closeMentions();
536
- return;
537
- }
538
- this.mentionsVisible = true;
539
- this.selectedUserIndex = 0;
540
- //Save the current range for later restoration (needed for click selection)
541
- //DAHNE NOTE - this is annoyingly neceessary because clicks and enter keys have different effects on the
542
- //focus of the contenteditable div
543
- this.savedRange = range.cloneRange();
544
- if (atPosition) {
545
- const atRange = document.createRange();
546
- atRange.setStart(atPosition.node, atPosition.offset);
547
- atRange.setEnd(atPosition.node, atPosition.offset + 1);
548
- this.mentionAnchor = atRange.getBoundingClientRect();
549
- }
550
- this.cdr.markForCheck();
551
- }
552
- getTextBeforeCursor(range) {
553
- const clonedRange = range.cloneRange();
554
- //We select all of the input contents, and then move the end point to the current cursor position
555
- clonedRange.selectNodeContents(this.inputElement.nativeElement);
556
- clonedRange.setEnd(range.endContainer, range.endOffset);
557
- //Create a temporary div so that we can extract text content from it
558
- const fragment = clonedRange.cloneContents();
559
- const div = document.createElement('div');
560
- div.appendChild(fragment);
561
- //Get text content, replacing mention spans with @name
562
- return div.textContent || '';
563
- }
564
- getFilteredUsers() {
565
- const users = !this.mentionSearchText
566
- ? this.users
567
- : this.users.filter(user => user.name
568
- .toLowerCase()
569
- .includes(this.mentionSearchText.toLowerCase()));
570
- return users.slice().sort((a, b) => a.name.localeCompare(b.name));
571
- }
572
- onUserHover(index) {
573
- this.selectedUserIndex = index;
574
- this.cdr.markForCheck();
575
- }
576
- selectUser(user) {
577
- if (!this.inputElement) {
578
- return;
579
- }
580
- //This gets DOM info from user (e.g. highlighted selections, and cursor position)
581
- const selection = window.getSelection();
582
- if (!selection) {
583
- return;
584
- }
585
- // Restore the saved range if available (needed when selecting via click)
586
- if (this.savedRange) {
587
- selection.removeAllRanges();
588
- selection.addRange(this.savedRange);
589
- }
590
- if (!selection.rangeCount) {
591
- return;
592
- }
593
- // Delete the "@" and search text
594
- this.deleteAtMentionSearch();
595
- //DAHNE NOTE - this would ideally be the same as contentItemToHTML, but we need an actual element reference here in order to append it to the DOM
596
- const mentionSpan = document.createElement('span');
597
- mentionSpan.className = this.readonly ? 'readonly-mention' : 'mention';
598
- mentionSpan.setAttribute('data-id', String(user.id));
599
- mentionSpan.setAttribute('data-type', 'mention');
600
- mentionSpan.setAttribute('contenteditable', 'false');
601
- mentionSpan.textContent = `@${user.name}`;
602
- this.insertNodesAtCursor([mentionSpan, document.createTextNode(' ')]);
603
- this.normalizeMentionPadding();
604
- this.closeMentions();
605
- this.emitContentChange();
606
- }
607
- deleteAtMentionSearch() {
608
- const selection = window.getSelection();
609
- if (!selection || !selection.rangeCount) {
610
- return;
611
- }
612
- //This represents the current position of the cursor
613
- const cursorRange = selection.getRangeAt(0);
614
- //This will return all of the raw text (HTML-stripped) before the cursor
615
- const textBeforeCursor = this.getTextBeforeCursor(cursorRange);
616
- //We do that^ so that we can find the correct index of the most recent '@'
617
- const lastAtIndex = textBeforeCursor.lastIndexOf('@');
618
- if (lastAtIndex === -1) {
619
- return;
620
- }
621
- const atPosition = this.findDomPositionAtCharIndex(lastAtIndex);
622
- if (!atPosition) {
623
- return;
624
- }
625
- // Create range from "@" to cursor and delete it
626
- const deleteRange = document.createRange();
627
- deleteRange.setStart(atPosition.node, atPosition.offset);
628
- deleteRange.setEnd(cursorRange.endContainer, cursorRange.endOffset);
629
- deleteRange.deleteContents();
630
- }
631
- isInsideMentionSpan(node) {
632
- let currentNode = node;
633
- while (currentNode && currentNode !== this.inputElement?.nativeElement) {
634
- if (MentionsInputComponent.isMention(currentNode)) {
635
- return true;
636
- }
637
- currentNode = currentNode.parentNode;
638
- }
639
- return false;
640
- }
641
- //This will go text node by node looking for the
642
- //@ mention and give its position in the context of that node
643
- findDomPositionAtCharIndex(charIndex) {
644
- if (!this.inputElement) {
645
- return null;
646
- }
647
- // Walk through all text nodes in the input, counting characters
648
- const treeWalker = document.createTreeWalker(this.inputElement.nativeElement, NodeFilter.SHOW_TEXT, null);
649
- let charCount = 0;
650
- while (treeWalker.nextNode()) {
651
- const node = treeWalker.currentNode;
652
- const text = node.textContent || '';
653
- // Check if our target character is in this text node
654
- if (charCount + text.length > charIndex) {
655
- return { node, offset: charIndex - charCount };
656
- }
657
- charCount += text.length;
658
- }
659
- return null;
660
- }
661
- closeMentions() {
662
- this.mentionsVisible = false;
663
- this.mentionSearchText = '';
664
- this.mentionAnchor = null;
665
- this.selectedUserIndex = 0;
666
- this.savedRange = null;
667
- this.cdr.markForCheck();
668
- }
669
- emitContentChange() {
670
- if (!this.inputElement) {
671
- return;
672
- }
673
- this.contentChange.emit(this.domToContentItems());
674
- }
675
- domToContentItems() {
676
- if (!this.inputElement?.nativeElement) {
677
- return [];
678
- }
679
- const items = [];
680
- const childNodes = this.inputElement.nativeElement.childNodes;
681
- for (const node of Array.from(childNodes)) {
682
- if (node.nodeType === Node.ELEMENT_NODE) {
683
- const element = node;
684
- if (element.tagName === 'SPAN' &&
685
- element.getAttribute('data-type') === 'mention') {
686
- const id = Number(element.getAttribute('data-id'));
687
- const name = element.textContent?.replace('@', '') || '';
688
- items.push({ type: 'mention', id, name });
689
- }
690
- else if (element.tagName === 'BR') {
691
- items.push({ type: 'newline' });
692
- }
693
- }
694
- else if (node.nodeType === Node.TEXT_NODE) {
695
- // ZWS pads are a DOM affordance — they shouldn't leak into the data model.
696
- const text = (node.textContent || '').replace(ZWS_REGEX, '');
697
- if (text) {
698
- items.push({ type: 'text', text });
699
- }
700
- }
701
- }
702
- return items;
703
- }
704
- onCalloutClose() {
705
- this.closeMentions();
706
- }
707
- }
708
- MentionsInputComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: MentionsInputComponent, deps: [{ token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
709
- MentionsInputComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.10", type: MentionsInputComponent, selector: "riv-mentions-input", inputs: { content: "content", users: "users", readonly: "readonly", placeholder: "placeholder" }, outputs: { contentChange: "contentChange" }, viewQueries: [{ propertyName: "inputElement", first: true, predicate: ["input"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<div class=\"mentions-container\" #container>\n <div\n *ngIf=\"!readonly\"\n #input\n class=\"text-content editable\"\n contenteditable=\"true\"\n [attr.data-placeholder]=\"placeholder\"\n (input)=\"onInput()\"\n (keydown)=\"onKeyDown($event)\"\n (paste)=\"onPaste($event)\"\n (copy)=\"onCopy($event)\"\n (cut)=\"onCut($event)\"\n ></div>\n\n <div *ngIf=\"readonly\" #input class=\"text-content\"></div>\n\n <riv-callout\n *ngIf=\"!readonly && mentionsVisible && mentionAnchor\"\n [anchor]=\"mentionAnchor\"\n [isModal]=\"true\"\n [showCaret]=\"false\"\n [allowedPositions]=\"['bottom-right', 'top-right']\"\n [theme]=\"'light'\"\n (close)=\"onCalloutClose()\"\n >\n <div class=\"mentions-content\">\n <div class=\"mentions-header\">Mention someone</div>\n <div class=\"mentions-list\">\n <button\n type=\"button\"\n *ngFor=\"let user of getFilteredUsers(); let i = index\"\n [class.selected]=\"i === selectedUserIndex\"\n (mouseenter)=\"onUserHover(i)\"\n (click)=\"selectUser(user)\"\n >\n {{ user.name }}\n </button>\n </div>\n </div>\n </riv-callout>\n</div>\n", styles: [".mentions-container{position:relative;width:100%}.mentions-input{width:100%;border:var(--border-width) solid var(--border-light);border-radius:var(--border-radius-small);color:var(--type-light-high-contrast);overflow-y:auto;white-space:pre-wrap;word-wrap:break-word}.mentions-input:empty:before{content:attr(data-placeholder);color:var(--type-light-low-contrast);pointer-events:none}.mentions-input:focus{outline:none;border:var(--border-width) solid var(--purp-60)}.mentions-input[contenteditable=false]{color:var(--type-light-disabled);background-color:var(--surface-light-1);cursor:not-allowed}span.mention{color:var(--type-light-link);font-weight:var(--font-weight-heavy);white-space:nowrap;display:inline}span.readonly-mention{font-weight:var(--font-weight-heavy);white-space:nowrap;display:inline}.mentions-input.warning{border-color:var(--surface-dark-caution)}.mentions-input.error{border-color:var(--surface-dark-danger);box-shadow:inset 0 0 0 var(--border-width-large) var(--surface-dark-danger)}.mentions-input.large{font:var(--input-large);padding:var(--size-medium)}.mentions-list{margin:0;padding:0;max-height:calc(var(--base-grid-size) * 50);overflow-y:auto;display:flex;flex-direction:column;gap:var(--size-xxsmall)}.mentions-list button{padding:var(--size-small) var(--size-small);border-radius:var(--border-radius-medium);cursor:pointer;transition:background-color .2s;font:var(--input-medium);text-align:left}.mentions-list button:hover,.mentions-list button.selected{background-color:var(--surface-light-2)}.mentions-content{max-height:50vh;min-width:calc(var(--base-grid-size) * 62);max-width:50vw;padding:var(--size-large);display:flex;flex-direction:column}.mentions-header{padding:var(--size-small) var(--size-small);font:var(--input-medium);color:var(--type-light-low-contrast)}.text-content{width:100%;min-height:9em;border-radius:var(--border-radius-small);font:var(--input-medium);color:var(--type-light-high-contrast);padding:var(--size-large);resize:vertical}.editable{border:var(--border-width) solid var(--border-light);background-color:var(--surface-light-0)}.text-content::placeholder{color:var(--type-light-low-contrast)}.text-content.editable[data-placeholder]:empty:before{content:attr(data-placeholder);color:var(--type-light-low-contrast)}.text-content:disabled{color:var(--type-light-disabled);background-color:var(--surface-light-1)}.text-content:focus{outline:none;border:var(--border-width) solid var(--purp-60)}.text-content.warning{border-color:var(--surface-dark-caution)}.text-content.error{border-color:var(--surface-dark-danger);box-shadow:inset 0 0 0 var(--border-width-large) var(--surface-dark-danger)}.text-content.large{font:var(--input-large);padding:var(--size-medium)}\n"], dependencies: [{ kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i2.CalloutComponent, selector: "riv-callout", inputs: ["anchor", "isModal", "preferredPosition", "allowedPositions", "fallbackDirection", "showCaret", "theme"], outputs: ["close"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
710
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: MentionsInputComponent, decorators: [{
711
- type: Component,
712
- args: [{ selector: 'riv-mentions-input', encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"mentions-container\" #container>\n <div\n *ngIf=\"!readonly\"\n #input\n class=\"text-content editable\"\n contenteditable=\"true\"\n [attr.data-placeholder]=\"placeholder\"\n (input)=\"onInput()\"\n (keydown)=\"onKeyDown($event)\"\n (paste)=\"onPaste($event)\"\n (copy)=\"onCopy($event)\"\n (cut)=\"onCut($event)\"\n ></div>\n\n <div *ngIf=\"readonly\" #input class=\"text-content\"></div>\n\n <riv-callout\n *ngIf=\"!readonly && mentionsVisible && mentionAnchor\"\n [anchor]=\"mentionAnchor\"\n [isModal]=\"true\"\n [showCaret]=\"false\"\n [allowedPositions]=\"['bottom-right', 'top-right']\"\n [theme]=\"'light'\"\n (close)=\"onCalloutClose()\"\n >\n <div class=\"mentions-content\">\n <div class=\"mentions-header\">Mention someone</div>\n <div class=\"mentions-list\">\n <button\n type=\"button\"\n *ngFor=\"let user of getFilteredUsers(); let i = index\"\n [class.selected]=\"i === selectedUserIndex\"\n (mouseenter)=\"onUserHover(i)\"\n (click)=\"selectUser(user)\"\n >\n {{ user.name }}\n </button>\n </div>\n </div>\n </riv-callout>\n</div>\n", styles: [".mentions-container{position:relative;width:100%}.mentions-input{width:100%;border:var(--border-width) solid var(--border-light);border-radius:var(--border-radius-small);color:var(--type-light-high-contrast);overflow-y:auto;white-space:pre-wrap;word-wrap:break-word}.mentions-input:empty:before{content:attr(data-placeholder);color:var(--type-light-low-contrast);pointer-events:none}.mentions-input:focus{outline:none;border:var(--border-width) solid var(--purp-60)}.mentions-input[contenteditable=false]{color:var(--type-light-disabled);background-color:var(--surface-light-1);cursor:not-allowed}span.mention{color:var(--type-light-link);font-weight:var(--font-weight-heavy);white-space:nowrap;display:inline}span.readonly-mention{font-weight:var(--font-weight-heavy);white-space:nowrap;display:inline}.mentions-input.warning{border-color:var(--surface-dark-caution)}.mentions-input.error{border-color:var(--surface-dark-danger);box-shadow:inset 0 0 0 var(--border-width-large) var(--surface-dark-danger)}.mentions-input.large{font:var(--input-large);padding:var(--size-medium)}.mentions-list{margin:0;padding:0;max-height:calc(var(--base-grid-size) * 50);overflow-y:auto;display:flex;flex-direction:column;gap:var(--size-xxsmall)}.mentions-list button{padding:var(--size-small) var(--size-small);border-radius:var(--border-radius-medium);cursor:pointer;transition:background-color .2s;font:var(--input-medium);text-align:left}.mentions-list button:hover,.mentions-list button.selected{background-color:var(--surface-light-2)}.mentions-content{max-height:50vh;min-width:calc(var(--base-grid-size) * 62);max-width:50vw;padding:var(--size-large);display:flex;flex-direction:column}.mentions-header{padding:var(--size-small) var(--size-small);font:var(--input-medium);color:var(--type-light-low-contrast)}.text-content{width:100%;min-height:9em;border-radius:var(--border-radius-small);font:var(--input-medium);color:var(--type-light-high-contrast);padding:var(--size-large);resize:vertical}.editable{border:var(--border-width) solid var(--border-light);background-color:var(--surface-light-0)}.text-content::placeholder{color:var(--type-light-low-contrast)}.text-content.editable[data-placeholder]:empty:before{content:attr(data-placeholder);color:var(--type-light-low-contrast)}.text-content:disabled{color:var(--type-light-disabled);background-color:var(--surface-light-1)}.text-content:focus{outline:none;border:var(--border-width) solid var(--purp-60)}.text-content.warning{border-color:var(--surface-dark-caution)}.text-content.error{border-color:var(--surface-dark-danger);box-shadow:inset 0 0 0 var(--border-width-large) var(--surface-dark-danger)}.text-content.large{font:var(--input-large);padding:var(--size-medium)}\n"] }]
713
- }], ctorParameters: function () { return [{ type: i0.ChangeDetectorRef }]; }, propDecorators: { content: [{
714
- type: Input
715
- }], users: [{
716
- type: Input
717
- }], readonly: [{
718
- type: Input
719
- }], placeholder: [{
720
- type: Input
721
- }], contentChange: [{
722
- type: Output
723
- }], inputElement: [{
724
- type: ViewChild,
725
- args: ['input', { static: false }]
726
- }] } });
727
- (function (MentionsInputComponent) {
728
- MentionsInputComponent.ContentTypes = ['mention', 'text', 'newline'];
729
- function contentToPlainText(content) {
730
- return content
731
- .map(item => {
732
- switch (item.type) {
733
- case 'mention':
734
- return `@${item.name}`;
735
- case 'text':
736
- return item.text;
737
- case 'newline':
738
- return '\n';
739
- }
740
- })
741
- .join('');
742
- }
743
- MentionsInputComponent.contentToPlainText = contentToPlainText;
744
- })(MentionsInputComponent || (MentionsInputComponent = {}));
745
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWVudGlvbnMtaW5wdXQuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvcml2L3NyYy9saWIvaW5wdXQvbWVudGlvbnMtaW5wdXQvbWVudGlvbnMtaW5wdXQuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvcml2L3NyYy9saWIvaW5wdXQvbWVudGlvbnMtaW5wdXQvbWVudGlvbnMtaW5wdXQuY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUVMLHVCQUF1QixFQUV2QixTQUFTLEVBRVQsWUFBWSxFQUNaLEtBQUssRUFFTCxNQUFNLEVBRU4sU0FBUyxFQUNULGlCQUFpQixHQUNsQixNQUFNLGVBQWUsQ0FBQzs7OztBQUV2QixNQUFNLEdBQUcsR0FBRyxHQUFHLENBQUM7QUFDaEIsTUFBTSxTQUFTLEdBQUcsSUFBSSxDQUFDO0FBRXZCOzs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBbUJHO0FBUUgsTUFBTSxPQUFPLHNCQUFzQjtJQUNqQyxZQUE2QixHQUFzQjtRQUF0QixRQUFHLEdBQUgsR0FBRyxDQUFtQjtRQUUxQyxZQUFPLEdBQXlDLEVBQUUsQ0FBQztRQUNuRCxVQUFLLEdBQWtDLEVBQUUsQ0FBQztRQUMxQyxhQUFRLEdBQUcsS0FBSyxDQUFDO1FBQ2pCLGdCQUFXLEdBQVcsZUFBZSxDQUFDO1FBRTVCLGtCQUFhLEdBQUcsSUFBSSxZQUFZLEVBRWhELENBQUM7UUFLSixvQkFBZSxHQUFHLEtBQUssQ0FBQztRQUN4QixzQkFBaUIsR0FBRyxFQUFFLENBQUM7UUFDdkIsa0JBQWEsR0FBbUIsSUFBSSxDQUFDO1FBQ3JDLHNCQUFpQixHQUFHLENBQUMsQ0FBQztRQUNkLGVBQVUsR0FBaUIsSUFBSSxDQUFDO0lBbEJjLENBQUM7SUFvQnZELGVBQWU7UUFDYixJQUFJLENBQUMsYUFBYSxFQUFFLENBQUM7SUFDdkIsQ0FBQztJQUVE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QUNuQixLQUFLLFNBQVM7b0JBQ1osT0FBTyxJQUFJLENBQUM7YUFDZjtRQUNILENBQUMsQ0FBQzthQUNELElBQUksQ0FBQyxFQUFFLENBQUMsQ0FBQztJQUNkLENBQUM7SUFiZSx5Q0FBa0IscUJBYWpDLENBQUE7QUFDSCxDQUFDLEVBOUJnQixzQkFBc0IsS0FBdEIsc0JBQXNCLFFBOEJ0QyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7XG4gIEFmdGVyVmlld0luaXQsXG4gIENoYW5nZURldGVjdGlvblN0cmF0ZWd5LFxuICBDaGFuZ2VEZXRlY3RvclJlZixcbiAgQ29tcG9uZW50LFxuICBFbGVtZW50UmVmLFxuICBFdmVudEVtaXR0ZXIsXG4gIElucHV0LFxuICBPbkNoYW5nZXMsXG4gIE91dHB1dCxcbiAgU2ltcGxlQ2hhbmdlcyxcbiAgVmlld0NoaWxkLFxuICBWaWV3RW5jYXBzdWxhdGlvbixcbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5cbmNvbnN0IFpXUyA9ICfigIsnO1xuY29uc3QgWldTX1JFR0VYID0gL+KAiy9nO1xuXG4vKipcbiAqIEEgcmljaCB0ZXh0IGlucHV0IHRoYXQgc3VwcG9ydHMgYEBgLW1lbnRpb25zIGluc2lkZSBhIGBjb250ZW50ZWRpdGFibGVgIGRpdi5cbiAqXG4gKiAjIyBEYXRhIE1vZGVsXG4gKiAtICoqSW5wdXQvT3V0cHV0Kio6IGBDb250ZW50SXRlbVtdYCAobWVudGlvbnMsIHRleHQsIG5ld2xpbmVzKVxuICpcbiAqICMjIERPTSBJbnZhcmlhbnRcbiAqIEV2ZXJ5IG1lbnRpb24gYDxzcGFuIGRhdGEtdHlwZT1cIm1lbnRpb25cIiBjb250ZW50ZWRpdGFibGU9XCJmYWxzZVwiPmAgaXMgd3JhcHBlZFxuICogYnkgZXhhY3RseSBvbmUgemVyby13aWR0aC1zcGFjZSAoWldTKSB0ZXh0IG5vZGUgYmVmb3JlIGFuZCBhZnRlciBpdC4gWldTIGdpdmVzXG4gKiB0aGUgY3Vyc29yIGEgdmFsaWQgbGFuZGluZyBzcG90IGFkamFjZW50IHRvIGEgbm9uLWVkaXRhYmxlIGVsZW1lbnQuIFRoZVxuICogaW52YXJpYW50IGlzIGVzdGFibGlzaGVkIGF0IHJlbmRlciB0aW1lIGFuZCByZS1lc3RhYmxpc2hlZCBieVxuICogYG5vcm1hbGl6ZU1lbnRpb25QYWRkaW5nKClgIGFmdGVyIGFueSBET00tbXV0YXRpbmcgb3BlcmF0aW9uLlxuICpcbiAqICMjIENvcHkvUGFzdGVcbiAqIC0gKipDb3B5Kio6IGByYW5nZS5jbG9uZUNvbnRlbnRzKClgIHByZXNlcnZlcyBgZGF0YS0qYCBhdHRyaWJ1dGVzIChvbmx5IHRoZVxuICogICBicm93c2VyJ3MgZGVmYXVsdCBjb3B5IHBhdGggc3RyaXBzIHRoZW0pLiBXZSBvdmVycmlkZSBjb3B5LCBzZXJpYWxpemUgdGhlXG4gKiAgIGNsb25lIG91cnNlbHZlcywgYW5kIHN0cmlwIFpXUyBmcm9tIHRoZSBvdXRwdXQuXG4gKiAtICoqUGFzdGUqKjogSFRNTCBwYXRocyBsb29rIGZvciBgZGF0YS10eXBlPVwibWVudGlvblwiYCBzcGFucyBhbmQgcmVidWlsZFxuICogICB0aGVtOyBvdGhlcndpc2UgcGxhaW50ZXh0IGZhbGxiYWNrLlxuICovXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICdyaXYtbWVudGlvbnMtaW5wdXQnLFxuICB0ZW1wbGF0ZVVybDogYC4vbWVudGlvbnMtaW5wdXQuY29tcG9uZW50Lmh0bWxgLFxuICBzdHlsZVVybHM6IFsnLi9tZW50aW9ucy1pbnB1dC5jb21wb25lbnQuY3NzJ10sXG4gIGVuY2Fwc3VsYXRpb246IFZpZXdFbmNhcHN1bGF0aW9uLk5vbmUsXG4gIGNoYW5nZURldGVjdGlvbjogQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3kuT25QdXNoLFxufSlcbmV4cG9ydCBjbGFzcyBNZW50aW9uc0lucHV0Q29tcG9uZW50IGltcGxlbWVudHMgT25DaGFuZ2VzLCBBZnRlclZpZXdJbml0IHtcbiAgY29uc3RydWN0b3IocHJpdmF0ZSByZWFkb25seSBjZHI6IENoYW5nZURldGVjdG9yUmVmKSB7fVxuXG4gIEBJbnB1dCgpIGNvbnRlbnQ6IE1lbnRpb25zSW5wdXRDb21wb25lbnQuQ29udGVudEl0ZW1bXSA9IFtdO1xuICBASW5wdXQoKSB1c2VyczogTWVudGlvbnNJbnB1dENvbXBvbmVudC5Vc2VyW10gPSBbXTtcbiAgQElucHV0KCkgcmVhZG9ubHkgPSBmYWxzZTtcbiAgQElucHV0KCkgcGxhY2Vob2xkZXI6IHN0cmluZyA9ICdBZGQgYSBjb21tZW50JztcblxuICBAT3V0cHV0KCkgcmVhZG9ubHkgY29udGVudENoYW5nZSA9IG5ldyBFdmVudEVtaXR0ZXI8XG4gICAgTWVudGlvbnNJbnB1dENvbXBvbmVudC5Db250ZW50SXRlbVtdXG4gID4oKTtcblxuICBAVmlld0NoaWxkKCdpbnB1dCcsIHsgc3RhdGljOiBmYWxzZSB9KVxuICBwcml2YXRlIHJlYWRvbmx5IGlucHV0RWxlbWVudD86IEVsZW1lbnRSZWY8SFRNTERpdkVsZW1lbnQ+O1xuXG4gIG1lbnRpb25zVmlzaWJsZSA9IGZhbHNlO1xuICBtZW50aW9uU2VhcmNoVGV4dCA9ICcnO1xuICBtZW50aW9uQW5jaG9yOiBET01SZWN0IHwgbnVsbCA9IG51bGw7XG4gIHNlbGVjdGVkVXNlckluZGV4ID0gMDtcbiAgcHJpdmF0ZSBzYXZlZFJhbmdlOiBSYW5nZSB8IG51bGwgPSBudWxsO1xuXG4gIG5nQWZ0ZXJWaWV3SW5pdCgpOiB2b2lkIHtcbiAgICB0aGlzLnJlbmRlckNvbnRlbnQoKTtcbiAgfVxuXG4gIC8vREFITkUgTk9URSAtIG5nT25DaGFuZ2VzIGlzIGNhbGxlZCB3aGVuZXZlciBhbnkgQElucHV0KCkgcHJvcGVydHkgY2hhbmdlcywgd2hlcmUgdGhlIGNoYW5nZWQgaW5wdXQgY29udGFpbnMgaW5mb3JtYXRpb24gYWJvdXQgdGhvc2UgY2hhbmdlc1xuICAvL1NvIGlmIEBJbnB1dCgpIGNvbnRlbnQgY2hhbmdlcyBhbmQgaXQncyBub3QgdGhlIGZpcnN0IGNoYW5nZSAodGhlIGZpcnN0IHJlbmRlciBpcyBoYW5kbGVkIGJ5IG5nQWZ0ZXJWaWV3SW5pdCgpKSwgd2UgcmVuZGVyIHRoZSBjb250ZW50XG4gIG5nT25DaGFuZ2VzKGNoYW5nZXM6IFNpbXBsZUNoYW5nZXMpOiB2b2lkIHtcbiAgICBpZiAoY2hhbmdlc1snY29udGVudCddICYmICFjaGFuZ2VzWydjb250ZW50J10uZmlyc3RDaGFuZ2UpIHtcbiAgICAgIHRoaXMucmVuZGVyQ29udGVudCgpO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgcmVuZGVyQ29udGVudCgpOiB2b2lkIHtcbiAgICAvL1RoaXMgaXMgbmVjZXNzYXJ5IGJlY2F1c2UgdGhlIEBWaWV3Q2hpbGQgcmVmZXJlbmNlIGlzbid0IGF2YWlsYWJsZSB1bnRpbCBhZnRlciB0aGUgdmlldyBpbml0aWFsaXplc1xuICAgIGlmICghdGhpcy5pbnB1dEVsZW1lbnQ/Lm5hdGl2ZUVsZW1lbnQpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgY29uc3QgaHRtbCA9IHRoaXMuY29udGVudFxuICAgICAgLm1hcChpdGVtID0+IHtcbiAgICAgICAgY29uc3QgaXRlbUh0bWwgPSBNZW50aW9uc0lucHV0Q29tcG9uZW50LmNvbnRlbnRJdGVtVG9IdG1sKFxuICAgICAgICAgIGl0ZW0sXG4gICAgICAgICAgdGhpcy5yZWFkb25seSxcbiAgICAgICAgKTtcbiAgICAgICAgcmV0dXJuIGl0ZW0udHlwZSA9PT0gJ21lbnRpb24nID8gYCR7WldTfSR7aXRlbUh0bWx9JHtaV1N9YCA6IGl0ZW1IdG1sO1xuICAgICAgfSlcbiAgICAgIC5qb2luKCcnKTtcbiAgICB0aGlzLmlucHV0RWxlbWVudC5uYXRpdmVFbGVtZW50LmlubmVySFRNTCA9IGh0bWw7XG4gIH1cblxuICBwcml2YXRlIHN0YXRpYyBjb250ZW50SXRlbVRvSHRtbChcbiAgICBpdGVtOiBNZW50aW9uc0lucHV0Q29tcG9uZW50LkNvbnRlbnRJdGVtLFxuICAgIHJlYWRvbmx5OiBib29sZWFuLFxuICApOiBzdHJpbmcge1xuICAgIHN3aXRjaCAoaXRlbS50eXBlKSB7XG4gICAgICAvL0RBSE5FIFRPRE8gLSBtYXliZSB3ZSBlc2NhcGUgSFRNTCBoZXJlIHRvbz8gQWx0aG91Z2ggSSBkb24ndCB0aGluayBpdCB3aWxsIGJlIHBvc3NpYmxlIGZvciB1c2VycyB0byBpbnB1dCBhbiBYU1MgYXR0YWNrIGluIGl0ZW0ubmFtZVxuICAgICAgY2FzZSAnbWVudGlvbic6XG4gICAgICAgIHJldHVybiBgPHNwYW4gY2xhc3M9XCIke1xuICAgICAgICAgIHJlYWRvbmx5ID8gJ3JlYWRvbmx5LW1lbnRpb24nIDogJ21lbnRpb24nXG4gICAgICAgIH1cIiBkYXRhLWlkPVwiJHtcbiAgICAgICAgICBpdGVtLmlkXG4gICAgICAgIH1cIiBkYXRhLXR5cGU9XCJtZW50aW9uXCIgY29udGVudGVkaXRhYmxlPVwiZmFsc2VcIj5AJHtNZW50aW9uc0lucHV0Q29tcG9uZW50LmVzY2FwZUh0bWwoXG4gICAgICAgICAgaXRlbS5uYW1lLFxuICAgICAgICApfTwvc3Bhbj5gO1xuICAgICAgY2FzZSAndGV4dCc6XG4gICAgICAgIHJldHVybiBNZW50aW9uc0lucHV0Q29tcG9uZW50LmVzY2FwZUh0bWwoaXRlbS50ZXh0KTtcbiAgICAgIGNhc2UgJ25ld2xpbmUnOlxuICAgICAgICByZXR1cm4gJzxicj4nO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgc3RhdGljIGVzY2FwZUh0bWwodGV4dDogc3RyaW5nKTogc3RyaW5nIHtcbiAgICBjb25zdCBkaXYgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcbiAgICBkaXYudGV4dENvbnRlbnQgPSB0ZXh0O1xuICAgIHJldHVybiBkaXYuaW5uZXJIVE1MO1xuICB9XG5cbiAgLy8g4pSA4pSA4pSAIEV2ZW50IGhhbmRsZXJzIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgFxuXG4gIG9uSW5wdXQoKTogdm9pZCB7XG4gICAgdGhpcy5ub3JtYWxpemVNZW50aW9uUGFkZGluZygpO1xuICAgIHRoaXMuY2hlY2tGb3JNZW50aW9uVHJpZ2dlcigpO1xuICAgIHRoaXMuZW1pdENvbnRlbnRDaGFuZ2UoKTtcbiAgfVxuXG4gIG9uS2V5RG93bihldmVudDogS2V5Ym9hcmRFdmVudCk6IHZvaWQge1xuICAgIGlmICh0aGlzLm1lbnRpb25zVmlzaWJsZSkge1xuICAgICAgdGhpcy5oYW5kbGVNZW50aW9uc0Ryb3Bkb3duTmF2KGV2ZW50KTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICAvLyBXb3JkL2xpbmUganVtcDogbmF0aXZlIGJlaGF2aW9yLlxuICAgIGlmIChldmVudC5tZXRhS2V5IHx8IGV2ZW50LmN0cmxLZXkpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZiAoZXZlbnQua2V5ID09PSAnQXJyb3dMZWZ0JyB8fCBldmVudC5rZXkgPT09ICdBcnJvd1JpZ2h0Jykge1xuICAgICAgY29uc3QgZGlyZWN0aW9uID0gZXZlbnQua2V5ID09PSAnQXJyb3dMZWZ0JyA/ICdiZWZvcmUnIDogJ2FmdGVyJztcbiAgICAgIGNvbnN0IG1lbnRpb24gPSB0aGlzLmZpbmRNZW50aW9uQWRqYWNlbnRUb0N1cnNvcihkaXJlY3Rpb24pO1xuICAgICAgaWYgKG1lbnRpb24pIHtcbiAgICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgaWYgKGV2ZW50LnNoaWZ0S2V5KSB7XG4gICAgICAgICAgdGhpcy5leHRlbmRTZWxlY3Rpb25BY3Jvc3NNZW50aW9uKG1lbnRpb24sIGRpcmVjdGlvbik7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdGhpcy5wbGFjZUN1cnNvckFkamFjZW50VG9NZW50aW9uKG1lbnRpb24sIGRpcmVjdGlvbik7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZiAoZXZlbnQua2V5ID09PSAnQmFja3NwYWNlJyB8fCBldmVudC5rZXkgPT09ICdEZWxldGUnKSB7XG4gICAgICBjb25zdCBkaXJlY3Rpb24gPSBldmVudC5rZXkgPT09ICdCYWNrc3BhY2UnID8gJ2JlZm9yZScgOiAnYWZ0ZXInO1xuICAgICAgY29uc3QgbWVudGlvbiA9IHRoaXMuZmluZE1lbnRpb25BZGphY2VudFRvQ3Vyc29yKGRpcmVjdGlvbik7XG4gICAgICBpZiAobWVudGlvbikge1xuICAgICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICB0aGlzLnJlbW92ZU1lbnRpb24obWVudGlvbik7XG4gICAgICAgIHRoaXMuZW1pdENvbnRlbnRDaGFuZ2UoKTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgaWYgKGV2ZW50LmtleSA9PT0gJ0JhY2tzcGFjZScpIHtcbiAgICAgICAgY29uc3QgYnIgPSB0aGlzLmZpbmRCckFkamFjZW50VG9DdXJzb3IoKTtcbiAgICAgICAgaWYgKGJyKSB7XG4gICAgICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgICBici5yZW1vdmUoKTtcbiAgICAgICAgICB0aGlzLmVtaXRDb250ZW50Q2hhbmdlKCk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgLy9IYW5kbGUgbmV3bGluZXMgd2hlbiBtZW50aW9ucyBhcmVuJ3QgdmlzaWJsZVxuICAgIGlmIChldmVudC5rZXkgPT09ICdFbnRlcicpIHtcbiAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgICB0aGlzLmluc2VydExpbmVCcmVhaygpO1xuICAgICAgdGhpcy5lbWl0Q29udGVudENoYW5nZSgpO1xuICAgIH1cbiAgfVxuXG4gIG9uUGFzdGUoZXZlbnQ6IENsaXBib2FyZEV2ZW50KTogdm9pZCB7XG4gICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICBpZiAoIWV2ZW50LmNsaXBib2FyZERhdGEpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgLy9Mb29rIGZvciBIVE1MIGZpcnN0XG4gICAgY29uc3QgaHRtbCA9IGV2ZW50LmNsaXBib2FyZERhdGEuZ2V0RGF0YSgndGV4dC9odG1sJyk7XG4gICAgY29uc3QgcGxhaW5UZXh0ID0gZXZlbnQuY2xpcGJvYXJkRGF0YS5nZXREYXRhKCd0ZXh0L3BsYWluJyk7XG5cbiAgICBjb25zdCBub2RlcyA9XG4gICAgICBodG1sICYmIGh0bWwuaW5jbHVkZXMoJ2RhdGEtdHlwZT1cIm1lbnRpb25cIicpXG4gICAgICAgID8gdGhpcy5wYXJzZVBhc3RlZEh0bWwoaHRtbClcbiAgICAgICAgOiB0aGlzLnBsYWluVGV4dFRvTm9kZXMocGxhaW5UZXh0KTtcblxuICAgIHRoaXMuaW5zZXJ0Tm9kZXNBdEN1cnNvcihub2Rlcyk7XG4gICAgdGhpcy5ub3JtYWxpemVNZW50aW9uUGFkZGluZygpO1xuICAgIHRoaXMuZW1pdENvbnRlbnRDaGFuZ2UoKTtcbiAgfVxuXG4gIC8vIFRoZSBicm93c2VyIHN0cmlwcyBkYXRhLSogYXR0cmlidXRlcyBkdXJpbmcgZGVmYXVsdCBjb3B5IHNlcmlhbGl6YXRpb24sIGJ1dFxuICAvLyByYW5nZS5jbG9uZUNvbnRlbnRzKCkgcHJlc2VydmVzIHRoZW0uIFdlIHNlcmlhbGl6ZSB0aGUgY2xvbmUgb3Vyc2VsdmVzIGFuZFxuICAvLyBzdHJpcCBaV1Mgc28gaXQgZG9lc24ndCBsZWFrIGludG8gdGhlIGNsaXBib2FyZC5cbiAgb25Db3B5KGV2ZW50OiBDbGlwYm9hcmRFdmVudCk6IHZvaWQge1xuICAgIGNvbnN0IHNlbGVjdGlvbiA9IHdpbmRvdy5nZXRTZWxlY3Rpb24oKTtcbiAgICBpZiAoIXNlbGVjdGlvbj8ucmFuZ2VDb3VudCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuXG4gICAgY29uc3QgZGl2ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XG4gICAgZGl2LmFwcGVuZENoaWxkKHNlbGVjdGlvbi5nZXRSYW5nZUF0KDApLmNsb25lQ29udGVudHMoKSk7XG5cbiAgICBjb25zdCBodG1sID0gZGl2LmlubmVySFRNTC5yZXBsYWNlKFpXU19SRUdFWCwgJycpO1xuICAgIGNvbnN0IHRleHQgPSAoZGl2LnRleHRDb250ZW50IHx8ICcnKS5yZXBsYWNlKFpXU19SRUdFWCwgJycpO1xuXG4gICAgZXZlbnQuY2xpcGJvYXJkRGF0YT8uc2V0RGF0YSgndGV4dC9odG1sJywgaHRtbCk7XG4gICAgZXZlbnQuY2xpcGJvYXJkRGF0YT8uc2V0RGF0YSgndGV4dC9wbGFpbicsIHRleHQpO1xuICB9XG5cbiAgb25DdXQoZXZlbnQ6IENsaXBib2FyZEV2ZW50KTogdm9pZCB7XG4gICAgdGhpcy5vbkNvcHkoZXZlbnQpO1xuICAgIGNvbnN0IHNlbGVjdGlvbiA9IHdpbmRvdy5nZXRTZWxlY3Rpb24oKTtcbiAgICBpZiAoIXNlbGVjdGlvbj8ucmFuZ2VDb3VudCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBzZWxlY3Rpb24uZ2V0UmFuZ2VBdCgwKS5kZWxldGVDb250ZW50cygpO1xuICAgIHRoaXMubm9ybWFsaXplTWVudGlvblBhZGRpbmcoKTtcbiAgICB0aGlzLmVtaXRDb250ZW50Q2hhbmdlKCk7XG4gIH1cblxuICAvLyDilIDilIDilIAgTWVudGlvbiBoZWxwZXJzIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgFxuXG4gIHByaXZhdGUgc3RhdGljIGlzTWVudGlvbihub2RlOiBOb2RlIHwgbnVsbCB8IHVuZGVmaW5lZCk6IG5vZGUgaXMgSFRNTEVsZW1lbnQge1xuICAgIHJldHVybiAoXG4gICAgICAhIW5vZGUgJiZcbiAgICAgIG5vZGUubm9kZVR5cGUgPT09IE5vZGUuRUxFTUVOVF9OT0RFICYmXG4gICAgICAobm9kZSBhcyBIVE1MRWxlbWVudCkuZ2V0QXR0cmlidXRlKCdkYXRhLXR5cGUnKSA9PT0gJ21lbnRpb24nXG4gICAgKTtcbiAgfVxuXG4gIHByaXZhdGUgc3RhdGljIGlzWndzKG5vZGU6IE5vZGUgfCBudWxsIHwgdW5kZWZpbmVkKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIChcbiAgICAgICEhbm9kZSAmJlxuICAgICAgbm9kZS5ub2RlVHlwZSA9PT0gTm9kZS5URVhUX05PREUgJiZcbiAgICAgIChub2RlLnRleHRDb250ZW50IHx8ICcnKS5yZXBsYWNlKFpXU19SRUdFWCwgJycpID09PSAnJ1xuICAgICk7XG4gIH1cblxuICAvLyBSZXNvbHZlIHRoZSBub2RlIGxvZ2ljYWxseSBhZGphY2VudCB0byAoY29udGFpbmVyLCBvZmZzZXQpIGluIHRoZSBnaXZlblxuICAvLyBkaXJlY3Rpb24sIHRyYW5zcGFyZW50bHkgc2tpcHBpbmcgYW55IFpXUy1vbmx5IHRleHQgbm9kZXMgaW4gYmV0d2Vlbi5cbiAgcHJpdmF0ZSByZXNvbHZlQWRqYWNlbnROb2RlKFxuICAgIGNvbnRhaW5lcjogTm9kZSxcbiAgICBvZmZzZXQ6IG51bWJlcixcbiAgICBkaXJlY3Rpb246ICdiZWZvcmUnIHwgJ2FmdGVyJyxcbiAgKTogTm9kZSB8IG51bGwge1xuICAgIGxldCBjYW5kaWRhdGU6IE5vZGUgfCBudWxsID0gbnVsbDtcblxuICAgIGlmIChjb250YWluZXIubm9kZVR5cGUgPT09IE5vZGUuVEVYVF9OT0RFKSB7XG4gICAgICBjb25zdCBsZW5ndGggPSAoY29udGFpbmVyLnRleHRDb250ZW50IHx8ICcnKS5sZW5ndGg7XG4gICAgICBjb25zdCBhdEJvdW5kYXJ5ID1cbiAgICAgICAgTWVudGlvbnNJbnB1dENvbXBvbmVudC5pc1p3cyhjb250YWluZXIpIHx8XG4gICAgICAgIChkaXJlY3Rpb24gPT09ICdiZWZvcmUnID8gb2Zmc2V0ID09PSAwIDogb2Zmc2V0ID09PSBsZW5ndGgpO1xuICAgICAgaWYgKCFhdEJvdW5kYXJ5KSB7XG4gICAgICAgIHJldHVybiBudWxsO1xuICAgICAgfVxuICAgICAgY2FuZGlkYXRlID1cbiAgICAgICAgZGlyZWN0aW9uID09PSAnYmVmb3JlJ1xuICAgICAgICAgID8gY29udGFpbmVyLnByZXZpb3VzU2libGluZ1xuICAgICAgICAgIDogY29udGFpbmVyLm5leHRTaWJsaW5nO1xuICAgIH0gZWxzZSBpZiAoY29udGFpbmVyLm5vZGVUeXBlID09PSBOb2RlLkVMRU1FTlRfTk9ERSkge1xuICAgICAgY29uc3QgY2hpbGRyZW4gPSAoY29udGFpbmVyIGFzIEhUTUxFbGVtZW50KS5jaGlsZE5vZGVzO1xuICAgICAgY2FuZGlkYXRlID1cbiAgICAgICAgZGlyZWN0aW9uID09PSAnYmVmb3JlJyA/IGNoaWxkcmVuW29mZnNldCAtIDFdIDogY2hpbGRyZW5bb2Zmc2V0XTtcbiAgICB9XG5cbiAgICB3aGlsZSAoY2FuZGlkYXRlICYmIE1lbnRpb25zSW5wdXRDb21wb25lbnQuaXNad3MoY2FuZGlkYXRlKSkge1xuICAgICAgY2FuZGlkYXRlID1cbiAgICAgICAgZGlyZWN0aW9uID09PSAnYmVmb3JlJ1xuICAgICAgICAgID8gY2FuZGlkYXRlLnByZXZpb3VzU2libGluZ1xuICAgICAgICAgIDogY2FuZGlkYXRlLm5leHRTaWJsaW5nO1xuICAgIH1cbiAgICByZXR1cm4gY2FuZGlkYXRlO1xuICB9XG5cbiAgcHJpdmF0ZSBmaW5kTWVudGlvbkFkamFjZW50VG9DdXJzb3IoXG4gICAgZGlyZWN0aW9uOiAnYmVmb3JlJyB8ICdhZnRlcicsXG4gICk6IEhUTUxFbGVtZW50IHwgbnVsbCB7XG4gICAgY29uc3Qgc2VsZWN0aW9uID0gd2luZG93LmdldFNlbGVjdGlvbigpO1xuICAgIGlmICghc2VsZWN0aW9uPy5pc0NvbGxhcHNlZCB8fCAhc2VsZWN0aW9uLnJhbmdlQ291bnQpIHtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cbiAgICBjb25zdCByYW5nZSA9IHNlbGVjdGlvbi5nZXRSYW5nZUF0KDApO1xuICAgIGNvbnN0IG5vZGUgPSB0aGlzLnJlc29sdmVBZGphY2VudE5vZGUoXG4gICAgICByYW5nZS5zdGFydENvbnRhaW5lcixcbiAgICAgIHJhbmdlLnN0YXJ0T2Zmc2V0LFxuICAgICAgZGlyZWN0aW9uLFxuICAgICk7XG4gICAgcmV0dXJuIE1lbnRpb25zSW5wdXRDb21wb25lbnQuaXNNZW50aW9uKG5vZGUpID8gbm9kZSA6IG51bGw7XG4gIH1cblxuICBwcml2YXRlIGZpbmRCckFkamFjZW50VG9DdXJzb3IoKTogSFRNTEVsZW1lbnQgfCBudWxsIHtcbiAgICBjb25zdCBzZWxlY3Rpb24gPSB3aW5kb3cuZ2V0U2VsZWN0aW9uKCk7XG4gICAgaWYgKCFzZWxlY3Rpb24/LmlzQ29sbGFwc2VkIHx8ICFzZWxlY3Rpb24ucmFuZ2VDb3VudCkge1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuICAgIGNvbnN0IHJhbmdlID0gc2VsZWN0aW9uLmdldFJhbmdlQXQoMCk7XG4gICAgY29uc3Qgbm9kZSA9IHRoaXMucmVzb2x2ZUFkamFjZW50Tm9kZShcbiAgICAgIHJhbmdlLnN0YXJ0Q29udGFpbmVyLFxuICAgICAgcmFuZ2Uuc3RhcnRPZmZzZXQsXG4gICAgICAnYmVmb3JlJyxcbiAgICApO1xuICAgIHJldHVybiBub2RlPy5ub2RlTmFtZSA9PT0gJ0JSJyA/IChub2RlIGFzIEhUTUxFbGVtZW50KSA6IG51bGw7XG4gIH1cblxuICBwcml2YXRlIGV4dGVuZFNlbGVjdGlvbkFjcm9zc01lbnRpb24oXG4gICAgbWVudGlvbjogSFRNTEVsZW1lbnQsXG4gICAgZGlyZWN0aW9uOiAnYmVmb3JlJyB8ICdhZnRlcicsXG4gICk6IHZvaWQge1xuICAgIGNvbnN0IHNlbGVjdGlvbiA9IHdpbmRvdy5nZXRTZWxlY3Rpb24oKTtcbiAgICBjb25zdCBwYXJlbnQgPSBtZW50aW9uLnBhcmVudE5vZGU7XG4gICAgaWYgKCFzZWxlY3Rpb24gfHwgIXBhcmVudCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBjb25zdCBpbmRleCA9IEFycmF5LmZyb20ocGFyZW50LmNoaWxkTm9kZXMpLmluZGV4T2YobWVudGlvbiBhcyBDaGlsZE5vZGUpO1xuICAgIHNlbGVjdGlvbi5leHRlbmQocGFyZW50LCBkaXJlY3Rpb24gPT09ICdiZWZvcmUnID8gaW5kZXggOiBpbmRleCArIDEpO1xuICB9XG5cbiAgcHJpdmF0ZSBwbGFjZUN1cnNvckFkamFjZW50VG9NZW50aW9uKFxuICAgIG1lbnRpb246IEhUTUxFbGVtZW50LFxuICAgIHNpZGU6ICdiZWZvcmUnIHwgJ2FmdGVyJyxcbiAgKTogdm9pZCB7XG4gICAgY29uc3QgcGFyZW50ID0gbWVudGlvbi5wYXJlbnROb2RlO1xuICAgIGlmICghcGFyZW50KSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGNvbnN0IHNpYmxpbmcgPVxuICAgICAgc2lkZSA9PT0gJ2JlZm9yZScgPyBtZW50aW9uLnByZXZpb3VzU2libGluZyA6IG1lbnRpb24ubmV4dFNpYmxpbmc7XG4gICAgbGV0IHp3czogTm9kZTtcbiAgICBpZiAoc2libGluZyAmJiBNZW50aW9uc0lucHV0Q29tcG9uZW50LmlzWndzKHNpYmxpbmcpKSB7XG4gICAgICB6d3MgPSBzaWJsaW5nO1xuICAgIH0gZWxzZSB7XG4gICAgICB6d3MgPSBkb2N1bWVudC5jcmVhdGVUZXh0Tm9kZShaV1MpO1xuICAgICAgcGFyZW50Lmluc2VydEJlZm9yZShcbiAgICAgICAgendzLFxuICAgICAgICBzaWRlID09PSAnYmVmb3JlJyA/IG1lbnRpb24gOiBtZW50aW9uLm5leHRTaWJsaW5nLFxuICAgICAgKTtcbiAgICB9XG4gICAgY29uc3QgcmFuZ2UgPSBkb2N1bWVudC5jcmVhdGVSYW5nZSgpO1xuICAgIHJhbmdlLnNldFN0YXJ0KHp3cywgc2lkZSA9PT0gJ2JlZm9yZScgPyAoendzLnRleHRDb250ZW50IHx8ICcnKS5sZW5ndGggOiAwKTtcbiAgICByYW5nZS5jb2xsYXBzZSh0cnVlKTtcbiAgICBjb25zdCBzZWxlY3Rpb24gPSB3aW5kb3cuZ2V0U2VsZWN0aW9uKCk7XG4gICAgc2VsZWN0aW9uPy5yZW1vdmVBbGxSYW5nZXMoKTtcbiAgICBzZWxlY3Rpb24/LmFkZFJhbmdlKHJhbmdlKTtcbiAgfVxuXG4gIHByaXZhdGUgcmVtb3ZlTWVudGlvbihtZW50aW9uOiBIVE1MRWxlbWVudCk6IHZvaWQge1xuICAgIGNvbnN0IHBhcmVudCA9IG1lbnRpb24ucGFyZW50Tm9kZTtcbiAgICBpZiAoIXBhcmVudCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICAvLyBFbXB0eSB0ZXh0LW5vZGUgYW5jaG9yIHByZXNlcnZlcyBjdXJzb3IgcG9zaXRpb24gdGhyb3VnaCB0aGUgcmVtb3ZhbC5cbiAgICBjb25zdCBhbmNob3IgPSBkb2N1bWVudC5jcmVhdGVUZXh0Tm9kZSgnJyk7XG4gICAgcGFyZW50Lmluc2VydEJlZm9yZShhbmNob3IsIG1lbnRpb24pO1xuXG4gICAgY29uc3QgcHJldiA9IG1lbnRpb24ucHJldmlvdXNTaWJsaW5nO1xuICAgIGNvbnN0IG5leHQgPSBtZW50aW9uLm5leHRTaWJsaW5nO1xuICAgIGlmIChwcmV2ICYmIE1lbnRpb25zSW5wdXRDb21wb25lbnQuaXNad3MocHJldikpIHtcbiAgICAgIHByZXYucmVtb3ZlKCk7XG4gICAgfVxuICAgIGlmIChuZXh0ICYmIE1lbnRpb25zSW5wdXRDb21wb25lbnQuaXNad3MobmV4dCkpIHtcbiAgICAgIG5leHQucmVtb3ZlKCk7XG4gICAgfVxuICAgIG1lbnRpb24ucmVtb3ZlKCk7XG5cbiAgICBjb25zdCByYW5nZSA9IGRvY3VtZW50LmNyZWF0ZVJhbmdlKCk7XG4gICAgcmFuZ2Uuc2V0U3RhcnQoYW5jaG9yLCAwKTtcbiAgICByYW5nZS5jb2xsYXBzZSh0cnVlKTtcbiAgICBjb25zdCBzZWxlY3Rpb24gPSB3aW5kb3cuZ2V0U2VsZWN0aW9uKCk7XG4gICAgc2VsZWN0aW9uPy5yZW1vdmVBbGxSYW5nZXMoKTtcbiAgICBzZWxlY3Rpb24/LmFkZFJhbmdlKHJhbmdlKTtcbiAgfVxuXG4gIC8vIFJlLWVzdGFibGlzaGVzIHRoZSBpbnZhcmlhbnQ6IGV2ZXJ5IG1lbnRpb24gaGFzIGV4YWN0bHkgb25lIFpXUyB0ZXh0XG4gIC8vIG5vZGUgaW1tZWRpYXRlbHkgYmVmb3JlIGFuZCBhZnRlciBpdCwgYW5kIHRoZXJlIGFyZSBubyBvcnBoYW4gWldTLW9ubHlcbiAgLy8gdGV4dCBub2RlcyBhbnl3aGVyZSBlbHNlLiBSdW4gYWZ0ZXIgYW55IG9wZXJhdGlvbiB0aGF0IG1heSBkaXN0dXJiIHRoZVxuICAvLyB0cmVlICh0eXBpbmcsIHBhc3RlLCBjdXQsIGRlbGV0ZSkgc28gY3J1ZnQgZG9lc24ndCBhY2N1bXVsYXRlIGFjcm9zc1xuICAvLyByZXBlYXRlZCBjb3B5L3Bhc3RlIGN5Y2xlcy5cbiAgcHJpdmF0ZSBub3JtYWxpemVNZW50aW9uUGFkZGluZygpOiB2b2lkIHtcbiAgICBjb25zdCByb290ID0gdGhpcy5pbnB1dEVsZW1lbnQ/Lm5hdGl2ZUVsZW1lbnQ7XG4gICAgaWYgKCFyb290KSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgLy8gMS4gRW5zdXJlIGVhY2ggbWVudGlvbiBoYXMgYSBaV1MgcGFkIG9uIGJvdGggc2lkZXMuXG4gICAgY29uc3QgbWVudGlvbnMgPSBBcnJheS5mcm9tKFxuICAgICAgcm9vdC5xdWVyeVNlbGVjdG9yQWxsKCdzcGFuW2RhdGEtdHlwZT1cIm1lbnRpb25cIl0nKSxcbiAgICApIGFzIEhUTUxFbGVtZW50W107XG4gICAgZm9yIChjb25zdCBtIG9mIG1lbnRpb25zKSB7XG4gICAgICBjb25zdCBwYXJlbnQgPSBtLnBhcmVudE5vZGU7XG4gICAgICBpZiAoIXBhcmVudCkge1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cbiAgICAgIGlmIChcbiAgICAgICAgIW0ucHJldmlvdXNTaWJsaW5nIHx8XG4gICAgICAgICFNZW50aW9uc0lucHV0Q29tcG9uZW50LmlzWndzKG0ucHJldmlvdXNTaWJsaW5nKVxuICAgICAgKSB7XG4gICAgICAgIHBhcmVudC5pbnNlcnRCZWZvcmUoZG9jdW1lbnQuY3JlYXRlVGV4dE5vZGUoWldTKSwgbSk7XG4gICAgICB9XG4gICAgICBpZiAoIW0ubmV4dFNpYmxpbmcgfHwgIU1lbnRpb25zSW5wdXRDb21wb25lbnQuaXNad3MobS5uZXh0U2libGluZykpIHtcbiAgICAgICAgcGFyZW50Lmluc2VydEJlZm9yZShkb2N1bWVudC5jcmVhdGVUZXh0Tm9kZShaV1MpLCBtLm5leHRTaWJsaW5nKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyAyLiBSZW1vdmUgYW55IFpXUy1vbmx5IHRleHQgbm9kZSB0aGF0IGlzbid0IGRpcmVjdGx5IGFkamFjZW50IHRvIGFcbiAgICAvLyAgICBtZW50aW9uIChvcnBoYW5zIGZyb20gbGluZS1icmVhayBwYWRzLCBsZWZ0b3ZlciBzcGxpdHMgZnJvbSBwcmV2aW91c1xuICAgIC8vICAgIHBhc3RlIGluc2VydGlvbnMsIGR1cGxpY2F0ZSBwYWRzIGZyb20gYWNjdW11bGF0ZWQgY29weS9wYXN0ZSBjeWNsZXMpLlxuICAgIC8vICAgIFNraXAgYSBub2RlIGlmIHRoZSBjdXJzb3IgY3VycmVudGx5IGxpdmVzIGluIGl0IOKAlCBwcmVzZXJ2ZXMgY2FyZXRcbiAgICAvLyAgICBwb3NpdGlvbiB3aXRob3V0IG5lZWRpbmcgbWFudWFsIHJlc3RvcmF0aW9uLlxuICAgIGNvbnN0IHNlbGVjdGlvbiA9IHdpbmRvdy5nZXRTZWxlY3Rpb24oKTtcbiAgICBjb25zdCBjdXJzb3JOb2RlID1cbiAgICAgIHNlbGVjdGlvbj8ucmFuZ2VDb3VudCAmJlxuICAgICAgcm9vdC5jb250YWlucyhzZWxlY3Rpb24uZ2V0UmFuZ2VBdCgwKS5zdGFydENvbnRhaW5lcilcbiAgICAgICAgPyBzZWxlY3Rpb24uZ2V0UmFuZ2VBdCgwKS5zdGFydENvbnRhaW5lclxuICAgICAgICA6IG51bGw7XG5cbiAgICBjb25zdCB3YWxrZXIgPSBkb2N1bWVudC5jcmVhdGVUcmVlV2Fsa2VyKHJvb3QsIE5vZGVGaWx0ZXIuU0hPV19URVhULCBudWxsKTtcbiAgICBjb25zdCBvcnBoYW5zOiBUZXh0W10gPSBbXTtcbiAgICB3aGlsZSAod2Fsa2VyLm5leHROb2RlKCkpIHtcbiAgICAgIGNvbnN0IG5vZGUgPSB3YWxrZXIuY3VycmVudE5vZGUgYXMgVGV4dDtcbiAgICAgIGlmICghTWVudGlvbnNJbnB1dENvbXBvbmVudC5pc1p3cyhub2RlKSB8fCBub2RlID09PSBjdXJzb3JOb2RlKSB7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuICAgICAgY29uc3QgYWRqYWNlbnRUb01lbnRpb24gPVxuICAgICAgICBNZW50aW9uc0lucHV0Q29tcG9uZW50LmlzTWVudGlvbihub2RlLnByZXZpb3VzU2libGluZykgfHxcbiAgICAgICAgTWVudGlvbnNJbnB1dENvbXBvbmVudC5pc01lbnRpb24obm9kZS5uZXh0U2libGluZyk7XG4gICAgICBpZiAoIWFkamFjZW50VG9NZW50aW9uKSB7XG4gICAgICAgIG9ycGhhbnMucHVzaChub2RlKTtcbiAgICAgIH1cbiAgICB9XG4gICAgZm9yIChjb25zdCBub2RlIG9mIG9ycGhhbnMpIHtcbiAgICAgIG5vZGUucmVtb3ZlKCk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBoYW5kbGVNZW50aW9uc0Ryb3Bkb3duTmF2KGV2ZW50OiBLZXlib2FyZEV2ZW50KTogdm9pZCB7XG4gICAgY29uc3QgZmlsdGVyZWRVc2VycyA9IHRoaXMuZ2V0RmlsdGVyZWRVc2VycygpO1xuICAgIGlmIChmaWx0ZXJlZFVzZXJzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgdGhpcy5jbG9zZU1lbnRpb25zKCk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgc3dpdGNoIChldmVudC5rZXkpIHtcbiAgICAgIGNhc2UgJ0Fycm93RG93bic6XG4gICAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgIHRoaXMuc2VsZWN0ZWRVc2VySW5kZXggPSBNYXRoLm1pbihcbiAgICAgICAgICB0aGlzLnNlbGVjdGVkVXNlckluZGV4ICsgMSxcbiAgICAgICAgICBmaWx0ZXJlZFVzZXJzLmxlbmd0aCAtIDEsXG4gICAgICAgICk7XG4gICAgICAgIHRoaXMuY2RyLm1hcmtGb3JDaGVjaygpO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJ0Fycm93VXAnOlxuICAgICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICB0aGlzLnNlbGVjdGVkVXNlckluZGV4ID0gTWF0aC5tYXgodGhpcy5zZWxlY3RlZFVzZXJJbmRleCAtIDEsIDApO1xuICAgICAgICB0aGlzLmNkci5tYXJrRm9yQ2hlY2soKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlICdFbnRlcic6XG4gICAgICBjYXNlICdUYWInOlxuICAgICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICBpZiAoZmlsdGVyZWRVc2Vyc1t0aGlzLnNlbGVjdGVkVXNlckluZGV4XSkge1xuICAgICAgICAgIHRoaXMuc2VsZWN0VXNlcihmaWx0ZXJlZFVzZXJzW3RoaXMuc2VsZWN0ZWRVc2VySW5kZXhdKTtcbiAgICAgICAgfVxuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJ0VzY2FwZSc6XG4gICAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgIHRoaXMuY2xvc2VNZW50aW9ucygpO1xuICAgICAgICBicmVhaztcbiAgICB9XG4gIH1cblxuICAvLyDilIDilIDilIAgSW5zZXJ0aW9uIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgFxuXG4gIHByaXZhdGUgcGxhaW5UZXh0VG9Ob2Rlcyh0ZXh0OiBzdHJpbmcpOiBOb2RlW10ge1xuICAgIGNvbnN0IG5vZGVzOiBOb2RlW10gPSBbXTtcbiAgICBjb25zdCBsaW5lcyA9IHRleHQuc3BsaXQoJ1xcbicpO1xuICAgIGxpbmVzLmZvckVhY2goKGxpbmUsIGluZGV4KSA9PiB7XG4gICAgICBpZiAobGluZSkge1xuICAgICAgICBub2Rlcy5wdXNoKGRvY3VtZW50LmNyZWF0ZVRleHROb2RlKGxpbmUpKTtcbiAgICAgIH1cbiAgICAgIGlmIChpbmRleCA8IGxpbmVzLmxlbmd0aCAtIDEpIHtcbiAgICAgICAgbm9kZXMucHVzaChkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdicicpKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgICByZXR1cm4gbm9kZXM7XG4gIH1cbiAgLy8gQ3JlYXRlIGEgdGVtcG9yYXJ5IGNvbnRhaW5lciB0byBwYXJzZSB0aGUgSFRNTFxuICBwcml2YXRlIHBhcnNlUGFzdGVkSHRtbChodG1sOiBzdHJpbmcpOiBOb2RlW10ge1xuICAgIC8vIENyZWF0ZSBhIHRlbXBvcmFyeSBjb250YWluZXIgdG8gcGFyc2UgdGhlIEhUTUxcbiAgICBjb25zdCB0ZW1wQ29udGFpbmVyID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XG4gICAgdGVtcENvbnRhaW5lci5pbm5lckhUTUwgPSBodG1sO1xuXG4gICAgY29uc3Qgbm9kZXM6IE5vZGVbXSA9IFtdO1xuICAgIGNvbnN0IHdhbGsgPSAobm9kZTogTm9kZSk6IHZvaWQgPT4ge1xuICAgICAgaWYgKG5vZGUubm9kZVR5cGUgPT09IE5vZGUuRUxFTUVOVF9OT0RFKSB7XG4gICAgICAgIGNvbnN0IGVsID0gbm9kZSBhcyBIVE1MRWxlbWVudDtcbiAgICAgICAgLy8gREFITkUgTk9URSAtIHdlIG9ubHkgd2FudCBtZW50aW9uIHNwYW5zLCBiciBlbGVtZW50cywgYW5kIHRleHRcbiAgICAgICAgaWYgKFxuICAgICAgICAgIGVsLnRhZ05hbWUgPT09ICdTUEFOJyAmJlxuICAgICAgICAgIGVsLmdldEF0dHJpYnV0ZSgnZGF0YS10eXBlJykgPT09ICdtZW50aW9uJyAmJlxuICAgICAgICAgIGVsLmhhc0F0dHJpYnV0ZSgnZGF0YS1pZCcpXG4gICAgICAgICkge1xuICAgICAgICAgIC8vQ3JlYXRlIG1lbnRpb24gdG8gdWx0aW1hdGVseSBpbnNlcnQgaW50byB0aGUgRE9NXG4gICAgICAgICAgY29uc3Qgc3BhbiA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ3NwYW4nKTtcbiAgICAgICAgICBzcGFuLmNsYXNzTmFtZSA9IHRoaXMucmVhZG9ubHkgPyAncmVhZG9ubHktbWVudGlvbicgOiAnbWVudGlvbic7XG4gICAgICAgICAgc3Bhbi5zZXRBdHRyaWJ1dGUoJ2RhdGEtaWQnLCBlbC5nZXRBdHRyaWJ1dGUoJ2RhdGEtaWQnKSB8fCAnJyk7XG4gICAgICAgICAgc3Bhbi5zZXRBdHRyaWJ1dGUoJ2RhdGEtdHlwZScsICdtZW50aW9uJyk7XG4gICAgICAgICAgc3Bhbi5zZXRBdHRyaWJ1dGUoJ2NvbnRlbnRlZGl0YWJsZScsICdmYWxzZScpO1xuICAgICAgICAgIGNvbnN0IHJhdyA9IGVsLnRleHRDb250ZW50IHx8ICcnO1xuICAgICAgICAgIHNwYW4udGV4dENvbnRlbnQgPSByYXcuc3RhcnRzV2l0aCgnQCcpID8gcmF3IDogYEAke3Jhd31gO1xuICAgICAgICAgIG5vZGVzLnB1c2goc3Bhbik7XG4gICAgICAgIH0gZWxzZSBpZiAoZWwudGFnTmFtZSA9PT0gJ0JSJykge1xuICAgICAgICAgIC8vIFByZXNlcnZlIGxpbmUgYnJlYWtzXG4gICAgICAgICAgbm9kZXMucHVzaChkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdicicpKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAvL1JlY3Vyc2l2ZWx5IGxvb2sgZm9yIG5lc3RlZCBjaGlsZHJlblxuICAgICAgICAgIGZvciAoY29uc3QgY2hpbGQgb2YgQXJyYXkuZnJvbShlbC5jaGlsZE5vZGVzKSkge1xuICAgICAgICAgICAgd2FsayhjaGlsZCk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9IGVsc2UgaWYgKG5vZGUubm9kZVR5cGUgPT09IE5vZGUuVEVYVF9OT0RFKSB7XG4gICAgICAgIGNvbnN0IHRleHQgPSAobm9kZS50ZXh0Q29udGVudCB8fCAnJykucmVwbGFjZShaV1NfUkVHRVgsICcnKTtcbiAgICAgICAgaWYgKHRleHQpIHtcbiAgICAgICAgICBub2Rlcy5wdXNoKGRvY3VtZW50LmNyZWF0ZVRleHROb2RlKHRleHQpKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH07XG5cbiAgICBmb3IgKGNvbnN0IGNoaWxkIG9mIEFycmF5LmZyb20odGVtcENvbnRhaW5lci5jaGlsZE5vZGVzKSkge1xuICAgICAgd2FsayhjaGlsZCk7XG4gICAgfVxuICAgIC8vREFITkUgTk9URSAtIHRoZSByZXN1bHQgaGVyZSBzaG91bGQgYmUgYW4gYXJyYXkgb2YgdGV4dC9zcGFuLW1lbnRpb24vYnIgbm9kZXNcbiAgICByZXR1cm4gbm9kZXM7XG4gIH1cblxuICBwcml2YXRlIGluc2VydE5vZGVzQXRDdXJzb3Iobm9kZXM6IE5vZGVbXSk6IHZvaWQge1xuICAgIC8vR2V0IHNlbGVjdGlvbiBvYmplY3QsIHJlcHJlc2VudGluZyB1c2VyIGN1cnNvciBwb3NpdGlvbi9zZWxlY3Rpb25cbiAgICAvL0dldCBSYW5nZSBvYmplY3QgYXQgc3RhcnQgb2Ygc2VsZWN0aW9uLCB3aGljaCBzaG91bGQgcmVwcmVzZW50IGN1cnNvciBwb3NpdGlvblxuICAgIC8vSWYgdGhlcmUgaXMgYSBzZWxlY3Rpb24sIGRlbGV0ZSBpdFxuICAgIC8vSW5zZXJ0IHRoZSBwYXJzZWQgbm9kZXMgZnJvbSBhYm92ZSwgbW92ZSByYW5nZSBlbmRzIHRvIGFmdGVyIG5vZGVcbiAgICAvL1RoZW4gcmVtb3ZlIHRoZSByYW5nZSBhbmQgcmVzZXQgaXQgdG8gbW92ZSB0aGUgY3Vyc29yIHBvc2l0aW9uIHRvIHRoZSBlbmRcbiAgICBjb25zdCBzZWxlY3Rpb24gPSB3aW5kb3cuZ2V0U2VsZWN0aW9uKCk7XG4gICAgaWYgKCFzZWxlY3Rpb24/LnJhbmdlQ291bnQpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgY29uc3QgcmFuZ2UgPSBzZWxlY3Rpb24uZ2V0UmFuZ2VBdCgwKTtcbiAgICByYW5nZS5kZWxldGVDb250ZW50cygpO1xuXG4gICAgbGV0IGN1cnNvclRhcmdldDogTm9kZSB8IG51bGwgPSBudWxsO1xuICAgIGZvciAoY29uc3Qgbm9kZSBvZiBub2Rlcykge1xuICAgICAgaWYgKE1lbnRpb25zSW5wdXRDb21wb25lbnQuaXNNZW50aW9uKG5vZGUpKSB7XG4gICAgICAgIGNvbnN0IGJlZm9yZSA9IGRvY3VtZW50LmNyZWF0ZVRleHROb2RlKFpXUyk7XG4gICAgICAgIGNvbnN0IGFmdGVyID0gZG9jdW1lbnQuY3JlYXRlVGV4dE5vZGUoWldTKTtcbiAgICAgICAgcmFuZ2UuaW5zZXJ0Tm9kZShiZWZvcmUpO1xuICAgICAgICByYW5nZS5zZXRTdGFydEFmdGVyKGJlZm9yZSk7XG4gICAgICAgIHJhbmdlLmluc2VydE5vZGUobm9kZSk7XG4gICAgICAgIHJhbmdlLnNldFN0YXJ0QWZ0ZXIobm9kZSk7XG4gICAgICAgIHJhbmdlLmluc2VydE5vZGUoYWZ0ZXIpO1xuICAgICAgICByYW5nZS5zZXRTdGFydEFmdGVyKGFmdGVyKTtcbiAgICAgICAgY3Vyc29yVGFyZ2V0ID0gYWZ0ZXI7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByYW5nZS5pbnNlcnROb2RlKG5vZGUpO1xuICAgICAgICByYW5nZS5zZXRTdGFydEFmdGVyKG5vZGUpO1xuICAgICAgICBjdXJzb3JUYXJnZXQgPSBub2RlO1xuICAgICAgfVxuICAgICAgcmFuZ2UuY29sbGFwc2UodHJ1ZSk7XG4gICAgfVxuXG4gICAgLy8gQWZ0ZXIgYSBtZW50aW9uLCBsZWF2ZSB0aGUgY3Vyc29yIGluc2lkZSB0aGUgdHJhaWxpbmcgWldTIHNvIEFycm93TGVmdFxuICAgIC8vIGNhbiBzdGVwIGJhY2sgdG8gYmVmb3JlLXRoZS1tZW50aW9uIG5hdHVyYWxseS5cbiAgICBpZiAoY3Vyc29yVGFyZ2V0ICYmIE1lbnRpb25zSW5wdXRDb21wb25lbnQuaXNad3MoY3Vyc29yVGFyZ2V0KSkge1xuICAgICAgcmFuZ2Uuc2V0U3RhcnQoY3Vyc29yVGFyZ2V0LCAwKTtcbiAgICAgIHJhbmdlLmNvbGxhcHNlKHRydWUpO1xuICAgIH1cblxuICAgIHNlbGVjdGlvbi5yZW1vdmVBbGxSYW5nZXMoKTtcbiAgICBzZWxlY3Rpb24uYWRkUmFuZ2UocmFuZ2UpO1xuICB9XG5cbiAgcHJpdmF0ZSBpbnNlcnRMaW5lQnJlYWsoKTogdm9pZCB7XG4gICAgY29uc3Qgc2VsZWN0aW9uID0gd2luZG93LmdldFNlbGVjdGlvbigpO1xuICAgIGlmICghc2VsZWN0aW9uPy5yYW5nZUNvdW50IHx8ICF0aGlzLmlucHV0RWxlbWVudD8ubmF0aXZlRWxlbWVudCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBjb25zdCByYW5nZSA9IHNlbGVjdGlvbi5nZXRSYW5nZUF0KDApO1xuICAgIHJhbmdlLmRlbGV0ZUNvbnRlbnRzKCk7XG5cbiAgICBjb25zdCBiciA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2JyJyk7XG4gICAgcmFuZ2UuaW5zZXJ0Tm9kZShicik7XG4gICAgcmFuZ2Uuc2V0U3RhcnRBZnRlcihicik7XG4gICAgcmFuZ2UuY29sbGFwc2UodHJ1ZSk7XG5cbiAgICAvLyBBIHRyYWlsaW5nIDxicj4gYWxvbmUgZG9lc24ndCByZW5kZXIgYW4gZW1wdHkgbGluZSBpbiBjb250ZW50ZWRpdGFibGUg4oCUXG4gICAgLy8gYSBaV1MgZ2l2ZXMgdGhlIGNhcmV0IGEgcGxhY2UgdG8gbGFuZC5cbiAgICBpZiAoIWJyLm5leHRTaWJsaW5nKSB7XG4gICAgICBjb25zdCB6d3MgPSBkb2N1bWVudC5jcmVhdGVUZXh0Tm9kZShaV1MpO1xuICAgICAgcmFuZ2UuaW5zZXJ0Tm9kZSh6d3MpO1xuICAgICAgcmFuZ2Uuc2V0U3RhcnQoendzLCAwKTtcbiAgICAgIHJhbmdlLmNvbGxhcHNlKHRydWUpO1xuICAgIH1cblxuICAgIHNlbGVjdGlvbi5yZW1vdmVBbGxSYW5nZXMoKTtcbiAgICBzZWxlY3Rpb24uYWRkUmFuZ2UocmFuZ2UpO1xuICB9XG5cbiAgLy8g4pSA4pSA4pSAIE1lbnRpb24gdHJpZ2dlciAvIGRyb3Bkb3duIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgFxuXG4gIHByaXZhdGUgY2hlY2tGb3JNZW50aW9uVHJpZ2dlcigpOiB2b2lkIHtcbiAgICBjb25zdCBzZWxlY3Rpb24gPSB3aW5kb3cuZ2V0U2VsZWN0aW9uKCk7XG4gICAgaWYgKCFzZWxlY3Rpb24gfHwgIXNlbGVjdGlvbi5yYW5nZUNvdW50IHx8ICF0aGlzLmlucHV0RWxlbWVudCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IHJhbmdlID0gc2VsZWN0aW9uLmdldFJhbmdlQXQoMCk7XG4gICAgY29uc3QgdGV4dEJlZm9yZUN1cnNvciA9IHRoaXMuZ2V0VGV4dEJlZm9yZUN1cnNvcihyYW5nZSk7XG4gICAgY29uc3QgbGFzdEF0SW5kZXggPSB0ZXh0QmVmb3JlQ3Vyc29yLmxhc3RJbmRleE9mKCdAJyk7XG5cbiAgICBpZiAobGFzdEF0SW5kZXggPT09IC0xKSB7XG4gICAgICB0aGlzLmNsb3NlTWVudGlvbnMoKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgLy9JZiB3ZSBhbGxvdyBmb3IgYSBzaW5nbGUgc3BhY2UsIHdlIG5lZWQgdG8gY2hlY2sgdG8gbWFrZSBzdXJlIHRoYXQgdGhpcyBsb2dpYyB3b24ndCBwaWNrIHVwIHByZXZpb3VzXG4gICAgLy8nQCcgbWVudGlvbnMgYW5kIGtlZXAgdGhlIG1lbnRpb24gZHJvcGRvd24gb3BlblxuICAgIGNvbnN0IGF0UG9zaXRpb24gPSB0aGlzLmZpbmREb21Qb3NpdGlvbkF0Q2hhckluZGV4KGxhc3RBdEluZGV4KTtcbiAgICBpZiAoYXRQb3NpdGlvbiAmJiB0aGlzLmlzSW5zaWRlTWVudGlvblNwYW4oYXRQb3NpdGlvbi5ub2RlKSkge1xuICAgICAgdGhpcy5jbG9zZU1lbnRpb25zKCk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc3QgdGV4dEFmdGVyQXQgPSB0ZXh0QmVmb3JlQ3Vyc29yLnN1YnN0cmluZyhsYXN0QXRJbmRleCArIDEpO1xuICAgIGNvbnN0IGNoYXIxID0gdGV4dEFmdGVyQXQuY2hhckNvZGVBdCgwKTtcbiAgICBjb25zdCBjaGFyTiA9IHRleHRBZnRlckF0LmNoYXJDb2RlQXQodGV4dEFmdGVyQXQubGVuZ3RoIC0gMSk7XG4gICAgY29uc3QgY2hhck5fMSA9IHRleHRBZnRlckF0LmNoYXJDb2RlQXQodGV4dEFmdGVyQXQubGVuZ3RoIC0gMik7XG4gICAgLy9UaGVzZSBhcmUgdGhlIFVuaWNvZGUgcmVwcmVzZW50YXRpb25zIG9mIG5vcm1hbCBzcGFjZSBhbmQgbm9uLWJyZWFraW5nIHNwYWNlXG4gICAgY29uc3QgdW5pY29kZVNwYWNlQ2hhcnMgPSBbMzIsIDE2MF07XG5cbiAgICAvLyBDbG9zZSBtZW50aW9ucyBpZjpcbiAgICAvLyAtIFRoZXJlJ3MgYSBkb3VibGUgc3BhY2UgKGFsbG93cyBzaW5nbGUgc3BhY2VzIGluIHRoZSBtaWRkbGUgb2Ygc2VhcmNoKVxuICAgIC8vIC0gVGhlIHRleHQgc3RhcnRzIHdpdGggYSBzcGFjZSAodHlwaW5nIFwiQCBcIiBzaG91bGQgbm90IHRyaWdnZXIgbWVudGlvbnMpXG4gICAgaWYgKFxuICAgICAgdGV4dEFmdGVyQXQuaW5jbHVkZXMoJyAgJykgfHxcbiAgICAgIHRleHRBZnRlckF0LnN0YXJ0c1dpdGgoJyAnKSB8fFxuICAgICAgY2hhcjEgPT0gMTYwIHx8XG4gICAgICAodW5pY29kZVNwYWNlQ2hhcnMuaW5jbHVkZXMoY2hhck4pICYmIHVuaWNvZGVTcGFjZUNoYXJzLmluY2x1ZGVzKGNoYXJOXzEpKVxuICAgICkge1xuICAgICAgdGhpcy5jbG9zZU1lbnRpb25zKCk7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIC8vIFRyaW0gdHJhaWxpbmcvbGVhZGluZyBzcGFjZXMgZnJvbSBzZWFyY2ggdGV4dCB3aGlsZSBwcmVzZXJ2aW5nIHNwYWNlcyBpbiB0aGUgbWlkZGxlXG4gICAgdGhpcy5tZW50aW9uU2VhcmNoVGV4dCA9IHRleHRBZnRlckF0LnRyaW0oKTtcbiAgICAvLyBPbmx5IHNob3cgbWVudGlvbnMgaWYgdGhlcmUgYXJlIGZpbHRlcmVkIHVzZXJzXG4gICAgY29uc3QgZmlsdGVyZWRVc2VycyA9IHRoaXMuZ2V0RmlsdGVyZWRVc2VycygpO1xuICAgIGlmIChmaWx0ZXJlZFVzZXJzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgdGhpcy5jbG9zZU1lbnRpb25zKCk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdGhpcy5tZW50aW9uc1Zpc2libGUgPSB0cnVlO1xuICAgIHRoaXMuc2VsZWN0ZWRVc2VySW5kZXggPSAwO1xuXG4gICAgLy9TYXZlIHRoZSBjdXJyZW50IHJhbmdlIGZvciBsYXRlciByZXN0b3JhdGlvbiAobmVlZGVkIGZvciBjbGljayBzZWxlY3Rpb24pXG4gICAgLy9EQUhORSBOT1RFIC0gdGhpcyBpcyBhbm5veWluZ2x5IG5lY2Vlc3NhcnkgYmVjYXVzZSBjbGlja3MgYW5kIGVudGVyIGtleXMgaGF2ZSBkaWZmZXJlbnQgZWZmZWN0cyBvbiB0aGVcbiAgICAvL2ZvY3VzIG9mIHRoZSBjb250ZW50ZWRpdGFibGUgZGl2XG4gICAgdGhpcy5zYXZlZFJhbmdlID0gcmFuZ2UuY2xvbmVSYW5nZSgpO1xuXG4gICAgaWYgKGF0UG9zaXRpb24pIHtcbiAgICAgIGNvbnN0IGF0UmFuZ2UgPSBkb2N1bWVudC5jcmVhdGVSYW5nZSgpO1xuICAgICAgYXRSYW5nZS5zZXRTdGFydChhdFBvc2l0aW9uLm5vZGUsIGF0UG9zaXRpb24ub2Zmc2V0KTtcbiAgICAgIGF0UmFuZ2Uuc2V0RW5kKGF0UG9zaXRpb24ubm9kZSwgYXRQb3NpdGlvbi5vZmZzZXQgKyAxKTtcbiAgICAgIHRoaXMubWVudGlvbkFuY2hvciA9IGF0UmFuZ2UuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG4gICAgfVxuICAgIHRoaXMuY2RyLm1hcmtGb3JDaGVjaygpO1xuICB9XG5cbiAgcHJpdmF0ZSBnZXRUZXh0QmVmb3JlQ3Vyc29yKHJhbmdlOiBSYW5nZSk6IHN0cmluZyB7XG4gICAgY29uc3QgY2xvbmVkUmFuZ2UgPSByYW5nZS5jbG9uZVJhbmdlKCk7XG4gICAgLy9XZSBzZWxlY3QgYWxsIG9mIHRoZSBpbnB1dCBjb250ZW50cywgYW5kIHRoZW4gbW92ZSB0aGUgZW5kIHBvaW50IHRvIHRoZSBjdXJyZW50IGN1cnNvciBwb3NpdGlvblxuICAgIGNsb25lZFJhbmdlLnNlbGVjdE5vZGVDb250ZW50cyh0aGlzLmlucHV0RWxlbWVudCEubmF0aXZlRWxlbWVudCk7XG4gICAgY2xvbmVkUmFuZ2Uuc2V0RW5kKHJhbmdlLmVuZENvbnRhaW5lciwgcmFuZ2UuZW5kT2Zmc2V0KTtcbiAgICAvL0NyZWF0ZSBhIHRlbXBvcmFyeSBkaXYgc28gdGhhdCB3ZSBjYW4gZXh0cmFjdCB0ZXh0IGNvbnRlbnQgZnJvbSBpdFxuICAgIGNvbnN0IGZyYWdtZW50ID0gY2xvbmVkUmFuZ2UuY2xvbmVDb250ZW50cygpO1xuICAgIGNvbnN0IGRpdiA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuICAgIGRpdi5hcHBlbmRDaGlsZChmcmFnbWVudCk7XG4gICAgLy9HZXQgdGV4dCBjb250ZW50LCByZXBsYWNpbmcgbWVudGlvbiBzcGFucyB3aXRoIEBuYW1lXG4gICAgcmV0dXJuIGRpdi50ZXh0Q29udGVudCB8fCAnJztcbiAgfVxuXG4gIGdldEZpbHRlcmVkVXNlcnMoKTogTWVudGlvbnNJbnB1dENvbXBvbmVudC5Vc2VyW10ge1xuICAgIGNvbnN0IHVzZXJzID0gIXRoaXMubWVudGlvblNlYXJjaFRleHRcbiAgICAgID8gdGhpcy51c2Vyc1xuICAgICAgOiB0aGlzLnVzZXJzLmZpbHRlcih1c2VyID0+XG4gICAgICAgICAgdXNlci5uYW1lXG4gICAgICAgICAgICAudG9Mb3dlckNhc2UoKVxuICAgICAgICAgICAgLmluY2x1ZGVzKHRoaXMubWVudGlvblNlYXJjaFRleHQudG9Mb3dlckNhc2UoKSksXG4gICAgICAgICk7XG4gICAgcmV0dXJuIHVzZXJzLnNsaWNlKCkuc29ydCgoYSwgYikgPT4gYS5uYW1lLmxvY2FsZUNvbXBhcmUoYi5uYW1lKSk7XG4gIH1cblxuICBvblVzZXJIb3ZlcihpbmRleDogbnVtYmVyKTogdm9pZCB7XG4gICAgdGhpcy5zZWxlY3RlZFVzZXJJbmRleCA9IGluZGV4O1xuICAgIHRoaXMuY2RyLm1hcmtGb3JDaGVjaygpO1xuICB9XG5cbiAgc2VsZWN0VXNlcih1c2VyOiBNZW50aW9uc0lucHV0Q29tcG9uZW50LlVzZXIpOiB2b2lkIHtcbiAgICBpZiAoIXRoaXMuaW5wdXRFbGVtZW50KSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIC8vVGhpcyBnZXRzIERPTSBpbmZvIGZyb20gdXNlciAoZS5nLiBoaWdobGlnaHRlZCBzZWxlY3Rpb25zLCBhbmQgY3Vyc29yIHBvc2l0aW9uKVxuICAgIGNvbnN0IHNlbGVjdGlvbiA9IHdpbmRvdy5nZXRTZWxlY3Rpb24oKTtcbiAgICBpZiAoIXNlbGVjdGlvbikge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICAvLyBSZXN0b3JlIHRoZSBzYXZlZCByYW5nZSBpZiBhdmFpbGFibGUgKG5lZWRlZCB3aGVuIHNlbGVjdGluZyB2aWEgY2xpY2spXG4gICAgaWYgKHRoaXMuc2F2ZWRSYW5nZSkge1xuICAgICAgc2VsZWN0aW9uLnJlbW92ZUFsbFJhbmdlcygpO1xuICAgICAgc2VsZWN0aW9uLmFkZFJhbmdlKHRoaXMuc2F2ZWRSYW5nZSk7XG4gICAgfVxuICAgIGlmICghc2VsZWN0aW9uLnJhbmdlQ291bnQpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgLy8gRGVsZXRlIHRoZSBcIkBcIiBhbmQgc2VhcmNoIHRleHRcbiAgICB0aGlzLmRlbGV0ZUF0TWVudGlvblNlYXJjaCgpO1xuXG4gICAgLy9EQUhORSBOT1RFIC0gdGhpcyB3b3VsZCBpZGVhbGx5IGJlIHRoZSBzYW1lIGFzIGNvbnRlbnRJdGVtVG9IVE1MLCBidXQgd2UgbmVlZCBhbiBhY3R1YWwgZWxlbWVudCByZWZlcmVuY2UgaGVyZSBpbiBvcmRlciB0byBhcHBlbmQgaXQgdG8gdGhlIERPTVxuICAgIGNvbnN0IG1lbnRpb25TcGFuID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnc3BhbicpO1xuICAgIG1lbnRpb25TcGFuLmNsYXNzTmFtZSA9IHRoaXMucmVhZG9ubHkgPyAncmVhZG9ubHktbWVudGlvbicgOiAnbWVudGlvbic7XG4gICAgbWVudGlvblNwYW4uc2V0QXR0cmlidXRlKCdkYXRhLWlkJywgU3RyaW5nKHVzZXIuaWQpKTtcbiAgICBtZW50aW9uU3Bhbi5zZXRBdHRyaWJ1dGUoJ2RhdGEtdHlwZScsICdtZW50aW9uJyk7XG4gICAgbWVudGlvblNwYW4uc2V0QXR0cmlidXRlKCdjb250ZW50ZWRpdGFibGUnLCAnZmFsc2UnKTtcbiAgICBtZW50aW9uU3Bhbi50ZXh0Q29udGVudCA9IGBAJHt1c2VyLm5hbWV9YDtcblxuICAgIHRoaXMuaW5zZXJ0Tm9kZXNBdEN1cnNvcihbbWVudGlvblNwYW4sIGRvY3VtZW50LmNyZWF0ZVRleHROb2RlKCcgJyldKTtcbiAgICB0aGlzLm5vcm1hbGl6ZU1lbnRpb25QYWRkaW5nKCk7XG5cbiAgICB0aGlzLmNsb3NlTWVudGlvbnMoKTtcbiAgICB0aGlzLmVtaXRDb250ZW50Q2hhbmdlKCk7XG4gIH1cblxuICBwcml2YXRlIGRlbGV0ZUF0TWVudGlvblNlYXJjaCgpOiB2b2lkIHtcbiAgICBjb25zdCBzZWxlY3Rpb24gPSB3aW5kb3cuZ2V0U2VsZWN0aW9uKCk7XG4gICAgaWYgKCFzZWxlY3Rpb24gfHwgIXNlbGVjdGlvbi5yYW5nZUNvdW50KSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIC8vVGhpcyByZXByZXNlbnRzIHRoZSBjdXJyZW50IHBvc2l0aW9uIG9mIHRoZSBjdXJzb3JcbiAgICBjb25zdCBjdXJzb3JSYW5nZSA9IHNlbGVjdGlvbi5nZXRSYW5nZUF0KDApO1xuICAgIC8vVGhpcyB3aWxsIHJldHVybiBhbGwgb2YgdGhlIHJhdyB0ZXh0IChIVE1MLXN0cmlwcGVkKSBiZWZvcmUgdGhlIGN1cnNvclxuICAgIGNvbnN0IHRleHRCZWZvcmVDdXJzb3IgPSB0aGlzLmdldFRleHRCZWZvcmVDdXJzb3IoY3Vyc29yUmFuZ2UpO1xuICAgIC8vV2UgZG8gdGhhdF4gc28gdGhhdCB3ZSBjYW4gZmluZCB0aGUgY29ycmVjdCBpbmRleCBvZiB0aGUgbW9zdCByZWNlbnQgJ0AnXG4gICAgY29uc3QgbGFzdEF0SW5kZXggPSB0ZXh0QmVmb3JlQ3Vyc29yLmxhc3RJbmRleE9mKCdAJyk7XG5cbiAgICBpZiAobGFzdEF0SW5kZXggPT09IC0xKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGNvbnN0IGF0UG9zaXRpb24gPSB0aGlzLmZpbmREb21Qb3NpdGlvbkF0Q2hhckluZGV4KGxhc3RBdEluZGV4KTtcbiAgICBpZiAoIWF0UG9zaXRpb24pIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgLy8gQ3JlYXRlIHJhbmdlIGZyb20gXCJAXCIgdG8gY3Vyc29yIGFuZCBkZWxldGUgaXRcbiAgICBjb25zdCBkZWxldGVSYW5nZSA9IGRvY3VtZW50LmNyZWF0ZVJhbmdlKCk7XG4gICAgZGVsZXRlUmFuZ2Uuc2V0U3RhcnQoYXRQb3NpdGlvbi5ub2RlLCBhdFBvc2l0aW9uLm9mZnNldCk7XG4gICAgZGVsZXRlUmFuZ2Uuc2V0RW5kKGN1cnNvclJhbmdlLmVuZENvbnRhaW5lciwgY3Vyc29yUmFuZ2UuZW5kT2Zmc2V0KTtcbiAgICBkZWxldGVSYW5nZS5kZWxldGVDb250ZW50cygpO1xuICB9XG5cbiAgcHJpdmF0ZSBpc0luc2lkZU1lbnRpb25TcGFuKG5vZGU6IE5vZGUpOiBib29sZWFuIHtcbiAgICBsZXQgY3VycmVudE5vZGU6IE5vZGUgfCBudWxsID0gbm9kZTtcbiAgICB3aGlsZSAoY3VycmVudE5vZGUgJiYgY3VycmVudE5vZGUgIT09IHRoaXMuaW5wdXRFbGVtZW50Py5uYXRpdmVFbGVtZW50KSB7XG4gICAgICBpZiAoTWVudGlvbnNJbnB1dENvbXBvbmVudC5pc01lbnRpb24oY3VycmVudE5vZGUpKSB7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgfVxuICAgICAgY3VycmVudE5vZGUgPSBjdXJyZW50Tm9kZS5wYXJlbnROb2RlO1xuICAgIH1cbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbiAgLy9UaGlzIHdpbGwgZ28gdGV4dCBub2RlIGJ5IG5vZGUgbG9va2luZyBmb3IgdGhlXG4gIC8vQCBtZW50aW9uIGFuZCBnaXZlIGl0cyBwb3NpdGlvbiBpbiB0aGUgY29udGV4dCBvZiB0aGF0IG5vZGVcbiAgcHJpdmF0ZSBmaW5kRG9tUG9zaXRpb25BdENoYXJJbmRleChcbiAgICBjaGFySW5kZXg6IG51bWJlcixcbiAgKTogeyBub2RlOiBOb2RlOyBvZmZzZXQ6IG51bWJlciB9IHwgbnVsbCB7XG4gICAgaWYgKCF0aGlzLmlucHV0RWxlbWVudCkge1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuICAgIC8vIFdhbGsgdGhyb3VnaCBhbGwgdGV4dCBub2RlcyBpbiB0aGUgaW5wdXQsIGNvdW50aW5nIGNoYXJhY3RlcnNcbiAgICBjb25zdCB0cmVlV2Fsa2VyID0gZG9jdW1lbnQuY3JlYXRlVHJlZVdhbGtlcihcbiAgICAgIHRoaXMuaW5wdXRFbGVtZW50Lm5hdGl2ZUVsZW1lbnQsXG4gICAgICBOb2RlRmlsdGVyLlNIT1dfVEVYVCxcbiAgICAgIG51bGwsXG4gICAgKTtcbiAgICBsZXQgY2hhckNvdW50ID0gMDtcbiAgICB3aGlsZSAodHJlZVdhbGtlci5uZXh0Tm9kZSgpKSB7XG4gICAgICBjb25zdCBub2RlID0gdHJlZVdhbGtlci5jdXJyZW50Tm9kZTtcbiAgICAgIGNvbnN0IHRleHQgPSBub2RlLnRleHRDb250ZW50IHx8ICcnO1xuICAgICAgLy8gQ2hlY2sgaWYgb3VyIHRhcmdldCBjaGFyYWN0ZXIgaXMgaW4gdGhpcyB0ZXh0IG5vZGVcbiAgICAgIGlmIChjaGFyQ291bnQgKyB0ZXh0Lmxlbmd0aCA+IGNoYXJJbmRleCkge1xuICAgICAgICByZXR1cm4geyBub2RlLCBvZmZzZXQ6IGNoYXJJbmRleCAtIGNoYXJDb3VudCB9O1xuICAgICAgfVxuICAgICAgY2hhckNvdW50ICs9IHRleHQubGVuZ3RoO1xuICAgIH1cbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIHByaXZhdGUgY2xvc2VNZW50aW9ucygpOiB2b2lkIHtcbiAgICB0aGlzLm1lbnRpb25zVmlzaWJsZSA9IGZhbHNlO1xuICAgIHRoaXMubWVudGlvblNlYXJjaFRleHQgPSAnJztcbiAgICB0aGlzLm1lbnRpb25BbmNob3IgPSBudWxsO1xuICAgIHRoaXMuc2VsZWN0ZWRVc2VySW5kZXggPSAwO1xuICAgIHRoaXMuc2F2ZWRSYW5nZSA9IG51bGw7XG4gICAgdGhpcy5jZHIubWFya0ZvckNoZWNrKCk7XG4gIH1cblxuICBwcml2YXRlIGVtaXRDb250ZW50Q2hhbmdlKCk6IHZvaWQge1xuICAgIGlmICghdGhpcy5pbnB1dEVsZW1lbnQpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdGhpcy5jb250ZW50Q2hhbmdlLmVtaXQodGhpcy5kb21Ub0NvbnRlbnRJdGVtcygpKTtcbiAgfVxuXG4gIHByaXZhdGUgZG9tVG9Db250ZW50SXRlbXMoKTogTWVudGlvbnNJbnB1dENvbXBvbmVudC5Db250ZW50SXRlbVtdIHtcbiAgICBpZiAoIXRoaXMuaW5wdXRFbGVtZW50Py5uYXRpdmVFbGVtZW50KSB7XG4gICAgICByZXR1cm4gW107XG4gICAgfVxuICAgIGNvbnN0IGl0ZW1zOiBNZW50aW9uc0lucHV0Q29tcG9uZW50LkNvbnRlbnRJdGVtW10gPSBbXTtcbiAgICBjb25zdCBjaGlsZE5vZGVzID0gdGhpcy5pbnB1dEVsZW1lbnQubmF0aXZlRWxlbWVudC5jaGlsZE5vZGVzO1xuXG4gICAgZm9yIChjb25zdCBub2RlIG9mIEFycmF5LmZyb20oY2hpbGROb2RlcykpIHtcbiAgICAgIGlmIChub2RlLm5vZGVUeXBlID09PSBOb2RlLkVMRU1FTlRfTk9ERSkge1xuICAgICAgICBjb25zdCBlbGVtZW50ID0gbm9kZSBhcyBIVE1MRWxlbWVudDtcbiAgICAgICAgaWYgKFxuICAgICAgICAgIGVsZW1lbnQudGFnTmFtZSA9PT0gJ1NQQU4nICYmXG4gICAgICAgICAgZWxlbWVudC5nZXRBdHRyaWJ1dGUoJ2RhdGEtdHlwZScpID09PSAnbWVudGlvbidcbiAgICAgICAgKSB7XG4gICAgICAgICAgY29uc3QgaWQgPSBOdW1iZXIoZWxlbWVudC5nZXRBdHRyaWJ1dGUoJ2RhdGEtaWQnKSk7XG4gICAgICAgICAgY29uc3QgbmFtZSA9IGVsZW1lbnQudGV4dENvbnRlbnQ/LnJlcGxhY2UoJ0AnLCAnJykgfHwgJyc7XG4gICAgICAgICAgaXRlbXMucHVzaCh7IHR5cGU6ICdtZW50aW9uJywgaWQsIG5hbWUgfSk7XG4gICAgICAgIH0gZWxzZSBpZiAoZWxlbWVudC50YWdOYW1lID09PSAnQlInKSB7XG4gICAgICAgICAgaXRlbXMucHVzaCh7IHR5cGU6ICduZXdsaW5lJyB9KTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIGlmIChub2RlLm5vZGVUeXBlID09PSBOb2RlLlRFWFRfTk9ERSkge1xuICAgICAgICAvLyBaV1MgcGFkcyBhcmUgYSBET00gYWZmb3JkYW5jZSDigJQgdGhleSBzaG91bGRuJ3QgbGVhayBpbnRvIHRoZSBkYXRhIG1vZGVsLlxuICAgICAgICBjb25zdCB0ZXh0ID0gKG5vZGUudGV4dENvbnRlbnQgfHwgJycpLnJlcGxhY2UoWldTX1JFR0VYLCAnJyk7XG4gICAgICAgIGlmICh0ZXh0KSB7XG4gICAgICAgICAgaXRlbXMucHVzaCh7IHR5cGU6ICd0ZXh0JywgdGV4dCB9KTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gaXRlbXM7XG4gIH1cblxuICBvbkNhbGxvdXRDbG9zZSgpOiB2b2lkIHtcbiAgICB0aGlzLmNsb3NlTWVudGlvbnMoKTtcbiAgfVxufVxuXG5leHBvcnQgbmFtZXNwYWNlIE1lbnRpb25zSW5wdXRDb21wb25lbnQge1xuICBleHBvcnQgY29uc3QgQ29udGVudFR5cGVzID0gWydtZW50aW9uJywgJ3RleHQnLCAnbmV3bGluZSddIGFzIGNvbnN0O1xuICBleHBvcnQgdHlwZSBDb250ZW50VHlwZSA9XG4gICAgKHR5cGVvZiBNZW50aW9uc0lucHV0Q29tcG9uZW50LkNvbnRlbnRUeXBlcylbbnVtYmVyXTtcbiAgZXhwb3J0IGludGVyZmFjZSBVc2VyIHtcbiAgICBpZDogbnVtYmVyO1xuICAgIG5hbWU6IHN0cmluZztcbiAgfVxuICBleHBvcnQgdHlwZSBDb250ZW50PFQgZXh0ZW5kcyBDb250ZW50VHlwZT4gPSB7IHR5cGU6IFQgfTtcblxuICBleHBvcnQgdHlwZSBVc2VyTWVudGlvbiA9IENvbnRlbnQ8J21lbnRpb24nPiAmIFVzZXI7XG4gIGV4cG9ydCB0eXBlIFRleHQgPSBDb250ZW50PCd0ZXh0Jz4gJiB7IHRleHQ6IHN0cmluZyB9O1xuICBleHBvcnQgdHlwZSBOZXdsaW5lID0gQ29udGVudDwnbmV3bGluZSc+O1xuXG4gIGV4cG9ydCB0eXBlIENvbnRlbnRJdGVtID0gVXNlck1lbnRpb24gfCBUZXh0IHwgTmV3bGluZTtcblxuICBleHBvcnQgZnVuY3Rpb24gY29udGVudFRvUGxhaW5UZXh0KGNvbnRlbnQ6IENvbnRlbnRJdGVtW10pOiBzdHJpbmcge1xuICAgIHJldHVybiBjb250ZW50XG4gICAgICAubWFwKGl0ZW0gPT4ge1xuICAgICAgICBzd2l0Y2ggKGl0ZW0udHlwZSkge1xuICAgICAgICAgIGNhc2UgJ21lbnRpb24nOlxuICAgICAgICAgICAgcmV0dXJuIGBAJHtpdGVtLm5hbWV9YDtcbiAgICAgICAgICBjYXNlICd0ZXh0JzpcbiAgICAgICAgICAgIHJldHVybiBpdGVtLnRleHQ7XG4gICAgICAgICAgY2FzZSAnbmV3bGluZSc6XG4gICAgICAgICAgICByZXR1cm4gJ1xcbic7XG4gICAgICAgIH1cbiAgICAgIH0pXG4gICAgICAuam9pbignJyk7XG4gIH1cbn1cbiIsIjxkaXYgY2xhc3M9XCJtZW50aW9ucy1jb250YWluZXJcIiAjY29udGFpbmVyPlxuICA8ZGl2XG4gICAgKm5nSWY9XCIhcmVhZG9ubHlcIlxuICAgICNpbnB1dFxuICAgIGNsYXNzPVwidGV4dC1jb250ZW50IGVkaXRhYmxlXCJcbiAgICBjb250ZW50ZWRpdGFibGU9XCJ0cnVlXCJcbiAgICBbYXR0ci5kYXRhLXBsYWNlaG9sZGVyXT1cInBsYWNlaG9sZGVyXCJcbiAgICAoaW5wdXQpPVwib25JbnB1dCgpXCJcbiAgICAoa2V5ZG93bik9XCJvbktleURvd24oJGV2ZW50KVwiXG4gICAgKHBhc3RlKT1cIm9uUGFzdGUoJGV2ZW50KVwiXG4gICAgKGNvcHkpPVwib25Db3B5KCRldmVudClcIlxuICAgIChjdXQpPVwib25DdXQoJGV2ZW50KVwiXG4gID48L2Rpdj5cblxuICA8ZGl2ICpuZ0lmPVwicmVhZG9ubHlcIiAjaW5wdXQgY2xhc3M9XCJ0ZXh0LWNvbnRlbnRcIj48L2Rpdj5cblxuICA8cml2LWNhbGxvdXRcbiAgICAqbmdJZj1cIiFyZWFkb25seSAmJiBtZW50aW9uc1Zpc2libGUgJiYgbWVudGlvbkFuY2hvclwiXG4gICAgW2FuY2hvcl09XCJtZW50aW9uQW5jaG9yXCJcbiAgICBbaXNNb2RhbF09XCJ0cnVlXCJcbiAgICBbc2hvd0NhcmV0XT1cImZhbHNlXCJcbiAgICBbYWxsb3dlZFBvc2l0aW9uc109XCJbJ2JvdHRvbS1yaWdodCcsICd0b3AtcmlnaHQnXVwiXG4gICAgW3RoZW1lXT1cIidsaWdodCdcIlxuICAgIChjbG9zZSk9XCJvbkNhbGxvdXRDbG9zZSgpXCJcbiAgPlxuICAgIDxkaXYgY2xhc3M9XCJtZW50aW9ucy1jb250ZW50XCI+XG4gICAgICA8ZGl2IGNsYXNzPVwibWVudGlvbnMtaGVhZGVyXCI+TWVudGlvbiBzb21lb25lPC9kaXY+XG4gICAgICA8ZGl2IGNsYXNzPVwibWVudGlvbnMtbGlzdFwiPlxuICAgICAgICA8YnV0dG9uXG4gICAgICAgICAgdHlwZT1cImJ1dHRvblwiXG4gICAgICAgICAgKm5nRm9yPVwibGV0IHVzZXIgb2YgZ2V0RmlsdGVyZWRVc2VycygpOyBsZXQgaSA9IGluZGV4XCJcbiAgICAgICAgICBbY2xhc3Muc2VsZWN0ZWRdPVwiaSA9PT0gc2VsZWN0ZWRVc2VySW5kZXhcIlxuICAgICAgICAgIChtb3VzZWVudGVyKT1cIm9uVXNlckhvdmVyKGkpXCJcbiAgICAgICAgICAoY2xpY2spPVwic2VsZWN0VXNlcih1c2VyKVwiXG4gICAgICAgID5cbiAgICAgICAgICB7eyB1c2VyLm5hbWUgfX1cbiAgICAgICAgPC9idXR0b24+XG4gICAgICA8L2Rpdj5cbiAgICA8L2Rpdj5cbiAgPC9yaXYtY2FsbG91dD5cbjwvZGl2PlxuIl19