@energycap/components 0.41.1-ECAP-26841-date-input-features.20250108-1012 → 0.42.0

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 (353) hide show
  1. package/{esm2020 → esm2022}/energycap-components.mjs +4 -4
  2. package/esm2022/lib/components.module.mjs +418 -0
  3. package/esm2022/lib/controls/banner/banner.component.mjs +109 -0
  4. package/esm2022/lib/controls/button/button.component.mjs +106 -0
  5. package/esm2022/lib/controls/button/copy-button-base.directive.mjs +67 -0
  6. package/{esm2020 → esm2022}/lib/controls/button/copy-button.directive.mjs +28 -28
  7. package/esm2022/lib/controls/button/copy-table-button.directive.mjs +43 -0
  8. package/esm2022/lib/controls/calendar/calendar-item.component.mjs +59 -0
  9. package/esm2022/lib/controls/calendar/calendar.component.mjs +200 -0
  10. package/esm2022/lib/controls/calendar/calendar.types.mjs +4 -0
  11. package/esm2022/lib/controls/checkbox/checkbox.component.mjs +140 -0
  12. package/{esm2020 → esm2022}/lib/controls/collapsible-toggle/collapsible-toggle.component.mjs +38 -38
  13. package/esm2022/lib/controls/combobox/combobox.component.mjs +879 -0
  14. package/esm2022/lib/controls/date-input/date-input.component.mjs +256 -0
  15. package/esm2022/lib/controls/dropdown/dropdown.component.mjs +243 -0
  16. package/esm2022/lib/controls/file-upload/file-upload.component.mjs +261 -0
  17. package/esm2022/lib/controls/form-control/form-control.component.mjs +104 -0
  18. package/esm2022/lib/controls/form-control-base.mjs +151 -0
  19. package/esm2022/lib/controls/form-control-label/form-control-label.component.mjs +136 -0
  20. package/esm2022/lib/controls/form-group/form-group.component.mjs +261 -0
  21. package/{esm2020 → esm2022}/lib/controls/help-popover/help-popover.component.mjs +31 -31
  22. package/esm2022/lib/controls/item-picker/item-picker.component.mjs +329 -0
  23. package/{esm2020 → esm2022}/lib/controls/link-button/link-button.component.mjs +11 -11
  24. package/esm2022/lib/controls/menu/menu.component.mjs +485 -0
  25. package/{esm2020 → esm2022}/lib/controls/navigation/link-item.mjs +1 -1
  26. package/esm2022/lib/controls/navigation/nav-group.mjs +39 -0
  27. package/esm2022/lib/controls/navigation/nav-item-active.directive.mjs +92 -0
  28. package/{esm2020 → esm2022}/lib/controls/navigation/nav-item.mjs +1 -1
  29. package/esm2022/lib/controls/numericbox/numericbox.component.mjs +372 -0
  30. package/esm2022/lib/controls/popover/popover.component.mjs +117 -0
  31. package/{esm2020 → esm2022}/lib/controls/radio-button/radio-button-option.mjs +2 -2
  32. package/esm2022/lib/controls/radio-button/radio-button.component.mjs +82 -0
  33. package/esm2022/lib/controls/select/select.component.mjs +88 -0
  34. package/esm2022/lib/controls/tabs/tabs.component.mjs +47 -0
  35. package/esm2022/lib/controls/textbox/textbox.component.mjs +155 -0
  36. package/esm2022/lib/core/cache.service.mjs +105 -0
  37. package/esm2022/lib/core/custom-validators.mjs +29 -0
  38. package/esm2022/lib/core/date-time-helper.mjs +220 -0
  39. package/esm2022/lib/core/error.service.mjs +61 -0
  40. package/esm2022/lib/core/router-helper.service.mjs +111 -0
  41. package/esm2022/lib/core/scroll.service.mjs +89 -0
  42. package/{esm2020 → esm2022}/lib/core/telemetry-tracker.service.mjs +16 -16
  43. package/{esm2020 → esm2022}/lib/core/telemetry.service.mjs +38 -38
  44. package/esm2022/lib/core/validation-message.service.mjs +185 -0
  45. package/{esm2020 → esm2022}/lib/core/validation-patterns.mjs +30 -30
  46. package/esm2022/lib/core/window.service.mjs +186 -0
  47. package/esm2022/lib/display/app-bar/app-bar.component.mjs +46 -0
  48. package/esm2022/lib/display/avatar/avatar.component.mjs +67 -0
  49. package/esm2022/lib/display/avatar/avatar.service.mjs +64 -0
  50. package/esm2022/lib/display/confirm/confirm.component.mjs +168 -0
  51. package/{esm2020 → esm2022}/lib/display/dialog/dialog-content.mjs +1 -1
  52. package/esm2022/lib/display/dialog/dialog-group/dialog-group.component.mjs +63 -0
  53. package/{esm2020 → esm2022}/lib/display/dialog/dialog-types.mjs +76 -76
  54. package/esm2022/lib/display/dialog/dialog.component.mjs +281 -0
  55. package/{esm2020 → esm2022}/lib/display/dialog/dialog.service.mjs +71 -71
  56. package/{esm2020 → esm2022}/lib/display/help/help-types.mjs +1 -1
  57. package/esm2022/lib/display/hierarchy/hierarchy-base.mjs +111 -0
  58. package/{esm2020 → esm2022}/lib/display/hierarchy/hierarchy-mocks.spec.mjs +53 -53
  59. package/esm2022/lib/display/hierarchy/hierarchy-tree/hierarchy-tree.component.mjs +61 -0
  60. package/esm2022/lib/display/item-display/item-display.component.mjs +81 -0
  61. package/esm2022/lib/display/json-display/json-display.component.mjs +47 -0
  62. package/esm2022/lib/display/resizable/resizable-base.mjs +120 -0
  63. package/{esm2020 → esm2022}/lib/display/resizable/resizable.component.mjs +52 -52
  64. package/{esm2020 → esm2022}/lib/display/spinner/spinner.component.mjs +12 -12
  65. package/esm2022/lib/display/splash/splash.component.mjs +42 -0
  66. package/{esm2020 → esm2022}/lib/display/splash/splash.service.mjs +35 -35
  67. package/{esm2020 → esm2022}/lib/display/table/resizable-column.component.mjs +20 -20
  68. package/esm2022/lib/display/table/resizable-table.directive.mjs +227 -0
  69. package/esm2022/lib/display/table/searchable-table.component.mjs +342 -0
  70. package/{esm2020 → esm2022}/lib/display/table/table-detail-row.component.mjs +19 -19
  71. package/esm2022/lib/display/table/table-locked-column.component.mjs +58 -0
  72. package/{esm2020 → esm2022}/lib/display/table/table-master-header-row.component.mjs +14 -14
  73. package/esm2022/lib/display/table/table-master-row.component.mjs +163 -0
  74. package/esm2022/lib/display/table/table-pagination.component.mjs +155 -0
  75. package/esm2022/lib/display/table/table-selectable-row.component.mjs +235 -0
  76. package/esm2022/lib/display/table/table.component.mjs +249 -0
  77. package/esm2022/lib/display/tags/tag.mjs +18 -0
  78. package/esm2022/lib/display/tags/tags.component.mjs +77 -0
  79. package/esm2022/lib/display/toast/toast/toast.component.mjs +77 -0
  80. package/{esm2020 → esm2022}/lib/display/toast/toast-types.mjs +7 -7
  81. package/{esm2020 → esm2022}/lib/display/toast/toast.service.mjs +35 -35
  82. package/esm2022/lib/display/toast/toaster/toaster.component.mjs +114 -0
  83. package/{esm2020 → esm2022}/lib/display/tooltip/tooltip.component.mjs +28 -28
  84. package/{esm2020 → esm2022}/lib/display/tooltip/tooltip.service.mjs +78 -78
  85. package/esm2022/lib/display/tooltip-directive/tooltip.directive.mjs +173 -0
  86. package/{esm2020 → esm2022}/lib/display/tour/tour-types.mjs +33 -33
  87. package/esm2022/lib/display/tour/tour.component.mjs +398 -0
  88. package/esm2022/lib/display/tour/tour.service.mjs +75 -0
  89. package/esm2022/lib/display/tree/tree.component.mjs +135 -0
  90. package/esm2022/lib/display/view-overlay/view-overlay.component.mjs +58 -0
  91. package/esm2022/lib/shared/directives/click-area-for/click-area-for.directive.mjs +32 -0
  92. package/esm2022/lib/shared/directives/if-viewport-width/if-viewport-width.directive.mjs +111 -0
  93. package/esm2022/lib/shared/directives/popup/popup-container.directive.mjs +166 -0
  94. package/esm2022/lib/shared/display/pipes/date-display.pipe.mjs +50 -0
  95. package/esm2022/lib/shared/display/pipes/highlight-text.pipe.mjs +30 -0
  96. package/esm2022/lib/shared/display/pipes/relative-date.pipe.mjs +62 -0
  97. package/esm2022/lib/shared/display/pipes/row-count.pipe.mjs +48 -0
  98. package/esm2022/lib/shared/display/pipes/time-display.pipe.mjs +41 -0
  99. package/esm2022/lib/shared/display.mjs +6 -0
  100. package/esm2022/lib/shared/form-group.helper.mjs +67 -0
  101. package/esm2022/lib/shared/json-helper.mjs +19 -0
  102. package/esm2022/lib/shared/lodash-helper.mjs +52 -0
  103. package/esm2022/lib/shared/page/page-base/page-base.component.mjs +387 -0
  104. package/{esm2020 → esm2022}/lib/shared/page/page-statuses.mjs +22 -22
  105. package/{esm2020 → esm2022}/lib/shared/page/page-title/page-title.component.mjs +23 -23
  106. package/esm2022/lib/shared/page/page-view/page-view.component.mjs +147 -0
  107. package/{esm2020 → esm2022}/lib/shared/testing/copy-button-base-test-injector-factory.spec.mjs +16 -16
  108. package/{esm2020 → esm2022}/lib/shared/testing/hierarchy-base-test-injector-factory.spec.mjs +16 -16
  109. package/{esm2020 → esm2022}/lib/shared/testing/page-base-component-test-helper.spec.mjs +37 -37
  110. package/esm2022/lib/shared/testing/page-base-component-test-injector-factory.spec.mjs +98 -0
  111. package/{esm2020 → esm2022}/lib/shared/testing/public-mocks.spec.mjs +148 -148
  112. package/{esm2020 → esm2022}/lib/shared/testing/spy-factory.spec.mjs +39 -39
  113. package/{esm2020 → esm2022}/lib/shared/testing/translation-mocks.spec.mjs +56 -56
  114. package/{esm2020 → esm2022}/lib/shared/user-preference.service.mjs +17 -17
  115. package/esm2022/lib/shared/wizard/wizard-base/wizard-base.component.mjs +246 -0
  116. package/{esm2020 → esm2022}/lib/shared/wizard/wizard-buttons/wizard-buttons.component.mjs +68 -68
  117. package/{esm2020 → esm2022}/lib/shared/wizard/wizard-progress/wizard-progress.component.mjs +18 -18
  118. package/esm2022/public-api.mjs +115 -0
  119. package/{fesm2020 → fesm2022}/energycap-components.mjs +11819 -12972
  120. package/fesm2022/energycap-components.mjs.map +1 -0
  121. package/index.d.ts +5 -5
  122. package/lib/components.module.d.ts +91 -92
  123. package/lib/controls/banner/banner.component.d.ts +50 -50
  124. package/lib/controls/button/button.component.d.ts +78 -78
  125. package/lib/controls/button/copy-button-base.directive.d.ts +20 -20
  126. package/lib/controls/button/copy-button.directive.d.ts +14 -14
  127. package/lib/controls/button/copy-table-button.directive.d.ts +19 -19
  128. package/lib/controls/calendar/calendar-item.component.d.ts +17 -22
  129. package/lib/controls/calendar/calendar.component.d.ts +54 -52
  130. package/lib/controls/calendar/calendar.types.d.ts +7 -11
  131. package/lib/controls/checkbox/checkbox.component.d.ts +65 -65
  132. package/lib/controls/collapsible-toggle/collapsible-toggle.component.d.ts +25 -25
  133. package/lib/controls/combobox/combobox.component.d.ts +418 -418
  134. package/lib/controls/date-input/date-input.component.d.ts +80 -115
  135. package/lib/controls/dropdown/dropdown.component.d.ts +161 -161
  136. package/lib/controls/file-upload/file-upload.component.d.ts +124 -124
  137. package/lib/controls/form-control/form-control.component.d.ts +30 -28
  138. package/lib/controls/form-control-base.d.ts +110 -110
  139. package/lib/controls/form-control-label/form-control-label.component.d.ts +73 -73
  140. package/lib/controls/form-group/form-group.component.d.ts +105 -105
  141. package/lib/controls/help-popover/help-popover.component.d.ts +11 -11
  142. package/lib/controls/item-picker/item-picker.component.d.ts +164 -164
  143. package/lib/controls/link-button/link-button.component.d.ts +5 -5
  144. package/lib/controls/menu/menu.component.d.ts +255 -255
  145. package/lib/controls/navigation/link-item.d.ts +32 -32
  146. package/lib/controls/navigation/nav-group.d.ts +18 -18
  147. package/lib/controls/navigation/nav-item-active.directive.d.ts +42 -42
  148. package/lib/controls/navigation/nav-item.d.ts +31 -31
  149. package/lib/controls/numericbox/numericbox.component.d.ts +148 -148
  150. package/lib/controls/popover/popover.component.d.ts +51 -51
  151. package/lib/controls/radio-button/radio-button-option.d.ts +19 -19
  152. package/lib/controls/radio-button/radio-button.component.d.ts +53 -53
  153. package/lib/controls/select/select.component.d.ts +44 -44
  154. package/lib/controls/tabs/tabs.component.d.ts +30 -30
  155. package/lib/controls/textbox/textbox.component.d.ts +107 -107
  156. package/lib/core/cache.service.d.ts +33 -33
  157. package/lib/core/custom-validators.d.ts +20 -20
  158. package/lib/core/date-time-helper.d.ts +101 -101
  159. package/lib/core/error.service.d.ts +20 -20
  160. package/lib/core/router-helper.service.d.ts +48 -48
  161. package/lib/core/scroll.service.d.ts +36 -36
  162. package/lib/core/telemetry-tracker.service.d.ts +13 -13
  163. package/lib/core/telemetry.service.d.ts +31 -31
  164. package/lib/core/validation-message.service.d.ts +26 -26
  165. package/lib/core/validation-patterns.d.ts +22 -22
  166. package/lib/core/window.service.d.ts +116 -116
  167. package/lib/display/app-bar/app-bar.component.d.ts +20 -20
  168. package/lib/display/avatar/avatar.component.d.ts +35 -35
  169. package/lib/display/avatar/avatar.service.d.ts +24 -24
  170. package/lib/display/confirm/confirm.component.d.ts +123 -123
  171. package/lib/display/dialog/dialog-content.d.ts +19 -19
  172. package/lib/display/dialog/dialog-group/dialog-group.component.d.ts +32 -32
  173. package/lib/display/dialog/dialog-types.d.ts +130 -130
  174. package/lib/display/dialog/dialog.component.d.ts +120 -120
  175. package/lib/display/dialog/dialog.service.d.ts +48 -48
  176. package/lib/display/help/help-types.d.ts +33 -33
  177. package/lib/display/hierarchy/hierarchy-base.d.ts +97 -97
  178. package/lib/display/hierarchy/hierarchy-mocks.spec.d.ts +53 -53
  179. package/lib/display/hierarchy/hierarchy-tree/hierarchy-tree.component.d.ts +34 -34
  180. package/lib/display/item-display/item-display.component.d.ts +43 -43
  181. package/lib/display/json-display/json-display.component.d.ts +16 -16
  182. package/lib/display/resizable/resizable-base.d.ts +67 -67
  183. package/lib/display/resizable/resizable.component.d.ts +31 -31
  184. package/lib/display/spinner/spinner.component.d.ts +5 -5
  185. package/lib/display/splash/splash.component.d.ts +16 -16
  186. package/lib/display/splash/splash.service.d.ts +22 -22
  187. package/lib/display/table/resizable-column.component.d.ts +10 -10
  188. package/lib/display/table/resizable-table.directive.d.ts +93 -93
  189. package/lib/display/table/searchable-table.component.d.ts +206 -206
  190. package/lib/display/table/table-detail-row.component.d.ts +8 -8
  191. package/lib/display/table/table-locked-column.component.d.ts +20 -20
  192. package/lib/display/table/table-master-header-row.component.d.ts +9 -9
  193. package/lib/display/table/table-master-row.component.d.ts +113 -113
  194. package/lib/display/table/table-pagination.component.d.ts +91 -91
  195. package/lib/display/table/table-selectable-row.component.d.ts +102 -102
  196. package/lib/display/table/table.component.d.ts +121 -121
  197. package/lib/display/tags/tag.d.ts +18 -18
  198. package/lib/display/tags/tags.component.d.ts +48 -48
  199. package/lib/display/toast/toast/toast.component.d.ts +23 -23
  200. package/lib/display/toast/toast-types.d.ts +24 -24
  201. package/lib/display/toast/toast.service.d.ts +20 -20
  202. package/lib/display/toast/toaster/toaster.component.d.ts +35 -35
  203. package/lib/display/tooltip/tooltip.component.d.ts +70 -70
  204. package/lib/display/tooltip/tooltip.service.d.ts +16 -16
  205. package/lib/display/tooltip-directive/tooltip.directive.d.ts +44 -44
  206. package/lib/display/tour/tour-types.d.ts +70 -70
  207. package/lib/display/tour/tour.component.d.ts +147 -147
  208. package/lib/display/tour/tour.service.d.ts +38 -38
  209. package/lib/display/tree/tree.component.d.ts +75 -75
  210. package/lib/display/view-overlay/view-overlay.component.d.ts +38 -38
  211. package/lib/shared/directives/click-area-for/click-area-for.directive.d.ts +14 -14
  212. package/lib/shared/directives/if-viewport-width/if-viewport-width.directive.d.ts +60 -60
  213. package/lib/shared/directives/popup/popup-container.directive.d.ts +101 -101
  214. package/lib/shared/display/pipes/date-display.pipe.d.ts +21 -21
  215. package/lib/shared/display/pipes/highlight-text.pipe.d.ts +9 -9
  216. package/lib/shared/display/pipes/relative-date.pipe.d.ts +36 -36
  217. package/lib/shared/display/pipes/row-count.pipe.d.ts +23 -23
  218. package/lib/shared/display/pipes/time-display.pipe.d.ts +18 -18
  219. package/lib/shared/display.d.ts +42 -42
  220. package/lib/shared/form-group.helper.d.ts +31 -31
  221. package/lib/shared/json-helper.d.ts +7 -7
  222. package/lib/shared/lodash-helper.d.ts +18 -18
  223. package/lib/shared/page/page-base/page-base.component.d.ts +259 -259
  224. package/lib/shared/page/page-statuses.d.ts +13 -13
  225. package/lib/shared/page/page-title/page-title.component.d.ts +9 -9
  226. package/lib/shared/page/page-view/page-view.component.d.ts +102 -102
  227. package/lib/shared/testing/copy-button-base-test-injector-factory.spec.d.ts +4 -4
  228. package/lib/shared/testing/hierarchy-base-test-injector-factory.spec.d.ts +4 -4
  229. package/lib/shared/testing/page-base-component-test-helper.spec.d.ts +30 -30
  230. package/lib/shared/testing/page-base-component-test-injector-factory.spec.d.ts +28 -28
  231. package/lib/shared/testing/public-mocks.spec.d.ts +90 -90
  232. package/lib/shared/testing/spy-factory.spec.d.ts +27 -27
  233. package/lib/shared/testing/translation-mocks.spec.d.ts +30 -30
  234. package/lib/shared/user-preference.service.d.ts +13 -13
  235. package/lib/shared/wizard/wizard-base/wizard-base.component.d.ts +134 -134
  236. package/lib/shared/wizard/wizard-buttons/wizard-buttons.component.d.ts +27 -27
  237. package/lib/shared/wizard/wizard-progress/wizard-progress.component.d.ts +10 -10
  238. package/package.json +12 -18
  239. package/public-api.d.ts +111 -113
  240. package/schematics/rxjs-7-upgrade/index.d.ts +3 -3
  241. package/schematics/rxjs-7-upgrade/index.js +67 -67
  242. package/schematics/rxjs-7-upgrade/index.js.map +1 -1
  243. package/schematics/rxjs-7-upgrade/schema.d.ts +4 -4
  244. package/schematics/rxjs-7-upgrade/schema.js +2 -2
  245. package/schematics/utilities/typescript.d.ts +7 -7
  246. package/schematics/utilities/typescript.js +41 -41
  247. package/schematics/utilities/workspace.d.ts +8 -8
  248. package/schematics/utilities/workspace.js +71 -71
  249. package/schematics/utilities/workspace.js.map +1 -1
  250. package/src/assets/locales/en_US.json +1 -9
  251. package/esm2020/lib/components.module.mjs +0 -423
  252. package/esm2020/lib/controls/banner/banner.component.mjs +0 -109
  253. package/esm2020/lib/controls/button/button.component.mjs +0 -106
  254. package/esm2020/lib/controls/button/copy-button-base.directive.mjs +0 -67
  255. package/esm2020/lib/controls/button/copy-table-button.directive.mjs +0 -43
  256. package/esm2020/lib/controls/calendar/calendar-item.component.mjs +0 -91
  257. package/esm2020/lib/controls/calendar/calendar.component.mjs +0 -248
  258. package/esm2020/lib/controls/calendar/calendar.types.mjs +0 -2
  259. package/esm2020/lib/controls/checkbox/checkbox.component.mjs +0 -140
  260. package/esm2020/lib/controls/combobox/combobox.component.mjs +0 -879
  261. package/esm2020/lib/controls/date-input/date-input-selection-strategies/date-input-selection-strategy-base.mjs +0 -57
  262. package/esm2020/lib/controls/date-input/date-input-selection-strategies/day-selection-strategy.mjs +0 -62
  263. package/esm2020/lib/controls/date-input/date-input-selection-strategies/last-28-days-selection-strategy.mjs +0 -100
  264. package/esm2020/lib/controls/date-input/date-input-selection-strategies/last-7-days-selection-strategy.mjs +0 -101
  265. package/esm2020/lib/controls/date-input/date-input-selection-strategies/month-selection-strategy.mjs +0 -76
  266. package/esm2020/lib/controls/date-input/date-input-selection-strategies/quarter-selection-strategy.mjs +0 -79
  267. package/esm2020/lib/controls/date-input/date-input-selection-strategies/range-selection-strategy.mjs +0 -210
  268. package/esm2020/lib/controls/date-input/date-input-selection-strategies/year-selection-strategy.mjs +0 -81
  269. package/esm2020/lib/controls/date-input/date-input.component.mjs +0 -463
  270. package/esm2020/lib/controls/date-input/date-input.types.mjs +0 -44
  271. package/esm2020/lib/controls/dropdown/dropdown.component.mjs +0 -243
  272. package/esm2020/lib/controls/file-upload/file-upload.component.mjs +0 -261
  273. package/esm2020/lib/controls/form-control/form-control.component.mjs +0 -98
  274. package/esm2020/lib/controls/form-control-base.mjs +0 -151
  275. package/esm2020/lib/controls/form-control-label/form-control-label.component.mjs +0 -136
  276. package/esm2020/lib/controls/form-group/form-group.component.mjs +0 -261
  277. package/esm2020/lib/controls/item-picker/item-picker.component.mjs +0 -329
  278. package/esm2020/lib/controls/menu/menu.component.mjs +0 -485
  279. package/esm2020/lib/controls/navigation/nav-group.mjs +0 -39
  280. package/esm2020/lib/controls/navigation/nav-item-active.directive.mjs +0 -92
  281. package/esm2020/lib/controls/numericbox/numericbox.component.mjs +0 -372
  282. package/esm2020/lib/controls/popover/popover.component.mjs +0 -117
  283. package/esm2020/lib/controls/radio-button/radio-button.component.mjs +0 -82
  284. package/esm2020/lib/controls/select/select.component.mjs +0 -88
  285. package/esm2020/lib/controls/tabs/tabs.component.mjs +0 -47
  286. package/esm2020/lib/controls/textbox/textbox.component.mjs +0 -155
  287. package/esm2020/lib/core/cache.service.mjs +0 -105
  288. package/esm2020/lib/core/custom-validators.mjs +0 -29
  289. package/esm2020/lib/core/date-time-helper.mjs +0 -228
  290. package/esm2020/lib/core/error.service.mjs +0 -61
  291. package/esm2020/lib/core/router-helper.service.mjs +0 -111
  292. package/esm2020/lib/core/scroll.service.mjs +0 -89
  293. package/esm2020/lib/core/validation-message.service.mjs +0 -185
  294. package/esm2020/lib/core/window.service.mjs +0 -186
  295. package/esm2020/lib/display/app-bar/app-bar.component.mjs +0 -46
  296. package/esm2020/lib/display/avatar/avatar.component.mjs +0 -67
  297. package/esm2020/lib/display/avatar/avatar.service.mjs +0 -64
  298. package/esm2020/lib/display/confirm/confirm.component.mjs +0 -168
  299. package/esm2020/lib/display/dialog/dialog-group/dialog-group.component.mjs +0 -63
  300. package/esm2020/lib/display/dialog/dialog.component.mjs +0 -281
  301. package/esm2020/lib/display/hierarchy/hierarchy-base.mjs +0 -111
  302. package/esm2020/lib/display/hierarchy/hierarchy-tree/hierarchy-tree.component.mjs +0 -61
  303. package/esm2020/lib/display/item-display/item-display.component.mjs +0 -81
  304. package/esm2020/lib/display/json-display/json-display.component.mjs +0 -47
  305. package/esm2020/lib/display/resizable/resizable-base.mjs +0 -120
  306. package/esm2020/lib/display/splash/splash.component.mjs +0 -42
  307. package/esm2020/lib/display/table/resizable-table.directive.mjs +0 -227
  308. package/esm2020/lib/display/table/searchable-table.component.mjs +0 -342
  309. package/esm2020/lib/display/table/table-locked-column.component.mjs +0 -58
  310. package/esm2020/lib/display/table/table-master-row.component.mjs +0 -163
  311. package/esm2020/lib/display/table/table-pagination.component.mjs +0 -155
  312. package/esm2020/lib/display/table/table-selectable-row.component.mjs +0 -235
  313. package/esm2020/lib/display/table/table.component.mjs +0 -249
  314. package/esm2020/lib/display/tags/tag.mjs +0 -18
  315. package/esm2020/lib/display/tags/tags.component.mjs +0 -77
  316. package/esm2020/lib/display/toast/toast/toast.component.mjs +0 -77
  317. package/esm2020/lib/display/toast/toaster/toaster.component.mjs +0 -114
  318. package/esm2020/lib/display/tooltip-directive/tooltip.directive.mjs +0 -173
  319. package/esm2020/lib/display/tour/tour.component.mjs +0 -398
  320. package/esm2020/lib/display/tour/tour.service.mjs +0 -75
  321. package/esm2020/lib/display/tree/tree.component.mjs +0 -135
  322. package/esm2020/lib/display/view-overlay/view-overlay.component.mjs +0 -58
  323. package/esm2020/lib/shared/directives/click-area-for/click-area-for.directive.mjs +0 -32
  324. package/esm2020/lib/shared/directives/if-viewport-width/if-viewport-width.directive.mjs +0 -111
  325. package/esm2020/lib/shared/directives/keyboard-nav-container/keyboard-nav-container.directive.mjs +0 -100
  326. package/esm2020/lib/shared/directives/popup/popup-container.directive.mjs +0 -163
  327. package/esm2020/lib/shared/display/pipes/date-display.pipe.mjs +0 -50
  328. package/esm2020/lib/shared/display/pipes/highlight-text.pipe.mjs +0 -30
  329. package/esm2020/lib/shared/display/pipes/relative-date.pipe.mjs +0 -62
  330. package/esm2020/lib/shared/display/pipes/row-count.pipe.mjs +0 -48
  331. package/esm2020/lib/shared/display/pipes/time-display.pipe.mjs +0 -41
  332. package/esm2020/lib/shared/display.mjs +0 -6
  333. package/esm2020/lib/shared/form-group.helper.mjs +0 -67
  334. package/esm2020/lib/shared/json-helper.mjs +0 -19
  335. package/esm2020/lib/shared/lodash-helper.mjs +0 -51
  336. package/esm2020/lib/shared/page/page-base/page-base.component.mjs +0 -387
  337. package/esm2020/lib/shared/page/page-view/page-view.component.mjs +0 -147
  338. package/esm2020/lib/shared/testing/page-base-component-test-injector-factory.spec.mjs +0 -98
  339. package/esm2020/lib/shared/wizard/wizard-base/wizard-base.component.mjs +0 -246
  340. package/esm2020/public-api.mjs +0 -117
  341. package/fesm2015/energycap-components.mjs +0 -13371
  342. package/fesm2015/energycap-components.mjs.map +0 -1
  343. package/fesm2020/energycap-components.mjs.map +0 -1
  344. package/lib/controls/date-input/date-input-selection-strategies/date-input-selection-strategy-base.d.ts +0 -42
  345. package/lib/controls/date-input/date-input-selection-strategies/day-selection-strategy.d.ts +0 -21
  346. package/lib/controls/date-input/date-input-selection-strategies/last-28-days-selection-strategy.d.ts +0 -21
  347. package/lib/controls/date-input/date-input-selection-strategies/last-7-days-selection-strategy.d.ts +0 -21
  348. package/lib/controls/date-input/date-input-selection-strategies/month-selection-strategy.d.ts +0 -18
  349. package/lib/controls/date-input/date-input-selection-strategies/quarter-selection-strategy.d.ts +0 -18
  350. package/lib/controls/date-input/date-input-selection-strategies/range-selection-strategy.d.ts +0 -21
  351. package/lib/controls/date-input/date-input-selection-strategies/year-selection-strategy.d.ts +0 -20
  352. package/lib/controls/date-input/date-input.types.d.ts +0 -62
  353. package/lib/shared/directives/keyboard-nav-container/keyboard-nav-container.directive.d.ts +0 -23
@@ -1,463 +0,0 @@
1
- import { Component, HostBinding, Input, ViewChild } from '@angular/core';
2
- import { FormControl, FormGroup } from '@angular/forms';
3
- import moment from 'moment';
4
- import { lastValueFrom } from 'rxjs';
5
- import { debounceTime, distinctUntilChanged, takeUntil } from 'rxjs/operators';
6
- import { DateTimeHelper } from '../../core/date-time-helper';
7
- import { FormControlBase } from '../form-control-base';
8
- import { DateInput } from './date-input.types';
9
- import * as i0 from "@angular/core";
10
- import * as i1 from "../../core/validation-message.service";
11
- import * as i2 from "../../shared/form-group.helper";
12
- import * as i3 from "../../shared/user-preference.service";
13
- import * as i4 from "@angular/cdk/overlay";
14
- import * as i5 from "./date-input.types";
15
- import * as i6 from "@angular/common";
16
- import * as i7 from "@angular/forms";
17
- import * as i8 from "../button/button.component";
18
- import * as i9 from "../form-control/form-control.component";
19
- import * as i10 from "../help-popover/help-popover.component";
20
- import * as i11 from "../link-button/link-button.component";
21
- import * as i12 from "../calendar/calendar.component";
22
- import * as i13 from "../../shared/directives/keyboard-nav-container/keyboard-nav-container.directive";
23
- import * as i14 from "@ngx-translate/core";
24
- export class DateInputComponent extends FormControlBase {
25
- constructor(validationMessageService, formGroupHelper, userPreferenceService, el, overlayService, selectionStrategies) {
26
- super(validationMessageService, formGroupHelper);
27
- this.validationMessageService = validationMessageService;
28
- this.formGroupHelper = formGroupHelper;
29
- this.userPreferenceService = userPreferenceService;
30
- this.el = el;
31
- this.overlayService = overlayService;
32
- this.selectionStrategies = selectionStrategies;
33
- this.id = '';
34
- /** The form control provided by the hosting form. */
35
- this.formModel = new FormControl(null);
36
- this.minDate = DateTimeHelper.minDatePickerDate;
37
- this.maxDate = DateTimeHelper.maxDatePickerDate;
38
- /** The initial selection mode for the calendar. Defaults to day if not provided */
39
- this.selectionMode = 'day';
40
- /** The available selection modes for the calendar. Defaults to only the initial selection mode if not provided. */
41
- this.selectionModeOptions = ['day'];
42
- /** Enables the next/previous selection buttons. */
43
- this.enableSteppers = false;
44
- /** The form group for the internal textboxes. Textbox2 is only used for ranges. */
45
- this.textboxGroup = new FormGroup({
46
- textbox: new FormControl(null),
47
- textbox2: new FormControl(null)
48
- });
49
- /**
50
- * The current calendar selection.
51
- * Updated when the user clicks on a calendar item or when the date entered into the textbox is parsed.
52
- */
53
- this.calendarSelection = null;
54
- /** Controls whether the calendar overlay is open or not. */
55
- this.isCalendarOpen = false;
56
- /** Placeholder for the textbox. Updated to reflect the user's date display preference. */
57
- this.placeholder = 'MM/DD/YYYY';
58
- /** Overlay scroll strategy for the calendar overlay. Closes the calendar on scroll. */
59
- this.overlayScrollStrategy = this.overlayService.scrollStrategies.close();
60
- this.primaryCalendarView = { mode: 'day', date: new Date() };
61
- this.secondaryCalendarView = { mode: 'day', date: new Date() };
62
- this.primaryCalendarMaxDate = DateTimeHelper.maxDatePickerDate;
63
- this.secondaryCalendarMinDate = DateTimeHelper.minDatePickerDate;
64
- this.disableSteppers = false;
65
- /**
66
- * Date parsing formats for user-entered dates. Defaults to month-first formats, but is updated in onInit
67
- * to use the user's preferred date format.
68
- */
69
- this.parseFormats = DateTimeHelper.getMomentParseFormats();
70
- }
71
- ngOnChanges(changes) {
72
- if (changes.selectionMode && !changes.selectionMode.isFirstChange()) {
73
- this.onSelectionModeChange(this.selectionMode);
74
- }
75
- }
76
- ngOnInit() {
77
- // Setup
78
- super.ngOnInit();
79
- this.setDateFormats();
80
- this.setSelectionMode(this.selectionMode);
81
- // Subscriptions
82
- this.onFormModelStatusChanges();
83
- this.onFormModelValueChanges();
84
- this.onTextboxValueChanges();
85
- // Sync the initial disabled status and value of the textbox
86
- this.syncTextboxControlDisabledStatus(this.formModel.status);
87
- const initialDisplayValue = this.selectionStrategy.formatSelection(this.formModel.value);
88
- this.textboxGroup.patchValue(initialDisplayValue, { emitEvent: false });
89
- // Update the calendar selection and view based on the initial form model value
90
- this.calendarSelection = this.formModel.value;
91
- this.updateCalendars(this.calendarSelection);
92
- this.updateSteppers(this.calendarSelection);
93
- }
94
- /** Focuses the input whenever the calendar is shift-tabbed out of. */
95
- onCalendarFocusOutStart() {
96
- this.focusInput();
97
- }
98
- /** Closes the calendar and focuses the input whenever the calendar is tabbed out of. */
99
- onCalendarFocusOutEnd() {
100
- this.isCalendarOpen = false;
101
- this.focusInput();
102
- }
103
- /** Closes the calendar if the user clicks outside of the calendar and date input. */
104
- onOverlayOutsideClick(event) {
105
- // Do not close the calendar if the click was within the date input or action button
106
- const rect = this.el.nativeElement.getBoundingClientRect();
107
- const clickedOutsideControl = event.clientY < rect.top ||
108
- event.clientY > rect.bottom ||
109
- event.clientX < rect.left ||
110
- event.clientX > rect.right;
111
- // It's possible that the user hit enter on the action button instead of clicking with the mouse.
112
- // In this case the "click" event will be outside of the component because the clientx and y are 0,
113
- // but we don't want to close in this case because button clicks trigger calendar open/close separately.
114
- const targetId = event.target.id;
115
- const isActionClick = targetId === `${this.id}_action` || targetId === `${this.id}_control2_action`;
116
- if (!isActionClick && clickedOutsideControl) {
117
- this.isCalendarOpen = false;
118
- }
119
- }
120
- /** If the user tabs out of the form control's action button and the calendar is open, focus the first item in the calendar overlay */
121
- onControlsFocusOutEnd() {
122
- if (this.isCalendarOpen) {
123
- this.calendar?.focus();
124
- }
125
- }
126
- onTextboxBlur() {
127
- // We want to prevent the fixed date range modes from re-autocompleting the first textbox when it is explicitly cleared.
128
- const previousValue = DateInput.isSelectionRange(this.formModel.value) ? this.formModel.value.start : this.formModel.value;
129
- const currentValue = this.textboxGroup.value.textbox;
130
- const cleared = !!previousValue && !currentValue;
131
- const options = { preventAutoComplete: cleared };
132
- // Parse the textbox values into a selection and update the form model
133
- const parsedSelection = this.selectionStrategy.parseTextboxValues(this.textboxGroup.value, this.parseFormats, options);
134
- this.updateFormModel(parsedSelection);
135
- }
136
- onTextbox2Blur() {
137
- // We want to prevent the fixed date range modes from re-autocompleting the second textbox when it is explicitly cleared.
138
- const previousValue = DateInput.isSelectionRange(this.formModel.value) ? this.formModel.value.end : null;
139
- const currentValue = this.textboxGroup.value.textbox2;
140
- const cleared = !!previousValue && !currentValue;
141
- const options = { parseFromEnd: true, preventAutoComplete: cleared };
142
- // Parse the textbox values into a selection and update the form model,
143
- // For the second box we're keying the parse from the end date in the selection.
144
- const parsedSelection = this.selectionStrategy.parseTextboxValues(this.textboxGroup.value, this.parseFormats, options);
145
- this.updateFormModel(parsedSelection);
146
- }
147
- onSelectionModeChange(mode) {
148
- this.setSelectionMode(mode);
149
- const newSelection = this.selectionStrategy.getNewSelectionFromExisting(this.calendarSelection);
150
- this.updateFormModel(newSelection);
151
- // On selection mode change, we want to force the calendars to show the right view mode for the new selection.
152
- // This prevents the user from seeing a view mode that doesn't make sense for the new selection,
153
- // Like when swiching from year mode to last 7 days mode.
154
- this.primaryCalendarView = { mode: this.selectionStrategy.selectionViewMode, date: this.primaryCalendarView.date };
155
- this.secondaryCalendarView = { mode: this.selectionStrategy.selectionViewMode, date: this.secondaryCalendarView.date };
156
- this.updateCalendarMinMaxDates();
157
- }
158
- onCalendarDateSelected(date) {
159
- const newSelection = this.selectionStrategy.getSelectionFromDate(date, this.calendarSelection);
160
- const displayValue = this.selectionStrategy.formatSelection(newSelection);
161
- // Don't emit events when patching values here. We don't want to trigger the calendar updates since the calendar is already
162
- // showing the selected date. We also don't want to trigger the textbox parsing logic since the date was selected from the calendar.
163
- this.textboxGroup.patchValue(displayValue, { emitEvent: false });
164
- this.formModel.patchValue(newSelection, { emitEvent: false });
165
- this.calendarSelection = newSelection;
166
- this.updateSteppers(newSelection);
167
- // Close the calendar if the selection mode is not a range mode where either the start or the end date can be changed.
168
- if (!this.selectionStrategy.showSecondaryTextbox) {
169
- this.isCalendarOpen = false;
170
- this.focusInput();
171
- }
172
- }
173
- onPrimaryCalendarViewChange(view) {
174
- this.primaryCalendarView = view;
175
- this.updateCalendarMinMaxDates();
176
- }
177
- onSecondaryCalendarViewChange(view) {
178
- this.secondaryCalendarView = view;
179
- this.updateCalendarMinMaxDates();
180
- }
181
- /** Shifts the calendar views to display today. Does not update the calendar selection. */
182
- goToToday() {
183
- // If both calendars are visible, show today in the secondary calendar and the month before in the primary calendar.
184
- if (this.selectionStrategy.showSecondaryCalendar) {
185
- this.primaryCalendarView = { mode: 'day', date: moment().subtract(1, 'month').toDate() };
186
- this.secondaryCalendarView = { mode: 'day', date: new Date() };
187
- // If we're in a single date mode, show today in the primary calendar.
188
- }
189
- else {
190
- this.primaryCalendarView = { mode: 'day', date: new Date() };
191
- }
192
- this.updateCalendarMinMaxDates();
193
- }
194
- goToQuickSelectDate() {
195
- if (this.quickSelectDate) {
196
- const newSelection = this.selectionStrategy.getSelectionForQuickSelectDate(this.quickSelectDate, this.calendarSelection);
197
- this.updateFormModel(newSelection);
198
- }
199
- }
200
- nextSelection() {
201
- const newSelection = this.selectionStrategy.getNextSelection(this.calendarSelection);
202
- this.updateFormModel(newSelection);
203
- }
204
- previousSelection() {
205
- const newSelection = this.selectionStrategy.getPreviousSelection(this.calendarSelection);
206
- this.updateFormModel(newSelection);
207
- }
208
- updateFormModel(value) {
209
- this.formModel.patchValue(value);
210
- // Validate the textboxes and sync the form errors
211
- // We do this after patching the form model because the form model patch will trigger
212
- // the date formatting logic and overwrite any errors on the controls from before.
213
- this.validateTextboxes();
214
- this.syncFormErrors();
215
- }
216
- onFormModelStatusChanges() {
217
- // Keep the textboxControl disabled status in sync with the formModel
218
- this.formModel.statusChanges.pipe(distinctUntilChanged(), takeUntil(this.componentDestroyed)).subscribe(status => {
219
- this.syncTextboxControlDisabledStatus(status);
220
- if (this.isCalendarOpen) {
221
- // As validation messages appear/disappear, the date input may have shifted up or down on the page.
222
- // Update the overlay position to ensure it's still aligned with the textbox and not blocking it.
223
- // Settimeout is needed to ensure the overlay is being updated after the message is rendered.
224
- setTimeout(() => {
225
- this.overlay?.overlayRef?.updatePosition();
226
- });
227
- }
228
- });
229
- }
230
- onFormModelValueChanges() {
231
- // Update the calendar selection textbox value with a formatted date when the form model changes.
232
- // This is triggered by the user selecting a date from the calendar or when the textbox is blurred.
233
- this.formModel.valueChanges.pipe(takeUntil(this.componentDestroyed)).subscribe(value => {
234
- const displayValue = this.selectionStrategy.formatSelection(value);
235
- // Don't emit an event when setting the textbox value to avoid circular updates between the textbox and form model.
236
- this.textboxGroup.patchValue(displayValue, { emitEvent: false });
237
- this.updateCalendars(value);
238
- this.updateSteppers(value);
239
- });
240
- }
241
- onTextboxValueChanges() {
242
- // Update the calendar selection when the textbox value changes to update the calendar.
243
- // We don't patch the formModel here because we don't want to trigger the
244
- // date formatting logic and overwrite the user's input.
245
- // We'll do that when the user blurs out of the textbox. See onTextboxBlur()
246
- this.textboxGroup.controls.textbox.valueChanges.pipe(debounceTime(300), distinctUntilChanged(), takeUntil(this.componentDestroyed)).subscribe(() => {
247
- const options = { shiftToCurrentYearIfBelow: this.minDate };
248
- const newSelection = this.selectionStrategy.parseTextboxValues(this.textboxGroup.value, this.parseFormats, options);
249
- // Calendar selection will be null if the dates are invalid. Don't update the calendars in this case.
250
- if (newSelection) {
251
- this.calendarSelection = newSelection;
252
- this.updatePrimaryCalendar(this.calendarSelection, this.selectionStrategy.showSecondaryCalendar);
253
- this.updateCalendarMinMaxDates();
254
- }
255
- });
256
- // The second textbox is only used in last7Days, last28Days, and range modes.
257
- this.textboxGroup.controls.textbox2.valueChanges.pipe(debounceTime(300), distinctUntilChanged(), takeUntil(this.componentDestroyed)).subscribe(() => {
258
- const options = { shiftToCurrentYearIfBelow: this.minDate, parseFromEnd: true };
259
- const newSelection = this.selectionStrategy.parseTextboxValues(this.textboxGroup.value, this.parseFormats, options);
260
- // Calendar selection will be null if the dates are invalid. Don't update the calendars in this case.
261
- if (newSelection) {
262
- this.calendarSelection = newSelection;
263
- // The secondary calendar is only shown in range mode. Update the primary calendar if we're not in range mode.
264
- if (this.selectionStrategy.showSecondaryCalendar) {
265
- this.updateSecondaryCalendar(this.calendarSelection, true);
266
- }
267
- else {
268
- this.updatePrimaryCalendar(this.calendarSelection);
269
- }
270
- this.updateCalendarMinMaxDates();
271
- }
272
- });
273
- }
274
- syncTextboxControlDisabledStatus(status) {
275
- // The textbox should only be disabled if the form model is disabled.
276
- // All other statuses are considered enabled.
277
- if (status === 'DISABLED' && this.textboxGroup.enabled) {
278
- this.textboxGroup.disable();
279
- }
280
- else if (status !== 'DISABLED' && this.textboxGroup.disabled) {
281
- this.textboxGroup.enable();
282
- }
283
- }
284
- ;
285
- syncFormErrors() {
286
- // Start with the existing form model errors
287
- let errors = this.formModel.errors;
288
- // Add the errors from the textboxes if they exist
289
- if (this.textboxGroup.controls.textbox.errors) {
290
- errors = { ...errors, ...this.textboxGroup.controls.textbox.errors };
291
- }
292
- if (this.textboxGroup.controls.textbox2.errors) {
293
- errors = { ...errors, ...this.textboxGroup.controls.textbox2.errors };
294
- }
295
- // Update the form model's errors with the combined errors
296
- this.formModel.setErrors(errors);
297
- // Update the form model's touched and dirty status based on the textbox's status.
298
- // Since the user interacts with a control that is internal to this component, the
299
- // form model's status won't be updated automatically.
300
- if (this.textboxGroup.touched && !this.formModel.touched) {
301
- this.formModel.markAsTouched();
302
- }
303
- if (this.textboxGroup.dirty && !this.formModel.dirty) {
304
- this.formModel.markAsDirty();
305
- }
306
- }
307
- /**
308
- * Updates the date parsing formats and placeholder based on the user's display preference.
309
- * NOTE: This is async because we're retrieving the user's preferences. We're not awaiting the result
310
- * because the only logic that depends on this is the text box date parsing logic and placeholder.
311
- * Our forms should always be behind a pending overlay, so the user won't be able to interact with the
312
- * form until the user is loaded anyway.
313
- */
314
- async setDateFormats() {
315
- const { preference } = await lastValueFrom(this.userPreferenceService.getPreferences());
316
- const dateFormat = preference?.dateFormat;
317
- this.placeholder = dateFormat ?? this.placeholder;
318
- this.parseFormats = DateTimeHelper.getMomentParseFormats(dateFormat);
319
- }
320
- /** Focuses the date input. */
321
- focusInput() {
322
- this.controls?.focus();
323
- }
324
- setSelectionMode(mode) {
325
- this.selectionMode = mode;
326
- this.selectionStrategy = this.selectionStrategies[mode];
327
- }
328
- /**
329
- * Sets the max date for the primary calendar and the min date for the secondary calendar based
330
- * on the current views in each. This prevents the user from moving the calendars out of order.
331
- */
332
- updateCalendarMinMaxDates() {
333
- // Only update the min/max dates when the view mode is 'day'.
334
- // When a calendar is in a month or year view mode, the view dates at the beginning of the year.
335
- // This would cause the dates in the other calendar to be unselectable if we were to
336
- // update the min/max dates in these cases.
337
- if (this.primaryCalendarView?.mode === 'day') {
338
- this.secondaryCalendarMinDate = moment(this.primaryCalendarView?.date).add(1, 'month').startOf('month').toDate();
339
- }
340
- if (this.secondaryCalendarView?.mode === 'day') {
341
- this.primaryCalendarMaxDate = moment(this.secondaryCalendarView?.date).subtract(1, 'month').endOf('month').toDate();
342
- }
343
- }
344
- updateCalendars(selection) {
345
- this.calendarSelection = selection;
346
- this.updatePrimaryCalendar(selection);
347
- // Only shift the primary calendar if we're showing the secondary calendar
348
- this.updateSecondaryCalendar(selection, this.selectionStrategy.showSecondaryCalendar);
349
- this.updateCalendarMinMaxDates();
350
- }
351
- updatePrimaryCalendar(selection, shiftSecondary = false) {
352
- this.primaryCalendarView = this.selectionStrategy.getPrimaryCalendarView(selection, this.minDate, this.maxDate, this.primaryCalendarView);
353
- // When entering a date into the first textbox, we really only want to update the primary calendar.
354
- // However, it's possible that the new date is after the secondary calendar's date. In this case,
355
- // We want to shift the secondary calendar so the calendars stay in order.
356
- if (shiftSecondary && this.secondaryCalendarView) {
357
- if (moment(this.primaryCalendarView.date).isSameOrAfter(this.secondaryCalendarView.date, 'month')) {
358
- let newSecondaryDate = moment(this.primaryCalendarView.date).add(1, 'month').toDate();
359
- this.secondaryCalendarView = { mode: this.selectionStrategy.selectionViewMode, date: newSecondaryDate };
360
- }
361
- }
362
- }
363
- updateSecondaryCalendar(selection, shiftPrimary = false) {
364
- this.secondaryCalendarView = this.selectionStrategy.getSecondaryCalendarView(selection, this.minDate, this.maxDate, this.secondaryCalendarView);
365
- // When entering a date into the second textbox, we really only want to update the secondary calendar.
366
- // However, it's possible that the new date is before the primary calendar's date. In this case,
367
- // We want to shift the primary calendar so the calendars stay in order.
368
- if (shiftPrimary && this.primaryCalendarView) {
369
- if (moment(this.primaryCalendarView.date).isSameOrAfter(this.secondaryCalendarView.date, 'month')) {
370
- let newPrimaryDate = moment(this.secondaryCalendarView.date).subtract(1, 'month').toDate();
371
- this.primaryCalendarView = { mode: this.selectionStrategy.selectionViewMode, date: newPrimaryDate };
372
- }
373
- }
374
- }
375
- updateSteppers(value) {
376
- // Disable the steppers if we either don't have a selection or only have one date in the selection.
377
- if (!value ||
378
- (DateInput.isSelectionRange(value) && (!value.start || !value.end))) {
379
- this.disableSteppers = true;
380
- }
381
- else {
382
- this.disableSteppers = false;
383
- }
384
- }
385
- validateTextboxes() {
386
- const control = this.textboxGroup.controls.textbox;
387
- const control2 = this.textboxGroup.controls.textbox2;
388
- // The first textbox should only have the required error if it's empty and the date input is required,
389
- // or if the date input is not required and the second control is visible and has a value (meaning a partial range)
390
- if (!control.value &&
391
- (this.required || (control2.value && this.selectionStrategy.showSecondaryTextbox))) {
392
- control.setErrors({ required: true });
393
- }
394
- // The same idea applies to the second textbox, but only if it's visible
395
- if (this.selectionStrategy.showSecondaryTextbox &&
396
- !control2.value &&
397
- (this.required || control.value)) {
398
- control2.setErrors({ required: true });
399
- }
400
- if (control.value) {
401
- const errors = this.validateDateString(control.value);
402
- if (errors) {
403
- control.setErrors(errors);
404
- }
405
- }
406
- if (control2.value && this.selectionStrategy.showSecondaryTextbox) {
407
- const errors = this.validateDateString(control2.value);
408
- if (errors) {
409
- control2.setErrors(errors);
410
- }
411
- }
412
- }
413
- validateDateString(date) {
414
- const value = this.selectionStrategy.parseString(date, this.parseFormats);
415
- if (value) {
416
- // We're using the view mode as the granularity. We don't want to invalidate
417
- // the date in the case where you have a month/quarter/year selected and the min
418
- // or max date is somewhere within that month/quarter/year.
419
- if (moment(value).isBefore(this.minDate, this.selectionStrategy.selectionViewMode)) {
420
- return { minDate: { minValue: this.minDate } };
421
- }
422
- else if (moment(value).isAfter(this.maxDate, this.selectionStrategy.selectionViewMode)) {
423
- return { maxDate: { maxValue: this.maxDate } };
424
- }
425
- }
426
- return null;
427
- }
428
- }
429
- DateInputComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: DateInputComponent, deps: [{ token: i1.ValidationMessageService }, { token: i2.FormGroupHelper }, { token: i3.UserPreferenceService }, { token: i0.ElementRef }, { token: i4.Overlay }, { token: i5.DateInput.SelectionStrategies }], target: i0.ɵɵFactoryTarget.Component });
430
- DateInputComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.9", type: DateInputComponent, selector: "ec-date-input", inputs: { id: "id", formModel: "formModel", minDate: "minDate", maxDate: "maxDate", selectionMode: "selectionMode", selectionModeOptions: "selectionModeOptions", quickSelectDate: "quickSelectDate", enableSteppers: "enableSteppers" }, host: { properties: { "attr.id": "this.id" } }, providers: [DateInput.SelectionStrategies], viewQueries: [{ propertyName: "calendar", first: true, predicate: ["calendar"], descendants: true }, { propertyName: "controls", first: true, predicate: ["controls"], descendants: true }, { propertyName: "overlay", first: true, predicate: ["overlay"], descendants: true }], usesInheritance: true, usesOnChanges: true, ngImport: i0, template: "<label *ngIf=\"label\">\r\n <span>{{label | translate}}</span>\r\n <span *ngIf=\"validationErrors.length > 0 && formModel.touched && formModel.invalid\">&nbsp;{{validationErrors}}</span>\r\n <ec-help-popover id=\"{{id}}_helpPopover\"\r\n *ngIf=\"helpPopover\"\r\n class=\"d-inline-block my-n3 mx-n1\"\r\n text=\"{{helpPopover | translate}}\"\r\n contentPosition=\"{{helpPopoverPosition}}\">\r\n </ec-help-popover>\r\n</label>\r\n\r\n<div class=\"d-flex align-items-center\"\r\n [ecKeyboardNavContainer]=\"isCalendarOpen\"\r\n #controls=\"ecKeyboardNavContainer\"\r\n (focusOutEnd)=\"onControlsFocusOutEnd()\">\r\n <ec-form-control id=\"{{id}}\"\r\n [required]=\"required\"\r\n [autofocus]=\"autofocus\"\r\n [pending]=\"pending\"\r\n [readonly]=\"readonly\"\r\n (actionClicked)=\"isCalendarOpen = !isCalendarOpen\"\r\n [showClear]=\"false\"\r\n actionIcon=\"icon-date\"\r\n cdkOverlayOrigin\r\n #overlayOrigin=\"cdkOverlayOrigin\"\r\n class=\"flex-grow\"\r\n style=\"height: 2rem;\">\r\n <input id=\"{{id}}_input\"\r\n type=\"text\"\r\n placeholder=\"{{placeholder}}\"\r\n [formControl]=\"textboxGroup.get('textbox')\"\r\n (blur)=\"onTextboxBlur()\">\r\n </ec-form-control>\r\n\r\n <ng-container *ngIf=\"selectionStrategy.showSecondaryTextbox\">\r\n <span class=\"flex-shrink mx-1\">&ndash;</span>\r\n <ec-form-control id=\"{{id}}_control2\"\r\n [required]=\"required\"\r\n [autofocus]=\"autofocus\"\r\n [pending]=\"pending\"\r\n [readonly]=\"readonly\"\r\n (actionClicked)=\"isCalendarOpen = !isCalendarOpen\"\r\n [showClear]=\"false\"\r\n actionIcon=\"icon-date\"\r\n class=\"flex-grow\"\r\n style=\"height: 2rem;\">\r\n <input id=\"{{id}}_input2\"\r\n type=\"text\"\r\n placeholder=\"{{placeholder}}\"\r\n [formControl]=\"textboxGroup.get('textbox2')\"\r\n (blur)=\"onTextbox2Blur()\">\r\n </ec-form-control>\r\n </ng-container>\r\n\r\n <div *ngIf=\"enableSteppers\"\r\n class=\"control-group ml-2\">\r\n <ec-button id=\"{{id}}_previousSelection\"\r\n type=\"secondary\"\r\n icon=\"icon-angle-down rotate-90\"\r\n (clicked)=\"previousSelection()\"\r\n [disabled]=\"isCalendarOpen || disableSteppers || formModel?.disabled\">\r\n </ec-button>\r\n <ec-button id=\"{{id}}_nextSelection\"\r\n type=\"secondary\"\r\n icon=\"icon-angle-down rotate-270\"\r\n (clicked)=\"nextSelection()\"\r\n [disabled]=\"isCalendarOpen || disableSteppers || formModel?.disabled\">\r\n </ec-button>\r\n </div>\r\n\r\n <ec-button *ngIf=\"quickSelectDate\"\r\n id=\"{{id}}_quickSelect\"\r\n icon=\"icon-day\"\r\n type=\"secondary\"\r\n title=\"{{'DateInput_LatestDataAvailableTitle' | translate}}\"\r\n (clicked)=\"goToQuickSelectDate()\"\r\n class=\"ml-2\">\r\n </ec-button>\r\n</div>\r\n\r\n<ng-template cdkConnectedOverlay\r\n #overlay=\"cdkConnectedOverlay\"\r\n [cdkConnectedOverlayOrigin]=\"overlayOrigin\"\r\n [cdkConnectedOverlayOpen]=\"isCalendarOpen\"\r\n [cdkConnectedOverlayScrollStrategy]=\"overlayScrollStrategy\"\r\n cdkConnectedOverlayPanelClass=\"my-1\"\r\n (overlayOutsideClick)=\"onOverlayOutsideClick($event)\"\r\n (detach)=\"isCalendarOpen = false\">\r\n <article id=\"{{id}}_datePicker\"\r\n class=\"card d-flex\"\r\n [ecKeyboardNavContainer]=\"isCalendarOpen\"\r\n #calendar=\"ecKeyboardNavContainer\"\r\n (focusOutStart)=\"onCalendarFocusOutStart()\"\r\n (focusOutEnd)=\"onCalendarFocusOutEnd()\">\r\n <ul *ngIf=\"selectionModeOptions.length > 1\"\r\n class=\"selection-mode-menu border-right p-1\">\r\n <li *ngFor=\"let option of selectionModeOptions\">\r\n <button id=\"{{id}}_selectionMode_{{option}}\"\r\n class=\"text-body-1\"\r\n [class.is-selected]=\"option === selectionMode\"\r\n (click)=\"onSelectionModeChange(option)\">\r\n {{'DateInputSelectionMode_' + option | translate}}\r\n </button>\r\n </li>\r\n </ul>\r\n\r\n <div>\r\n <div class=\"d-flex\">\r\n <ec-calendar id=\"{{id}}_calendar\"\r\n [view]=\"primaryCalendarView\"\r\n (viewChange)=\"onPrimaryCalendarViewChange($event)\"\r\n [selectionMode]=\"selectionMode\"\r\n [selection]=\"calendarSelection\"\r\n (dateSelected)=\"onCalendarDateSelected($event)\"\r\n [minDate]=\"minDate\"\r\n [maxDate]=\"selectionStrategy.showSecondaryCalendar ? primaryCalendarMaxDate : maxDate\">\r\n </ec-calendar>\r\n\r\n <ec-calendar *ngIf=\"selectionStrategy.showSecondaryCalendar\"\r\n id=\"{{id}}_secondaryCalendar\"\r\n [view]=\"secondaryCalendarView\"\r\n (viewChange)=\"onSecondaryCalendarViewChange($event)\"\r\n [selectionMode]=\"selectionMode\"\r\n [selection]=\"calendarSelection\"\r\n (dateSelected)=\"onCalendarDateSelected($event)\"\r\n [minDate]=\"secondaryCalendarMinDate\"\r\n [maxDate]=\"maxDate\">\r\n </ec-calendar>\r\n </div>\r\n\r\n <footer *ngIf=\"selectionStrategy.selectionViewMode === 'day'\"\r\n class=\"px-2 my-2 d-flex\">\r\n <button id=\"{{id}}_today_button\"\r\n ecLinkButton\r\n class=\"ml-auto d-inline-block\"\r\n (click)=\"goToToday()\"\r\n style=\"height: 1.75rem;\">\r\n {{'Today' | translate}}\r\n </button>\r\n </footer>\r\n </div>\r\n </article>\r\n</ng-template>\r\n", styles: [":host{display:block}label{color:var(--ec-form-control-label-color, var(--ec-color-secondary-dark));display:block;font-size:var(--ec-font-size-label);line-height:1;margin:calc(var(--ec-font-size-label) / 2) 0}.date-picker{display:grid;grid-template-areas:\"menu calendar calendar\" \"menu footer footer\"}.date-picker footer{grid-area:footer}ul.selection-mode-menu{grid-area:menu;list-style:none;padding:0;margin:0;min-width:7rem}ul.selection-mode-menu li{margin-bottom:.25rem}ul.selection-mode-menu li button{font-size:var(--ec-font-size-action);height:2rem;line-height:1.25rem;padding:.3125rem .5rem;border:0;border-radius:var(--ec-border-radius);display:flex;align-items:center;justify-content:center;cursor:pointer;background-color:transparent;width:100%;height:1.75rem}ul.selection-mode-menu li button .label{display:flex;align-items:center;justify-content:center;white-space:nowrap;flex:auto}ul.selection-mode-menu li button .ec-icon{flex:none}ul.selection-mode-menu li button .ec-icon+.label{flex:none;margin-left:.25rem}ul.selection-mode-menu li button.has-badge{padding-right:.0625rem}ul.selection-mode-menu li button:focus{outline:none;position:relative;z-index:1}ul.selection-mode-menu li button:disabled{background-color:var(--ec-background-color-disabled);border:1px solid var(--ec-form-control-border-color-disabled);color:var(--ec-color-disabled-dark);opacity:var(--ec-form-control-opacity-disabled);cursor:default}ul.selection-mode-menu li button:disabled{background-color:transparent;border-color:transparent;color:var(--ec-color-hint-dark);--ec-color-icon: var(--ec-color-hint-dark)}ul.selection-mode-menu li button:hover:not(:disabled){background-color:var(--ec-background-color-hover)}ul.selection-mode-menu li button:active:not(:disabled){background-color:var(--ec-background-color-selected);font-weight:700}ul.selection-mode-menu li button:focus:not(:disabled){box-shadow:var(--ec-button-box-shadow-active, 0 0 0 2px var(--ec-border-color-focus))}ul.selection-mode-menu li button.is-selected{background-color:var(--ec-background-color-selected);font-weight:700}ec-button{--ec-button-border-color-secondary: var(--ec-border-color-control)}.control-group ec-button:has(+ ec-button) ::ng-deep button{border-right:0}.control-group ec-button+ec-button ::ng-deep button{border-left:0}\n"], dependencies: [{ kind: "directive", type: i6.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i6.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i7.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i7.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i7.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: i4.CdkConnectedOverlay, selector: "[cdk-connected-overlay], [connected-overlay], [cdkConnectedOverlay]", inputs: ["cdkConnectedOverlayOrigin", "cdkConnectedOverlayPositions", "cdkConnectedOverlayPositionStrategy", "cdkConnectedOverlayOffsetX", "cdkConnectedOverlayOffsetY", "cdkConnectedOverlayWidth", "cdkConnectedOverlayHeight", "cdkConnectedOverlayMinWidth", "cdkConnectedOverlayMinHeight", "cdkConnectedOverlayBackdropClass", "cdkConnectedOverlayPanelClass", "cdkConnectedOverlayViewportMargin", "cdkConnectedOverlayScrollStrategy", "cdkConnectedOverlayOpen", "cdkConnectedOverlayDisableClose", "cdkConnectedOverlayTransformOriginOn", "cdkConnectedOverlayHasBackdrop", "cdkConnectedOverlayLockPosition", "cdkConnectedOverlayFlexibleDimensions", "cdkConnectedOverlayGrowAfterOpen", "cdkConnectedOverlayPush"], outputs: ["backdropClick", "positionChange", "attach", "detach", "overlayKeydown", "overlayOutsideClick"], exportAs: ["cdkConnectedOverlay"] }, { kind: "directive", type: i4.CdkOverlayOrigin, selector: "[cdk-overlay-origin], [overlay-origin], [cdkOverlayOrigin]", exportAs: ["cdkOverlayOrigin"] }, { kind: "component", type: i8.ButtonComponent, selector: "ec-button", inputs: ["id", "disabled", "icon", "label", "badge", "tabindex", "type", "pending", "pendingIcon", "customTemplate", "isSubmit", "autofocus"], outputs: ["clicked"] }, { kind: "component", type: i9.FormControlComponent, selector: "ec-form-control", inputs: ["id", "icon", "actionIcon", "showClear", "formModel", "autofocus", "pending", "required", "readonly"], outputs: ["actionClicked"] }, { kind: "component", type: i10.HelpPopoverComponent, selector: "ec-help-popover", inputs: ["id", "text", "contentPosition", "maxWidth"] }, { kind: "component", type: i11.LinkButtonComponent, selector: "button[ecLinkButton]" }, { kind: "component", type: i12.CalendarComponent, selector: "ec-calendar", inputs: ["id", "selection", "selectionMode", "minDate", "maxDate", "view"], outputs: ["dateSelected", "viewChange"] }, { kind: "directive", type: i13.KeyboardNavContainerDirective, selector: "[ecKeyboardNavContainer]", inputs: ["ecKeyboardNavContainer"], outputs: ["focusOutStart", "focusOutEnd"], exportAs: ["ecKeyboardNavContainer"] }, { kind: "pipe", type: i14.TranslatePipe, name: "translate" }] });
431
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: DateInputComponent, decorators: [{
432
- type: Component,
433
- args: [{ selector: 'ec-date-input', providers: [DateInput.SelectionStrategies], template: "<label *ngIf=\"label\">\r\n <span>{{label | translate}}</span>\r\n <span *ngIf=\"validationErrors.length > 0 && formModel.touched && formModel.invalid\">&nbsp;{{validationErrors}}</span>\r\n <ec-help-popover id=\"{{id}}_helpPopover\"\r\n *ngIf=\"helpPopover\"\r\n class=\"d-inline-block my-n3 mx-n1\"\r\n text=\"{{helpPopover | translate}}\"\r\n contentPosition=\"{{helpPopoverPosition}}\">\r\n </ec-help-popover>\r\n</label>\r\n\r\n<div class=\"d-flex align-items-center\"\r\n [ecKeyboardNavContainer]=\"isCalendarOpen\"\r\n #controls=\"ecKeyboardNavContainer\"\r\n (focusOutEnd)=\"onControlsFocusOutEnd()\">\r\n <ec-form-control id=\"{{id}}\"\r\n [required]=\"required\"\r\n [autofocus]=\"autofocus\"\r\n [pending]=\"pending\"\r\n [readonly]=\"readonly\"\r\n (actionClicked)=\"isCalendarOpen = !isCalendarOpen\"\r\n [showClear]=\"false\"\r\n actionIcon=\"icon-date\"\r\n cdkOverlayOrigin\r\n #overlayOrigin=\"cdkOverlayOrigin\"\r\n class=\"flex-grow\"\r\n style=\"height: 2rem;\">\r\n <input id=\"{{id}}_input\"\r\n type=\"text\"\r\n placeholder=\"{{placeholder}}\"\r\n [formControl]=\"textboxGroup.get('textbox')\"\r\n (blur)=\"onTextboxBlur()\">\r\n </ec-form-control>\r\n\r\n <ng-container *ngIf=\"selectionStrategy.showSecondaryTextbox\">\r\n <span class=\"flex-shrink mx-1\">&ndash;</span>\r\n <ec-form-control id=\"{{id}}_control2\"\r\n [required]=\"required\"\r\n [autofocus]=\"autofocus\"\r\n [pending]=\"pending\"\r\n [readonly]=\"readonly\"\r\n (actionClicked)=\"isCalendarOpen = !isCalendarOpen\"\r\n [showClear]=\"false\"\r\n actionIcon=\"icon-date\"\r\n class=\"flex-grow\"\r\n style=\"height: 2rem;\">\r\n <input id=\"{{id}}_input2\"\r\n type=\"text\"\r\n placeholder=\"{{placeholder}}\"\r\n [formControl]=\"textboxGroup.get('textbox2')\"\r\n (blur)=\"onTextbox2Blur()\">\r\n </ec-form-control>\r\n </ng-container>\r\n\r\n <div *ngIf=\"enableSteppers\"\r\n class=\"control-group ml-2\">\r\n <ec-button id=\"{{id}}_previousSelection\"\r\n type=\"secondary\"\r\n icon=\"icon-angle-down rotate-90\"\r\n (clicked)=\"previousSelection()\"\r\n [disabled]=\"isCalendarOpen || disableSteppers || formModel?.disabled\">\r\n </ec-button>\r\n <ec-button id=\"{{id}}_nextSelection\"\r\n type=\"secondary\"\r\n icon=\"icon-angle-down rotate-270\"\r\n (clicked)=\"nextSelection()\"\r\n [disabled]=\"isCalendarOpen || disableSteppers || formModel?.disabled\">\r\n </ec-button>\r\n </div>\r\n\r\n <ec-button *ngIf=\"quickSelectDate\"\r\n id=\"{{id}}_quickSelect\"\r\n icon=\"icon-day\"\r\n type=\"secondary\"\r\n title=\"{{'DateInput_LatestDataAvailableTitle' | translate}}\"\r\n (clicked)=\"goToQuickSelectDate()\"\r\n class=\"ml-2\">\r\n </ec-button>\r\n</div>\r\n\r\n<ng-template cdkConnectedOverlay\r\n #overlay=\"cdkConnectedOverlay\"\r\n [cdkConnectedOverlayOrigin]=\"overlayOrigin\"\r\n [cdkConnectedOverlayOpen]=\"isCalendarOpen\"\r\n [cdkConnectedOverlayScrollStrategy]=\"overlayScrollStrategy\"\r\n cdkConnectedOverlayPanelClass=\"my-1\"\r\n (overlayOutsideClick)=\"onOverlayOutsideClick($event)\"\r\n (detach)=\"isCalendarOpen = false\">\r\n <article id=\"{{id}}_datePicker\"\r\n class=\"card d-flex\"\r\n [ecKeyboardNavContainer]=\"isCalendarOpen\"\r\n #calendar=\"ecKeyboardNavContainer\"\r\n (focusOutStart)=\"onCalendarFocusOutStart()\"\r\n (focusOutEnd)=\"onCalendarFocusOutEnd()\">\r\n <ul *ngIf=\"selectionModeOptions.length > 1\"\r\n class=\"selection-mode-menu border-right p-1\">\r\n <li *ngFor=\"let option of selectionModeOptions\">\r\n <button id=\"{{id}}_selectionMode_{{option}}\"\r\n class=\"text-body-1\"\r\n [class.is-selected]=\"option === selectionMode\"\r\n (click)=\"onSelectionModeChange(option)\">\r\n {{'DateInputSelectionMode_' + option | translate}}\r\n </button>\r\n </li>\r\n </ul>\r\n\r\n <div>\r\n <div class=\"d-flex\">\r\n <ec-calendar id=\"{{id}}_calendar\"\r\n [view]=\"primaryCalendarView\"\r\n (viewChange)=\"onPrimaryCalendarViewChange($event)\"\r\n [selectionMode]=\"selectionMode\"\r\n [selection]=\"calendarSelection\"\r\n (dateSelected)=\"onCalendarDateSelected($event)\"\r\n [minDate]=\"minDate\"\r\n [maxDate]=\"selectionStrategy.showSecondaryCalendar ? primaryCalendarMaxDate : maxDate\">\r\n </ec-calendar>\r\n\r\n <ec-calendar *ngIf=\"selectionStrategy.showSecondaryCalendar\"\r\n id=\"{{id}}_secondaryCalendar\"\r\n [view]=\"secondaryCalendarView\"\r\n (viewChange)=\"onSecondaryCalendarViewChange($event)\"\r\n [selectionMode]=\"selectionMode\"\r\n [selection]=\"calendarSelection\"\r\n (dateSelected)=\"onCalendarDateSelected($event)\"\r\n [minDate]=\"secondaryCalendarMinDate\"\r\n [maxDate]=\"maxDate\">\r\n </ec-calendar>\r\n </div>\r\n\r\n <footer *ngIf=\"selectionStrategy.selectionViewMode === 'day'\"\r\n class=\"px-2 my-2 d-flex\">\r\n <button id=\"{{id}}_today_button\"\r\n ecLinkButton\r\n class=\"ml-auto d-inline-block\"\r\n (click)=\"goToToday()\"\r\n style=\"height: 1.75rem;\">\r\n {{'Today' | translate}}\r\n </button>\r\n </footer>\r\n </div>\r\n </article>\r\n</ng-template>\r\n", styles: [":host{display:block}label{color:var(--ec-form-control-label-color, var(--ec-color-secondary-dark));display:block;font-size:var(--ec-font-size-label);line-height:1;margin:calc(var(--ec-font-size-label) / 2) 0}.date-picker{display:grid;grid-template-areas:\"menu calendar calendar\" \"menu footer footer\"}.date-picker footer{grid-area:footer}ul.selection-mode-menu{grid-area:menu;list-style:none;padding:0;margin:0;min-width:7rem}ul.selection-mode-menu li{margin-bottom:.25rem}ul.selection-mode-menu li button{font-size:var(--ec-font-size-action);height:2rem;line-height:1.25rem;padding:.3125rem .5rem;border:0;border-radius:var(--ec-border-radius);display:flex;align-items:center;justify-content:center;cursor:pointer;background-color:transparent;width:100%;height:1.75rem}ul.selection-mode-menu li button .label{display:flex;align-items:center;justify-content:center;white-space:nowrap;flex:auto}ul.selection-mode-menu li button .ec-icon{flex:none}ul.selection-mode-menu li button .ec-icon+.label{flex:none;margin-left:.25rem}ul.selection-mode-menu li button.has-badge{padding-right:.0625rem}ul.selection-mode-menu li button:focus{outline:none;position:relative;z-index:1}ul.selection-mode-menu li button:disabled{background-color:var(--ec-background-color-disabled);border:1px solid var(--ec-form-control-border-color-disabled);color:var(--ec-color-disabled-dark);opacity:var(--ec-form-control-opacity-disabled);cursor:default}ul.selection-mode-menu li button:disabled{background-color:transparent;border-color:transparent;color:var(--ec-color-hint-dark);--ec-color-icon: var(--ec-color-hint-dark)}ul.selection-mode-menu li button:hover:not(:disabled){background-color:var(--ec-background-color-hover)}ul.selection-mode-menu li button:active:not(:disabled){background-color:var(--ec-background-color-selected);font-weight:700}ul.selection-mode-menu li button:focus:not(:disabled){box-shadow:var(--ec-button-box-shadow-active, 0 0 0 2px var(--ec-border-color-focus))}ul.selection-mode-menu li button.is-selected{background-color:var(--ec-background-color-selected);font-weight:700}ec-button{--ec-button-border-color-secondary: var(--ec-border-color-control)}.control-group ec-button:has(+ ec-button) ::ng-deep button{border-right:0}.control-group ec-button+ec-button ::ng-deep button{border-left:0}\n"] }]
434
- }], ctorParameters: function () { return [{ type: i1.ValidationMessageService }, { type: i2.FormGroupHelper }, { type: i3.UserPreferenceService }, { type: i0.ElementRef }, { type: i4.Overlay }, { type: i5.DateInput.SelectionStrategies }]; }, propDecorators: { id: [{
435
- type: HostBinding,
436
- args: ['attr.id']
437
- }, {
438
- type: Input
439
- }], formModel: [{
440
- type: Input
441
- }], minDate: [{
442
- type: Input
443
- }], maxDate: [{
444
- type: Input
445
- }], selectionMode: [{
446
- type: Input
447
- }], selectionModeOptions: [{
448
- type: Input
449
- }], quickSelectDate: [{
450
- type: Input
451
- }], enableSteppers: [{
452
- type: Input
453
- }], calendar: [{
454
- type: ViewChild,
455
- args: ['calendar']
456
- }], controls: [{
457
- type: ViewChild,
458
- args: ['controls']
459
- }], overlay: [{
460
- type: ViewChild,
461
- args: ['overlay']
462
- }] } });
463
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGF0ZS1pbnB1dC5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9jb21wb25lbnRzL3NyYy9saWIvY29udHJvbHMvZGF0ZS1pbnB1dC9kYXRlLWlucHV0LmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL2NvbXBvbmVudHMvc3JjL2xpYi9jb250cm9scy9kYXRlLWlucHV0L2RhdGUtaW5wdXQuY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQ0EsT0FBTyxFQUFFLFNBQVMsRUFBYyxXQUFXLEVBQUUsS0FBSyxFQUFvQyxTQUFTLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDdkgsT0FBTyxFQUFFLFdBQVcsRUFBcUIsU0FBUyxFQUFvQixNQUFNLGdCQUFnQixDQUFDO0FBQzdGLE9BQU8sTUFBTSxNQUFNLFFBQVEsQ0FBQztBQUM1QixPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBQ3JDLE9BQU8sRUFBRSxZQUFZLEVBQUUsb0JBQW9CLEVBQUUsU0FBUyxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFFL0UsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLDZCQUE2QixDQUFDO0FBSzdELE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSxzQkFBc0IsQ0FBQztBQUV2RCxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0sb0JBQW9CLENBQUM7Ozs7Ozs7Ozs7Ozs7Ozs7QUFRL0MsTUFBTSxPQUFPLGtCQUFtQixTQUFRLGVBQWU7SUFxRXJELFlBQ1ksd0JBQWtELEVBQ2xELGVBQWdDLEVBQ2xDLHFCQUE0QyxFQUM1QyxFQUFjLEVBQ2QsY0FBdUIsRUFDdkIsbUJBQWtEO1FBRTFELEtBQUssQ0FBQyx3QkFBd0IsRUFBRSxlQUFlLENBQUMsQ0FBQztRQVB2Qyw2QkFBd0IsR0FBeEIsd0JBQXdCLENBQTBCO1FBQ2xELG9CQUFlLEdBQWYsZUFBZSxD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ZGtDb25uZWN0ZWRPdmVybGF5LCBPdmVybGF5IH0gZnJvbSAnQGFuZ3VsYXIvY2RrL292ZXJsYXknO1xyXG5pbXBvcnQgeyBDb21wb25lbnQsIEVsZW1lbnRSZWYsIEhvc3RCaW5kaW5nLCBJbnB1dCwgT25DaGFuZ2VzLCBPbkluaXQsIFNpbXBsZUNoYW5nZXMsIFZpZXdDaGlsZCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xyXG5pbXBvcnQgeyBGb3JtQ29udHJvbCwgRm9ybUNvbnRyb2xTdGF0dXMsIEZvcm1Hcm91cCwgVmFsaWRhdGlvbkVycm9ycyB9IGZyb20gJ0Bhbmd1bGFyL2Zvcm1zJztcclxuaW1wb3J0IG1vbWVudCBmcm9tICdtb21lbnQnO1xyXG5pbXBvcnQgeyBsYXN0VmFsdWVGcm9tIH0gZnJvbSAncnhqcyc7XHJcbmltcG9ydCB7IGRlYm91bmNlVGltZSwgZGlzdGluY3RVbnRpbENoYW5nZWQsIHRha2VVbnRpbCB9IGZyb20gJ3J4anMvb3BlcmF0b3JzJztcclxuaW1wb3J0IHsgS2V5Ym9hcmROYXZDb250YWluZXJEaXJlY3RpdmUgfSBmcm9tICcuLi8uLi8uLi9wdWJsaWMtYXBpJztcclxuaW1wb3J0IHsgRGF0ZVRpbWVIZWxwZXIgfSBmcm9tICcuLi8uLi9jb3JlL2RhdGUtdGltZS1oZWxwZXInO1xyXG5pbXBvcnQgeyBWYWxpZGF0aW9uTWVzc2FnZVNlcnZpY2UgfSBmcm9tICcuLi8uLi9jb3JlL3ZhbGlkYXRpb24tbWVzc2FnZS5zZXJ2aWNlJztcclxuaW1wb3J0IHsgRm9ybUdyb3VwSGVscGVyIH0gZnJvbSAnLi4vLi4vc2hhcmVkL2Zvcm0tZ3JvdXAuaGVscGVyJztcclxuaW1wb3J0IHsgVXNlclByZWZlcmVuY2VTZXJ2aWNlIH0gZnJvbSAnLi4vLi4vc2hhcmVkL3VzZXItcHJlZmVyZW5jZS5zZXJ2aWNlJztcclxuaW1wb3J0IHsgQ2FsZW5kYXIgfSBmcm9tICcuLi9jYWxlbmRhci9jYWxlbmRhci50eXBlcyc7XHJcbmltcG9ydCB7IEZvcm1Db250cm9sQmFzZSB9IGZyb20gJy4uL2Zvcm0tY29udHJvbC1iYXNlJztcclxuaW1wb3J0IHsgRGF0ZUlucHV0U2VsZWN0aW9uU3RyYXRlZ3lCYXNlIH0gZnJvbSAnLi9kYXRlLWlucHV0LXNlbGVjdGlvbi1zdHJhdGVnaWVzL2RhdGUtaW5wdXQtc2VsZWN0aW9uLXN0cmF0ZWd5LWJhc2UnO1xyXG5pbXBvcnQgeyBEYXRlSW5wdXQgfSBmcm9tICcuL2RhdGUtaW5wdXQudHlwZXMnO1xyXG5cclxuQENvbXBvbmVudCh7XHJcbiAgc2VsZWN0b3I6ICdlYy1kYXRlLWlucHV0JyxcclxuICB0ZW1wbGF0ZVVybDogJy4vZGF0ZS1pbnB1dC5jb21wb25lbnQuaHRtbCcsXHJcbiAgc3R5bGVVcmxzOiBbJy4vZGF0ZS1pbnB1dC5jb21wb25lbnQuc2NzcyddLFxyXG4gIHByb3ZpZGVyczogW0RhdGVJbnB1dC5TZWxlY3Rpb25TdHJhdGVnaWVzXVxyXG59KVxyXG5leHBvcnQgY2xhc3MgRGF0ZUlucHV0Q29tcG9uZW50IGV4dGVuZHMgRm9ybUNvbnRyb2xCYXNlIGltcGxlbWVudHMgT25Jbml0LCBPbkNoYW5nZXMge1xyXG5cclxuICBASG9zdEJpbmRpbmcoJ2F0dHIuaWQnKVxyXG4gIEBJbnB1dCgpIHB1YmxpYyBpZDogc3RyaW5nID0gJyc7XHJcblxyXG4gIC8qKiBUaGUgZm9ybSBjb250cm9sIHByb3ZpZGVkIGJ5IHRoZSBob3N0aW5nIGZvcm0uICovXHJcbiAgQElucHV0KCkgcHVibGljIGZvcm1Nb2RlbDogRGF0ZUlucHV0LkZvcm1Nb2RlbCA9IG5ldyBGb3JtQ29udHJvbChudWxsKTtcclxuXHJcbiAgQElucHV0KCkgcHVibGljIG1pbkRhdGU6IERhdGUgPSBEYXRlVGltZUhlbHBlci5taW5EYXRlUGlja2VyRGF0ZTtcclxuICBASW5wdXQoKSBwdWJsaWMgbWF4RGF0ZTogRGF0ZSA9IERhdGVUaW1lSGVscGVyLm1heERhdGVQaWNrZXJEYXRlO1xyXG5cclxuICAvKiogVGhlIGluaXRpYWwgc2VsZWN0aW9uIG1vZGUgZm9yIHRoZSBjYWxlbmRhci4gRGVmYXVsdHMgdG8gZGF5IGlmIG5vdCBwcm92aWRlZCAqL1xyXG4gIEBJbnB1dCgpIHNlbGVjdGlvbk1vZGU6IERhdGVJbnB1dC5TZWxlY3Rpb25Nb2RlID0gJ2RheSc7XHJcblxyXG4gIC8qKiBUaGUgYXZhaWxhYmxlIHNlbGVjdGlvbiBtb2RlcyBmb3IgdGhlIGNhbGVuZGFyLiBEZWZhdWx0cyB0byBvbmx5IHRoZSBpbml0aWFsIHNlbGVjdGlvbiBtb2RlIGlmIG5vdCBwcm92aWRlZC4gICovXHJcbiAgQElucHV0KCkgc2VsZWN0aW9uTW9kZU9wdGlvbnM6IERhdGVJbnB1dC5TZWxlY3Rpb25Nb2RlW10gPSBbJ2RheSddO1xyXG5cclxuICAvKiogXHJcbiAgICogV2hlbiBhIGRhdGUgaXMgcHJvdmlkZWQsIGVuYWJsZXMgdGhlICdxdWljayBzZWxlY3QnIGJ1dHRvbi5cclxuICAgKiBDbGlja2luZyB0aGUgYnV0dG9uIHdpbGwgc2hpZnQgdGhlIHNlbGVjdGVkIGRhdGUgcmFuZ2UgdG8gdGhlIHByb3ZpZGVkIGRhdGUuXHJcbiAgICovXHJcbiAgQElucHV0KCkgcXVpY2tTZWxlY3REYXRlPzogRGF0ZTtcclxuXHJcbiAgLyoqIEVuYWJsZXMgdGhlIG5leHQvcHJldmlvdXMgc2VsZWN0aW9uIGJ1dHRvbnMuICovXHJcbiAgQElucHV0KCkgZW5hYmxlU3RlcHBlcnM6IGJvb2xlYW4gPSBmYWxzZTtcclxuXHJcbiAgLyoqIFRoZSBmb3JtIGdyb3VwIGZvciB0aGUgaW50ZXJuYWwgdGV4dGJveGVzLiBUZXh0Ym94MiBpcyBvbmx5IHVzZWQgZm9yIHJhbmdlcy4gKi9cclxuICBwdWJsaWMgdGV4dGJveEdyb3VwOiBEYXRlSW5wdXQuVGV4dGJveEdyb3VwID0gbmV3IEZvcm1Hcm91cCh7XHJcbiAgICB0ZXh0Ym94OiBuZXcgRm9ybUNvbnRyb2w8c3RyaW5nIHwgbnVsbD4obnVsbCksXHJcbiAgICB0ZXh0Ym94MjogbmV3IEZvcm1Db250cm9sPHN0cmluZyB8IG51bGw+KG51bGwpXHJcbiAgfSk7XHJcblxyXG4gIC8qKlxyXG4gICAqIFRoZSBjdXJyZW50IGNhbGVuZGFyIHNlbGVjdGlvbi5cclxuICAgKiBVcGRhdGVkIHdoZW4gdGhlIHVzZXIgY2xpY2tzIG9uIGEgY2FsZW5kYXIgaXRlbSBvciB3aGVuIHRoZSBkYXRlIGVudGVyZWQgaW50byB0aGUgdGV4dGJveCBpcyBwYXJzZWQuXHJcbiAgICovXHJcbiAgcHVibGljIGNhbGVuZGFyU2VsZWN0aW9uOiBEYXRlSW5wdXQuU2VsZWN0aW9uIHwgbnVsbCA9IG51bGw7XHJcblxyXG4gIC8qKiBDb250cm9scyB3aGV0aGVyIHRoZSBjYWxlbmRhciBvdmVybGF5IGlzIG9wZW4gb3Igbm90LiAqL1xyXG4gIHB1YmxpYyBpc0NhbGVuZGFyT3BlbiA9IGZhbHNlO1xyXG5cclxuICAvKiogUGxhY2Vob2xkZXIgZm9yIHRoZSB0ZXh0Ym94LiBVcGRhdGVkIHRvIHJlZmxlY3QgdGhlIHVzZXIncyBkYXRlIGRpc3BsYXkgcHJlZmVyZW5jZS4gKi9cclxuICBwdWJsaWMgcGxhY2Vob2xkZXI6IHN0cmluZyA9ICdNTS9ERC9ZWVlZJztcclxuXHJcbiAgLyoqIE92ZXJsYXkgc2Nyb2xsIHN0cmF0ZWd5IGZvciB0aGUgY2FsZW5kYXIgb3ZlcmxheS4gQ2xvc2VzIHRoZSBjYWxlbmRhciBvbiBzY3JvbGwuICovXHJcbiAgcHVibGljIG92ZXJsYXlTY3JvbGxTdHJhdGVneSA9IHRoaXMub3ZlcmxheVNlcnZpY2Uuc2Nyb2xsU3RyYXRlZ2llcy5jbG9zZSgpO1xyXG5cclxuICBwdWJsaWMgcHJpbWFyeUNhbGVuZGFyVmlldzogQ2FsZW5kYXIuVmlldyA9IHsgbW9kZTogJ2RheScsIGRhdGU6IG5ldyBEYXRlKCkgfTtcclxuICBwdWJsaWMgc2Vjb25kYXJ5Q2FsZW5kYXJWaWV3OiBDYWxlbmRhci5WaWV3ID0geyBtb2RlOiAnZGF5JywgZGF0ZTogbmV3IERhdGUoKSB9O1xyXG5cclxuICBwdWJsaWMgcHJpbWFyeUNhbGVuZGFyTWF4RGF0ZTogRGF0ZSA9IERhdGVUaW1lSGVscGVyLm1heERhdGVQaWNrZXJEYXRlO1xyXG4gIHB1YmxpYyBzZWNvbmRhcnlDYWxlbmRhck1pbkRhdGU6IERhdGUgPSBEYXRlVGltZUhlbHBlci5taW5EYXRlUGlja2VyRGF0ZTtcclxuXHJcbiAgcHVibGljIGRpc2FibGVTdGVwcGVyczogYm9vbGVhbiA9IGZhbHNlO1xyXG5cclxuICBwdWJsaWMgc2VsZWN0aW9uU3RyYXRlZ3khOiBEYXRlSW5wdXRTZWxlY3Rpb25TdHJhdGVneUJhc2U7XHJcblxyXG4gIC8qKiBcclxuICAgKiBEYXRlIHBhcnNpbmcgZm9ybWF0cyBmb3IgdXNlci1lbnRlcmVkIGRhdGVzLiBEZWZhdWx0cyB0byBtb250aC1maXJzdCBmb3JtYXRzLCBidXQgaXMgdXBkYXRlZCBpbiBvbkluaXRcclxuICAgKiB0byB1c2UgdGhlIHVzZXIncyBwcmVmZXJyZWQgZGF0ZSBmb3JtYXQuXHJcbiAgICovXHJcbiAgcHJpdmF0ZSBwYXJzZUZvcm1hdHM6IHN0cmluZ1tdID0gRGF0ZVRpbWVIZWxwZXIuZ2V0TW9tZW50UGFyc2VGb3JtYXRzKCk7XHJcblxyXG4gIEBWaWV3Q2hpbGQoJ2NhbGVuZGFyJykgY2FsZW5kYXI/OiBLZXlib2FyZE5hdkNvbnRhaW5lckRpcmVjdGl2ZTtcclxuICBAVmlld0NoaWxkKCdjb250cm9scycpIGNvbnRyb2xzPzogS2V5Ym9hcmROYXZDb250YWluZXJEaXJlY3RpdmU7XHJcblxyXG4gIC8qKiBSZWZlcmVuY2UgdG8gdGhlIG92ZXJsYXkgZGlyZWN0aXZlIChzZWUgdGVtcGxhdGUpLiBVc2VkIHRvIHVwZGF0ZSB0aGUgb3ZlcmxheSBwb3NpdGlvbiBvbiB2YWxpZGF0aW9uIGNoYW5nZXMuICovXHJcbiAgQFZpZXdDaGlsZCgnb3ZlcmxheScpIG92ZXJsYXk/OiBDZGtDb25uZWN0ZWRPdmVybGF5O1xyXG5cclxuICBjb25zdHJ1Y3RvcihcclxuICAgIHByb3RlY3RlZCB2YWxpZGF0aW9uTWVzc2FnZVNlcnZpY2U6IFZhbGlkYXRpb25NZXNzYWdlU2VydmljZSxcclxuICAgIHByb3RlY3RlZCBmb3JtR3JvdXBIZWxwZXI6IEZvcm1Hcm91cEhlbHBlcixcclxuICAgIHByaXZhdGUgdXNlclByZWZlcmVuY2VTZXJ2aWNlOiBVc2VyUHJlZmVyZW5jZVNlcnZpY2UsXHJcbiAgICBwcml2YXRlIGVsOiBFbGVtZW50UmVmLFxyXG4gICAgcHJpdmF0ZSBvdmVybGF5U2VydmljZTogT3ZlcmxheSxcclxuICAgIHByaXZhdGUgc2VsZWN0aW9uU3RyYXRlZ2llczogRGF0ZUlucHV0LlNlbGVjdGlvblN0cmF0ZWdpZXNcclxuICApIHtcclxuICAgIHN1cGVyKHZhbGlkYXRpb25NZXNzYWdlU2VydmljZSwgZm9ybUdyb3VwSGVscGVyKTtcclxuICB9XHJcblxyXG4gIG5nT25DaGFuZ2VzKGNoYW5nZXM6IFNpbXBsZUNoYW5nZXMpIHtcclxuICAgIGlmIChjaGFuZ2VzLnNlbGVjdGlvbk1vZGUgJiYgIWNoYW5nZXMuc2VsZWN0aW9uTW9kZS5pc0ZpcnN0Q2hhbmdlKCkpIHtcclxuICAgICAgdGhpcy5vblNlbGVjdGlvbk1vZGVDaGFuZ2UodGhpcy5zZWxlY3Rpb25Nb2RlKTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIG5nT25Jbml0KCkge1xyXG4gICAgLy8gU2V0dXBcclxuICAgIHN1cGVyLm5nT25Jbml0KCk7XHJcbiAgICB0aGlzLnNldERhdGVGb3JtYXRzKCk7XHJcbiAgICB0aGlzLnNldFNlbGVjdGlvbk1vZGUodGhpcy5zZWxlY3Rpb25Nb2RlKTtcclxuXHJcbiAgICAvLyBTdWJzY3JpcHRpb25zXHJcbiAgICB0aGlzLm9uRm9ybU1vZGVsU3RhdHVzQ2hhbmdlcygpO1xyXG4gICAgdGhpcy5vbkZvcm1Nb2RlbFZhbHVlQ2hhbmdlcygpO1xyXG4gICAgdGhpcy5vblRleHRib3hWYWx1ZUNoYW5nZXMoKTtcclxuXHJcbiAgICAvLyBTeW5jIHRoZSBpbml0aWFsIGRpc2FibGVkIHN0YXR1cyBhbmQgdmFsdWUgb2YgdGhlIHRleHRib3hcclxuICAgIHRoaXMuc3luY1RleHRib3hDb250cm9sRGlzYWJsZWRTdGF0dXModGhpcy5mb3JtTW9kZWwuc3RhdHVzKTtcclxuICAgIGNvbnN0IGluaXRpYWxEaXNwbGF5VmFsdWUgPSB0aGlzLnNlbGVjdGlvblN0cmF0ZWd5LmZvcm1hdFNlbGVjdGlvbih0aGlzLmZvcm1Nb2RlbC52YWx1ZSk7XHJcbiAgICB0aGlzLnRleHRib3hHcm91cC5wYXRjaFZhbHVlKGluaXRpYWxEaXNwbGF5VmFsdWUsIHsgZW1pdEV2ZW50OiBmYWxzZSB9KTtcclxuXHJcbiAgICAvLyBVcGRhdGUgdGhlIGNhbGVuZGFyIHNlbGVjdGlvbiBhbmQgdmlldyBiYXNlZCBvbiB0aGUgaW5pdGlhbCBmb3JtIG1vZGVsIHZhbHVlXHJcbiAgICB0aGlzLmNhbGVuZGFyU2VsZWN0aW9uID0gdGhpcy5mb3JtTW9kZWwudmFsdWU7XHJcbiAgICB0aGlzLnVwZGF0ZUNhbGVuZGFycyh0aGlzLmNhbGVuZGFyU2VsZWN0aW9uKTtcclxuICAgIHRoaXMudXBkYXRlU3RlcHBlcnModGhpcy5jYWxlbmRhclNlbGVjdGlvbik7XHJcbiAgfVxyXG5cclxuICAvKiogRm9jdXNlcyB0aGUgaW5wdXQgd2hlbmV2ZXIgdGhlIGNhbGVuZGFyIGlzIHNoaWZ0LXRhYmJlZCBvdXQgb2YuICovXHJcbiAgcHVibGljIG9uQ2FsZW5kYXJGb2N1c091dFN0YXJ0KCkge1xyXG4gICAgdGhpcy5mb2N1c0lucHV0KCk7XHJcbiAgfVxyXG5cclxuICAvKiogQ2xvc2VzIHRoZSBjYWxlbmRhciBhbmQgZm9jdXNlcyB0aGUgaW5wdXQgd2hlbmV2ZXIgdGhlIGNhbGVuZGFyIGlzIHRhYmJlZCBvdXQgb2YuICovXHJcbiAgcHVibGljIG9uQ2FsZW5kYXJGb2N1c091dEVuZCgpIHtcclxuICAgIHRoaXMuaXNDYWxlbmRhck9wZW4gPSBmYWxzZTtcclxuICAgIHRoaXMuZm9jdXNJbnB1dCgpO1xyXG4gIH1cclxuXHJcbiAgLyoqIENsb3NlcyB0aGUgY2FsZW5kYXIgaWYgdGhlIHVzZXIgY2xpY2tzIG91dHNpZGUgb2YgdGhlIGNhbGVuZGFyIGFuZCBkYXRlIGlucHV0LiAqL1xyXG4gIHB1YmxpYyBvbk92ZXJsYXlPdXRzaWRlQ2xpY2soZXZlbnQ6IE1vdXNlRXZlbnQpIHtcclxuICAgIC8vIERvIG5vdCBjbG9zZSB0aGUgY2FsZW5kYXIgaWYgdGhlIGNsaWNrIHdhcyB3aXRoaW4gdGhlIGRhdGUgaW5wdXQgb3IgYWN0aW9uIGJ1dHRvblxyXG4gICAgY29uc3QgcmVjdCA9IHRoaXMuZWwubmF0aXZlRWxlbWVudC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcclxuICAgIGNvbnN0IGNsaWNrZWRPdXRzaWRlQ29udHJvbCA9IGV2ZW50LmNsaWVudFkgPCByZWN0LnRvcCB8fFxyXG4gICAgICBldmVudC5jbGllbnRZID4gcmVjdC5ib3R0b20gfHxcclxuICAgICAgZXZlbnQuY2xpZW50WCA8IHJlY3QubGVmdCB8fFxyXG4gICAgICBldmVudC5jbGllbnRYID4gcmVjdC5yaWdodDtcclxuICAgIC8vIEl0J3MgcG9zc2libGUgdGhhdCB0aGUgdXNlciBoaXQgZW50ZXIgb24gdGhlIGFjdGlvbiBidXR0b24gaW5zdGVhZCBvZiBjbGlja2luZyB3aXRoIHRoZSBtb3VzZS5cclxuICAgIC8vIEluIHRoaXMgY2FzZSB0aGUgXCJjbGlja1wiIGV2ZW50IHdpbGwgYmUgb3V0c2lkZSBvZiB0aGUgY29tcG9uZW50IGJlY2F1c2UgdGhlIGNsaWVudHggYW5kIHkgYXJlIDAsXHJcbiAgICAvLyBidXQgd2UgZG9uJ3Qgd2FudCB0byBjbG9zZSBpbiB0aGlzIGNhc2UgYmVjYXVzZSBidXR0b24gY2xpY2tzIHRyaWdnZXIgY2FsZW5kYXIgb3Blbi9jbG9zZSBzZXBhcmF0ZWx5LlxyXG4gICAgY29uc3QgdGFyZ2V0SWQgPSAoPEhUTUxFbGVtZW50PmV2ZW50LnRhcmdldCkuaWQ7XHJcbiAgICBjb25zdCBpc0FjdGlvbkNsaWNrID0gdGFyZ2V0SWQgPT09IGAke3RoaXMuaWR9X2FjdGlvbmAgfHwgdGFyZ2V0SWQgPT09IGAke3RoaXMuaWR9X2NvbnRyb2wyX2FjdGlvbmA7XHJcblxyXG4gICAgaWYgKCFpc0FjdGlvbkNsaWNrICYmIGNsaWNrZWRPdXRzaWRlQ29udHJvbCkge1xyXG4gICAgICB0aGlzLmlzQ2FsZW5kYXJPcGVuID0gZmFsc2U7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICAvKiogSWYgdGhlIHVzZXIgdGFicyBvdXQgb2YgdGhlIGZvcm0gY29udHJvbCdzIGFjdGlvbiBidXR0b24gYW5kIHRoZSBjYWxlbmRhciBpcyBvcGVuLCBmb2N1cyB0aGUgZmlyc3QgaXRlbSBpbiB0aGUgY2FsZW5kYXIgb3ZlcmxheSAqL1xyXG4gIHB1YmxpYyBvbkNvbnRyb2xzRm9jdXNPdXRFbmQoKSB7XHJcbiAgICBpZiAodGhpcy5pc0NhbGVuZGFyT3Blbikge1xyXG4gICAgICB0aGlzLmNhbGVuZGFyPy5mb2N1cygpO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgcHVibGljIG9uVGV4dGJveEJsdXIoKSB7XHJcbiAgICAvLyBXZSB3YW50IHRvIHByZXZlbnQgdGhlIGZpeGVkIGRhdGUgcmFuZ2UgbW9kZXMgZnJvbSByZS1hdXRvY29tcGxldGluZyB0aGUgZmlyc3QgdGV4dGJveCB3aGVuIGl0IGlzIGV4cGxpY2l0bHkgY2xlYXJlZC5cclxuICAgIGNvbnN0IHByZXZpb3VzVmFsdWUgPSBEYXRlSW5wdXQuaXNTZWxlY3Rpb25SYW5nZSh0aGlzLmZvcm1Nb2RlbC52YWx1ZSkgPyB0aGlzLmZvcm1Nb2RlbC52YWx1ZS5zdGFydCA6IHRoaXMuZm9ybU1vZGVsLnZhbHVlO1xyXG4gICAgY29uc3QgY3VycmVudFZhbHVlID0gdGhpcy50ZXh0Ym94R3JvdXAudmFsdWUudGV4dGJveDtcclxuICAgIGNvbnN0IGNsZWFyZWQgPSAhIXByZXZpb3VzVmFsdWUgJiYgIWN1cnJlbnRWYWx1ZTtcclxuICAgIGNvbnN0IG9wdGlvbnM6IERhdGVJbnB1dC5QYXJzaW5nT3B0aW9ucyA9IHsgcHJldmVudEF1dG9Db21wbGV0ZTogY2xlYXJlZCB9O1xyXG5cclxuICAgIC8vIFBhcnNlIHRoZSB0ZXh0Ym94IHZhbHVlcyBpbnRvIGEgc2VsZWN0aW9uIGFuZCB1cGRhdGUgdGhlIGZvcm0gbW9kZWxcclxuICAgIGNvbnN0IHBhcnNlZFNlbGVjdGlvbiA9IHRoaXMuc2VsZWN0aW9uU3RyYXRlZ3kucGFyc2VUZXh0Ym94VmFsdWVzKHRoaXMudGV4dGJveEdyb3VwLnZhbHVlLCB0aGlzLnBhcnNlRm9ybWF0cywgb3B0aW9ucyk7XHJcbiAgICB0aGlzLnVwZGF0ZUZvcm1Nb2RlbChwYXJzZWRTZWxlY3Rpb24pO1xyXG4gIH1cclxuXHJcbiAgcHVibGljIG9uVGV4dGJveDJCbHVyKCkge1xyXG4gICAgLy8gV2Ugd2FudCB0byBwcmV2ZW50IHRoZSBmaXhlZCBkYXRlIHJhbmdlIG1vZGVzIGZyb20gcmUtYXV0b2NvbXBsZXRpbmcgdGhlIHNlY29uZCB0ZXh0Ym94IHdoZW4gaXQgaXMgZXhwbGljaXRseSBjbGVhcmVkLlxyXG4gICAgY29uc3QgcHJldmlvdXNWYWx1ZSA9IERhdGVJbnB1dC5pc1NlbGVjdGlvblJhbmdlKHRoaXMuZm9ybU1vZGVsLnZhbHVlKSA/IHRoaXMuZm9ybU1vZGVsLnZhbHVlLmVuZCA6IG51bGw7XHJcbiAgICBjb25zdCBjdXJyZW50VmFsdWUgPSB0aGlzLnRleHRib3hHcm91cC52YWx1ZS50ZXh0Ym94MjtcclxuICAgIGNvbnN0IGNsZWFyZWQgPSAhIXByZXZpb3VzVmFsdWUgJiYgIWN1cnJlbnRWYWx1ZTtcclxuICAgIGNvbnN0IG9wdGlvbnM6IERhdGVJbnB1dC5QYXJzaW5nT3B0aW9ucyA9IHsgcGFyc2VGcm9tRW5kOiB0cnVlLCBwcmV2ZW50QXV0b0NvbXBsZXRlOiBjbGVhcmVkIH07XHJcblxyXG4gICAgLy8gUGFyc2UgdGhlIHRleHRib3ggdmFsdWVzIGludG8gYSBzZWxlY3Rpb24gYW5kIHVwZGF0ZSB0aGUgZm9ybSBtb2RlbCxcclxuICAgIC8vIEZvciB0aGUgc2Vjb25kIGJveCB3ZSdyZSBrZXlpbmcgdGhlIHBhcnNlIGZyb20gdGhlIGVuZCBkYXRlIGluIHRoZSBzZWxlY3Rpb24uXHJcbiAgICBjb25zdCBwYXJzZWRTZWxlY3Rpb24gPSB0aGlzLnNlbGVjdGlvblN0cmF0ZWd5LnBhcnNlVGV4dGJveFZhbHVlcyh0aGlzLnRleHRib3hHcm91cC52YWx1ZSwgdGhpcy5wYXJzZUZvcm1hdHMsIG9wdGlvbnMpO1xyXG4gICAgdGhpcy51cGRhdGVGb3JtTW9kZWwocGFyc2VkU2VsZWN0aW9uKTtcclxuICB9XHJcblxyXG4gIHB1YmxpYyBvblNlbGVjdGlvbk1vZGVDaGFuZ2UobW9kZTogRGF0ZUlucHV0LlNlbGVjdGlvbk1vZGUpIHtcclxuICAgIHRoaXMuc2V0U2VsZWN0aW9uTW9kZShtb2RlKTtcclxuICAgIGNvbnN0IG5ld1NlbGVjdGlvbiA9IHRoaXMuc2VsZWN0aW9uU3RyYXRlZ3kuZ2V0TmV3U2VsZWN0aW9uRnJvbUV4aXN0aW5nKHRoaXMuY2FsZW5kYXJTZWxlY3Rpb24pO1xyXG4gICAgdGhpcy51cGRhdGVGb3JtTW9kZWwobmV3U2VsZWN0aW9uKTtcclxuXHJcbiAgICAvLyBPbiBzZWxlY3Rpb24gbW9kZSBjaGFuZ2UsIHdlIHdhbnQgdG8gZm9yY2UgdGhlIGNhbGVuZGFycyB0byBzaG93IHRoZSByaWdodCB2aWV3IG1vZGUgZm9yIHRoZSBuZXcgc2VsZWN0aW9uLlxyXG4gICAgLy8gVGhpcyBwcmV2ZW50cyB0aGUgdXNlciBmcm9tIHNlZWluZyBhIHZpZXcgbW9kZSB0aGF0IGRvZXNuJ3QgbWFrZSBzZW5zZSBmb3IgdGhlIG5ldyBzZWxlY3Rpb24sXHJcbiAgICAvLyBMaWtlIHdoZW4gc3dpY2hpbmcgZnJvbSB5ZWFyIG1vZGUgdG8gbGFzdCA3IGRheXMgbW9kZS5cclxuICAgIHRoaXMucHJpbWFyeUNhbGVuZGFyVmlldyA9IHsgbW9kZTogdGhpcy5zZWxlY3Rpb25TdHJhdGVneS5zZWxlY3Rpb25WaWV3TW9kZSwgZGF0ZTogdGhpcy5wcmltYXJ5Q2FsZW5kYXJWaWV3LmRhdGUgfTtcclxuICAgIHRoaXMuc2Vjb25kYXJ5Q2FsZW5kYXJWaWV3ID0geyBtb2RlOiB0aGlzLnNlbGVjdGlvblN0cmF0ZWd5LnNlbGVjdGlvblZpZXdNb2RlLCBkYXRlOiB0aGlzLnNlY29uZGFyeUNhbGVuZGFyVmlldy5kYXRlIH07XHJcbiAgICB0aGlzLnVwZGF0ZUNhbGVuZGFyTWluTWF4RGF0ZXMoKTtcclxuICB9XHJcblxyXG4gIHB1YmxpYyBvbkNhbGVuZGFyRGF0ZVNlbGVjdGVkKGRhdGU6IERhdGUpIHtcclxuICAgIGNvbnN0IG5ld1NlbGVjdGlvbiA9IHRoaXMuc2VsZWN0aW9uU3RyYXRlZ3kuZ2V0U2VsZWN0aW9uRnJvbURhdGUoZGF0ZSwgdGhpcy5jYWxlbmRhclNlbGVjdGlvbik7XHJcbiAgICBjb25zdCBkaXNwbGF5VmFsdWUgPSB0aGlzLnNlbGVjdGlvblN0cmF0ZWd5LmZvcm1hdFNlbGVjdGlvbihuZXdTZWxlY3Rpb24pO1xyXG4gICAgLy8gRG9uJ3QgZW1pdCBldmVudHMgd2hlbiBwYXRjaGluZyB2YWx1ZXMgaGVyZS4gV2UgZG9uJ3Qgd2FudCB0byB0cmlnZ2VyIHRoZSBjYWxlbmRhciB1cGRhdGVzIHNpbmNlIHRoZSBjYWxlbmRhciBpcyBhbHJlYWR5XHJcbiAgICAvLyBzaG93aW5nIHRoZSBzZWxlY3RlZCBkYXRlLiBXZSBhbHNvIGRvbid0IHdhbnQgdG8gdHJpZ2dlciB0aGUgdGV4dGJveCBwYXJzaW5nIGxvZ2ljIHNpbmNlIHRoZSBkYXRlIHdhcyBzZWxlY3RlZCBmcm9tIHRoZSBjYWxlbmRhci5cclxuICAgIHRoaXMudGV4dGJveEdyb3VwLnBhdGNoVmFsdWUoZGlzcGxheVZhbHVlLCB7IGVtaXRFdmVudDogZmFsc2UgfSk7XHJcbiAgICB0aGlzLmZvcm1Nb2RlbC5wYXRjaFZhbHVlKG5ld1NlbGVjdGlvbiwgeyBlbWl0RXZlbnQ6IGZhbHNlIH0pO1xyXG4gICAgdGhpcy5jYWxlbmRhclNlbGVjdGlvbiA9IG5ld1NlbGVjdGlvbjtcclxuICAgIHRoaXMudXBkYXRlU3RlcHBlcnMobmV3U2VsZWN0aW9uKTtcclxuXHJcbiAgICAvLyBDbG9zZSB0aGUgY2FsZW5kYXIgaWYgdGhlIHNlbGVjdGlvbiBtb2RlIGlzIG5vdCBhIHJhbmdlIG1vZGUgd2hlcmUgZWl0aGVyIHRoZSBzdGFydCBvciB0aGUgZW5kIGRhdGUgY2FuIGJlIGNoYW5nZWQuXHJcbiAgICBpZiAoIXRoaXMuc2VsZWN0aW9uU3RyYXRlZ3kuc2hvd1NlY29uZGFyeVRleHRib3gpIHtcclxuICAgICAgdGhpcy5pc0NhbGVuZGFyT3BlbiA9IGZhbHNlO1xyXG4gICAgICB0aGlzLmZvY3VzSW5wdXQoKTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIHB1YmxpYyBvblByaW1hcnlDYWxlbmRhclZpZXdDaGFuZ2UodmlldzogQ2FsZW5kYXIuVmlldykge1xyXG4gICAgdGhpcy5wcmltYXJ5Q2FsZW5kYXJWaWV3ID0gdmlldztcclxuICAgIHRoaXMudXBkYXRlQ2FsZW5kYXJNaW5NYXhEYXRlcygpO1xyXG4gIH1cclxuXHJcbiAgcHVibGljIG9uU2Vjb25kYXJ5Q2FsZW5kYXJWaWV3Q2hhbmdlKHZpZXc6IENhbGVuZGFyLlZpZXcpIHtcclxuICAgIHRoaXMuc2Vjb25kYXJ5Q2FsZW5kYXJWaWV3ID0gdmlldztcclxuICAgIHRoaXMudXBkYXRlQ2FsZW5kYXJNaW5NYXhEYXRlcygpO1xyXG4gIH1cclxuXHJcbiAgLyoqIFNoaWZ0cyB0aGUgY2FsZW5kYXIgdmlld3MgdG8gZGlzcGxheSB0b2RheS4gRG9lcyBub3QgdXBkYXRlIHRoZSBjYWxlbmRhciBzZWxlY3Rpb24uICovXHJcbiAgcHVibGljIGdvVG9Ub2RheSgpIHtcclxuICAgIC8vIElmIGJvdGggY2FsZW5kYXJzIGFyZSB2aXNpYmxlLCBzaG93IHRvZGF5IGluIHRoZSBzZWNvbmRhcnkgY2FsZW5kYXIgYW5kIHRoZSBtb250aCBiZWZvcmUgaW4gdGhlIHByaW1hcnkgY2FsZW5kYXIuXHJcbiAgICBpZiAodGhpcy5zZWxlY3Rpb25TdHJhdGVneS5zaG93U2Vjb25kYXJ5Q2FsZW5kYXIpIHtcclxuICAgICAgdGhpcy5wcmltYXJ5Q2FsZW5kYXJWaWV3ID0geyBtb2RlOiAnZGF5JywgZGF0ZTogbW9tZW50KCkuc3VidHJhY3QoMSwgJ21vbnRoJykudG9EYXRlKCkgfTtcclxuICAgICAgdGhpcy5zZWNvbmRhcnlDYWxlbmRhclZpZXcgPSB7IG1vZGU6ICdkYXknLCBkYXRlOiBuZXcgRGF0ZSgpIH07XHJcbiAgICAgIC8vIElmIHdlJ3JlIGluIGEgc2luZ2xlIGRhdGUgbW9kZSwgc2hvdyB0b2RheSBpbiB0aGUgcHJpbWFyeSBjYWxlbmRhci5cclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIHRoaXMucHJpbWFyeUNhbGVuZGFyVmlldyA9IHsgbW9kZTogJ2RheScsIGRhdGU6IG5ldyBEYXRlKCkgfTtcclxuICAgIH1cclxuICAgIHRoaXMudXBkYXRlQ2FsZW5kYXJNaW5NYXhEYXRlcygpO1xyXG4gIH1cclxuXHJcbiAgcHVibGljIGdvVG9RdWlja1NlbGVjdERhdGUoKSB7XHJcbiAgICBpZiAodGhpcy5xdWlja1NlbGVjdERhdGUpIHtcclxuICAgICAgY29uc3QgbmV3U2VsZWN0aW9uID0gdGhpcy5zZWxlY3Rpb25TdHJhdGVneS5nZXRTZWxlY3Rpb25Gb3JRdWlja1NlbGVjdERhdGUodGhpcy5xdWlja1NlbGVjdERhdGUsIHRoaXMuY2FsZW5kYXJTZWxlY3Rpb24pO1xyXG4gICAgICB0aGlzLnVwZGF0ZUZvcm1Nb2RlbChuZXdTZWxlY3Rpb24pO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgcHVibGljIG5leHRTZWxlY3Rpb24oKSB7XHJcbiAgICBjb25zdCBuZXdTZWxlY3Rpb24gPSB0aGlzLnNlbGVjdGlvblN0cmF0ZWd5LmdldE5leHRTZWxlY3Rpb24odGhpcy5jYWxlbmRhclNlbGVjdGlvbik7XHJcbiAgICB0aGlzLnVwZGF0ZUZvcm1Nb2RlbChuZXdTZWxlY3Rpb24pO1xyXG4gIH1cclxuXHJcbiAgcHVibGljIHByZXZpb3VzU2VsZWN0aW9uKCkge1xyXG4gICAgY29uc3QgbmV3U2VsZWN0aW9uID0gdGhpcy5zZWxlY3Rpb25TdHJhdGVneS5nZXRQcmV2aW91c1NlbGVjdGlvbih0aGlzLmNhbGVuZGFyU2VsZWN0aW9uKTtcclxuICAgIHRoaXMudXBkYXRlRm9ybU1vZGVsKG5ld1NlbGVjdGlvbik7XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIHVwZGF0ZUZvcm1Nb2RlbCh2YWx1ZTogRGF0ZUlucHV0LlNlbGVjdGlvbiB8IG51bGwpIHtcclxuICAgIHRoaXMuZm9ybU1vZGVsLnBhdGNoVmFsdWUodmFsdWUpO1xyXG5cclxuICAgIC8vIFZhbGlkYXRlIHRoZSB0ZXh0Ym94ZXMgYW5kIHN5bmMgdGhlIGZvcm0gZXJyb3JzXHJcbiAgICAvLyBXZSBkbyB0aGlzIGFmdGVyIHBhdGNoaW5nIHRoZSBmb3JtIG1vZGVsIGJlY2F1c2UgdGhlIGZvcm0gbW9kZWwgcGF0Y2ggd2lsbCB0cmlnZ2VyXHJcbiAgICAvLyB0aGUgZGF0ZSBmb3JtYXR0aW5nIGxvZ2ljIGFuZCBvdmVyd3JpdGUgYW55IGVycm9ycyBvbiB0aGUgY29udHJvbHMgZnJvbSBiZWZvcmUuXHJcbiAgICB0aGlzLnZhbGlkYXRlVGV4dGJveGVzKCk7XHJcbiAgICB0aGlzLnN5bmNGb3JtRXJyb3JzKCk7XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIG9uRm9ybU1vZGVsU3RhdHVzQ2hhbmdlcygpIHtcclxuICAgIC8vIEtlZXAgdGhlIHRleHRib3hDb250cm9sIGRpc2FibGVkIHN0YXR1cyBpbiBzeW5jIHdpdGggdGhlIGZvcm1Nb2RlbFxyXG4gICAgdGhpcy5mb3JtTW9kZWwuc3RhdHVzQ2hhbmdlcy5waXBlKFxyXG4gICAgICBkaXN0aW5jdFVudGlsQ2hhbmdlZCgpLFxyXG4gICAgICB0YWtlVW50aWwodGhpcy5jb21wb25lbnREZXN0cm95ZWQpXHJcbiAgICApLnN1YnNjcmliZShzdGF0dXMgPT4ge1xyXG4gICAgICB0aGlzLnN5bmNUZXh0Ym94Q29udHJvbERpc2FibGVkU3RhdHVzKHN0YXR1cyk7XHJcblxyXG4gICAgICBpZiAodGhpcy5pc0NhbGVuZGFyT3Blbikge1xyXG4gICAgICAgIC8vIEFzIHZhbGlkYXRpb24gbWVzc2FnZXMgYXBwZWFyL2Rpc2FwcGVhciwgdGhlIGRhdGUgaW5wdXQgbWF5IGhhdmUgc2hpZnRlZCB1cCBvciBkb3duIG9uIHRoZSBwYWdlLlxyXG4gICAgICAgIC8vIFVwZGF0ZSB0aGUgb3ZlcmxheSBwb3NpdGlvbiB0byBlbnN1cmUgaXQncyBzdGlsbCBhbGlnbmVkIHdpdGggdGhlIHRleHRib3ggYW5kIG5vdCBibG9ja2luZyBpdC5cclxuICAgICAgICAvLyBTZXR0aW1lb3V0IGlzIG5lZWRlZCB0byBlbnN1cmUgdGhlIG92ZXJsYXkgaXMgYmVpbmcgdXBkYXRlZCBhZnRlciB0aGUgbWVzc2FnZSBpcyByZW5kZXJlZC5cclxuICAgICAgICBzZXRUaW1lb3V0KCgpID0+IHtcclxuICAgICAgICAgIHRoaXMub3ZlcmxheT8ub3ZlcmxheVJlZj8udXBkYXRlUG9zaXRpb24oKTtcclxuICAgICAgICB9KTtcclxuICAgICAgfVxyXG4gICAgfSk7XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIG9uRm9ybU1vZGVsVmFsdWVDaGFuZ2VzKCkge1xyXG4gICAgLy8gVXBkYXRlIHRoZSBjYWxlbmRhciBzZWxlY3Rpb24gdGV4dGJveCB2YWx1ZSB3aXRoIGEgZm9ybWF0dGVkIGRhdGUgd2hlbiB0aGUgZm9ybSBtb2RlbCBjaGFuZ2VzLlxyXG4gICAgLy8gVGhpcyBpcyB0cmlnZ2VyZWQgYnkgdGhlIHVzZXIgc2VsZWN0aW5nIGEgZGF0ZSBmcm9tIHRoZSBjYWxlbmRhciBvciB3aGVuIHRoZSB0ZXh0Ym94IGlzIGJsdXJyZWQuXHJcbiAgICB0aGlzLmZvcm1Nb2RlbC52YWx1ZUNoYW5nZXMucGlwZShcclxuICAgICAgdGFrZVVudGlsKHRoaXMuY29tcG9uZW50RGVzdHJveWVkKVxyXG4gICAgKS5zdWJzY3JpYmUodmFsdWUgPT4ge1xyXG4gICAgICBjb25zdCBkaXNwbGF5VmFsdWUgPSB0aGlzLnNlbGVjdGlvblN0cmF0ZWd5LmZvcm1hdFNlbGVjdGlvbih2YWx1ZSk7XHJcbiAgICAgIC8vIERvbid0IGVtaXQgYW4gZXZlbnQgd2hlbiBzZXR0aW5nIHRoZSB0ZXh0Ym94IHZhbHVlIHRvIGF2b2lkIGNpcmN1bGFyIHVwZGF0ZXMgYmV0d2VlbiB0aGUgdGV4dGJveCBhbmQgZm9ybSBtb2RlbC5cclxuICAgICAgdGhpcy50ZXh0Ym94R3JvdXAucGF0Y2hWYWx1ZShkaXNwbGF5VmFsdWUsIHsgZW1pdEV2ZW50OiBmYWxzZSB9KTtcclxuICAgICAgdGhpcy51cGRhdGVDYWxlbmRhcnModmFsdWUpO1xyXG4gICAgICB0aGlzLnVwZGF0ZVN0ZXBwZXJzKHZhbHVlKTtcclxuICAgIH0pO1xyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBvblRleHRib3hWYWx1ZUNoYW5nZXMoKSB7XHJcbiAgICAvLyBVcGRhdGUgdGhlIGNhbGVuZGFyIHNlbGVjdGlvbiB3aGVuIHRoZSB0ZXh0Ym94IHZhbHVlIGNoYW5nZXMgdG8gdXBkYXRlIHRoZSBjYWxlbmRhci5cclxuICAgIC8vIFdlIGRvbid0IHBhdGNoIHRoZSBmb3JtTW9kZWwgaGVyZSBiZWNhdXNlIHdlIGRvbid0IHdhbnQgdG8gdHJpZ2dlciB0aGVcclxuICAgIC8vIGRhdGUgZm9ybWF0dGluZyBsb2dpYyBhbmQgb3ZlcndyaXRlIHRoZSB1c2VyJ3MgaW5wdXQuXHJcbiAgICAvLyBXZSdsbCBkbyB0aGF0IHdoZW4gdGhlIHVzZXIgYmx1cnMgb3V0IG9mIHRoZSB0ZXh0Ym94LiBTZWUgb25UZXh0Ym94Qmx1cigpXHJcbiAgICB0aGlzLnRleHRib3hHcm91cC5jb250cm9scy50ZXh0Ym94LnZhbHVlQ2hhbmdlcy5waXBlKFxyXG4gICAgICBkZWJvdW5jZVRpbWUoMzAwKSxcclxuICAgICAgZGlzdGluY3RVbnRpbENoYW5nZWQoKSxcclxuICAgICAgdGFrZVVudGlsKHRoaXMuY29tcG9uZW50RGVzdHJveWVkKVxyXG4gICAgKS5zdWJzY3JpYmUoKCkgPT4ge1xyXG4gICAgICBjb25zdCBvcHRpb25zOiBEYXRlSW5wdXQuUGFyc2luZ09wdGlvbnMgPSB7IHNoaWZ0VG9DdXJyZW50WWVhcklmQmVsb3c6IHRoaXMubWluRGF0ZSB9O1xyXG4gICAgICBjb25zdCBuZXdTZWxlY3Rpb24gPSB0aGlzLnNlbGVjdGlvblN0cmF0ZWd5LnBhcnNlVGV4dGJveFZhbHVlcyh0aGlzLnRleHRib3hHcm91cC52YWx1ZSwgdGhpcy5wYXJzZUZvcm1hdHMsIG9wdGlvbnMpO1xyXG5cclxuICAgICAgLy8gQ2FsZW5kYXIgc2VsZWN0aW9uIHdpbGwgYmUgbnVsbCBpZiB0aGUgZGF0ZXMgYXJlIGludmFsaWQuIERvbid0IHVwZGF0ZSB0aGUgY2FsZW5kYXJzIGluIHRoaXMgY2FzZS5cclxuICAgICAgaWYgKG5ld1NlbGVjdGlvbikge1xyXG4gICAgICAgIHRoaXMuY2FsZW5kYXJTZWxlY3Rpb24gPSBuZXdTZWxlY3Rpb247XHJcbiAgICAgICAgdGhpcy51cGRhdGVQcmltYXJ5Q2FsZW5kYXIodGhpcy5jYWxlbmRhclNlbGVjdGlvbiwgdGhpcy5zZWxlY3Rpb25TdHJhdGVneS5zaG93U2Vjb25kYXJ5Q2FsZW5kYXIpO1xyXG4gICAgICAgIHRoaXMudXBkYXRlQ2FsZW5kYXJNaW5NYXhEYXRlcygpO1xyXG4gICAgICB9XHJcbiAgICB9KTtcclxuXHJcbiAgICAvLyBUaGUgc2Vjb25kIHRleHRib3ggaXMgb25seSB1c2VkIGluIGxhc3Q3RGF5cywgbGFzdDI4RGF5cywgYW5kIHJhbmdlIG1vZGVzLlxyXG4gICAgdGhpcy50ZXh0Ym94R3JvdXAuY29udHJvbHMudGV4dGJveDIudmFsdWVDaGFuZ2VzLnBpcGUoXHJcbiAgICAgIGRlYm91bmNlVGltZSgzMDApLFxyXG4gICAgICBkaXN0aW5jdFVudGlsQ2hhbmdlZCgpLFxyXG4gICAgICB0YWtlVW50aWwodGhpcy5jb21wb25lbnREZXN0cm95ZWQpXHJcbiAgICApLnN1YnNjcmliZSgoKSA9PiB7XHJcbiAgICAgIGNvbnN0IG9wdGlvbnM6IERhdGVJbnB1dC5QYXJzaW5nT3B0aW9ucyA9IHsgc2hpZnRUb0N1cnJlbnRZZWFySWZCZWxvdzogdGhpcy5taW5EYXRlLCBwYXJzZUZyb21FbmQ6IHRydWUgfTtcclxuICAgICAgY29uc3QgbmV3U2VsZWN0aW9uID0gdGhpcy5zZWxlY3Rpb25TdHJhdGVneS5wYXJzZVRleHRib3hWYWx1ZXModGhpcy50ZXh0Ym94R3JvdXAudmFsdWUsIHRoaXMucGFyc2VGb3JtYXRzLCBvcHRpb25zKTtcclxuXHJcbiAgICAgIC8vIENhbGVuZGFyIHNlbGVjdGlvbiB3aWxsIGJlIG51bGwgaWYgdGhlIGRhdGVzIGFyZSBpbnZhbGlkLiBEb24ndCB1cGRhdGUgdGhlIGNhbGVuZGFycyBpbiB0aGlzIGNhc2UuXHJcbiAgICAgIGlmIChuZXdTZWxlY3Rpb24pIHtcclxuICAgICAgICB0aGlzLmNhbGVuZGFyU2VsZWN0aW9uID0gbmV3U2VsZWN0aW9uO1xyXG4gICAgICAgIC8vIFRoZSBzZWNvbmRhcnkgY2FsZW5kYXIgaXMgb25seSBzaG93biBpbiByYW5nZSBtb2RlLiBVcGRhdGUgdGhlIHByaW1hcnkgY2FsZW5kYXIgaWYgd2UncmUgbm90IGluIHJhbmdlIG1vZGUuXHJcbiAgICAgICAgaWYgKHRoaXMuc2VsZWN0aW9uU3RyYXRlZ3kuc2hvd1NlY29uZGFyeUNhbGVuZGFyKSB7XHJcbiAgICAgICAgICB0aGlzLnVwZGF0ZVNlY29uZGFyeUNhbGVuZGFyKHRoaXMuY2FsZW5kYXJTZWxlY3Rpb24sIHRydWUpO1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICB0aGlzLnVwZGF0ZVByaW1hcnlDYWxlbmRhcih0aGlzLmNhbGVuZGFyU2VsZWN0aW9uKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgdGhpcy51cGRhdGVDYWxlbmRhck1pbk1heERhdGVzKCk7XHJcbiAgICAgIH1cclxuICAgIH0pO1xyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBzeW5jVGV4dGJveENvbnRyb2xEaXNhYmxlZFN0YXR1cyhzdGF0dXM6IEZvcm1Db250cm9sU3RhdHVzKSB7XHJcbiAgICAvLyBUaGUgdGV4dGJveCBzaG91bGQgb25seSBiZSBkaXNhYmxlZCBpZiB0aGUgZm9ybSBtb2RlbCBpcyBkaXNhYmxlZC5cclxuICAgIC8vIEFsbCBvdGhlciBzdGF0dXNlcyBhcmUgY29uc2lkZXJlZCBlbmFibGVkLlxyXG4gICAgaWYgKHN0YXR1cyA9PT0gJ0RJU0FCTEVEJyAmJiB0aGlzLnRleHRib3hHcm91cC5lbmFibGVkKSB7XHJcbiAgICAgIHRoaXMudGV4dGJveEdyb3VwLmRpc2FibGUoKTtcclxuICAgIH0gZWxzZSBpZiAoc3RhdHVzICE9PSAnRElTQUJMRUQnICYmIHRoaXMudGV4dGJveEdyb3VwLmRpc2FibGVkKSB7XHJcbiAgICAgIHRoaXMudGV4dGJveEdyb3VwLmVuYWJsZSgpO1xyXG4gICAgfVxyXG4gIH07XHJcblxyXG4gIHByaXZhdGUgc3luY0Zvcm1FcnJvcnMoKSB7XHJcbiAgICAvLyBTdGFydCB3aXRoIHRoZSBleGlzdGluZyBmb3JtIG1vZGVsIGVycm9yc1xyXG4gICAgbGV0IGVycm9ycyA9IHRoaXMuZm9ybU1vZGVsLmVycm9ycztcclxuXHJcbiAgICAvLyBBZGQgdGhlIGVycm9ycyBmcm9tIHRoZSB0ZXh0Ym94ZXMgaWYgdGhleSBleGlzdFxyXG4gICAgaWYgKHRoaXMudGV4dGJveEdyb3VwLmNvbnRyb2xzLnRleHRib3guZXJyb3JzKSB7XHJcbiAgICAgIGVycm9ycyA9IHsgLi4uZXJyb3JzLCAuLi50aGlzLnRleHRib3hHcm91cC5jb250cm9scy50ZXh0Ym94LmVycm9ycyB9O1xyXG4gICAgfVxyXG4gICAgaWYgKHRoaXMudGV4dGJveEdyb3VwLmNvbnRyb2xzLnRleHRib3gyLmVycm9ycykge1xyXG4gICAgICBlcnJvcnMgPSB7IC4uLmVycm9ycywgLi4udGhpcy50ZXh0Ym94R3JvdXAuY29udHJvbHMudGV4dGJveDIuZXJyb3JzIH07XHJcbiAgICB9XHJcblxyXG4gICAgLy8gVXBkYXRlIHRoZSBmb3JtIG1vZGVsJ3MgZXJyb3JzIHdpdGggdGhlIGNvbWJpbmVkIGVycm9yc1xyXG4gICAgdGhpcy5mb3JtTW9kZWwuc2V0RXJyb3JzKGVycm9ycyk7XHJcblxyXG4gICAgLy8gVXBkYXRlIHRoZSBmb3JtIG1vZGVsJ3MgdG91Y2hlZCBhbmQgZGlydHkgc3RhdHVzIGJhc2VkIG9uIHRoZSB0ZXh0Ym94J3Mgc3RhdHVzLlxyXG4gICAgLy8gU2luY2UgdGhlIHVzZXIgaW50ZXJhY3RzIHdpdGggYSBjb250cm9sIHRoYXQgaXMgaW50ZXJuYWwgdG8gdGhpcyBjb21wb25lbnQsIHRoZVxyXG4gICAgLy8gZm9ybSBtb2RlbCdzIHN0YXR1cyB3b24ndCBiZSB1cGRhdGVkIGF1dG9tYXRpY2FsbHkuXHJcbiAgICBpZiAodGhpcy50ZXh0Ym94R3JvdXAudG91Y2hlZCAmJiAhdGhpcy5mb3JtTW9kZWwudG91Y2hlZCkge1xyXG4gICAgICB0aGlzLmZvcm1Nb2RlbC5tYXJrQXNUb3VjaGVkKCk7XHJcbiAgICB9XHJcbiAgICBpZiAodGhpcy50ZXh0Ym94R3JvdXAuZGlydHkgJiYgIXRoaXMuZm9ybU1vZGVsLmRpcnR5KSB7XHJcbiAgICAgIHRoaXMuZm9ybU1vZGVsLm1hcmtBc0RpcnR5KCk7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICAvKiogXHJcbiAgICogVXBkYXRlcyB0aGUgZGF0ZSBwYXJzaW5nIGZvcm1hdHMgYW5kIHBsYWNlaG9sZGVyIGJhc2VkIG9uIHRoZSB1c2VyJ3MgZGlzcGxheSBwcmVmZXJlbmNlLlxyXG4gICAqIE5PVEU6IFRoaXMgaXMgYXN5bmMgYmVjYXVzZSB3ZSdyZSByZXRyaWV2aW5nIHRoZSB1c2VyJ3MgcHJlZmVyZW5jZXMuIFdlJ3JlIG5vdCBhd2FpdGluZyB0aGUgcmVzdWx0XHJcbiAgICogYmVjYXVzZSB0aGUgb25seSBsb2dpYyB0aGF0IGRlcGVuZHMgb24gdGhpcyBpcyB0aGUgdGV4dCBib3ggZGF0ZSBwYXJzaW5nIGxvZ2ljIGFuZCBwbGFjZWhvbGRlci5cclxuICAgKiBPdXIgZm9ybXMgc2hvdWxkIGFsd2F5cyBiZSBiZWhpbmQgYSBwZW5kaW5nIG92ZXJsYXksIHNvIHRoZSB1c2VyIHdvbid0IGJlIGFibGUgdG8gaW50ZXJhY3Qgd2l0aCB0aGVcclxuICAgKiBmb3JtIHVudGlsIHRoZSB1c2VyIGlzIGxvYWRlZCBhbnl3YXkuXHJcbiAgICovXHJcbiAgcHJpdmF0ZSBhc3luYyBzZXREYXRlRm9ybWF0cygpIHtcclxuICAgIGNvbnN0IHsgcHJlZmVyZW5jZSB9ID0gYXdhaXQgbGFzdFZhbHVlRnJvbSh0aGlzLnVzZXJQcmVmZXJlbmNlU2VydmljZS5nZXRQcmVmZXJlbmNlcygpKTtcclxuICAgIGNvbnN0IGRhdGVGb3JtYXQgPSBwcmVmZXJlbmNlPy5kYXRlRm9ybWF0O1xyXG4gICAgdGhpcy5wbGFjZWhvbGRlciA9IGRhdGVGb3JtYXQgPz8gdGhpcy5wbGFjZWhvbGRlcjtcclxuICAgIHRoaXMucGFyc2VGb3JtYXRzID0gRGF0ZVRpbWVIZWxwZXIuZ2V0TW9tZW50UGFyc2VGb3JtYXRzKGRhdGVGb3JtYXQpO1xyXG4gIH1cclxuXHJcbiAgLyoqIEZvY3VzZXMgdGhlIGRhdGUgaW5wdXQuICovXHJcbiAgcHJpdmF0ZSBmb2N1c0lucHV0KCkge1xyXG4gICAgdGhpcy5jb250cm9scz8uZm9jdXMoKTtcclxuICB9XHJcblxyXG4gIHByaXZhdGUgc2V0U2VsZWN0aW9uTW9kZShtb2RlOiBEYXRlSW5wdXQuU2VsZWN0aW9uTW9kZSkge1xyXG4gICAgdGhpcy5zZWxlY3Rpb25Nb2RlID0gbW9kZTtcclxuICAgIHRoaXMuc2VsZWN0aW9uU3RyYXRlZ3kgPSB0aGlzLnNlbGVjdGlvblN0cmF0ZWdpZXNbbW9kZV07XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBTZXRzIHRoZSBtYXggZGF0ZSBmb3IgdGhlIHByaW1hcnkgY2FsZW5kYXIgYW5kIHRoZSBtaW4gZGF0ZSBmb3IgdGhlIHNlY29uZGFyeSBjYWxlbmRhciBiYXNlZFxyXG4gICAqIG9uIHRoZSBjdXJyZW50IHZpZXdzIGluIGVhY2guIFRoaXMgcHJldmVudHMgdGhlIHVzZXIgZnJvbSBtb3ZpbmcgdGhlIGNhbGVuZGFycyBvdXQgb2Ygb3JkZXIuXHJcbiAgICovXHJcbiAgcHJpdmF0ZSB1cGRhdGVDYWxlbmRhck1pbk1heERhdGVzKCkge1xyXG4gICAgLy8gT25seSB1cGRhdGUgdGhlIG1pbi9tYXggZGF0ZXMgd2hlbiB0aGUgdmlldyBtb2RlIGlzICdkYXknLlxyXG4gICAgLy8gV2hlbiBhIGNhbGVuZGFyIGlzIGluIGEgbW9udGggb3IgeWVhciB2aWV3IG1vZGUsIHRoZSB2aWV3IGRhdGVzIGF0IHRoZSBiZWdpbm5pbmcgb2YgdGhlIHllYXIuXHJcbiAgICAvLyBUaGlzIHdvdWxkIGNhdXNlIHRoZSBkYXRlcyBpbiB0aGUgb3RoZXIgY2FsZW5kYXIgdG8gYmUgdW5zZWxlY3RhYmxlIGlmIHdlIHdlcmUgdG9cclxuICAgIC8vIHVwZGF0ZSB0aGUgbWluL21heCBkYXRlcyBpbiB0aGVzZSBjYXNlcy5cclxuICAgIGlmICh0aGlzLnByaW1hcnlDYWxlbmRhclZpZXc/Lm1vZGUgPT09ICdkYXknKSB7XHJcbiAgICAgIHRoaXMuc2Vjb25kYXJ5Q2FsZW5kYXJNaW5EYXRlID0gbW9tZW50KHRoaXMucHJpbWFyeUNhbGVuZGFyVmlldz8uZGF0ZSkuYWRkKDEsICdtb250aCcpLnN0YXJ0T2YoJ21vbnRoJykudG9EYXRlKCk7XHJcbiAgICB9XHJcbiAgICBpZiAodGhpcy5zZWNvbmRhcnlDYWxlbmRhclZpZXc/Lm1vZGUgPT09ICdkYXknKSB7XHJcbiAgICAgIHRoaXMucHJpbWFyeUNhbGVuZGFyTWF4RGF0ZSA9IG1vbWVudCh0aGlzLnNlY29uZGFyeUNhbGVuZGFyVmlldz8uZGF0ZSkuc3VidHJhY3QoMSwgJ21vbnRoJykuZW5kT2YoJ21vbnRoJykudG9EYXRlKCk7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIHVwZGF0ZUNhbGVuZGFycyhzZWxlY3Rpb246IERhdGVJbnB1dC5TZWxlY3Rpb24gfCBudWxsKSB7XHJcbiAgICB0aGlzLmNhbGVuZGFyU2VsZWN0aW9uID0gc2VsZWN0aW9uO1xyXG4gICAgdGhpcy51cGRhdGVQcmltYXJ5Q2FsZW5kYXIoc2VsZWN0aW9uKTtcclxuICAgIC8vIE9ubHkgc2hpZnQgdGhlIHByaW1hcnkgY2FsZW5kYXIgaWYgd2UncmUgc2hvd2luZyB0aGUgc2Vjb25kYXJ5IGNhbGVuZGFyXHJcbiAgICB0aGlzLnVwZGF0ZVNlY29uZGFyeUNhbGVuZGFyKHNlbGVjdGlvbiwgdGhpcy5zZWxlY3Rpb25TdHJhdGVneS5zaG93U2Vjb25kYXJ5Q2FsZW5kYXIpO1xyXG5cclxuICAgIHRoaXMudXBkYXRlQ2FsZW5kYXJNaW5NYXhEYXRlcygpO1xyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSB1cGRhdGVQcmltYXJ5Q2FsZW5kYXIoc2VsZWN0aW9uOiBEYXRlSW5wdXQuU2VsZWN0aW9uIHwgbnVsbCwgc2hpZnRTZWNvbmRhcnk6IGJvb2xlYW4gPSBmYWxzZSkge1xyXG4gICAgdGhpcy5wcmltYXJ5Q2FsZW5kYXJWaWV3ID0gdGhpcy5zZWxlY3Rpb25TdHJhdGVneS5nZXRQcmltYXJ5Q2FsZW5kYXJWaWV3KHNlbGVjdGlvbiwgdGhpcy5taW5EYXRlLCB0aGlzLm1heERhdGUsIHRoaXMucHJpbWFyeUNhbGVuZGFyVmlldyk7XHJcblxyXG4gICAgLy8gV2hlbiBlbnRlcmluZyBhIGRhdGUgaW50byB0aGUgZmlyc3QgdGV4dGJveCwgd2UgcmVhbGx5IG9ubHkgd2FudCB0byB1cGRhdGUgdGhlIHByaW1hcnkgY2FsZW5kYXIuXHJcbiAgICAvLyBIb3dldmVyLCBpdCdzIHBvc3NpYmxlIHRoYXQgdGhlIG5ldyBkYXRlIGlzIGFmdGVyIHRoZSBzZWNvbmRhcnkgY2FsZW5kYXIncyBkYXRlLiBJbiB0aGlzIGNhc2UsXHJcbiAgICAvLyBXZSB3YW50IHRvIHNoaWZ0IHRoZSBzZWNvbmRhcnkgY2FsZW5kYXIgc28gdGhlIGNhbGVuZGFycyBzdGF5IGluIG9yZGVyLlxyXG4gICAgaWYgKHNoaWZ0U2Vjb25kYXJ5ICYmIHRoaXMuc2Vjb25kYXJ5Q2FsZW5kYXJWaWV3KSB7XHJcbiAgICAgIGlmIChtb21lbnQodGhpcy5wcmltYXJ5Q2FsZW5kYXJWaWV3LmRhdGUpLmlzU2FtZU9yQWZ0ZXIodGhpcy5zZWNvbmRhcnlDYWxlbmRhclZpZXcuZGF0ZSwgJ21vbnRoJykpIHtcclxuICAgICAgICBsZXQgbmV3U2Vjb25kYXJ5RGF0ZSA9IG1vbWVudCh0aGlzLnByaW1hcnlDYWxlbmRhclZpZXcuZGF0ZSkuYWRkKDEsICdtb250aCcpLnRvRGF0ZSgpO1xyXG4gICAgICAgIHRoaXMuc2Vjb25kYXJ5Q2FsZW5kYXJWaWV3ID0geyBtb2RlOiB0aGlzLnNlbGVjdGlvblN0cmF0ZWd5LnNlbGVjdGlvblZpZXdNb2RlLCBkYXRlOiBuZXdTZWNvbmRhcnlEYXRlIH07XHJcbiAgICAgIH1cclxuICAgIH1cclxuICB9XHJcblxyXG4gIHByaXZhdGUgdXBkYXRlU2Vjb25kYXJ5Q2FsZW5kYXIoc2VsZWN0aW9uOiBEYXRlSW5wdXQuU2VsZWN0aW9uIHwgbnVsbCwgc2hpZnRQcmltYXJ5OiBib29sZWFuID0gZmFsc2UpIHtcclxuICAgIHRoaXMuc2Vjb25kYXJ5Q2FsZW5kYXJWaWV3ID0gdGhpcy5zZWxlY3Rpb25TdHJhdGVneS5nZXRTZWNvbmRhcnlDYWxlbmRhclZpZXcoc2VsZWN0aW9uLCB0aGlzLm1pbkRhdGUsIHRoaXMubWF4RGF0ZSwgdGhpcy5zZWNvbmRhcnlDYWxlbmRhclZpZXcpO1xyXG5cclxuICAgIC8vIFdoZW4gZW50ZXJpbmcgYSBkYXRlIGludG8gdGhlIHNlY29uZCB0ZXh0Ym94LCB3ZSByZWFsbHkgb25seSB3YW50IHRvIHVwZGF0ZSB0aGUgc2Vjb25kYXJ5IGNhbGVuZGFyLlxyXG4gICAgLy8gSG93ZXZlciwgaXQncyBwb3NzaWJsZSB0aGF0IHRoZSBuZXcgZGF0ZSBpcyBiZWZvcmUgdGhlIHByaW1hcnkgY2FsZW5kYXIncyBkYXRlLiBJbiB0aGlzIGNhc2UsXHJcbiAgICAvLyBXZSB3YW50IHRvIHNoaWZ0IHRoZSBwcmltYXJ5IGNhbGVuZGFyIHNvIHRoZSBjYWxlbmRhcnMgc3RheSBpbiBvcmRlci5cclxuICAgIGlmIChzaGlmdFByaW1hcnkgJiYgdGhpcy5wcmltYXJ5Q2FsZW5kYXJWaWV3KSB7XHJcbiAgICAgIGlmIChtb21lbnQodGhpcy5wcmltYXJ5Q2FsZW5kYXJWaWV3LmRhdGUpLmlzU2FtZU9yQWZ0ZXIodGhpcy5zZWNvbmRhcnlDYWxlbmRhclZpZXcuZGF0ZSwgJ21vbnRoJykpIHtcclxuICAgICAgICBsZXQgbmV3UHJpbWFyeURhdGUgPSBtb21lbnQodGhpcy5zZWNvbmRhcnlDYWxlbmRhclZpZXcuZGF0ZSkuc3VidHJhY3QoMSwgJ21vbnRoJykudG9EYXRlKCk7XHJcbiAgICAgICAgdGhpcy5wcmltYXJ5Q2FsZW5kYXJWaWV3ID0geyBtb2RlOiB0aGlzLnNlbGVjdGlvblN0cmF0ZWd5LnNlbGVjdGlvblZpZXdNb2RlLCBkYXRlOiBuZXdQcmltYXJ5RGF0ZSB9O1xyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIHVwZGF0ZVN0ZXBwZXJzKHZhbHVlOiBEYXRlSW5wdXQuU2VsZWN0aW9uIHwgbnVsbCkge1xyXG4gICAgLy8gRGlzYWJsZSB0aGUgc3RlcHBlcnMgaWYgd2UgZWl0aGVyIGRvbid0IGhhdmUgYSBzZWxlY3Rpb24gb3Igb25seSBoYXZlIG9uZSBkYXRlIGluIHRoZSBzZWxlY3Rpb24uXHJcbiAgICBpZiAoXHJcbiAgICAgICF2YWx1ZSB8fFxyXG4gICAgICAoRGF0ZUlucHV0LmlzU2VsZWN0aW9uUmFuZ2UodmFsdWUpICYmICghdmFsdWUuc3RhcnQgfHwgIXZhbHVlLmVuZCkpXHJcbiAgICApIHtcclxuICAgICAgdGhpcy5kaXNhYmxlU3RlcHBlcnMgPSB0cnVlO1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgdGhpcy5kaXNhYmxlU3RlcHBlcnMgPSBmYWxzZTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIHByaXZhdGUgdmFsaWRhdGVUZXh0Ym94ZXMoKSB7XHJcbiAgICBjb25zdCBjb250cm9sID0gdGhpcy50ZXh0Ym94R3JvdXAuY29udHJvbHMudGV4dGJveDtcclxuICAgIGNvbnN0IGNvbnRyb2wyID0gdGhpcy50ZXh0Ym94R3JvdXAuY29udHJvbHMudGV4dGJveDI7XHJcblxyXG4gICAgLy8gVGhlIGZpcnN0IHRleHRib3ggc2hvdWxkIG9ubHkgaGF2ZSB0aGUgcmVxdWlyZWQgZXJyb3IgaWYgaXQncyBlbXB0eSBhbmQgdGhlIGRhdGUgaW5wdXQgaXMgcmVxdWlyZWQsXHJcbiAgICAvLyBvciBpZiB0aGUgZGF0ZSBpbnB1dCBpcyBub3QgcmVxdWlyZWQgYW5kIHRoZSBzZWNvbmQgY29udHJvbCBpcyB2aXNpYmxlIGFuZCBoYXMgYSB2YWx1ZSAobWVhbmluZyBhIHBhcnRpYWwgcmFuZ2UpXHJcbiAgICBpZiAoXHJcbiAgICAgICFjb250cm9sLnZhbHVlICYmXHJcbiAgICAgICh0aGlzLnJlcXVpcmVkIHx8IChjb250cm9sMi52YWx1ZSAmJiB0aGlzLnNlbGVjdGlvblN0cmF0ZWd5LnNob3dTZWNvbmRhcnlUZXh0Ym94KSlcclxuICAgICkge1xyXG4gICAgICBjb250cm9sLnNldEVycm9ycyh7IHJlcXVpcmVkOiB0cnVlIH0pO1xyXG4gICAgfVxyXG4gICAgLy8gVGhlIHNhbWUgaWRlYSBhcHBsaWVzIHRvIHRoZSBzZWNvbmQgdGV4dGJveCwgYnV0IG9ubHkgaWYgaXQncyB2aXNpYmxlXHJcbiAgICBpZiAoXHJcbiAgICAgIHRoaXMuc2VsZWN0aW9uU3RyYXRlZ3kuc2hvd1NlY29uZGFyeVRleHRib3ggJiZcclxuICAgICAgIWNvbnRyb2wyLnZhbHVlICYmXHJcbiAgICAgICh0aGlzLnJlcXVpcmVkIHx8IGNvbnRyb2wudmFsdWUpXHJcbiAgICApIHtcclxuICAgICAgY29udHJvbDIuc2V0RXJyb3JzKHsgcmVxdWlyZWQ6IHRydWUgfSk7XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKGNvbnRyb2wudmFsdWUpIHtcclxuICAgICAgY29uc3QgZXJyb3JzID0gdGhpcy52YWxpZGF0ZURhdGVTdHJpbmcoY29udHJvbC52YWx1ZSk7XHJcbiAgICAgIGlmIChlcnJvcnMpIHtcclxuICAgICAgICBjb250cm9sLnNldEVycm9ycyhlcnJvcnMpO1xyXG4gICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKGNvbnRyb2wyLnZhbHVlICYmIHRoaXMuc2VsZWN0aW9uU3RyYXRlZ3kuc2hvd1NlY29uZGFyeVRleHRib3gpIHtcclxuICAgICAgY29uc3QgZXJyb3JzID0gdGhpcy52YWxpZGF0ZURhdGVTdHJpbmcoY29udHJvbDIudmFsdWUpO1xyXG4gICAgICBpZiAoZXJyb3JzKSB7XHJcbiAgICAgICAgY29udHJvbDIuc2V0RXJyb3JzKGVycm9ycyk7XHJcbiAgICAgIH1cclxuICAgIH1cclxuICB9XHJcblxyXG4gIHByaXZhdGUgdmFsaWRhdGVEYXRlU3RyaW5nKGRhdGU6IHN0cmluZyk6IFZhbGlkYXRpb25FcnJvcnMgfCBudWxsIHtcclxuICAgIGNvbnN0IHZhbHVlID0gdGhpcy5zZWxlY3Rpb25TdHJhdGVneS5wYXJzZVN0cmluZyhkYXRlLCB0aGlzLnBhcnNlRm9ybWF0cyk7XHJcbiAgICBpZiAodmFsdWUpIHtcclxuICAgICAgLy8gV2UncmUgdXNpbmcgdGhlIHZpZXcgbW9kZSBhcyB0aGUgZ3JhbnVsYXJpdHkuIFdlIGRvbid0IHdhbnQgdG8gaW52YWxpZGF0ZVxyXG4gICAgICAvLyB0aGUgZGF0ZSBpbiB0aGUgY2FzZSB3aGVyZSB5b3UgaGF2ZSBhIG1vbnRoL3F1YXJ0ZXIveWVhciBzZWxlY3RlZCBhbmQgdGhlIG1pblxyXG4gICAgICAvLyBvciBtYXggZGF0ZSBpcyBzb21ld2hlcmUgd2l0aGluIHRoYXQgbW9udGgvcXVhcnRlci95ZWFyLlxyXG4gICAgICBpZiAobW9tZW50KHZhbHVlKS5pc0JlZm9yZSh0aGlzLm1pbkRhdGUsIHRoaXMuc2VsZWN0aW9uU3RyYXRlZ3kuc2VsZWN0aW9uVmlld01vZGUpKSB7XHJcbiAgICAgICAgcmV0dXJuIHsgbWluRGF0ZTogeyBtaW5WYWx1ZTogdGhpcy5taW5EYXRlIH0gfTtcclxuICAgICAgfSBlbHNlIGlmIChtb21lbnQodmFsdWUpLmlzQWZ0ZXIodGhpcy5tYXhEYXRlLCB0aGlzLnNlbGVjdGlvblN0cmF0ZWd5LnNlbGVjdGlvblZpZXdNb2RlKSkge1xyXG4gICAgICAgIHJldHVybiB7IG1heERhdGU6IHsgbWF4VmFsdWU6IHRoaXMubWF4RGF0ZSB9IH07XHJcbiAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICByZXR1cm4gbnVsbDtcclxuICB9XHJcbn1cclxuIiwiPGxhYmVsICpuZ0lmPVwibGFiZWxcIj5cclxuICA8c3Bhbj57e2xhYmVsIHwgdHJhbnNsYXRlfX08L3NwYW4+XHJcbiAgPHNwYW4gKm5nSWY9XCJ2YWxpZGF0aW9uRXJyb3JzLmxlbmd0aCA+IDAgJiYgZm9ybU1vZGVsLnRvdWNoZWQgJiYgZm9ybU1vZGVsLmludmFsaWRcIj4mbmJzcDt7e3ZhbGlkYXRpb25FcnJvcnN9fTwvc3Bhbj5cclxuICA8ZWMtaGVscC1wb3BvdmVyIGlkPVwie3tpZH19X2hlbHBQb3BvdmVyXCJcclxuICAgICAgICAgICAgICAgICAgICpuZ0lmPVwiaGVscFBvcG92ZXJcIlxyXG4gICAgICAgICAgICAgICAgICAgY2xhc3M9XCJkLWlubGluZS1ibG9jayBteS1uMyBteC1uMVwiXHJcbiAgICAgICAgICAgICAgICAgICB0ZXh0PVwie3toZWxwUG9wb3ZlciB8IHRyYW5zbGF0ZX19XCJcclxuICAgICAgICAgICAgICAgICAgIGNvbnRlbnRQb3NpdGlvbj1cInt7aGVscFBvcG92ZXJQb3NpdGlvbn19XCI+XHJcbiAgPC9lYy1oZWxwLXBvcG92ZXI+XHJcbjwvbGFiZWw+XHJcblxyXG48ZGl2IGNsYXNzPVwiZC1mbGV4IGFsaWduLWl0ZW1zLWNlbnRlclwiXHJcbiAgICAgW2VjS2V5Ym9hcmROYXZDb250YWluZXJdPVwiaXNDYWxlbmRhck9wZW5cIlxyXG4gICAgICNjb250cm9scz1cImVjS2V5Ym9hcmROYXZDb250YWluZXJcIlxyXG4gICAgIChmb2N1c091dEVuZCk9XCJvbkNvbnRyb2xzRm9jdXNPdXRFbmQoKVwiPlxyXG4gIDxlYy1mb3JtLWNvbnRyb2wgaWQ9XCJ7e2lkfX1cIlxyXG4gICAgICAgICAgICAgICAgICAgW3JlcXVpcmVkXT1cInJlcXVpcmVkXCJcclxuICAgICAgICAgICAgICAgICAgIFthdXRvZm9jdXNdPVwiYXV0b2ZvY3VzXCJcclxuICAgICAgICAgICAgICAgICAgIFtwZW5kaW5nXT1cInBlbmRpbmdcIlxyXG4gICAgICAgICAgICAgICAgICAgW3JlYWRvbmx5XT1cInJlYWRvbmx5XCJcclxuICAgICAgICAgICAgICAgICAgIChhY3Rpb25DbGlja2VkKT1cImlzQ2FsZW5kYXJPcGVuID0gIWlzQ2FsZW5kYXJPcGVuXCJcclxuICAgICAgICAgICAgICAgICAgIFtzaG93Q2xlYXJdPVwiZmFsc2VcIlxyXG4gICAgICAgICAgICAgICAgICAgYWN0aW9uSWNvbj1cImljb24tZGF0ZVwiXHJcbiAgICAgICAgICAgICAgICAgICBjZGtPdmVybGF5T3JpZ2luXHJcbiAgICAgICAgICAgICAgICAgICAjb3ZlcmxheU9yaWdpbj1cImNka092ZXJsYXlPcmlnaW5cIlxyXG4gICAgICAgICAgICAgICAgICAgY2xhc3M9XCJmbGV4LWdyb3dcIlxyXG4gICAgICAgICAgICAgICAgICAgc3R5bGU9XCJoZWlnaHQ6IDJyZW07XCI+XHJcbiAgICA8aW5wdXQgaWQ9XCJ7e2lkfX1faW5wdXRcIlxyXG4gICAgICAgICAgIHR5cGU9XCJ0ZXh0XCJcclxuICAgICAgICAgICBwbGFjZWhvbGRlcj1cInt7cGxhY2Vob2xkZXJ9fVwiXHJcbiAgICAgICAgICAgW2Zvcm1Db250cm9sXT1cInRleHRib3hHcm91cC5nZXQoJ3RleHRib3gnKVwiXHJcbiAgICAgICAgICAgKGJsdXIpPVwib25UZXh0Ym94Qmx1cigpXCI+XHJcbiAgPC9lYy1mb3JtLWNvbnRyb2w+XHJcblxyXG4gIDxuZy1jb250YWluZXIgKm5nSWY9XCJzZWxlY3Rpb25TdHJhdGVneS5zaG93U2Vjb25kYXJ5VGV4dGJveFwiPlxyXG4gICAgPHNwYW4gY2xhc3M9XCJmbGV4LXNocmluayBteC0xXCI+Jm5kYXNoOzwvc3Bhbj5cclxuICAgIDxlYy1mb3JtLWNvbnRyb2wgaWQ9XCJ7e2lkfX1fY29udHJvbDJcIlxyXG4gICAgICAgICAgICAgICAgICAgICBbcmVxdWlyZWRdPVwicmVxdWlyZWRcIlxyXG4gICAgICAgICAgICAgICAgICAgICBbYXV0b2ZvY3VzXT1cImF1dG9mb2N1c1wiXHJcbiAgICAgICAgICAgICAgICAgICAgIFtwZW5kaW5nXT1cInBlbmRpbmdcIlxyXG4gICAgICAgICAgICAgICAgICAgICBbcmVhZG9ubHldPVwicmVhZG9ubHlcIlxyXG4gICAgICAgICAgICAgICAgICAgICAoYWN0aW9uQ2xpY2tlZCk9XCJpc0NhbGVuZGFyT3BlbiA9ICFpc0NhbGVuZGFyT3BlblwiXHJcbiAgICAgICAgICAgICAgICAgICAgIFtzaG93Q2xlYXJdPVwiZmFsc2VcIlxyXG4gICAgICAgICAgICAgICAgICAgICBhY3Rpb25JY29uPVwiaWNvbi1kYXRlXCJcclxuICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJmbGV4LWdyb3dcIlxyXG4gICAgICAgICAgICAgICAgICAgICBzdHlsZT1cImhlaWdodDogMnJlbTtcIj5cclxuICAgICAgPGlucHV0IGlkPVwie3tpZH19X2lucHV0MlwiXHJcbiAgICAgICAgICAgICB0eXBlPVwidGV4dFwiXHJcbiAgICAgICAgICAgICBwbGFjZWhvbGRlcj1cInt7cGxhY2Vob2xkZXJ9fVwiXHJcbiAgICAgICAgICAgICBbZm9ybUNvbnRyb2xdPVwidGV4dGJveEdyb3VwLmdldCgndGV4dGJveDInKVwiXHJcbiAgICAgICAgICAgICAoYmx1cik9XCJvblRleHRib3gyQmx1cigpXCI+XHJcbiAgICA8L2VjLWZvcm0tY29udHJvbD5cclxuICA8L25nLWNvbnRhaW5lcj5cclxuXHJcbiAgPGRpdiAqbmdJZj1cImVuYWJsZVN0ZXBwZXJzXCJcclxuICAgICAgIGNsYXNzPVwiY29udHJvbC1ncm91cCBtbC0yXCI+XHJcbiAgICA8ZWMtYnV0dG9uIGlkPVwie3tpZH19X3ByZXZpb3VzU2VsZWN0aW9uXCJcclxuICAgICAgICAgICAgICAgdHlwZT1cInNlY29uZGFyeVwiXHJcbiAgICAgICAgICAgICAgIGljb249XCJpY29uLWFuZ2xlLWRvd24gcm90YXRlLTkwXCJcclxuICAgICAgICAgICAgICAgKGNsaWNrZWQpPVwicHJldmlvdXNTZWxlY3Rpb24oKVwiXHJcbiAgICAgICAgICAgICAgIFtkaXNhYmxlZF09XCJpc0NhbGVuZGFyT3BlbiB8fCBkaXNhYmxlU3RlcHBlcnMgfHwgZm9ybU1vZGVsPy5kaXNhYmxlZFwiPlxyXG4gICAgPC9lYy1idXR0b24+XHJcbiAgICA8ZWMtYnV0dG9uIGlkPVwie3tpZH19X25leHRTZWxlY3Rpb25cIlxyXG4gICAgICAgICAgICAgICB0eXBlPVwic2Vjb25kYXJ5XCJcclxuICAgICAgICAgICAgICAgaWNvbj1cImljb24tYW5nbGUtZG93biByb3RhdGUtMjcwXCJcclxuICAgICAgICAgICAgICAgKGNsaWNrZWQpPVwibmV4dFNlbGVjdGlvbigpXCJcclxuICAgICAgICAgICAgICAgW2Rpc2FibGVkXT1cImlzQ2FsZW5kYXJPcGVuIHx8IGRpc2FibGVTdGVwcGVycyB8fCBmb3JtTW9kZWw/LmRpc2FibGVkXCI+XHJcbiAgICA8L2VjLWJ1dHRvbj5cclxuICA8L2Rpdj5cclxuXHJcbiAgPGVjLWJ1dHRvbiAqbmdJZj1cInF1aWNrU2VsZWN0RGF0ZVwiXHJcbiAgICAgICAgICAgICBpZD1cInt7aWR9fV9xdWlja1NlbGVjdFwiXHJcbiAgICAgICAgICAgICBpY29uPVwiaWNvbi1kYXlcIlxyXG4gICAgICAgICAgICAgdHlwZT1cInNlY29uZGFyeVwiXHJcbiAgICAgICAgICAgICB0aXRsZT1cInt7J0RhdGVJbnB1dF9MYXRlc3REYXRhQXZhaWxhYmxlVGl0bGUnIHwgdHJhbnNsYXRlfX1cIlxyXG4gICAgICAgICAgICAgKGNsaWNrZWQpPVwiZ29Ub1F1aWNrU2VsZWN0RGF0ZSgpXCJcclxuICAgICAgICAgICAgIGNsYXNzPVwibWwtMlwiPlxyXG4gIDwvZWMtYnV0dG9uPlxyXG48L2Rpdj5cclxuXHJcbjxuZy10ZW1wbGF0ZSBjZGtDb25uZWN0ZWRPdmVybGF5XHJcbiAgICAgICAgICAgICAjb3ZlcmxheT1cImNka0Nvbm5lY3RlZE92ZXJsYXlcIlxyXG4gICAgICAgICAgICAgW2Nka0Nvbm5lY3RlZE92ZXJsYXlPcmlnaW5dPVwib3ZlcmxheU9yaWdpblwiXHJcbiAgICAgICAgICAgICBbY2RrQ29ubmVjdGVkT3ZlcmxheU9wZW5dPVwiaXNDYWxlbmRhck9wZW5cIlxyXG4gICAgICAgICAgICAgW2Nka0Nvbm5lY3RlZE92ZXJsYXlTY3JvbGxTdHJhdGVneV09XCJvdmVybGF5U2Nyb2xsU3RyYXRlZ3lcIlxyXG4gICAgICAgICAgICAgY2RrQ29ubmVjdGVkT3ZlcmxheVBhbmVsQ2xhc3M9XCJteS0xXCJcclxuICAgICAgICAgICAgIChvdmVybGF5T3V0c2lkZUNsaWNrKT1cIm9uT3ZlcmxheU91dHNpZGVDbGljaygkZXZlbnQpXCJcclxuICAgICAgICAgICAgIChkZXRhY2gpPVwiaXNDYWxlbmRhck9wZW4gPSBmYWxzZVwiPlxyXG4gIDxhcnRpY2xlIGlkPVwie3tpZH19X2RhdGVQaWNrZXJcIlxyXG4gICAgICAgICAgIGNsYXNzPVwiY2FyZCBkLWZsZXhcIlxyXG4gICAgICAgICAgIFtlY0tleWJvYXJkTmF2Q29udGFpbmVyXT1cImlzQ2FsZW5kYXJPcGVuXCJcclxuICAgICAgICAgICAjY2FsZW5kYXI9XCJlY0tleWJvYXJkTmF2Q29udGFpbmVyXCJcclxuICAgICAgICAgICAoZm9jdXNPdXRTdGFydCk9XCJvbkNhbGVuZGFyRm9jdXNPdXRTdGFydCgpXCJcclxuICAgICAgICAgICAoZm9jdXNPdXRFbmQpPVwib25DYWxlbmRhckZvY3VzT3V0RW5kKClcIj5cclxuICAgIDx1bCAqbmdJZj1cInNlbGVjdGlvbk1vZGVPcHRpb25zLmxlbmd0aCA+IDFcIlxyXG4gICAgICAgIGNsYXNzPVwic2VsZWN0aW9uLW1vZGUtbWVudSBib3JkZXItcmlnaHQgcC0xXCI+XHJcbiAgICAgIDxsaSAqbmdGb3I9XCJsZXQgb3B0aW9uIG9mIHNlbGVjdGlvbk1vZGVPcHRpb25zXCI+XHJcbiAgICAgICAgPGJ1dHRvbiBpZD1cInt7aWR9fV9zZWxlY3Rpb25Nb2RlX3t7b3B0aW9ufX1cIlxyXG4gICAgICAgICAgICAgICAgY2xhc3M9XCJ0ZXh0LWJvZHktMVwiXHJcbiAgICAgICAgICAgICAgICBbY2xhc3MuaXMtc2VsZWN0ZWRdPVwib3B0aW9uID09PSBzZWxlY3Rpb25Nb2RlXCJcclxuICAgICAgICAgICAgICAgIChjbGljayk9XCJvblNlbGVjdGlvbk1vZGVDaGFuZ2Uob3B0aW9uKVwiPlxyXG4gICAgICAgICAge3snRGF0ZUlucHV0U2VsZWN0aW9uTW9kZV8nICsgb3B0aW9uIHwgdHJhbnNsYXRlfX1cclxuICAgICAgICA8L2J1dHRvbj5cclxuICAgICAgPC9saT5cclxuICAgIDwvdWw+XHJcblxyXG4gICAgPGRpdj5cclxuICAgICAgPGRpdiBjbGFzcz1cImQtZmxleFwiPlxyXG4gICAgICAgIDxlYy1jYWxlbmRhciBpZD1cInt7aWR9fV9jYWxlbmRhclwiXHJcbiAgICAgICAgICAgICAgICAgICAgIFt2aWV3XT1cInByaW1hcnlDYWxlbmRhclZpZXdcIlxyXG4gICAgICAgICAgICAgICAgICAgICAodmlld0NoYW5nZSk9XCJvblByaW1hcnlDYWxlbmRhclZpZXdDaGFuZ2UoJGV2ZW50KVwiXHJcbiAgICAgICAgICAgICAgICAgICAgIFtzZWxlY3Rpb25Nb2RlXT1cInNlbGVjdGlvbk1vZGVcIlxyXG4gICAgICAgICAgICAgICAgICAgICBbc2VsZWN0aW9uXT1cImNhbGVuZGFyU2VsZWN0aW9uXCJcclxuICAgICAgICAgICAgICAgICAgICAgKGRhdGVTZWxlY3RlZCk9XCJvbkNhbGVuZGFyRGF0ZVNlbGVjdGVkKCRldmVudClcIlxyXG4gICAgICAgICAgICAgICAgICAgICBbbWluRGF0ZV09XCJtaW5EYXRlXCJcclxuICAgICAgICAgICAgICAgICAgICAgW21heERhdGVdPVwic2VsZWN0aW9uU3RyYXRlZ3kuc2hvd1NlY29uZGFyeUNhbGVuZGFyID8gcHJpbWFyeUNhbGVuZGFyTWF4RGF0ZSA6IG1heERhdGVcIj5cclxuICAgICAgICA8L2VjLWNhbGVuZGFyPlxyXG5cclxuICAgICAgICA8ZWMtY2FsZW5kYXIgKm5nSWY9XCJzZWxlY3Rpb25TdHJhdGVneS5zaG93U2Vjb25kYXJ5Q2FsZW5kYXJcIlxyXG4gICAgICAgICAgICAgICAgICAgICBpZD1cInt7aWR9fV9zZWNvbmRhcnlDYWxlbmRhclwiXHJcbiAgICAgICAgICAgICAgICAgICAgIFt2aWV3XT1cInNlY29uZGFyeUNhbGVuZGFyVmlld1wiXHJcbiAgICAgICAgICAgICAgICAgICAgICh2aWV3Q2hhbmdlKT1cIm9uU2Vjb25kYXJ5Q2FsZW5kYXJWaWV3Q2hhbmdlKCRldmVudClcIlxyXG4gICAgICAgICAgICAgICAgICAgICBbc2VsZWN0aW9uTW9kZV09XCJzZWxlY3Rpb25Nb2RlXCJcclxuICAgICAgICAgICAgICAgICAgICAgW3NlbGVjdGlvbl09XCJjYWxlbmRhclNlbGVjdGlvblwiXHJcbiAgICAgICAgICAgICAgICAgICAgIChkYXRlU2VsZWN0ZWQpPVwib25DYWxlbmRhckRhdGVTZWxlY3RlZCgkZXZlbnQpXCJcclxuICAgICAgICAgICAgICAgICAgICAgW21pbkRhdGVdPVwic2Vjb25kYXJ5Q2FsZW5kYXJNaW5EYXRlXCJcclxuICAgICAgICAgICAgICAgICAgICAgW21heERhdGVdPVwibWF4RGF0ZVwiPlxyXG4gICAgICAgIDwvZWMtY2FsZW5kYXI+XHJcbiAgICAgIDwvZGl2PlxyXG5cclxuICAgICAgPGZvb3RlciAqbmdJZj1cInNlbGVjdGlvblN0cmF0ZWd5LnNlbGVjdGlvblZpZXdNb2RlID09PSAnZGF5J1wiXHJcbiAgICAgICAgICAgICAgY2xhc3M9XCJweC0yIG15LTIgZC1mbGV4XCI+XHJcbiAgICAgICAgPGJ1dHRvbiBpZD1cInt7aWR9fV90b2RheV9idXR0b25cIlxyXG4gICAgICAgICAgICAgICAgZWNMaW5rQnV0dG9uXHJcbiAgICAgICAgICAgICAgICBjbGFzcz1cIm1sLWF1dG8gZC1pbmxpbmUtYmxvY2tcIlxyXG4gICAgICAgICAgICAgICAgKGNsaWNrKT1cImdvVG9Ub2RheSgpXCJcclxuICAgICAgICAgICAgICAgIHN0eWxlPVwiaGVpZ2h0OiAxLjc1cmVtO1wiPlxyXG4gICAgICAgICAge3snVG9kYXknIHwgdHJhbnNsYXRlfX1cclxuICAgICAgICA8L2J1dHRvbj5cclxuICAgICAgPC9mb290ZXI+XHJcbiAgICA8L2Rpdj5cclxuICA8L2FydGljbGU+XHJcbjwvbmctdGVtcGxhdGU+XHJcbiJdfQ==