@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
@@ -0,0 +1,745 @@
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
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: MentionsInputComponent, deps: [{ token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component }); }
708
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.12", 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 }); }
709
+ }
710
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", 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: () => [{ 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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aEIsQ0FBQztRQUNILENBQUMsQ0FBQzthQUNELElBQUksQ0FBQyxFQUFFLENBQUMsQ0FBQztJQUNkLENBQUM7SUFiZSx5Q0FBa0IscUJBYWpDLENBQUE7QUFDSCxDQUFDLEVBOUJnQixzQkFBc0IsS0FBdEIsc0JBQXNCLFFBOEJ0QyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7XG4gIEFmdGVyVmlld0luaXQsXG4gIENoYW5nZURldGVjdGlvblN0cmF0ZWd5LFxuICBDaGFuZ2VEZXRlY3RvclJlZixcbiAgQ29tcG9uZW50LFxuICBFbGVtZW50UmVmLFxuICBFdmVudEVtaXR0ZXIsXG4gIElucHV0LFxuICBPbkNoYW5nZXMsXG4gIE91dHB1dCxcbiAgU2ltcGxlQ2hhbmdlcyxcbiAgVmlld0NoaWxkLFxuICBWaWV3RW5jYXBzdWxhdGlvbixcbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5cbmNvbnN0IFpXUyA9ICfigIsnO1xuY29uc3QgWldTX1JFR0VYID0gL+KAiy9nO1xuXG4vKipcbiAqIEEgcmljaCB0ZXh0IGlucHV0IHRoYXQgc3VwcG9ydHMgYEBgLW1lbnRpb25zIGluc2lkZSBhIGBjb250ZW50ZWRpdGFibGVgIGRpdi5cbiAqXG4gKiAjIyBEYXRhIE1vZGVsXG4gKiAtICoqSW5wdXQvT3V0cHV0Kio6IGBDb250ZW50SXRlbVtdYCAobWVudGlvbnMsIHRleHQsIG5ld2xpbmVzKVxuICpcbiAqICMjIERPTSBJbnZhcmlhbnRcbiAqIEV2ZXJ5IG1lbnRpb24gYDxzcGFuIGRhdGEtdHlwZT1cIm1lbnRpb25cIiBjb250ZW50ZWRpdGFibGU9XCJmYWxzZVwiPmAgaXMgd3JhcHBlZFxuICogYnkgZXhhY3RseSBvbmUgemVyby13aWR0aC1zcGFjZSAoWldTKSB0ZXh0IG5vZGUgYmVmb3JlIGFuZCBhZnRlciBpdC4gWldTIGdpdmVzXG4gKiB0aGUgY3Vyc29yIGEgdmFsaWQgbGFuZGluZyBzcG90IGFkamFjZW50IHRvIGEgbm9uLWVkaXRhYmxlIGVsZW1lbnQuIFRoZVxuICogaW52YXJpYW50IGlzIGVzdGFibGlzaGVkIGF0IHJlbmRlciB0aW1lIGFuZCByZS1lc3RhYmxpc2hlZCBieVxuICogYG5vcm1hbGl6ZU1lbnRpb25QYWRkaW5nKClgIGFmdGVyIGFueSBET00tbXV0YXRpbmcgb3BlcmF0aW9uLlxuICpcbiAqICMjIENvcHkvUGFzdGVcbiAqIC0gKipDb3B5Kio6IGByYW5nZS5jbG9uZUNvbnRlbnRzKClgIHByZXNlcnZlcyBgZGF0YS0qYCBhdHRyaWJ1dGVzIChvbmx5IHRoZVxuICogICBicm93c2VyJ3MgZGVmYXVsdCBjb3B5IHBhdGggc3RyaXBzIHRoZW0pLiBXZSBvdmVycmlkZSBjb3B5LCBzZXJpYWxpemUgdGhlXG4gKiAgIGNsb25lIG91cnNlbHZlcywgYW5kIHN0cmlwIFpXUyBmcm9tIHRoZSBvdXRwdXQuXG4gKiAtICoqUGFzdGUqKjogSFRNTCBwYXRocyBsb29rIGZvciBgZGF0YS10eXBlPVwibWVudGlvblwiYCBzcGFucyBhbmQgcmVidWlsZFxuICogICB0aGVtOyBvdGhlcndpc2UgcGxhaW50ZXh0IGZhbGxiYWNrLlxuICovXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICdyaXYtbWVudGlvbnMtaW5wdXQnLFxuICB0ZW1wbGF0ZVVybDogYC4vbWVudGlvbnMtaW5wdXQuY29tcG9uZW50Lmh0bWxgLFxuICBzdHlsZVVybHM6IFsnLi9tZW50aW9ucy1pbnB1dC5jb21wb25lbnQuY3NzJ10sXG4gIGVuY2Fwc3VsYXRpb246IFZpZXdFbmNhcHN1bGF0aW9uLk5vbmUsXG4gIGNoYW5nZURldGVjdGlvbjogQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3kuT25QdXNoLFxufSlcbmV4cG9ydCBjbGFzcyBNZW50aW9uc0lucHV0Q29tcG9uZW50IGltcGxlbWVudHMgT25DaGFuZ2VzLCBBZnRlclZpZXdJbml0IHtcbiAgY29uc3RydWN0b3IocHJpdmF0ZSByZWFkb25seSBjZHI6IENoYW5nZURldGVjdG9yUmVmKSB7fVxuXG4gIEBJbnB1dCgpIGNvbnRlbnQ6IE1lbnRpb25zSW5wdXRDb21wb25lbnQuQ29udGVudEl0ZW1bXSA9IFtdO1xuICBASW5wdXQoKSB1c2VyczogTWVudGlvbnNJbnB1dENvbXBvbmVudC5Vc2VyW10gPSBbXTtcbiAgQElucHV0KCkgcmVhZG9ubHkgPSBmYWxzZTtcbiAgQElucHV0KCkgcGxhY2Vob2xkZXI6IHN0cmluZyA9ICdBZGQgYSBjb21tZW50JztcblxuICBAT3V0cHV0KCkgcmVhZG9ubHkgY29udGVudENoYW5nZSA9IG5ldyBFdmVudEVtaXR0ZXI8XG4gICAgTWVudGlvbnNJbnB1dENvbXBvbmVudC5Db250ZW50SXRlbVtdXG4gID4oKTtcblxuICBAVmlld0NoaWxkKCdpbnB1dCcsIHsgc3RhdGljOiBmYWxzZSB9KVxuICBwcml2YXRlIHJlYWRvbmx5IGlucHV0RWxlbWVudD86IEVsZW1lbnRSZWY8SFRNTERpdkVsZW1lbnQ+O1xuXG4gIG1lbnRpb25zVmlzaWJsZSA9IGZhbHNlO1xuICBtZW50aW9uU2VhcmNoVGV4dCA9ICcnO1xuICBtZW50aW9uQW5jaG9yOiBET01SZWN0IHwgbnVsbCA9IG51bGw7XG4gIHNlbGVjdGVkVXNlckluZGV4ID0gMDtcbiAgcHJpdmF0ZSBzYXZlZFJhbmdlOiBSYW5nZSB8IG51bGwgPSBudWxsO1xuXG4gIG5nQWZ0ZXJWaWV3SW5pdCgpOiB2b2lkIHtcbiAgICB0aGlzLnJlbmRlckNvbnRlbnQoKTtcbiAgfVxuXG4gIC8vREFITkUgTk9URSAtIG5nT25DaGFuZ2VzIGlzIGNhbGxlZCB3aGVuZXZlciBhbnkgQElucHV0KCkgcHJvcGVydHkgY2hhbmdlcywgd2hlcmUgdGhlIGNoYW5nZWQgaW5wdXQgY29udGFpbnMgaW5mb3JtYXRpb24gYWJvdXQgdGhvc2UgY2hhbmdlc1xuICAvL1NvIGlmIEBJbnB1dCgpIGNvbnRlbnQgY2hhbmdlcyBhbmQgaXQncyBub3QgdGhlIGZpcnN0IGNoYW5nZSAodGhlIGZpcnN0IHJlbmRlciBpcyBoYW5kbGVkIGJ5IG5nQWZ0ZXJWaWV3SW5pdCgpKSwgd2UgcmVuZGVyIHRoZSBjb250ZW50XG4gIG5nT25DaGFuZ2VzKGNoYW5nZXM6IFNpbXBsZUNoYW5nZXMpOiB2b2lkIHtcbiAgICBpZiAoY2hhbmdlc1snY29udGVudCddICYmICFjaGFuZ2VzWydjb250ZW50J10uZmlyc3RDaGFuZ2UpIHtcbiAgICAgIHRoaXMucmVuZGVyQ29udGVudCgpO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgcmVuZGVyQ29udGVudCgpOiB2b2lkIHtcbiAgICAvL1RoaXMgaXMgbmVjZXNzYXJ5IGJlY2F1c2UgdGhlIEBWaWV3Q2hpbGQgcmVmZXJlbmNlIGlzbid0IGF2YWlsYWJsZSB1bnRpbCBhZnRlciB0aGUgdmlldyBpbml0aWFsaXplc1xuICAgIGlmICghdGhpcy5pbnB1dEVsZW1lbnQ/Lm5hdGl2ZUVsZW1lbnQpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgY29uc3QgaHRtbCA9IHRoaXMuY29udGVudFxuICAgICAgLm1hcChpdGVtID0+IHtcbiAgICAgICAgY29uc3QgaXRlbUh0bWwgPSBNZW50aW9uc0lucHV0Q29tcG9uZW50LmNvbnRlbnRJdGVtVG9IdG1sKFxuICAgICAgICAgIGl0ZW0sXG4gICAgICAgICAgdGhpcy5yZWFkb25seSxcbiAgICAgICAgKTtcbiAgICAgICAgcmV0dXJuIGl0ZW0udHlwZSA9PT0gJ21lbnRpb24nID8gYCR7WldTfSR7aXRlbUh0bWx9JHtaV1N9YCA6IGl0ZW1IdG1sO1xuICAgICAgfSlcbiAgICAgIC5qb2luKCcnKTtcbiAgICB0aGlzLmlucHV0RWxlbWVudC5uYXRpdmVFbGVtZW50LmlubmVySFRNTCA9IGh0bWw7XG4gIH1cblxuICBwcml2YXRlIHN0YXRpYyBjb250ZW50SXRlbVRvSHRtbChcbiAgICBpdGVtOiBNZW50aW9uc0lucHV0Q29tcG9uZW50LkNvbnRlbnRJdGVtLFxuICAgIHJlYWRvbmx5OiBib29sZWFuLFxuICApOiBzdHJpbmcge1xuICAgIHN3aXRjaCAoaXRlbS50eXBlKSB7XG4gICAgICAvL0RBSE5FIFRPRE8gLSBtYXliZSB3ZSBlc2NhcGUgSFRNTCBoZXJlIHRvbz8gQWx0aG91Z2ggSSBkb24ndCB0aGluayBpdCB3aWxsIGJlIHBvc3NpYmxlIGZvciB1c2VycyB0byBpbnB1dCBhbiBYU1MgYXR0YWNrIGluIGl0ZW0ubmFtZVxuICAgICAgY2FzZSAnbWVudGlvbic6XG4gICAgICAgIHJldHVybiBgPHNwYW4gY2xhc3M9XCIke1xuICAgICAgICAgIHJlYWRvbmx5ID8gJ3JlYWRvbmx5LW1lbnRpb24nIDogJ21lbnRpb24nXG4gICAgICAgIH1cIiBkYXRhLWlkPVwiJHtcbiAgICAgICAgICBpdGVtLmlkXG4gICAgICAgIH1cIiBkYXRhLXR5cGU9XCJtZW50aW9uXCIgY29udGVudGVkaXRhYmxlPVwiZmFsc2VcIj5AJHtNZW50aW9uc0lucHV0Q29tcG9uZW50LmVzY2FwZUh0bWwoXG4gICAgICAgICAgaXRlbS5uYW1lLFxuICAgICAgICApfTwvc3Bhbj5gO1xuICAgICAgY2FzZSAndGV4dCc6XG4gICAgICAgIHJldHVybiBNZW50aW9uc0lucHV0Q29tcG9uZW50LmVzY2FwZUh0bWwoaXRlbS50ZXh0KTtcbiAgICAgIGNhc2UgJ25ld2xpbmUnOlxuICAgICAgICByZXR1cm4gJzxicj4nO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgc3RhdGljIGVzY2FwZUh0bWwodGV4dDogc3RyaW5nKTogc3RyaW5nIHtcbiAgICBjb25zdCBkaXYgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcbiAgICBkaXYudGV4dENvbnRlbnQgPSB0ZXh0O1xuICAgIHJldHVybiBkaXYuaW5uZXJIVE1MO1xuICB9XG5cbiAgLy8g4pSA4pSA4pSAIEV2ZW50IGhhbmRsZXJzIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgFxuXG4gIG9uSW5wdXQoKTogdm9pZCB7XG4gICAgdGhpcy5ub3JtYWxpemVNZW50aW9uUGFkZGluZygpO1xuICAgIHRoaXMuY2hlY2tGb3JNZW50aW9uVHJpZ2dlcigpO1xuICAgIHRoaXMuZW1pdENvbnRlbnRDaGFuZ2UoKTtcbiAgfVxuXG4gIG9uS2V5RG93bihldmVudDogS2V5Ym9hcmRFdmVudCk6IHZvaWQge1xuICAgIGlmICh0aGlzLm1lbnRpb25zVmlzaWJsZSkge1xuICAgICAgdGhpcy5oYW5kbGVNZW50aW9uc0Ryb3Bkb3duTmF2KGV2ZW50KTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICAvLyBXb3JkL2xpbmUganVtcDogbmF0aXZlIGJlaGF2aW9yLlxuICAgIGlmIChldmVudC5tZXRhS2V5IHx8IGV2ZW50LmN0cmxLZXkpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZiAoZXZlbnQua2V5ID09PSAnQXJyb3dMZWZ0JyB8fCBldmVudC5rZXkgPT09ICdBcnJvd1JpZ2h0Jykge1xuICAgICAgY29uc3QgZGlyZWN0aW9uID0gZXZlbnQua2V5ID09PSAnQXJyb3dMZWZ0JyA/ICdiZWZvcmUnIDogJ2FmdGVyJztcbiAgICAgIGNvbnN0IG1lbnRpb24gPSB0aGlzLmZpbmRNZW50aW9uQWRqYWNlbnRUb0N1cnNvcihkaXJlY3Rpb24pO1xuICAgICAgaWYgKG1lbnRpb24pIHtcbiAgICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgaWYgKGV2ZW50LnNoaWZ0S2V5KSB7XG4gICAgICAgICAgdGhpcy5leHRlbmRTZWxlY3Rpb25BY3Jvc3NNZW50aW9uKG1lbnRpb24sIGRpcmVjdGlvbik7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdGhpcy5wbGFjZUN1cnNvckFkamFjZW50VG9NZW50aW9uKG1lbnRpb24sIGRpcmVjdGlvbik7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZiAoZXZlbnQua2V5ID09PSAnQmFja3NwYWNlJyB8fCBldmVudC5rZXkgPT09ICdEZWxldGUnKSB7XG4gICAgICBjb25zdCBkaXJlY3Rpb24gPSBldmVudC5rZXkgPT09ICdCYWNrc3BhY2UnID8gJ2JlZm9yZScgOiAnYWZ0ZXInO1xuICAgICAgY29uc3QgbWVudGlvbiA9IHRoaXMuZmluZE1lbnRpb25BZGphY2VudFRvQ3Vyc29yKGRpcmVjdGlvbik7XG4gICAgICBpZiAobWVudGlvbikge1xuICAgICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICB0aGlzLnJlbW92ZU1lbnRpb24obWVudGlvbik7XG4gICAgICAgIHRoaXMuZW1pdENvbnRlbnRDaGFuZ2UoKTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgaWYgKGV2ZW50LmtleSA9PT0gJ0JhY2tzcGFjZScpIHtcbiAgICAgICAgY29uc3QgYnIgPSB0aGlzLmZpbmRCckFkamFjZW50VG9DdXJzb3IoKTtcbiAgICAgICAgaWYgKGJyKSB7XG4gICAgICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgICBici5yZW1vdmUoKTtcbiAgICAgICAgICB0aGlzLmVtaXRDb250ZW50Q2hhbmdlKCk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgLy9IYW5kbGUgbmV3bGluZXMgd2hlbiBtZW50aW9ucyBhcmVuJ3QgdmlzaWJsZVxuICAgIGlmIChldmVudC5rZXkgPT09ICdFbnRlcicpIHtcbiAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgICB0aGlzLmluc2VydExpbmVCcmVhaygpO1xuICAgICAgdGhpcy5lbWl0Q29udGVudENoYW5nZSgpO1xuICAgIH1cbiAgfVxuXG4gIG9uUGFzdGUoZXZlbnQ6IENsaXBib2FyZEV2ZW50KTogdm9pZCB7XG4gICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICBpZiAoIWV2ZW50LmNsaXBib2FyZERhdGEpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgLy9Mb29rIGZvciBIVE1MIGZpcnN0XG4gICAgY29uc3QgaHRtbCA9IGV2ZW50LmNsaXBib2FyZERhdGEuZ2V0RGF0YSgndGV4dC9odG1sJyk7XG4gICAgY29uc3QgcGxhaW5UZXh0ID0gZXZlbnQuY2xpcGJvYXJkRGF0YS5nZXREYXRhKCd0ZXh0L3BsYWluJyk7XG5cbiAgICBjb25zdCBub2RlcyA9XG4gICAgICBodG1sICYmIGh0bWwuaW5jbHVkZXMoJ2RhdGEtdHlwZT1cIm1lbnRpb25cIicpXG4gICAgICAgID8gdGhpcy5wYXJzZVBhc3RlZEh0bWwoaHRtbClcbiAgICAgICAgOiB0aGlzLnBsYWluVGV4dFRvTm9kZXMocGxhaW5UZXh0KTtcblxuICAgIHRoaXMuaW5zZXJ0Tm9kZXNBdEN1cnNvcihub2Rlcyk7XG4gICAgdGhpcy5ub3JtYWxpemVNZW50aW9uUGFkZGluZygpO1xuICAgIHRoaXMuZW1pdENvbnRlbnRDaGFuZ2UoKTtcbiAgfVxuXG4gIC8vIFRoZSBicm93c2VyIHN0cmlwcyBkYXRhLSogYXR0cmlidXRlcyBkdXJpbmcgZGVmYXVsdCBjb3B5IHNlcmlhbGl6YXRpb24sIGJ1dFxuICAvLyByYW5nZS5jbG9uZUNvbnRlbnRzKCkgcHJlc2VydmVzIHRoZW0uIFdlIHNlcmlhbGl6ZSB0aGUgY2xvbmUgb3Vyc2VsdmVzIGFuZFxuICAvLyBzdHJpcCBaV1Mgc28gaXQgZG9lc24ndCBsZWFrIGludG8gdGhlIGNsaXBib2FyZC5cbiAgb25Db3B5KGV2ZW50OiBDbGlwYm9hcmRFdmVudCk6IHZvaWQge1xuICAgIGNvbnN0IHNlbGVjdGlvbiA9IHdpbmRvdy5nZXRTZWxlY3Rpb24oKTtcbiAgICBpZiAoIXNlbGVjdGlvbj8ucmFuZ2VDb3VudCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuXG4gICAgY29uc3QgZGl2ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XG4gICAgZGl2LmFwcGVuZENoaWxkKHNlbGVjdGlvbi5nZXRSYW5nZUF0KDApLmNsb25lQ29udGVudHMoKSk7XG5cbiAgICBjb25zdCBodG1sID0gZGl2LmlubmVySFRNTC5yZXBsYWNlKFpXU19SRUdFWCwgJycpO1xuICAgIGNvbnN0IHRleHQgPSAoZGl2LnRleHRDb250ZW50IHx8ICcnKS5yZXBsYWNlKFpXU19SRUdFWCwgJycpO1xuXG4gICAgZXZlbnQuY2xpcGJvYXJkRGF0YT8uc2V0RGF0YSgndGV4dC9odG1sJywgaHRtbCk7XG4gICAgZXZlbnQuY2xpcGJvYXJkRGF0YT8uc2V0RGF0YSgndGV4dC9wbGFpbicsIHRleHQpO1xuICB9XG5cbiAgb25DdXQoZXZlbnQ6IENsaXBib2FyZEV2ZW50KTogdm9pZCB7XG4gICAgdGhpcy5vbkNvcHkoZXZlbnQpO1xuICAgIGNvbnN0IHNlbGVjdGlvbiA9IHdpbmRvdy5nZXRTZWxlY3Rpb24oKTtcbiAgICBpZiAoIXNlbGVjdGlvbj8ucmFuZ2VDb3VudCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBzZWxlY3Rpb24uZ2V0UmFuZ2VBdCgwKS5kZWxldGVDb250ZW50cygpO1xuICAgIHRoaXMubm9ybWFsaXplTWVudGlvblBhZGRpbmcoKTtcbiAgICB0aGlzLmVtaXRDb250ZW50Q2hhbmdlKCk7XG4gIH1cblxuICAvLyDilIDilIDilIAgTWVudGlvbiBoZWxwZXJzIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgFxuXG4gIHByaXZhdGUgc3RhdGljIGlzTWVudGlvbihub2RlOiBOb2RlIHwgbnVsbCB8IHVuZGVmaW5lZCk6IG5vZGUgaXMgSFRNTEVsZW1lbnQge1xuICAgIHJldHVybiAoXG4gICAgICAhIW5vZGUgJiZcbiAgICAgIG5vZGUubm9kZVR5cGUgPT09IE5vZGUuRUxFTUVOVF9OT0RFICYmXG4gICAgICAobm9kZSBhcyBIVE1MRWxlbWVudCkuZ2V0QXR0cmlidXRlKCdkYXRhLXR5cGUnKSA9PT0gJ21lbnRpb24nXG4gICAgKTtcbiAgfVxuXG4gIHByaXZhdGUgc3RhdGljIGlzWndzKG5vZGU6IE5vZGUgfCBudWxsIHwgdW5kZWZpbmVkKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIChcbiAgICAgICEhbm9kZSAmJlxuICAgICAgbm9kZS5ub2RlVHlwZSA9PT0gTm9kZS5URVhUX05PREUgJiZcbiAgICAgIChub2RlLnRleHRDb250ZW50IHx8ICcnKS5yZXBsYWNlKFpXU19SRUdFWCwgJycpID09PSAnJ1xuICAgICk7XG4gIH1cblxuICAvLyBSZXNvbHZlIHRoZSBub2RlIGxvZ2ljYWxseSBhZGphY2VudCB0byAoY29udGFpbmVyLCBvZmZzZXQpIGluIHRoZSBnaXZlblxuICAvLyBkaXJlY3Rpb24sIHRyYW5zcGFyZW50bHkgc2tpcHBpbmcgYW55IFpXUy1vbmx5IHRleHQgbm9kZXMgaW4gYmV0d2Vlbi5cbiAgcHJpdmF0ZSByZXNvbHZlQWRqYWNlbnROb2RlKFxuICAgIGNvbnRhaW5lcjogTm9kZSxcbiAgICBvZmZzZXQ6IG51bWJlcixcbiAgICBkaXJlY3Rpb246ICdiZWZvcmUnIHwgJ2FmdGVyJyxcbiAgKTogTm9kZSB8IG51bGwge1xuICAgIGxldCBjYW5kaWRhdGU6IE5vZGUgfCBudWxsID0gbnVsbDtcblxuICAgIGlmIChjb250YWluZXIubm9kZVR5cGUgPT09IE5vZGUuVEVYVF9OT0RFKSB7XG4gICAgICBjb25zdCBsZW5ndGggPSAoY29udGFpbmVyLnRleHRDb250ZW50IHx8ICcnKS5sZW5ndGg7XG4gICAgICBjb25zdCBhdEJvdW5kYXJ5ID1cbiAgICAgICAgTWVudGlvbnNJbnB1dENvbXBvbmVudC5pc1p3cyhjb250YWluZXIpIHx8XG4gICAgICAgIChkaXJlY3Rpb24gPT09ICdiZWZvcmUnID8gb2Zmc2V0ID09PSAwIDogb2Zmc2V0ID09PSBsZW5ndGgpO1xuICAgICAgaWYgKCFhdEJvdW5kYXJ5KSB7XG4gICAgICAgIHJldHVybiBudWxsO1xuICAgICAgfVxuICAgICAgY2FuZGlkYXRlID1cbiAgICAgICAgZGlyZWN0aW9uID09PSAnYmVmb3JlJ1xuICAgICAgICAgID8gY29udGFpbmVyLnByZXZpb3VzU2libGluZ1xuICAgICAgICAgIDogY29udGFpbmVyLm5leHRTaWJsaW5nO1xuICAgIH0gZWxzZSBpZiAoY29udGFpbmVyLm5vZGVUeXBlID09PSBOb2RlLkVMRU1FTlRfTk9ERSkge1xuICAgICAgY29uc3QgY2hpbGRyZW4gPSAoY29udGFpbmVyIGFzIEhUTUxFbGVtZW50KS5jaGlsZE5vZGVzO1xuICAgICAgY2FuZGlkYXRlID1cbiAgICAgICAgZGlyZWN0aW9uID09PSAnYmVmb3JlJyA/IGNoaWxkcmVuW29mZnNldCAtIDFdIDogY2hpbGRyZW5bb2Zmc2V0XTtcbiAgICB9XG5cbiAgICB3aGlsZSAoY2FuZGlkYXRlICYmIE1lbnRpb25zSW5wdXRDb21wb25lbnQuaXNad3MoY2FuZGlkYXRlKSkge1xuICAgICAgY2FuZGlkYXRlID1cbiAgICAgICAgZGlyZWN0aW9uID09PSAnYmVmb3JlJ1xuICAgICAgICAgID8gY2FuZGlkYXRlLnByZXZpb3VzU2libGluZ1xuICAgICAgICAgIDogY2FuZGlkYXRlLm5leHRTaWJsaW5nO1xuICAgIH1cbiAgICByZXR1cm4gY2FuZGlkYXRlO1xuICB9XG5cbiAgcHJpdmF0ZSBmaW5kTWVudGlvbkFkamFjZW50VG9DdXJzb3IoXG4gICAgZGlyZWN0aW9uOiAnYmVmb3JlJyB8ICdhZnRlcicsXG4gICk6IEhUTUxFbGVtZW50IHwgbnVsbCB7XG4gICAgY29uc3Qgc2VsZWN0aW9uID0gd2luZG93LmdldFNlbGVjdGlvbigpO1xuICAgIGlmICghc2VsZWN0aW9uPy5pc0NvbGxhcHNlZCB8fCAhc2VsZWN0aW9uLnJhbmdlQ291bnQpIHtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cbiAgICBjb25zdCByYW5nZSA9IHNlbGVjdGlvbi5nZXRSYW5nZUF0KDApO1xuICAgIGNvbnN0IG5vZGUgPSB0aGlzLnJlc29sdmVBZGphY2VudE5vZGUoXG4gICAgICByYW5nZS5zdGFydENvbnRhaW5lcixcbiAgICAgIHJhbmdlLnN0YXJ0T2Zmc2V0LFxuICAgICAgZGlyZWN0aW9uLFxuICAgICk7XG4gICAgcmV0dXJuIE1lbnRpb25zSW5wdXRDb21wb25lbnQuaXNNZW50aW9uKG5vZGUpID8gbm9kZSA6IG51bGw7XG4gIH1cblxuICBwcml2YXRlIGZpbmRCckFkamFjZW50VG9DdXJzb3IoKTogSFRNTEVsZW1lbnQgfCBudWxsIHtcbiAgICBjb25zdCBzZWxlY3Rpb24gPSB3aW5kb3cuZ2V0U2VsZWN0aW9uKCk7XG4gICAgaWYgKCFzZWxlY3Rpb24/LmlzQ29sbGFwc2VkIHx8ICFzZWxlY3Rpb24ucmFuZ2VDb3VudCkge1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuICAgIGNvbnN0IHJhbmdlID0gc2VsZWN0aW9uLmdldFJhbmdlQXQoMCk7XG4gICAgY29uc3Qgbm9kZSA9IHRoaXMucmVzb2x2ZUFkamFjZW50Tm9kZShcbiAgICAgIHJhbmdlLnN0YXJ0Q29udGFpbmVyLFxuICAgICAgcmFuZ2Uuc3RhcnRPZmZzZXQsXG4gICAgICAnYmVmb3JlJyxcbiAgICApO1xuICAgIHJldHVybiBub2RlPy5ub2RlTmFtZSA9PT0gJ0JSJyA/IChub2RlIGFzIEhUTUxFbGVtZW50KSA6IG51bGw7XG4gIH1cblxuICBwcml2YXRlIGV4dGVuZFNlbGVjdGlvbkFjcm9zc01lbnRpb24oXG4gICAgbWVudGlvbjogSFRNTEVsZW1lbnQsXG4gICAgZGlyZWN0aW9uOiAnYmVmb3JlJyB8ICdhZnRlcicsXG4gICk6IHZvaWQge1xuICAgIGNvbnN0IHNlbGVjdGlvbiA9IHdpbmRvdy5nZXRTZWxlY3Rpb24oKTtcbiAgICBjb25zdCBwYXJlbnQgPSBtZW50aW9uLnBhcmVudE5vZGU7XG4gICAgaWYgKCFzZWxlY3Rpb24gfHwgIXBhcmVudCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBjb25zdCBpbmRleCA9IEFycmF5LmZyb20ocGFyZW50LmNoaWxkTm9kZXMpLmluZGV4T2YobWVudGlvbiBhcyBDaGlsZE5vZGUpO1xuICAgIHNlbGVjdGlvbi5leHRlbmQocGFyZW50LCBkaXJlY3Rpb24gPT09ICdiZWZvcmUnID8gaW5kZXggOiBpbmRleCArIDEpO1xuICB9XG5cbiAgcHJpdmF0ZSBwbGFjZUN1cnNvckFkamFjZW50VG9NZW50aW9uKFxuICAgIG1lbnRpb246IEhUTUxFbGVtZW50LFxuICAgIHNpZGU6ICdiZWZvcmUnIHwgJ2FmdGVyJyxcbiAgKTogdm9pZCB7XG4gICAgY29uc3QgcGFyZW50ID0gbWVudGlvbi5wYXJlbnROb2RlO1xuICAgIGlmICghcGFyZW50KSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGNvbnN0IHNpYmxpbmcgPVxuICAgICAgc2lkZSA9PT0gJ2JlZm9yZScgPyBtZW50aW9uLnByZXZpb3VzU2libGluZyA6IG1lbnRpb24ubmV4dFNpYmxpbmc7XG4gICAgbGV0IHp3czogTm9kZTtcbiAgICBpZiAoc2libGluZyAmJiBNZW50aW9uc0lucHV0Q29tcG9uZW50LmlzWndzKHNpYmxpbmcpKSB7XG4gICAgICB6d3MgPSBzaWJsaW5nO1xuICAgIH0gZWxzZSB7XG4gICAgICB6d3MgPSBkb2N1bWVudC5jcmVhdGVUZXh0Tm9kZShaV1MpO1xuICAgICAgcGFyZW50Lmluc2VydEJlZm9yZShcbiAgICAgICAgendzLFxuICAgICAgICBzaWRlID09PSAnYmVmb3JlJyA/IG1lbnRpb24gOiBtZW50aW9uLm5leHRTaWJsaW5nLFxuICAgICAgKTtcbiAgICB9XG4gICAgY29uc3QgcmFuZ2UgPSBkb2N1bWVudC5jcmVhdGVSYW5nZSgpO1xuICAgIHJhbmdlLnNldFN0YXJ0KHp3cywgc2lkZSA9PT0gJ2JlZm9yZScgPyAoendzLnRleHRDb250ZW50IHx8ICcnKS5sZW5ndGggOiAwKTtcbiAgICByYW5nZS5jb2xsYXBzZSh0cnVlKTtcbiAgICBjb25zdCBzZWxlY3Rpb24gPSB3aW5kb3cuZ2V0U2VsZWN0aW9uKCk7XG4gICAgc2VsZWN0aW9uPy5yZW1vdmVBbGxSYW5nZXMoKTtcbiAgICBzZWxlY3Rpb24/LmFkZFJhbmdlKHJhbmdlKTtcbiAgfVxuXG4gIHByaXZhdGUgcmVtb3ZlTWVudGlvbihtZW50aW9uOiBIVE1MRWxlbWVudCk6IHZvaWQge1xuICAgIGNvbnN0IHBhcmVudCA9IG1lbnRpb24ucGFyZW50Tm9kZTtcbiAgICBpZiAoIXBhcmVudCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICAvLyBFbXB0eSB0ZXh0LW5vZGUgYW5jaG9yIHByZXNlcnZlcyBjdXJzb3IgcG9zaXRpb24gdGhyb3VnaCB0aGUgcmVtb3ZhbC5cbiAgICBjb25zdCBhbmNob3IgPSBkb2N1bWVudC5jcmVhdGVUZXh0Tm9kZSgnJyk7XG4gICAgcGFyZW50Lmluc2VydEJlZm9yZShhbmNob3IsIG1lbnRpb24pO1xuXG4gICAgY29uc3QgcHJldiA9IG1lbnRpb24ucHJldmlvdXNTaWJsaW5nO1xuICAgIGNvbnN0IG5leHQgPSBtZW50aW9uLm5leHRTaWJsaW5nO1xuICAgIGlmIChwcmV2ICYmIE1lbnRpb25zSW5wdXRDb21wb25lbnQuaXNad3MocHJldikpIHtcbiAgICAgIHByZXYucmVtb3ZlKCk7XG4gICAgfVxuICAgIGlmIChuZXh0ICYmIE1lbnRpb25zSW5wdXRDb21wb25lbnQuaXNad3MobmV4dCkpIHtcbiAgICAgIG5leHQucmVtb3ZlKCk7XG4gICAgfVxuICAgIG1lbnRpb24ucmVtb3ZlKCk7XG5cbiAgICBjb25zdCByYW5nZSA9IGRvY3VtZW50LmNyZWF0ZVJhbmdlKCk7XG4gICAgcmFuZ2Uuc2V0U3RhcnQoYW5jaG9yLCAwKTtcbiAgICByYW5nZS5jb2xsYXBzZSh0cnVlKTtcbiAgICBjb25zdCBzZWxlY3Rpb24gPSB3aW5kb3cuZ2V0U2VsZWN0aW9uKCk7XG4gICAgc2VsZWN0aW9uPy5yZW1vdmVBbGxSYW5nZXMoKTtcbiAgICBzZWxlY3Rpb24/LmFkZFJhbmdlKHJhbmdlKTtcbiAgfVxuXG4gIC8vIFJlLWVzdGFibGlzaGVzIHRoZSBpbnZhcmlhbnQ6IGV2ZXJ5IG1lbnRpb24gaGFzIGV4YWN0bHkgb25lIFpXUyB0ZXh0XG4gIC8vIG5vZGUgaW1tZWRpYXRlbHkgYmVmb3JlIGFuZCBhZnRlciBpdCwgYW5kIHRoZXJlIGFyZSBubyBvcnBoYW4gWldTLW9ubHlcbiAgLy8gdGV4dCBub2RlcyBhbnl3aGVyZSBlbHNlLiBSdW4gYWZ0ZXIgYW55IG9wZXJhdGlvbiB0aGF0IG1heSBkaXN0dXJiIHRoZVxuICAvLyB0cmVlICh0eXBpbmcsIHBhc3RlLCBjdXQsIGRlbGV0ZSkgc28gY3J1ZnQgZG9lc24ndCBhY2N1bXVsYXRlIGFjcm9zc1xuICAvLyByZXBlYXRlZCBjb3B5L3Bhc3RlIGN5Y2xlcy5cbiAgcHJpdmF0ZSBub3JtYWxpemVNZW50aW9uUGFkZGluZygpOiB2b2lkIHtcbiAgICBjb25zdCByb290ID0gdGhpcy5pbnB1dEVsZW1lbnQ/Lm5hdGl2ZUVsZW1lbnQ7XG4gICAgaWYgKCFyb290KSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgLy8gMS4gRW5zdXJlIGVhY2ggbWVudGlvbiBoYXMgYSBaV1MgcGFkIG9uIGJvdGggc2lkZXMuXG4gICAgY29uc3QgbWVudGlvbnMgPSBBcnJheS5mcm9tKFxuICAgICAgcm9vdC5xdWVyeVNlbGVjdG9yQWxsKCdzcGFuW2RhdGEtdHlwZT1cIm1lbnRpb25cIl0nKSxcbiAgICApIGFzIEhUTUxFbGVtZW50W107XG4gICAgZm9yIChjb25zdCBtIG9mIG1lbnRpb25zKSB7XG4gICAgICBjb25zdCBwYXJlbnQgPSBtLnBhcmVudE5vZGU7XG4gICAgICBpZiAoIXBhcmVudCkge1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cbiAgICAgIGlmIChcbiAgICAgICAgIW0ucHJldmlvdXNTaWJsaW5nIHx8XG4gICAgICAgICFNZW50aW9uc0lucHV0Q29tcG9uZW50LmlzWndzKG0ucHJldmlvdXNTaWJsaW5nKVxuICAgICAgKSB7XG4gICAgICAgIHBhcmVudC5pbnNlcnRCZWZvcmUoZG9jdW1lbnQuY3JlYXRlVGV4dE5vZGUoWldTKSwgbSk7XG4gICAgICB9XG4gICAgICBpZiAoIW0ubmV4dFNpYmxpbmcgfHwgIU1lbnRpb25zSW5wdXRDb21wb25lbnQuaXNad3MobS5uZXh0U2libGluZykpIHtcbiAgICAgICAgcGFyZW50Lmluc2VydEJlZm9yZShkb2N1bWVudC5jcmVhdGVUZXh0Tm9kZShaV1MpLCBtLm5leHRTaWJsaW5nKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyAyLiBSZW1vdmUgYW55IFpXUy1vbmx5IHRleHQgbm9kZSB0aGF0IGlzbid0IGRpcmVjdGx5IGFkamFjZW50IHRvIGFcbiAgICAvLyAgICBtZW50aW9uIChvcnBoYW5zIGZyb20gbGluZS1icmVhayBwYWRzLCBsZWZ0b3ZlciBzcGxpdHMgZnJvbSBwcmV2aW91c1xuICAgIC8vICAgIHBhc3RlIGluc2VydGlvbnMsIGR1cGxpY2F0ZSBwYWRzIGZyb20gYWNjdW11bGF0ZWQgY29weS9wYXN0ZSBjeWNsZXMpLlxuICAgIC8vICAgIFNraXAgYSBub2RlIGlmIHRoZSBjdXJzb3IgY3VycmVudGx5IGxpdmVzIGluIGl0IOKAlCBwcmVzZXJ2ZXMgY2FyZXRcbiAgICAvLyAgICBwb3NpdGlvbiB3aXRob3V0IG5lZWRpbmcgbWFudWFsIHJlc3RvcmF0aW9uLlxuICAgIGNvbnN0IHNlbGVjdGlvbiA9IHdpbmRvdy5nZXRTZWxlY3Rpb24oKTtcbiAgICBjb25zdCBjdXJzb3JOb2RlID1cbiAgICAgIHNlbGVjdGlvbj8ucmFuZ2VDb3VudCAmJlxuICAgICAgcm9vdC5jb250YWlucyhzZWxlY3Rpb24uZ2V0UmFuZ2VBdCgwKS5zdGFydENvbnRhaW5lcilcbiAgICAgICAgPyBzZWxlY3Rpb24uZ2V0UmFuZ2VBdCgwKS5zdGFydENvbnRhaW5lclxuICAgICAgICA6IG51bGw7XG5cbiAgICBjb25zdCB3YWxrZXIgPSBkb2N1bWVudC5jcmVhdGVUcmVlV2Fsa2VyKHJvb3QsIE5vZGVGaWx0ZXIuU0hPV19URVhULCBudWxsKTtcbiAgICBjb25zdCBvcnBoYW5zOiBUZXh0W10gPSBbXTtcbiAgICB3aGlsZSAod2Fsa2VyLm5leHROb2RlKCkpIHtcbiAgICAgIGNvbnN0IG5vZGUgPSB3YWxrZXIuY3VycmVudE5vZGUgYXMgVGV4dDtcbiAgICAgIGlmICghTWVudGlvbnNJbnB1dENvbXBvbmVudC5pc1p3cyhub2RlKSB8fCBub2RlID09PSBjdXJzb3JOb2RlKSB7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuICAgICAgY29uc3QgYWRqYWNlbnRUb01lbnRpb24gPVxuICAgICAgICBNZW50aW9uc0lucHV0Q29tcG9uZW50LmlzTWVudGlvbihub2RlLnByZXZpb3VzU2libGluZykgfHxcbiAgICAgICAgTWVudGlvbnNJbnB1dENvbXBvbmVudC5pc01lbnRpb24obm9kZS5uZXh0U2libGluZyk7XG4gICAgICBpZiAoIWFkamFjZW50VG9NZW50aW9uKSB7XG4gICAgICAgIG9ycGhhbnMucHVzaChub2RlKTtcbiAgICAgIH1cbiAgICB9XG4gICAgZm9yIChjb25zdCBub2RlIG9mIG9ycGhhbnMpIHtcbiAgICAgIG5vZGUucmVtb3ZlKCk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBoYW5kbGVNZW50aW9uc0Ryb3Bkb3duTmF2KGV2ZW50OiBLZXlib2FyZEV2ZW50KTogdm9pZCB7XG4gICAgY29uc3QgZmlsdGVyZWRVc2VycyA9IHRoaXMuZ2V0RmlsdGVyZWRVc2VycygpO1xuICAgIGlmIChmaWx0ZXJlZFVzZXJzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgdGhpcy5jbG9zZU1lbnRpb25zKCk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgc3dpdGNoIChldmVudC5rZXkpIHtcbiAgICAgIGNhc2UgJ0Fycm93RG93bic6XG4gICAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgIHRoaXMuc2VsZWN0ZWRVc2VySW5kZXggPSBNYXRoLm1pbihcbiAgICAgICAgICB0aGlzLnNlbGVjdGVkVXNlckluZGV4ICsgMSxcbiAgICAgICAgICBmaWx0ZXJlZFVzZXJzLmxlbmd0aCAtIDEsXG4gICAgICAgICk7XG4gICAgICAgIHRoaXMuY2RyLm1hcmtGb3JDaGVjaygpO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJ0Fycm93VXAnOlxuICAgICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICB0aGlzLnNlbGVjdGVkVXNlckluZGV4ID0gTWF0aC5tYXgodGhpcy5zZWxlY3RlZFVzZXJJbmRleCAtIDEsIDApO1xuICAgICAgICB0aGlzLmNkci5tYXJrRm9yQ2hlY2soKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlICdFbnRlcic6XG4gICAgICBjYXNlICdUYWInOlxuICAgICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICBpZiAoZmlsdGVyZWRVc2Vyc1t0aGlzLnNlbGVjdGVkVXNlckluZGV4XSkge1xuICAgICAgICAgIHRoaXMuc2VsZWN0VXNlcihmaWx0ZXJlZFVzZXJzW3RoaXMuc2VsZWN0ZWRVc2VySW5kZXhdKTtcbiAgICAgICAgfVxuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJ0VzY2FwZSc6XG4gICAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgIHRoaXMuY2xvc2VNZW50aW9ucygpO1xuICAgICAgICBicmVhaztcbiAgICB9XG4gIH1cblxuICAvLyDilIDilIDilIAgSW5zZXJ0aW9uIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgFxuXG4gIHByaXZhdGUgcGxhaW5UZXh0VG9Ob2Rlcyh0ZXh0OiBzdHJpbmcpOiBOb2RlW10ge1xuICAgIGNvbnN0IG5vZGVzOiBOb2RlW10gPSBbXTtcbiAgICBjb25zdCBsaW5lcyA9IHRleHQuc3BsaXQoJ1xcbicpO1xuICAgIGxpbmVzLmZvckVhY2goKGxpbmUsIGluZGV4KSA9PiB7XG4gICAgICBpZiAobGluZSkge1xuICAgICAgICBub2Rlcy5wdXNoKGRvY3VtZW50LmNyZWF0ZVRleHROb2RlKGxpbmUpKTtcbiAgICAgIH1cbiAgICAgIGlmIChpbmRleCA8IGxpbmVzLmxlbmd0aCAtIDEpIHtcbiAgICAgICAgbm9kZXMucHVzaChkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdicicpKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgICByZXR1cm4gbm9kZXM7XG4gIH1cbiAgLy8gQ3JlYXRlIGEgdGVtcG9yYXJ5IGNvbnRhaW5lciB0byBwYXJzZSB0aGUgSFRNTFxuICBwcml2YXRlIHBhcnNlUGFzdGVkSHRtbChodG1sOiBzdHJpbmcpOiBOb2RlW10ge1xuICAgIC8vIENyZWF0ZSBhIHRlbXBvcmFyeSBjb250YWluZXIgdG8gcGFyc2UgdGhlIEhUTUxcbiAgICBjb25zdCB0ZW1wQ29udGFpbmVyID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XG4gICAgdGVtcENvbnRhaW5lci5pbm5lckhUTUwgPSBodG1sO1xuXG4gICAgY29uc3Qgbm9kZXM6IE5vZGVbXSA9IFtdO1xuICAgIGNvbnN0IHdhbGsgPSAobm9kZTogTm9kZSk6IHZvaWQgPT4ge1xuICAgICAgaWYgKG5vZGUubm9kZVR5cGUgPT09IE5vZGUuRUxFTUVOVF9OT0RFKSB7XG4gICAgICAgIGNvbnN0IGVsID0gbm9kZSBhcyBIVE1MRWxlbWVudDtcbiAgICAgICAgLy8gREFITkUgTk9URSAtIHdlIG9ubHkgd2FudCBtZW50aW9uIHNwYW5zLCBiciBlbGVtZW50cywgYW5kIHRleHRcbiAgICAgICAgaWYgKFxuICAgICAgICAgIGVsLnRhZ05hbWUgPT09ICdTUEFOJyAmJlxuICAgICAgICAgIGVsLmdldEF0dHJpYnV0ZSgnZGF0YS10eXBlJykgPT09ICdtZW50aW9uJyAmJlxuICAgICAgICAgIGVsLmhhc0F0dHJpYnV0ZSgnZGF0YS1pZCcpXG4gICAgICAgICkge1xuICAgICAgICAgIC8vQ3JlYXRlIG1lbnRpb24gdG8gdWx0aW1hdGVseSBpbnNlcnQgaW50byB0aGUgRE9NXG4gICAgICAgICAgY29uc3Qgc3BhbiA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ3NwYW4nKTtcbiAgICAgICAgICBzcGFuLmNsYXNzTmFtZSA9IHRoaXMucmVhZG9ubHkgPyAncmVhZG9ubHktbWVudGlvbicgOiAnbWVudGlvbic7XG4gICAgICAgICAgc3Bhbi5zZXRBdHRyaWJ1dGUoJ2RhdGEtaWQnLCBlbC5nZXRBdHRyaWJ1dGUoJ2RhdGEtaWQnKSB8fCAnJyk7XG4gICAgICAgICAgc3Bhbi5zZXRBdHRyaWJ1dGUoJ2RhdGEtdHlwZScsICdtZW50aW9uJyk7XG4gICAgICAgICAgc3Bhbi5zZXRBdHRyaWJ1dGUoJ2NvbnRlbnRlZGl0YWJsZScsICdmYWxzZScpO1xuICAgICAgICAgIGNvbnN0IHJhdyA9IGVsLnRleHRDb250ZW50IHx8ICcnO1xuICAgICAgICAgIHNwYW4udGV4dENvbnRlbnQgPSByYXcuc3RhcnRzV2l0aCgnQCcpID8gcmF3IDogYEAke3Jhd31gO1xuICAgICAgICAgIG5vZGVzLnB1c2goc3Bhbik7XG4gICAgICAgIH0gZWxzZSBpZiAoZWwudGFnTmFtZSA9PT0gJ0JSJykge1xuICAgICAgICAgIC8vIFByZXNlcnZlIGxpbmUgYnJlYWtzXG4gICAgICAgICAgbm9kZXMucHVzaChkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdicicpKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAvL1JlY3Vyc2l2ZWx5IGxvb2sgZm9yIG5lc3RlZCBjaGlsZHJlblxuICAgICAgICAgIGZvciAoY29uc3QgY2hpbGQgb2YgQXJyYXkuZnJvbShlbC5jaGlsZE5vZGVzKSkge1xuICAgICAgICAgICAgd2FsayhjaGlsZCk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9IGVsc2UgaWYgKG5vZGUubm9kZVR5cGUgPT09IE5vZGUuVEVYVF9OT0RFKSB7XG4gICAgICAgIGNvbnN0IHRleHQgPSAobm9kZS50ZXh0Q29udGVudCB8fCAnJykucmVwbGFjZShaV1NfUkVHRVgsICcnKTtcbiAgICAgICAgaWYgKHRleHQpIHtcbiAgICAgICAgICBub2Rlcy5wdXNoKGRvY3VtZW50LmNyZWF0ZVRleHROb2RlKHRleHQpKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH07XG5cbiAgICBmb3IgKGNvbnN0IGNoaWxkIG9mIEFycmF5LmZyb20odGVtcENvbnRhaW5lci5jaGlsZE5vZGVzKSkge1xuICAgICAgd2FsayhjaGlsZCk7XG4gICAgfVxuICAgIC8vREFITkUgTk9URSAtIHRoZSByZXN1bHQgaGVyZSBzaG91bGQgYmUgYW4gYXJyYXkgb2YgdGV4dC9zcGFuLW1lbnRpb24vYnIgbm9kZXNcbiAgICByZXR1cm4gbm9kZXM7XG4gIH1cblxuICBwcml2YXRlIGluc2VydE5vZGVzQXRDdXJzb3Iobm9kZXM6IE5vZGVbXSk6IHZvaWQge1xuICAgIC8vR2V0IHNlbGVjdGlvbiBvYmplY3QsIHJlcHJlc2VudGluZyB1c2VyIGN1cnNvciBwb3NpdGlvbi9zZWxlY3Rpb25cbiAgICAvL0dldCBSYW5nZSBvYmplY3QgYXQgc3RhcnQgb2Ygc2VsZWN0aW9uLCB3aGljaCBzaG91bGQgcmVwcmVzZW50IGN1cnNvciBwb3NpdGlvblxuICAgIC8vSWYgdGhlcmUgaXMgYSBzZWxlY3Rpb24sIGRlbGV0ZSBpdFxuICAgIC8vSW5zZXJ0IHRoZSBwYXJzZWQgbm9kZXMgZnJvbSBhYm92ZSwgbW92ZSByYW5nZSBlbmRzIHRvIGFmdGVyIG5vZGVcbiAgICAvL1RoZW4gcmVtb3ZlIHRoZSByYW5nZSBhbmQgcmVzZXQgaXQgdG8gbW92ZSB0aGUgY3Vyc29yIHBvc2l0aW9uIHRvIHRoZSBlbmRcbiAgICBjb25zdCBzZWxlY3Rpb24gPSB3aW5kb3cuZ2V0U2VsZWN0aW9uKCk7XG4gICAgaWYgKCFzZWxlY3Rpb24/LnJhbmdlQ291bnQpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgY29uc3QgcmFuZ2UgPSBzZWxlY3Rpb24uZ2V0UmFuZ2VBdCgwKTtcbiAgICByYW5nZS5kZWxldGVDb250ZW50cygpO1xuXG4gICAgbGV0IGN1cnNvclRhcmdldDogTm9kZSB8IG51bGwgPSBudWxsO1xuICAgIGZvciAoY29uc3Qgbm9kZSBvZiBub2Rlcykge1xuICAgICAgaWYgKE1lbnRpb25zSW5wdXRDb21wb25lbnQuaXNNZW50aW9uKG5vZGUpKSB7XG4gICAgICAgIGNvbnN0IGJlZm9yZSA9IGRvY3VtZW50LmNyZWF0ZVRleHROb2RlKFpXUyk7XG4gICAgICAgIGNvbnN0IGFmdGVyID0gZG9jdW1lbnQuY3JlYXRlVGV4dE5vZGUoWldTKTtcbiAgICAgICAgcmFuZ2UuaW5zZXJ0Tm9kZShiZWZvcmUpO1xuICAgICAgICByYW5nZS5zZXRTdGFydEFmdGVyKGJlZm9yZSk7XG4gICAgICAgIHJhbmdlLmluc2VydE5vZGUobm9kZSk7XG4gICAgICAgIHJhbmdlLnNldFN0YXJ0QWZ0ZXIobm9kZSk7XG4gICAgICAgIHJhbmdlLmluc2VydE5vZGUoYWZ0ZXIpO1xuICAgICAgICByYW5nZS5zZXRTdGFydEFmdGVyKGFmdGVyKTtcbiAgICAgICAgY3Vyc29yVGFyZ2V0ID0gYWZ0ZXI7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByYW5nZS5pbnNlcnROb2RlKG5vZGUpO1xuICAgICAgICByYW5nZS5zZXRTdGFydEFmdGVyKG5vZGUpO1xuICAgICAgICBjdXJzb3JUYXJnZXQgPSBub2RlO1xuICAgICAgfVxuICAgICAgcmFuZ2UuY29sbGFwc2UodHJ1ZSk7XG4gICAgfVxuXG4gICAgLy8gQWZ0ZXIgYSBtZW50aW9uLCBsZWF2ZSB0aGUgY3Vyc29yIGluc2lkZSB0aGUgdHJhaWxpbmcgWldTIHNvIEFycm93TGVmdFxuICAgIC8vIGNhbiBzdGVwIGJhY2sgdG8gYmVmb3JlLXRoZS1tZW50aW9uIG5hdHVyYWxseS5cbiAgICBpZiAoY3Vyc29yVGFyZ2V0ICYmIE1lbnRpb25zSW5wdXRDb21wb25lbnQuaXNad3MoY3Vyc29yVGFyZ2V0KSkge1xuICAgICAgcmFuZ2Uuc2V0U3RhcnQoY3Vyc29yVGFyZ2V0LCAwKTtcbiAgICAgIHJhbmdlLmNvbGxhcHNlKHRydWUpO1xuICAgIH1cblxuICAgIHNlbGVjdGlvbi5yZW1vdmVBbGxSYW5nZXMoKTtcbiAgICBzZWxlY3Rpb24uYWRkUmFuZ2UocmFuZ2UpO1xuICB9XG5cbiAgcHJpdmF0ZSBpbnNlcnRMaW5lQnJlYWsoKTogdm9pZCB7XG4gICAgY29uc3Qgc2VsZWN0aW9uID0gd2luZG93LmdldFNlbGVjdGlvbigpO1xuICAgIGlmICghc2VsZWN0aW9uPy5yYW5nZUNvdW50IHx8ICF0aGlzLmlucHV0RWxlbWVudD8ubmF0aXZlRWxlbWVudCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBjb25zdCByYW5nZSA9IHNlbGVjdGlvbi5nZXRSYW5nZUF0KDApO1xuICAgIHJhbmdlLmRlbGV0ZUNvbnRlbnRzKCk7XG5cbiAgICBjb25zdCBiciA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2JyJyk7XG4gICAgcmFuZ2UuaW5zZXJ0Tm9kZShicik7XG4gICAgcmFuZ2Uuc2V0U3RhcnRBZnRlcihicik7XG4gICAgcmFuZ2UuY29sbGFwc2UodHJ1ZSk7XG5cbiAgICAvLyBBIHRyYWlsaW5nIDxicj4gYWxvbmUgZG9lc24ndCByZW5kZXIgYW4gZW1wdHkgbGluZSBpbiBjb250ZW50ZWRpdGFibGUg4oCUXG4gICAgLy8gYSBaV1MgZ2l2ZXMgdGhlIGNhcmV0IGEgcGxhY2UgdG8gbGFuZC5cbiAgICBpZiAoIWJyLm5leHRTaWJsaW5nKSB7XG4gICAgICBjb25zdCB6d3MgPSBkb2N1bWVudC5jcmVhdGVUZXh0Tm9kZShaV1MpO1xuICAgICAgcmFuZ2UuaW5zZXJ0Tm9kZSh6d3MpO1xuICAgICAgcmFuZ2Uuc2V0U3RhcnQoendzLCAwKTtcbiAgICAgIHJhbmdlLmNvbGxhcHNlKHRydWUpO1xuICAgIH1cblxuICAgIHNlbGVjdGlvbi5yZW1vdmVBbGxSYW5nZXMoKTtcbiAgICBzZWxlY3Rpb24uYWRkUmFuZ2UocmFuZ2UpO1xuICB9XG5cbiAgLy8g4pSA4pSA4pSAIE1lbnRpb24gdHJpZ2dlciAvIGRyb3Bkb3duIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgFxuXG4gIHByaXZhdGUgY2hlY2tGb3JNZW50aW9uVHJpZ2dlcigpOiB2b2lkIHtcbiAgICBjb25zdCBzZWxlY3Rpb24gPSB3aW5kb3cuZ2V0U2VsZWN0aW9uKCk7XG4gICAgaWYgKCFzZWxlY3Rpb24gfHwgIXNlbGVjdGlvbi5yYW5nZUNvdW50IHx8ICF0aGlzLmlucHV0RWxlbWVudCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IHJhbmdlID0gc2VsZWN0aW9uLmdldFJhbmdlQXQoMCk7XG4gICAgY29uc3QgdGV4dEJlZm9yZUN1cnNvciA9IHRoaXMuZ2V0VGV4dEJlZm9yZUN1cnNvcihyYW5nZSk7XG4gICAgY29uc3QgbGFzdEF0SW5kZXggPSB0ZXh0QmVmb3JlQ3Vyc29yLmxhc3RJbmRleE9mKCdAJyk7XG5cbiAgICBpZiAobGFzdEF0SW5kZXggPT09IC0xKSB7XG4gICAgICB0aGlzLmNsb3NlTWVudGlvbnMoKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgLy9JZiB3ZSBhbGxvdyBmb3IgYSBzaW5nbGUgc3BhY2UsIHdlIG5lZWQgdG8gY2hlY2sgdG8gbWFrZSBzdXJlIHRoYXQgdGhpcyBsb2dpYyB3b24ndCBwaWNrIHVwIHByZXZpb3VzXG4gICAgLy8nQCcgbWVudGlvbnMgYW5kIGtlZXAgdGhlIG1lbnRpb24gZHJvcGRvd24gb3BlblxuICAgIGNvbnN0IGF0UG9zaXRpb24gPSB0aGlzLmZpbmREb21Qb3NpdGlvbkF0Q2hhckluZGV4KGxhc3RBdEluZGV4KTtcbiAgICBpZiAoYXRQb3NpdGlvbiAmJiB0aGlzLmlzSW5zaWRlTWVudGlvblNwYW4oYXRQb3NpdGlvbi5ub2RlKSkge1xuICAgICAgdGhpcy5jbG9zZU1lbnRpb25zKCk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc3QgdGV4dEFmdGVyQXQgPSB0ZXh0QmVmb3JlQ3Vyc29yLnN1YnN0cmluZyhsYXN0QXRJbmRleCArIDEpO1xuICAgIGNvbnN0IGNoYXIxID0gdGV4dEFmdGVyQXQuY2hhckNvZGVBdCgwKTtcbiAgICBjb25zdCBjaGFyTiA9IHRleHRBZnRlckF0LmNoYXJDb2RlQXQodGV4dEFmdGVyQXQubGVuZ3RoIC0gMSk7XG4gICAgY29uc3QgY2hhck5fMSA9IHRleHRBZnRlckF0LmNoYXJDb2RlQXQodGV4dEFmdGVyQXQubGVuZ3RoIC0gMik7XG4gICAgLy9UaGVzZSBhcmUgdGhlIFVuaWNvZGUgcmVwcmVzZW50YXRpb25zIG9mIG5vcm1hbCBzcGFjZSBhbmQgbm9uLWJyZWFraW5nIHNwYWNlXG4gICAgY29uc3QgdW5pY29kZVNwYWNlQ2hhcnMgPSBbMzIsIDE2MF07XG5cbiAgICAvLyBDbG9zZSBtZW50aW9ucyBpZjpcbiAgICAvLyAtIFRoZXJlJ3MgYSBkb3VibGUgc3BhY2UgKGFsbG93cyBzaW5nbGUgc3BhY2VzIGluIHRoZSBtaWRkbGUgb2Ygc2VhcmNoKVxuICAgIC8vIC0gVGhlIHRleHQgc3RhcnRzIHdpdGggYSBzcGFjZSAodHlwaW5nIFwiQCBcIiBzaG91bGQgbm90IHRyaWdnZXIgbWVudGlvbnMpXG4gICAgaWYgKFxuICAgICAgdGV4dEFmdGVyQXQuaW5jbHVkZXMoJyAgJykgfHxcbiAgICAgIHRleHRBZnRlckF0LnN0YXJ0c1dpdGgoJyAnKSB8fFxuICAgICAgY2hhcjEgPT0gMTYwIHx8XG4gICAgICAodW5pY29kZVNwYWNlQ2hhcnMuaW5jbHVkZXMoY2hhck4pICYmIHVuaWNvZGVTcGFjZUNoYXJzLmluY2x1ZGVzKGNoYXJOXzEpKVxuICAgICkge1xuICAgICAgdGhpcy5jbG9zZU1lbnRpb25zKCk7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIC8vIFRyaW0gdHJhaWxpbmcvbGVhZGluZyBzcGFjZXMgZnJvbSBzZWFyY2ggdGV4dCB3aGlsZSBwcmVzZXJ2aW5nIHNwYWNlcyBpbiB0aGUgbWlkZGxlXG4gICAgdGhpcy5tZW50aW9uU2VhcmNoVGV4dCA9IHRleHRBZnRlckF0LnRyaW0oKTtcbiAgICAvLyBPbmx5IHNob3cgbWVudGlvbnMgaWYgdGhlcmUgYXJlIGZpbHRlcmVkIHVzZXJzXG4gICAgY29uc3QgZmlsdGVyZWRVc2VycyA9IHRoaXMuZ2V0RmlsdGVyZWRVc2VycygpO1xuICAgIGlmIChmaWx0ZXJlZFVzZXJzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgdGhpcy5jbG9zZU1lbnRpb25zKCk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdGhpcy5tZW50aW9uc1Zpc2libGUgPSB0cnVlO1xuICAgIHRoaXMuc2VsZWN0ZWRVc2VySW5kZXggPSAwO1xuXG4gICAgLy9TYXZlIHRoZSBjdXJyZW50IHJhbmdlIGZvciBsYXRlciByZXN0b3JhdGlvbiAobmVlZGVkIGZvciBjbGljayBzZWxlY3Rpb24pXG4gICAgLy9EQUhORSBOT1RFIC0gdGhpcyBpcyBhbm5veWluZ2x5IG5lY2Vlc3NhcnkgYmVjYXVzZSBjbGlja3MgYW5kIGVudGVyIGtleXMgaGF2ZSBkaWZmZXJlbnQgZWZmZWN0cyBvbiB0aGVcbiAgICAvL2ZvY3VzIG9mIHRoZSBjb250ZW50ZWRpdGFibGUgZGl2XG4gICAgdGhpcy5zYXZlZFJhbmdlID0gcmFuZ2UuY2xvbmVSYW5nZSgpO1xuXG4gICAgaWYgKGF0UG9zaXRpb24pIHtcbiAgICAgIGNvbnN0IGF0UmFuZ2UgPSBkb2N1bWVudC5jcmVhdGVSYW5nZSgpO1xuICAgICAgYXRSYW5nZS5zZXRTdGFydChhdFBvc2l0aW9uLm5vZGUsIGF0UG9zaXRpb24ub2Zmc2V0KTtcbiAgICAgIGF0UmFuZ2Uuc2V0RW5kKGF0UG9zaXRpb24ubm9kZSwgYXRQb3NpdGlvbi5vZmZzZXQgKyAxKTtcbiAgICAgIHRoaXMubWVudGlvbkFuY2hvciA9IGF0UmFuZ2UuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG4gICAgfVxuICAgIHRoaXMuY2RyLm1hcmtGb3JDaGVjaygpO1xuICB9XG5cbiAgcHJpdmF0ZSBnZXRUZXh0QmVmb3JlQ3Vyc29yKHJhbmdlOiBSYW5nZSk6IHN0cmluZyB7XG4gICAgY29uc3QgY2xvbmVkUmFuZ2UgPSByYW5nZS5jbG9uZVJhbmdlKCk7XG4gICAgLy9XZSBzZWxlY3QgYWxsIG9mIHRoZSBpbnB1dCBjb250ZW50cywgYW5kIHRoZW4gbW92ZSB0aGUgZW5kIHBvaW50IHRvIHRoZSBjdXJyZW50IGN1cnNvciBwb3NpdGlvblxuICAgIGNsb25lZFJhbmdlLnNlbGVjdE5vZGVDb250ZW50cyh0aGlzLmlucHV0RWxlbWVudCEubmF0aXZlRWxlbWVudCk7XG4gICAgY2xvbmVkUmFuZ2Uuc2V0RW5kKHJhbmdlLmVuZENvbnRhaW5lciwgcmFuZ2UuZW5kT2Zmc2V0KTtcbiAgICAvL0NyZWF0ZSBhIHRlbXBvcmFyeSBkaXYgc28gdGhhdCB3ZSBjYW4gZXh0cmFjdCB0ZXh0IGNvbnRlbnQgZnJvbSBpdFxuICAgIGNvbnN0IGZyYWdtZW50ID0gY2xvbmVkUmFuZ2UuY2xvbmVDb250ZW50cygpO1xuICAgIGNvbnN0IGRpdiA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuICAgIGRpdi5hcHBlbmRDaGlsZChmcmFnbWVudCk7XG4gICAgLy9HZXQgdGV4dCBjb250ZW50LCByZXBsYWNpbmcgbWVudGlvbiBzcGFucyB3aXRoIEBuYW1lXG4gICAgcmV0dXJuIGRpdi50ZXh0Q29udGVudCB8fCAnJztcbiAgfVxuXG4gIGdldEZpbHRlcmVkVXNlcnMoKTogTWVudGlvbnNJbnB1dENvbXBvbmVudC5Vc2VyW10ge1xuICAgIGNvbnN0IHVzZXJzID0gIXRoaXMubWVudGlvblNlYXJjaFRleHRcbiAgICAgID8gdGhpcy51c2Vyc1xuICAgICAgOiB0aGlzLnVzZXJzLmZpbHRlcih1c2VyID0+XG4gICAgICAgICAgdXNlci5uYW1lXG4gICAgICAgICAgICAudG9Mb3dlckNhc2UoKVxuICAgICAgICAgICAgLmluY2x1ZGVzKHRoaXMubWVudGlvblNlYXJjaFRleHQudG9Mb3dlckNhc2UoKSksXG4gICAgICAgICk7XG4gICAgcmV0dXJuIHVzZXJzLnNsaWNlKCkuc29ydCgoYSwgYikgPT4gYS5uYW1lLmxvY2FsZUNvbXBhcmUoYi5uYW1lKSk7XG4gIH1cblxuICBvblVzZXJIb3ZlcihpbmRleDogbnVtYmVyKTogdm9pZCB7XG4gICAgdGhpcy5zZWxlY3RlZFVzZXJJbmRleCA9IGluZGV4O1xuICAgIHRoaXMuY2RyLm1hcmtGb3JDaGVjaygpO1xuICB9XG5cbiAgc2VsZWN0VXNlcih1c2VyOiBNZW50aW9uc0lucHV0Q29tcG9uZW50LlVzZXIpOiB2b2lkIHtcbiAgICBpZiAoIXRoaXMuaW5wdXRFbGVtZW50KSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIC8vVGhpcyBnZXRzIERPTSBpbmZvIGZyb20gdXNlciAoZS5nLiBoaWdobGlnaHRlZCBzZWxlY3Rpb25zLCBhbmQgY3Vyc29yIHBvc2l0aW9uKVxuICAgIGNvbnN0IHNlbGVjdGlvbiA9IHdpbmRvdy5nZXRTZWxlY3Rpb24oKTtcbiAgICBpZiAoIXNlbGVjdGlvbikge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICAvLyBSZXN0b3JlIHRoZSBzYXZlZCByYW5nZSBpZiBhdmFpbGFibGUgKG5lZWRlZCB3aGVuIHNlbGVjdGluZyB2aWEgY2xpY2spXG4gICAgaWYgKHRoaXMuc2F2ZWRSYW5nZSkge1xuICAgICAgc2VsZWN0aW9uLnJlbW92ZUFsbFJhbmdlcygpO1xuICAgICAgc2VsZWN0aW9uLmFkZFJhbmdlKHRoaXMuc2F2ZWRSYW5nZSk7XG4gICAgfVxuICAgIGlmICghc2VsZWN0aW9uLnJhbmdlQ291bnQpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgLy8gRGVsZXRlIHRoZSBcIkBcIiBhbmQgc2VhcmNoIHRleHRcbiAgICB0aGlzLmRlbGV0ZUF0TWVudGlvblNlYXJjaCgpO1xuXG4gICAgLy9EQUhORSBOT1RFIC0gdGhpcyB3b3VsZCBpZGVhbGx5IGJlIHRoZSBzYW1lIGFzIGNvbnRlbnRJdGVtVG9IVE1MLCBidXQgd2UgbmVlZCBhbiBhY3R1YWwgZWxlbWVudCByZWZlcmVuY2UgaGVyZSBpbiBvcmRlciB0byBhcHBlbmQgaXQgdG8gdGhlIERPTVxuICAgIGNvbnN0IG1lbnRpb25TcGFuID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnc3BhbicpO1xuICAgIG1lbnRpb25TcGFuLmNsYXNzTmFtZSA9IHRoaXMucmVhZG9ubHkgPyAncmVhZG9ubHktbWVudGlvbicgOiAnbWVudGlvbic7XG4gICAgbWVudGlvblNwYW4uc2V0QXR0cmlidXRlKCdkYXRhLWlkJywgU3RyaW5nKHVzZXIuaWQpKTtcbiAgICBtZW50aW9uU3Bhbi5zZXRBdHRyaWJ1dGUoJ2RhdGEtdHlwZScsICdtZW50aW9uJyk7XG4gICAgbWVudGlvblNwYW4uc2V0QXR0cmlidXRlKCdjb250ZW50ZWRpdGFibGUnLCAnZmFsc2UnKTtcbiAgICBtZW50aW9uU3Bhbi50ZXh0Q29udGVudCA9IGBAJHt1c2VyLm5hbWV9YDtcblxuICAgIHRoaXMuaW5zZXJ0Tm9kZXNBdEN1cnNvcihbbWVudGlvblNwYW4sIGRvY3VtZW50LmNyZWF0ZVRleHROb2RlKCcgJyldKTtcbiAgICB0aGlzLm5vcm1hbGl6ZU1lbnRpb25QYWRkaW5nKCk7XG5cbiAgICB0aGlzLmNsb3NlTWVudGlvbnMoKTtcbiAgICB0aGlzLmVtaXRDb250ZW50Q2hhbmdlKCk7XG4gIH1cblxuICBwcml2YXRlIGRlbGV0ZUF0TWVudGlvblNlYXJjaCgpOiB2b2lkIHtcbiAgICBjb25zdCBzZWxlY3Rpb24gPSB3aW5kb3cuZ2V0U2VsZWN0aW9uKCk7XG4gICAgaWYgKCFzZWxlY3Rpb24gfHwgIXNlbGVjdGlvbi5yYW5nZUNvdW50KSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIC8vVGhpcyByZXByZXNlbnRzIHRoZSBjdXJyZW50IHBvc2l0aW9uIG9mIHRoZSBjdXJzb3JcbiAgICBjb25zdCBjdXJzb3JSYW5nZSA9IHNlbGVjdGlvbi5nZXRSYW5nZUF0KDApO1xuICAgIC8vVGhpcyB3aWxsIHJldHVybiBhbGwgb2YgdGhlIHJhdyB0ZXh0IChIVE1MLXN0cmlwcGVkKSBiZWZvcmUgdGhlIGN1cnNvclxuICAgIGNvbnN0IHRleHRCZWZvcmVDdXJzb3IgPSB0aGlzLmdldFRleHRCZWZvcmVDdXJzb3IoY3Vyc29yUmFuZ2UpO1xuICAgIC8vV2UgZG8gdGhhdF4gc28gdGhhdCB3ZSBjYW4gZmluZCB0aGUgY29ycmVjdCBpbmRleCBvZiB0aGUgbW9zdCByZWNlbnQgJ0AnXG4gICAgY29uc3QgbGFzdEF0SW5kZXggPSB0ZXh0QmVmb3JlQ3Vyc29yLmxhc3RJbmRleE9mKCdAJyk7XG5cbiAgICBpZiAobGFzdEF0SW5kZXggPT09IC0xKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGNvbnN0IGF0UG9zaXRpb24gPSB0aGlzLmZpbmREb21Qb3NpdGlvbkF0Q2hhckluZGV4KGxhc3RBdEluZGV4KTtcbiAgICBpZiAoIWF0UG9zaXRpb24pIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgLy8gQ3JlYXRlIHJhbmdlIGZyb20gXCJAXCIgdG8gY3Vyc29yIGFuZCBkZWxldGUgaXRcbiAgICBjb25zdCBkZWxldGVSYW5nZSA9IGRvY3VtZW50LmNyZWF0ZVJhbmdlKCk7XG4gICAgZGVsZXRlUmFuZ2Uuc2V0U3RhcnQoYXRQb3NpdGlvbi5ub2RlLCBhdFBvc2l0aW9uLm9mZnNldCk7XG4gICAgZGVsZXRlUmFuZ2Uuc2V0RW5kKGN1cnNvclJhbmdlLmVuZENvbnRhaW5lciwgY3Vyc29yUmFuZ2UuZW5kT2Zmc2V0KTtcbiAgICBkZWxldGVSYW5nZS5kZWxldGVDb250ZW50cygpO1xuICB9XG5cbiAgcHJpdmF0ZSBpc0luc2lkZU1lbnRpb25TcGFuKG5vZGU6IE5vZGUpOiBib29sZWFuIHtcbiAgICBsZXQgY3VycmVudE5vZGU6IE5vZGUgfCBudWxsID0gbm9kZTtcbiAgICB3aGlsZSAoY3VycmVudE5vZGUgJiYgY3VycmVudE5vZGUgIT09IHRoaXMuaW5wdXRFbGVtZW50Py5uYXRpdmVFbGVtZW50KSB7XG4gICAgICBpZiAoTWVudGlvbnNJbnB1dENvbXBvbmVudC5pc01lbnRpb24oY3VycmVudE5vZGUpKSB7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgfVxuICAgICAgY3VycmVudE5vZGUgPSBjdXJyZW50Tm9kZS5wYXJlbnROb2RlO1xuICAgIH1cbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbiAgLy9UaGlzIHdpbGwgZ28gdGV4dCBub2RlIGJ5IG5vZGUgbG9va2luZyBmb3IgdGhlXG4gIC8vQCBtZW50aW9uIGFuZCBnaXZlIGl0cyBwb3NpdGlvbiBpbiB0aGUgY29udGV4dCBvZiB0aGF0IG5vZGVcbiAgcHJpdmF0ZSBmaW5kRG9tUG9zaXRpb25BdENoYXJJbmRleChcbiAgICBjaGFySW5kZXg6IG51bWJlcixcbiAgKTogeyBub2RlOiBOb2RlOyBvZmZzZXQ6IG51bWJlciB9IHwgbnVsbCB7XG4gICAgaWYgKCF0aGlzLmlucHV0RWxlbWVudCkge1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuICAgIC8vIFdhbGsgdGhyb3VnaCBhbGwgdGV4dCBub2RlcyBpbiB0aGUgaW5wdXQsIGNvdW50aW5nIGNoYXJhY3RlcnNcbiAgICBjb25zdCB0cmVlV2Fsa2VyID0gZG9jdW1lbnQuY3JlYXRlVHJlZVdhbGtlcihcbiAgICAgIHRoaXMuaW5wdXRFbGVtZW50Lm5hdGl2ZUVsZW1lbnQsXG4gICAgICBOb2RlRmlsdGVyLlNIT1dfVEVYVCxcbiAgICAgIG51bGwsXG4gICAgKTtcbiAgICBsZXQgY2hhckNvdW50ID0gMDtcbiAgICB3aGlsZSAodHJlZVdhbGtlci5uZXh0Tm9kZSgpKSB7XG4gICAgICBjb25zdCBub2RlID0gdHJlZVdhbGtlci5jdXJyZW50Tm9kZTtcbiAgICAgIGNvbnN0IHRleHQgPSBub2RlLnRleHRDb250ZW50IHx8ICcnO1xuICAgICAgLy8gQ2hlY2sgaWYgb3VyIHRhcmdldCBjaGFyYWN0ZXIgaXMgaW4gdGhpcyB0ZXh0IG5vZGVcbiAgICAgIGlmIChjaGFyQ291bnQgKyB0ZXh0Lmxlbmd0aCA+IGNoYXJJbmRleCkge1xuICAgICAgICByZXR1cm4geyBub2RlLCBvZmZzZXQ6IGNoYXJJbmRleCAtIGNoYXJDb3VudCB9O1xuICAgICAgfVxuICAgICAgY2hhckNvdW50ICs9IHRleHQubGVuZ3RoO1xuICAgIH1cbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIHByaXZhdGUgY2xvc2VNZW50aW9ucygpOiB2b2lkIHtcbiAgICB0aGlzLm1lbnRpb25zVmlzaWJsZSA9IGZhbHNlO1xuICAgIHRoaXMubWVudGlvblNlYXJjaFRleHQgPSAnJztcbiAgICB0aGlzLm1lbnRpb25BbmNob3IgPSBudWxsO1xuICAgIHRoaXMuc2VsZWN0ZWRVc2VySW5kZXggPSAwO1xuICAgIHRoaXMuc2F2ZWRSYW5nZSA9IG51bGw7XG4gICAgdGhpcy5jZHIubWFya0ZvckNoZWNrKCk7XG4gIH1cblxuICBwcml2YXRlIGVtaXRDb250ZW50Q2hhbmdlKCk6IHZvaWQge1xuICAgIGlmICghdGhpcy5pbnB1dEVsZW1lbnQpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdGhpcy5jb250ZW50Q2hhbmdlLmVtaXQodGhpcy5kb21Ub0NvbnRlbnRJdGVtcygpKTtcbiAgfVxuXG4gIHByaXZhdGUgZG9tVG9Db250ZW50SXRlbXMoKTogTWVudGlvbnNJbnB1dENvbXBvbmVudC5Db250ZW50SXRlbVtdIHtcbiAgICBpZiAoIXRoaXMuaW5wdXRFbGVtZW50Py5uYXRpdmVFbGVtZW50KSB7XG4gICAgICByZXR1cm4gW107XG4gICAgfVxuICAgIGNvbnN0IGl0ZW1zOiBNZW50aW9uc0lucHV0Q29tcG9uZW50LkNvbnRlbnRJdGVtW10gPSBbXTtcbiAgICBjb25zdCBjaGlsZE5vZGVzID0gdGhpcy5pbnB1dEVsZW1lbnQubmF0aXZlRWxlbWVudC5jaGlsZE5vZGVzO1xuXG4gICAgZm9yIChjb25zdCBub2RlIG9mIEFycmF5LmZyb20oY2hpbGROb2RlcykpIHtcbiAgICAgIGlmIChub2RlLm5vZGVUeXBlID09PSBOb2RlLkVMRU1FTlRfTk9ERSkge1xuICAgICAgICBjb25zdCBlbGVtZW50ID0gbm9kZSBhcyBIVE1MRWxlbWVudDtcbiAgICAgICAgaWYgKFxuICAgICAgICAgIGVsZW1lbnQudGFnTmFtZSA9PT0gJ1NQQU4nICYmXG4gICAgICAgICAgZWxlbWVudC5nZXRBdHRyaWJ1dGUoJ2RhdGEtdHlwZScpID09PSAnbWVudGlvbidcbiAgICAgICAgKSB7XG4gICAgICAgICAgY29uc3QgaWQgPSBOdW1iZXIoZWxlbWVudC5nZXRBdHRyaWJ1dGUoJ2RhdGEtaWQnKSk7XG4gICAgICAgICAgY29uc3QgbmFtZSA9IGVsZW1lbnQudGV4dENvbnRlbnQ/LnJlcGxhY2UoJ0AnLCAnJykgfHwgJyc7XG4gICAgICAgICAgaXRlbXMucHVzaCh7IHR5cGU6ICdtZW50aW9uJywgaWQsIG5hbWUgfSk7XG4gICAgICAgIH0gZWxzZSBpZiAoZWxlbWVudC50YWdOYW1lID09PSAnQlInKSB7XG4gICAgICAgICAgaXRlbXMucHVzaCh7IHR5cGU6ICduZXdsaW5lJyB9KTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIGlmIChub2RlLm5vZGVUeXBlID09PSBOb2RlLlRFWFRfTk9ERSkge1xuICAgICAgICAvLyBaV1MgcGFkcyBhcmUgYSBET00gYWZmb3JkYW5jZSDigJQgdGhleSBzaG91bGRuJ3QgbGVhayBpbnRvIHRoZSBkYXRhIG1vZGVsLlxuICAgICAgICBjb25zdCB0ZXh0ID0gKG5vZGUudGV4dENvbnRlbnQgfHwgJycpLnJlcGxhY2UoWldTX1JFR0VYLCAnJyk7XG4gICAgICAgIGlmICh0ZXh0KSB7XG4gICAgICAgICAgaXRlbXMucHVzaCh7IHR5cGU6ICd0ZXh0JywgdGV4dCB9KTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gaXRlbXM7XG4gIH1cblxuICBvbkNhbGxvdXRDbG9zZSgpOiB2b2lkIHtcbiAgICB0aGlzLmNsb3NlTWVudGlvbnMoKTtcbiAgfVxufVxuXG5leHBvcnQgbmFtZXNwYWNlIE1lbnRpb25zSW5wdXRDb21wb25lbnQge1xuICBleHBvcnQgY29uc3QgQ29udGVudFR5cGVzID0gWydtZW50aW9uJywgJ3RleHQnLCAnbmV3bGluZSddIGFzIGNvbnN0O1xuICBleHBvcnQgdHlwZSBDb250ZW50VHlwZSA9XG4gICAgKHR5cGVvZiBNZW50aW9uc0lucHV0Q29tcG9uZW50LkNvbnRlbnRUeXBlcylbbnVtYmVyXTtcbiAgZXhwb3J0IGludGVyZmFjZSBVc2VyIHtcbiAgICBpZDogbnVtYmVyO1xuICAgIG5hbWU6IHN0cmluZztcbiAgfVxuICBleHBvcnQgdHlwZSBDb250ZW50PFQgZXh0ZW5kcyBDb250ZW50VHlwZT4gPSB7IHR5cGU6IFQgfTtcblxuICBleHBvcnQgdHlwZSBVc2VyTWVudGlvbiA9IENvbnRlbnQ8J21lbnRpb24nPiAmIFVzZXI7XG4gIGV4cG9ydCB0eXBlIFRleHQgPSBDb250ZW50PCd0ZXh0Jz4gJiB7IHRleHQ6IHN0cmluZyB9O1xuICBleHBvcnQgdHlwZSBOZXdsaW5lID0gQ29udGVudDwnbmV3bGluZSc+O1xuXG4gIGV4cG9ydCB0eXBlIENvbnRlbnRJdGVtID0gVXNlck1lbnRpb24gfCBUZXh0IHwgTmV3bGluZTtcblxuICBleHBvcnQgZnVuY3Rpb24gY29udGVudFRvUGxhaW5UZXh0KGNvbnRlbnQ6IENvbnRlbnRJdGVtW10pOiBzdHJpbmcge1xuICAgIHJldHVybiBjb250ZW50XG4gICAgICAubWFwKGl0ZW0gPT4ge1xuICAgICAgICBzd2l0Y2ggKGl0ZW0udHlwZSkge1xuICAgICAgICAgIGNhc2UgJ21lbnRpb24nOlxuICAgICAgICAgICAgcmV0dXJuIGBAJHtpdGVtLm5hbWV9YDtcbiAgICAgICAgICBjYXNlICd0ZXh0JzpcbiAgICAgICAgICAgIHJldHVybiBpdGVtLnRleHQ7XG4gICAgICAgICAgY2FzZSAnbmV3bGluZSc6XG4gICAgICAgICAgICByZXR1cm4gJ1xcbic7XG4gICAgICAgIH1cbiAgICAgIH0pXG4gICAgICAuam9pbignJyk7XG4gIH1cbn1cbiIsIjxkaXYgY2xhc3M9XCJtZW50aW9ucy1jb250YWluZXJcIiAjY29udGFpbmVyPlxuICA8ZGl2XG4gICAgKm5nSWY9XCIhcmVhZG9ubHlcIlxuICAgICNpbnB1dFxuICAgIGNsYXNzPVwidGV4dC1jb250ZW50IGVkaXRhYmxlXCJcbiAgICBjb250ZW50ZWRpdGFibGU9XCJ0cnVlXCJcbiAgICBbYXR0ci5kYXRhLXBsYWNlaG9sZGVyXT1cInBsYWNlaG9sZGVyXCJcbiAgICAoaW5wdXQpPVwib25JbnB1dCgpXCJcbiAgICAoa2V5ZG93bik9XCJvbktleURvd24oJGV2ZW50KVwiXG4gICAgKHBhc3RlKT1cIm9uUGFzdGUoJGV2ZW50KVwiXG4gICAgKGNvcHkpPVwib25Db3B5KCRldmVudClcIlxuICAgIChjdXQpPVwib25DdXQoJGV2ZW50KVwiXG4gID48L2Rpdj5cblxuICA8ZGl2ICpuZ0lmPVwicmVhZG9ubHlcIiAjaW5wdXQgY2xhc3M9XCJ0ZXh0LWNvbnRlbnRcIj48L2Rpdj5cblxuICA8cml2LWNhbGxvdXRcbiAgICAqbmdJZj1cIiFyZWFkb25seSAmJiBtZW50aW9uc1Zpc2libGUgJiYgbWVudGlvbkFuY2hvclwiXG4gICAgW2FuY2hvcl09XCJtZW50aW9uQW5jaG9yXCJcbiAgICBbaXNNb2RhbF09XCJ0cnVlXCJcbiAgICBbc2hvd0NhcmV0XT1cImZhbHNlXCJcbiAgICBbYWxsb3dlZFBvc2l0aW9uc109XCJbJ2JvdHRvbS1yaWdodCcsICd0b3AtcmlnaHQnXVwiXG4gICAgW3RoZW1lXT1cIidsaWdodCdcIlxuICAgIChjbG9zZSk9XCJvbkNhbGxvdXRDbG9zZSgpXCJcbiAgPlxuICAgIDxkaXYgY2xhc3M9XCJtZW50aW9ucy1jb250ZW50XCI+XG4gICAgICA8ZGl2IGNsYXNzPVwibWVudGlvbnMtaGVhZGVyXCI+TWVudGlvbiBzb21lb25lPC9kaXY+XG4gICAgICA8ZGl2IGNsYXNzPVwibWVudGlvbnMtbGlzdFwiPlxuICAgICAgICA8YnV0dG9uXG4gICAgICAgICAgdHlwZT1cImJ1dHRvblwiXG4gICAgICAgICAgKm5nRm9yPVwibGV0IHVzZXIgb2YgZ2V0RmlsdGVyZWRVc2VycygpOyBsZXQgaSA9IGluZGV4XCJcbiAgICAgICAgICBbY2xhc3Muc2VsZWN0ZWRdPVwiaSA9PT0gc2VsZWN0ZWRVc2VySW5kZXhcIlxuICAgICAgICAgIChtb3VzZWVudGVyKT1cIm9uVXNlckhvdmVyKGkpXCJcbiAgICAgICAgICAoY2xpY2spPVwic2VsZWN0VXNlcih1c2VyKVwiXG4gICAgICAgID5cbiAgICAgICAgICB7eyB1c2VyLm5hbWUgfX1cbiAgICAgICAgPC9idXR0b24+XG4gICAgICA8L2Rpdj5cbiAgICA8L2Rpdj5cbiAgPC9yaXYtY2FsbG91dD5cbjwvZGl2PlxuIl19