@ethlete/cdk 4.2.2 → 4.3.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 (220) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/esm2022/lib/components/accordion/components/accordion/accordion.component.mjs +3 -3
  3. package/esm2022/lib/components/accordion/components/accordion-group/accordion-group.component.mjs +3 -3
  4. package/esm2022/lib/components/accordion/partials/accordion-hint/accordion-hint.directive.mjs +3 -3
  5. package/esm2022/lib/components/accordion/partials/accordion-hint-wrapper/accordion-hint-wrapper.directive.mjs +3 -3
  6. package/esm2022/lib/components/accordion/partials/accordion-label/accordion-label.directive.mjs +3 -3
  7. package/esm2022/lib/components/accordion/partials/accordion-label-wrapper/accordion-label-wrapper.directive.mjs +3 -3
  8. package/esm2022/lib/components/bracket/components/bracket/bracket.component.mjs +3 -3
  9. package/esm2022/lib/components/bracket/directives/bracket-match/bracket-match.directive.mjs +3 -3
  10. package/esm2022/lib/components/bracket/directives/bracket-round/bracket-round.directive.mjs +3 -3
  11. package/esm2022/lib/components/bracket/partials/bracket-match/bracket-match.component.mjs +3 -3
  12. package/esm2022/lib/components/bracket/partials/bracket-round-header/bracket-round-header.component.mjs +3 -3
  13. package/esm2022/lib/components/button/components/button/button.component.mjs +3 -3
  14. package/esm2022/lib/components/button/components/query-button/query-button.component.mjs +3 -3
  15. package/esm2022/lib/components/button/directives/button/button.directive.mjs +3 -3
  16. package/esm2022/lib/components/button/directives/query-button/query-button.directive.mjs +3 -3
  17. package/esm2022/lib/components/filter/filter-overlay/components/filter-overlay-page-outlet/filter-overlay-page-outlet.component.mjs +3 -3
  18. package/esm2022/lib/components/filter/filter-overlay/directives/filter-overlay-back-or-close/filter-overlay-back-or-close.directive.mjs +3 -3
  19. package/esm2022/lib/components/filter/filter-overlay/directives/filter-overlay-link/filter-overlay-link.directive.mjs +3 -3
  20. package/esm2022/lib/components/filter/filter-overlay/directives/filter-overlay-reset/filter-overlay-reset.directive.mjs +3 -3
  21. package/esm2022/lib/components/filter/filter-overlay/directives/filter-overlay-submit/filter-overlay-submit.directive.mjs +3 -3
  22. package/esm2022/lib/components/filter/filter-overlay/services/filter-overlay.service.mjs +3 -3
  23. package/esm2022/lib/components/filter/rich-filter/components/rich-filter-host/rich-filter-host.component.mjs +3 -3
  24. package/esm2022/lib/components/filter/rich-filter/directives/rich-filter-button/rich-filter-button.directive.mjs +3 -3
  25. package/esm2022/lib/components/filter/rich-filter/directives/rich-filter-button-slot/rich-filter-button-slot.directive.mjs +3 -3
  26. package/esm2022/lib/components/filter/rich-filter/directives/rich-filter-content/rich-filter-content.directive.mjs +3 -3
  27. package/esm2022/lib/components/filter/rich-filter/directives/rich-filter-top/rich-filter-top.directive.mjs +3 -3
  28. package/esm2022/lib/components/forms/components/checkbox/components/checkbox/checkbox.component.mjs +3 -3
  29. package/esm2022/lib/components/forms/components/checkbox/components/checkbox-field/checkbox-field.component.mjs +3 -3
  30. package/esm2022/lib/components/forms/components/checkbox/components/checkbox-group/checkbox-group.component.mjs +3 -3
  31. package/esm2022/lib/components/forms/components/checkbox/directives/checkbox/checkbox.directive.mjs +3 -3
  32. package/esm2022/lib/components/forms/components/checkbox/directives/checkbox-field/checkbox-field.directive.mjs +3 -3
  33. package/esm2022/lib/components/forms/components/checkbox/directives/checkbox-group/checkbox-group.directive.mjs +3 -3
  34. package/esm2022/lib/components/forms/components/checkbox/directives/checkbox-group-control/checkbox-group-control.directive.mjs +3 -3
  35. package/esm2022/lib/components/forms/components/error/components/error/error.component.mjs +3 -3
  36. package/esm2022/lib/components/forms/components/input/components/date-input/date-input.component.mjs +3 -3
  37. package/esm2022/lib/components/forms/components/input/components/email-input/email-input.component.mjs +3 -3
  38. package/esm2022/lib/components/forms/components/input/components/input-field/input-field.component.mjs +3 -3
  39. package/esm2022/lib/components/forms/components/input/components/number-input/number-input.component.mjs +3 -3
  40. package/esm2022/lib/components/forms/components/input/components/password-input/password-input.component.mjs +3 -3
  41. package/esm2022/lib/components/forms/components/input/components/search-input/search-input.component.mjs +3 -3
  42. package/esm2022/lib/components/forms/components/input/components/text-input/text-input.component.mjs +3 -3
  43. package/esm2022/lib/components/forms/components/input/components/textarea-input/textarea-input.component.mjs +3 -3
  44. package/esm2022/lib/components/forms/components/input/directives/autosize-textarea/autosize-textarea.directive.mjs +3 -3
  45. package/esm2022/lib/components/forms/components/input/directives/date-input/date-input.directive.mjs +3 -3
  46. package/esm2022/lib/components/forms/components/input/directives/email-input/email-input.directive.mjs +3 -3
  47. package/esm2022/lib/components/forms/components/input/directives/number-input/number-input.directive.mjs +3 -3
  48. package/esm2022/lib/components/forms/components/input/directives/password-input/password-input.directive.mjs +3 -3
  49. package/esm2022/lib/components/forms/components/input/directives/search-input/search-input.directive.mjs +3 -3
  50. package/esm2022/lib/components/forms/components/input/directives/text-input/text-input.directive.mjs +3 -3
  51. package/esm2022/lib/components/forms/components/input/directives/textarea-input/textarea-input.directive.mjs +3 -3
  52. package/esm2022/lib/components/forms/components/input/partials/password-input-toggle/password-input-toggle.component.mjs +3 -3
  53. package/esm2022/lib/components/forms/components/input/partials/search-input-clear/search-input-clear.component.mjs +3 -3
  54. package/esm2022/lib/components/forms/components/label/components/label/label.component.mjs +3 -3
  55. package/esm2022/lib/components/forms/components/label/directives/label-suffix/label-suffix.directive.mjs +3 -3
  56. package/esm2022/lib/components/forms/components/radio/components/radio/radio.component.mjs +3 -3
  57. package/esm2022/lib/components/forms/components/radio/components/radio-field/radio-field.component.mjs +3 -3
  58. package/esm2022/lib/components/forms/components/radio/components/radio-group/radio-group.component.mjs +3 -3
  59. package/esm2022/lib/components/forms/components/radio/directives/radio/radio.directive.mjs +3 -3
  60. package/esm2022/lib/components/forms/components/radio/directives/radio-field/radio-field.directive.mjs +3 -3
  61. package/esm2022/lib/components/forms/components/radio/directives/radio-group/radio-group.directive.mjs +3 -3
  62. package/esm2022/lib/components/forms/components/segmented-button/components/segmented-button/segmented-button.component.mjs +3 -3
  63. package/esm2022/lib/components/forms/components/segmented-button/components/segmented-button-field/segmented-button-field.component.mjs +3 -3
  64. package/esm2022/lib/components/forms/components/segmented-button/components/segmented-button-group/segmented-button-group.component.mjs +3 -3
  65. package/esm2022/lib/components/forms/components/segmented-button/directives/segmented-button/segmented-button.directive.mjs +3 -3
  66. package/esm2022/lib/components/forms/components/segmented-button/directives/segmented-button-field/segmented-button-field.directive.mjs +3 -3
  67. package/esm2022/lib/components/forms/components/segmented-button/directives/segmented-button-group/segmented-button-group.directive.mjs +3 -3
  68. package/esm2022/lib/components/forms/components/select/components/combobox/components/combobox/combobox.component.mjs +3 -3
  69. package/esm2022/lib/components/forms/components/select/components/combobox/directives/combobox/combobox.directive.mjs +3 -3
  70. package/esm2022/lib/components/forms/components/select/components/combobox/directives/combobox-body-empty-template/combobox-body-empty-template.directive.mjs +3 -3
  71. package/esm2022/lib/components/forms/components/select/components/combobox/directives/combobox-body-error-template/combobox-body-error-template.directive.mjs +3 -3
  72. package/esm2022/lib/components/forms/components/select/components/combobox/directives/combobox-body-loading-template/combobox-body-loading-template.directive.mjs +3 -3
  73. package/esm2022/lib/components/forms/components/select/components/combobox/directives/combobox-body-more-items-hint-template/combobox-body-more-items-hint-template.directive.mjs +3 -3
  74. package/esm2022/lib/components/forms/components/select/components/combobox/directives/combobox-option-template/combobox-option-template.directive.mjs +3 -3
  75. package/esm2022/lib/components/forms/components/select/components/combobox/directives/combobox-selected-option-template/combobox-selected-option-template.directive.mjs +3 -3
  76. package/esm2022/lib/components/forms/components/select/components/combobox/partials/combobox-body/combobox-body.component.mjs +3 -3
  77. package/esm2022/lib/components/forms/components/select/components/combobox/partials/combobox-option/combobox-option.component.mjs +3 -3
  78. package/esm2022/lib/components/forms/components/select/components/native-select/components/native-select/native-select.component.mjs +3 -3
  79. package/esm2022/lib/components/forms/components/select/components/native-select/directives/native-select-input/native-select-input.directive.mjs +3 -3
  80. package/esm2022/lib/components/forms/components/select/components/native-select/directives/native-select-option/native-select-option.directive.mjs +3 -3
  81. package/esm2022/lib/components/forms/components/select/components/native-select/partials/native-select-option/native-select-option.component.mjs +3 -3
  82. package/esm2022/lib/components/forms/components/select/components/select/components/select/select.component.mjs +3 -3
  83. package/esm2022/lib/components/forms/components/select/components/select/directives/select/select.directive.mjs +3 -3
  84. package/esm2022/lib/components/forms/components/select/components/select/directives/select-body/select-body.directive.mjs +3 -3
  85. package/esm2022/lib/components/forms/components/select/components/select/directives/select-option/select-option.directive.mjs +3 -3
  86. package/esm2022/lib/components/forms/components/select/components/select/partials/select-body/select-body.component.mjs +3 -3
  87. package/esm2022/lib/components/forms/components/select/components/select/partials/select-option/select-option.component.mjs +3 -3
  88. package/esm2022/lib/components/forms/components/select/components/select-field/select-field.component.mjs +3 -3
  89. package/esm2022/lib/components/forms/components/select/directives/select-field/select-field.directive.mjs +3 -3
  90. package/esm2022/lib/components/forms/components/selection-list/components/selection-list-field/selection-list-field.component.mjs +3 -3
  91. package/esm2022/lib/components/forms/components/selection-list/components/selection-list-option/selection-list-option.component.mjs +3 -3
  92. package/esm2022/lib/components/forms/components/selection-list/directives/selection-list-field/selection-list-field.directive.mjs +3 -3
  93. package/esm2022/lib/components/forms/components/selection-list/directives/selection-list-option/selection-list-option.directive.mjs +3 -3
  94. package/esm2022/lib/components/forms/components/slide-toggle/components/slide-toggle/slide-toggle.component.mjs +3 -3
  95. package/esm2022/lib/components/forms/components/slide-toggle/components/slide-toggle-field/slide-toggle-field.component.mjs +3 -3
  96. package/esm2022/lib/components/forms/components/slide-toggle/directives/slide-toggle/slide-toggle.directive.mjs +3 -3
  97. package/esm2022/lib/components/forms/components/slider/components/slider/slider.component.mjs +3 -3
  98. package/esm2022/lib/components/forms/components/slider/components/slider-field/slider-field.component.mjs +3 -3
  99. package/esm2022/lib/components/forms/directives/dynamic-form-field/dynamic-form-field.directive.mjs +3 -3
  100. package/esm2022/lib/components/forms/directives/dynamic-form-group/dynamic-form-group.directive.mjs +3 -3
  101. package/esm2022/lib/components/forms/directives/expose-input-vars/expose-input-vars.directive.mjs +3 -3
  102. package/esm2022/lib/components/forms/directives/if-input-empty/if-input-empty.directive.mjs +3 -3
  103. package/esm2022/lib/components/forms/directives/if-input-filled/if-input-filled.directive.mjs +3 -3
  104. package/esm2022/lib/components/forms/directives/input/input.directive.mjs +3 -3
  105. package/esm2022/lib/components/forms/directives/input-prefix/input-prefix.directive.mjs +3 -3
  106. package/esm2022/lib/components/forms/directives/input-suffix/input-suffix.directive.mjs +3 -3
  107. package/esm2022/lib/components/forms/directives/native-input-ref/native-input-ref.directive.mjs +3 -3
  108. package/esm2022/lib/components/forms/directives/static-form-field/static-form-field.directive.mjs +3 -3
  109. package/esm2022/lib/components/forms/directives/static-form-group/static-form-group.directive.mjs +3 -3
  110. package/esm2022/lib/components/forms/directives/writeable-input/writeable-input.directive.mjs +3 -3
  111. package/esm2022/lib/components/forms/services/default-validator-errors.service.mjs +3 -3
  112. package/esm2022/lib/components/forms/services/form-field-state.service.mjs +3 -3
  113. package/esm2022/lib/components/forms/services/form-group-state.service.mjs +3 -3
  114. package/esm2022/lib/components/forms/services/input-state.service.mjs +3 -3
  115. package/esm2022/lib/components/forms/utils/decorated-form-field.base.mjs +3 -3
  116. package/esm2022/lib/components/forms/utils/decorated-input.base.mjs +3 -3
  117. package/esm2022/lib/components/forms/utils/input.base.mjs +3 -3
  118. package/esm2022/lib/components/icons/chevron-icon/chevron-icon.component.mjs +3 -3
  119. package/esm2022/lib/components/masonry/components/masonry/masonry.component.mjs +3 -3
  120. package/esm2022/lib/components/masonry/partials/masonry-item/masonry-item.component.mjs +3 -3
  121. package/esm2022/lib/components/overlay/components/bottom-sheet/components/bottom-sheet-container/bottom-sheet-container.component.mjs +3 -3
  122. package/esm2022/lib/components/overlay/components/bottom-sheet/partials/bottom-sheet-container-base/bottom-sheet-container-base.component.mjs +3 -3
  123. package/esm2022/lib/components/overlay/components/bottom-sheet/partials/bottom-sheet-drag-handle/bottom-sheet-drag-handle.component.mjs +3 -3
  124. package/esm2022/lib/components/overlay/components/bottom-sheet/partials/bottom-sheet-title/bottom-sheet-title.directive.mjs +3 -3
  125. package/esm2022/lib/components/overlay/components/bottom-sheet/services/bottom-sheet-base.service.mjs +3 -3
  126. package/esm2022/lib/components/overlay/components/bottom-sheet/services/bottom-sheet-swipe-handler.service.mjs +3 -3
  127. package/esm2022/lib/components/overlay/components/bottom-sheet/services/bottom-sheet.service.mjs +3 -3
  128. package/esm2022/lib/components/overlay/components/dialog/components/dialog-container/dialog-container.component.mjs +3 -3
  129. package/esm2022/lib/components/overlay/components/dialog/partials/dialog-close/dialog-close.directive.mjs +3 -3
  130. package/esm2022/lib/components/overlay/components/dialog/partials/dialog-container-base/dialog-container-base.component.mjs +3 -3
  131. package/esm2022/lib/components/overlay/components/dialog/partials/dialog-title/dialog-title.directive.mjs +3 -3
  132. package/esm2022/lib/components/overlay/components/dialog/services/dialog-base.service.mjs +3 -3
  133. package/esm2022/lib/components/overlay/components/dialog/services/dialog.service.mjs +3 -3
  134. package/esm2022/lib/components/overlay/components/menu/context-menu-trigger.mjs +6 -6
  135. package/esm2022/lib/components/overlay/components/menu/menu-aim.mjs +6 -6
  136. package/esm2022/lib/components/overlay/components/menu/menu-bar.mjs +3 -3
  137. package/esm2022/lib/components/overlay/components/menu/menu-base.mjs +3 -3
  138. package/esm2022/lib/components/overlay/components/menu/menu-group.mjs +3 -3
  139. package/esm2022/lib/components/overlay/components/menu/menu-item-checkbox.mjs +3 -3
  140. package/esm2022/lib/components/overlay/components/menu/menu-item-radio.mjs +3 -3
  141. package/esm2022/lib/components/overlay/components/menu/menu-item-selectable.mjs +3 -3
  142. package/esm2022/lib/components/overlay/components/menu/menu-item.mjs +3 -3
  143. package/esm2022/lib/components/overlay/components/menu/menu-module.mjs +4 -4
  144. package/esm2022/lib/components/overlay/components/menu/menu-stack.mjs +3 -3
  145. package/esm2022/lib/components/overlay/components/menu/menu-trigger-base.mjs +3 -3
  146. package/esm2022/lib/components/overlay/components/menu/menu-trigger.mjs +3 -3
  147. package/esm2022/lib/components/overlay/components/menu/menu.mjs +3 -3
  148. package/esm2022/lib/components/overlay/components/overlay/components/overlay-container/overlay-container.component.mjs +3 -3
  149. package/esm2022/lib/components/overlay/components/overlay/partials/overlay-close/overlay-close.directive.mjs +3 -3
  150. package/esm2022/lib/components/overlay/components/overlay/partials/overlay-title/overlay-title.directive.mjs +3 -3
  151. package/esm2022/lib/components/overlay/components/overlay/services/overlay.service.mjs +3 -3
  152. package/esm2022/lib/components/overlay/components/toggletip/components/toggletip/toggletip.component.mjs +3 -3
  153. package/esm2022/lib/components/overlay/components/toggletip/directives/toggletip/toggletip.directive.mjs +3 -3
  154. package/esm2022/lib/components/overlay/components/tooltip/components/tooltip/tooltip.component.mjs +3 -3
  155. package/esm2022/lib/components/overlay/components/tooltip/directives/tooltip/tooltip.directive.mjs +3 -3
  156. package/esm2022/lib/components/overlay/directives/dynamic-overlay-title/dynamic-overlay-title.directive.mjs +3 -3
  157. package/esm2022/lib/components/overlay/directives/overlay-close-auto-blocker/overlay-close-auto-blocker.directive.mjs +3 -3
  158. package/esm2022/lib/components/overlay/services/dynamic-overlay.service.mjs +3 -3
  159. package/esm2022/lib/components/pagination/components/pagination/pagination.component.mjs +3 -3
  160. package/esm2022/lib/components/pagination/partials/pagination-link/pagination-link.directive.mjs +3 -3
  161. package/esm2022/lib/components/pagination/services/pagination-head.service.mjs +3 -3
  162. package/esm2022/lib/components/picture/picture-data.directive.mjs +3 -3
  163. package/esm2022/lib/components/picture/picture.component.mjs +3 -3
  164. package/esm2022/lib/components/picture/pipes/normalize-source/normalize-source.pipe.mjs +3 -3
  165. package/esm2022/lib/components/progress-spinner/progress-spinner.component.mjs +3 -3
  166. package/esm2022/lib/components/query-error/components/query-error/query-error.component.mjs +3 -3
  167. package/esm2022/lib/components/query-error/directives/query-error/query-error.directive.mjs +3 -3
  168. package/esm2022/lib/components/scrollable/components/scrollable/scrollable.component.mjs +297 -166
  169. package/esm2022/lib/components/scrollable/directives/index.mjs +2 -0
  170. package/esm2022/lib/components/scrollable/directives/public-api.mjs +2 -0
  171. package/esm2022/lib/components/scrollable/directives/scrollable-ignore-child/public-api.mjs +2 -0
  172. package/esm2022/lib/components/scrollable/directives/scrollable-ignore-child/scrollable-ignore-child.directive.mjs +44 -0
  173. package/esm2022/lib/components/scrollable/public-api.mjs +2 -1
  174. package/esm2022/lib/components/skeleton/components/skeleton/skeleton.component.mjs +3 -3
  175. package/esm2022/lib/components/skeleton/partials/skeleton-item/skeleton-item.component.mjs +3 -3
  176. package/esm2022/lib/components/sort/components/sort-header/sort-header.component.mjs +3 -3
  177. package/esm2022/lib/components/sort/partials/sort/sort.directive.mjs +3 -3
  178. package/esm2022/lib/components/sort/services/sort-header-intl.mjs +3 -3
  179. package/esm2022/lib/components/table/components/table/table.component.mjs +3 -3
  180. package/esm2022/lib/components/table/partials/cells/cell/cell.directive.mjs +3 -3
  181. package/esm2022/lib/components/table/partials/cells/cell-def/cell-def.directive.mjs +3 -3
  182. package/esm2022/lib/components/table/partials/cells/column-def/column-def.directive.mjs +3 -3
  183. package/esm2022/lib/components/table/partials/cells/footer-cell/footer-cell.directive.mjs +3 -3
  184. package/esm2022/lib/components/table/partials/cells/footer-cell-def/footer-cell-def.directive.mjs +3 -3
  185. package/esm2022/lib/components/table/partials/cells/header-cell/header-cell.directive.mjs +3 -3
  186. package/esm2022/lib/components/table/partials/cells/header-cell-def/header-cell-def.directive.mjs +3 -3
  187. package/esm2022/lib/components/table/partials/cells/text-column/text-column.component.mjs +3 -3
  188. package/esm2022/lib/components/table/partials/rows/footer-row/footer-row.component.mjs +3 -3
  189. package/esm2022/lib/components/table/partials/rows/footer-row-def/footer-row-def.directive.mjs +3 -3
  190. package/esm2022/lib/components/table/partials/rows/header-row/header-row.component.mjs +3 -3
  191. package/esm2022/lib/components/table/partials/rows/header-row-def/header-row-def.directive.mjs +3 -3
  192. package/esm2022/lib/components/table/partials/rows/no-data-row/no-data-row.directive.mjs +3 -3
  193. package/esm2022/lib/components/table/partials/rows/recycle-rows/recycle-rows.directive.mjs +3 -3
  194. package/esm2022/lib/components/table/partials/rows/row/row.component.mjs +3 -3
  195. package/esm2022/lib/components/table/partials/rows/row-def/row-def.directive.mjs +3 -3
  196. package/esm2022/lib/components/table/partials/table-busy/table-busy.directive.mjs +3 -3
  197. package/esm2022/lib/components/table/partials/table-busy-outlet/table-busy-outlet.directive.mjs +3 -3
  198. package/esm2022/lib/components/tabs/components/inline-tabs/inline-tabs.component.mjs +3 -3
  199. package/esm2022/lib/components/tabs/components/nav-tabs/nav-tabs.component.mjs +3 -3
  200. package/esm2022/lib/components/tabs/partials/inline-tabs/inline-tab/inline-tab.component.mjs +3 -3
  201. package/esm2022/lib/components/tabs/partials/inline-tabs/inline-tab-body/inline-tab-body.component.mjs +3 -3
  202. package/esm2022/lib/components/tabs/partials/inline-tabs/inline-tab-body-host/inline-tab-body-host.directive.mjs +3 -3
  203. package/esm2022/lib/components/tabs/partials/inline-tabs/inline-tab-content/inline-tab-content.directive.mjs +3 -3
  204. package/esm2022/lib/components/tabs/partials/inline-tabs/inline-tab-header/inline-tab-header.component.mjs +3 -3
  205. package/esm2022/lib/components/tabs/partials/inline-tabs/inline-tab-label/inline-tab-label.directive.mjs +3 -3
  206. package/esm2022/lib/components/tabs/partials/inline-tabs/inline-tab-label-wrapper/inline-tab-label-wrapper.directive.mjs +3 -3
  207. package/esm2022/lib/components/tabs/partials/nav-tabs/nav-tab-link/nav-tab-link.directive.mjs +3 -3
  208. package/esm2022/lib/components/tabs/partials/nav-tabs/nav-tabs-outlet/nav-tabs-outlet.component.mjs +3 -3
  209. package/esm2022/lib/components/tabs/utils/active-tab-underline.util.mjs +3 -3
  210. package/esm2022/lib/components/tabs/utils/paginated-tab-header.directive.mjs +3 -3
  211. package/esm2022/lib/services/swipe-handler.service.mjs +3 -3
  212. package/fesm2022/ethlete-cdk.mjs +955 -785
  213. package/fesm2022/ethlete-cdk.mjs.map +1 -1
  214. package/lib/components/scrollable/components/scrollable/scrollable.component.d.ts +37 -32
  215. package/lib/components/scrollable/directives/index.d.ts +1 -0
  216. package/lib/components/scrollable/directives/public-api.d.ts +1 -0
  217. package/lib/components/scrollable/directives/scrollable-ignore-child/public-api.d.ts +1 -0
  218. package/lib/components/scrollable/directives/scrollable-ignore-child/scrollable-ignore-child.directive.d.ts +16 -0
  219. package/lib/components/scrollable/public-api.d.ts +1 -0
  220. package/package.json +7 -7
@@ -1,9 +1,23 @@
1
1
  import { NgClass } from '@angular/common';
2
2
  import { ChangeDetectionStrategy, Component, ContentChildren, ElementRef, EventEmitter, Input, Output, ViewChild, ViewEncapsulation, booleanAttribute, computed, effect, inject, isDevMode, numberAttribute, signal, } from '@angular/core';
3
- import { CursorDragScrollDirective, IS_ACTIVE_ELEMENT, IS_ELEMENT, LetDirective, ObserveScrollStateDirective, TypedQueryList, createDestroy, getElementVisibleStates, isElementVisible, nextFrame, scrollToElement, signalElementIntersection, signalElementScrollState, signalHostAttributes, signalHostClasses, } from '@ethlete/core';
4
- import { BehaviorSubject, debounceTime, fromEvent, merge, of, startWith, takeUntil, tap } from 'rxjs';
3
+ import { takeUntilDestroyed, toObservable } from '@angular/core/rxjs-interop';
4
+ import { CursorDragScrollDirective, IS_ACTIVE_ELEMENT, LetDirective, ObserveScrollStateDirective, TypedQueryList, getFirstAndLastPartialIntersection, isElementVisible, nextFrame, scrollToElement, signalElementChildren, signalElementIntersection, signalElementScrollState, signalHostAttributes, signalHostClasses, } from '@ethlete/core';
5
+ import { BehaviorSubject, Subject, combineLatest, debounceTime, filter, fromEvent, map, take, takeUntil, tap, } from 'rxjs';
5
6
  import { ChevronIconComponent } from '../../../icons';
7
+ import { ScrollableIgnoreChildDirective, isScrollableChildIgnored } from '../../directives';
6
8
  import * as i0 from "@angular/core";
9
+ // Thresholds for the intersection observer.
10
+ const ELEMENT_INTERSECTION_THRESHOLD = [
11
+ // We use 51 steps to get a 2% step size.
12
+ ...Array.from({ length: 51 }, (_, i) => i / 50),
13
+ // Additional steps needed since display scaling can cause the intersection ratio to be slightly off.
14
+ 0.01,
15
+ 0.005,
16
+ 0.001,
17
+ 0.99,
18
+ 0.995,
19
+ 0.999,
20
+ ];
7
21
  export class ScrollableComponent {
8
22
  set _itemSize(v) {
9
23
  this.itemSize.set(v);
@@ -17,6 +31,9 @@ export class ScrollableComponent {
17
31
  set _scrollableClass(v) {
18
32
  this.scrollableClass.set(v);
19
33
  }
34
+ set _renderNavigation(v) {
35
+ this.renderNavigation.set(v);
36
+ }
20
37
  set _renderMasks(v) {
21
38
  this.renderMasks.set(v);
22
39
  }
@@ -47,6 +64,9 @@ export class ScrollableComponent {
47
64
  set _scrollable(e) {
48
65
  this.scrollable.set(e);
49
66
  }
67
+ set _scrollableContainer(e) {
68
+ this.scrollableContainer.set(e);
69
+ }
50
70
  set _firstElement(e) {
51
71
  this.firstElement.set(e);
52
72
  }
@@ -56,65 +76,14 @@ export class ScrollableComponent {
56
76
  set _activeElementList(e) {
57
77
  this.activeElementList.set(e);
58
78
  }
59
- set _elementList(e) {
60
- this.elementList.set(e);
61
- }
62
- get highestVisibleIntersection() {
63
- const elements = this._latestVisibilityStates$.value;
64
- if (!elements.length) {
65
- return null;
66
- }
67
- return elements.reduce((prev, curr) => {
68
- if (!prev) {
69
- return curr;
70
- }
71
- return curr.intersectionRatio > prev.intersectionRatio ? curr : prev;
72
- });
73
- }
74
- get nextPartialIntersection() {
75
- const elements = this._latestVisibilityStates$.value;
76
- if (!elements.length) {
77
- return null;
78
- }
79
- const highestVisibleIntersection = this.highestVisibleIntersection;
80
- if (!highestVisibleIntersection) {
81
- return null;
82
- }
83
- const nextIndex = elements.slice(highestVisibleIntersection.index).findIndex((e) => !e.isIntersecting);
84
- if (nextIndex === -1) {
85
- return null;
86
- }
87
- const nextElement = elements[highestVisibleIntersection.index + nextIndex];
88
- return nextElement || null;
89
- }
90
- get previousPartialIntersection() {
91
- const elements = this._latestVisibilityStates$.value;
92
- if (!elements.length) {
93
- return null;
94
- }
95
- const highestVisibleIntersection = this.highestVisibleIntersection;
96
- if (!highestVisibleIntersection) {
97
- return null;
98
- }
99
- const previousIndex = elements
100
- .slice(0, highestVisibleIntersection.index)
101
- .reverse()
102
- .findIndex((e) => !e.isIntersecting);
103
- if (previousIndex === -1) {
104
- return null;
105
- }
106
- const previousElement = elements[highestVisibleIntersection.index - previousIndex - 1];
107
- return previousElement || null;
108
- }
109
79
  constructor() {
110
- this._destroy$ = createDestroy();
111
80
  this._elementRef = inject(ElementRef);
112
81
  this._isCursorDragging$ = new BehaviorSubject(false);
113
- this._latestVisibilityStates$ = new BehaviorSubject([]);
114
82
  this.itemSize = signal('auto');
115
83
  this.direction = signal('horizontal');
116
84
  this.scrollableRole = signal(null);
117
85
  this.scrollableClass = signal(null);
86
+ this.renderNavigation = signal(false);
118
87
  this.renderMasks = signal(true);
119
88
  this.renderButtons = signal(true);
120
89
  this.renderScrollbars = signal(false);
@@ -127,15 +96,24 @@ export class ScrollableComponent {
127
96
  this.scrollStateChange = new EventEmitter();
128
97
  this.intersectionChange = new EventEmitter();
129
98
  this.scrollable = signal(null);
99
+ this.scrollableContainer = signal(null);
130
100
  this.firstElement = signal(null);
131
101
  this.lastElement = signal(null);
132
102
  this.activeElementList = signal(null);
133
- this.elementList = signal(null);
134
103
  this.containerScrollState = signalElementScrollState(this.scrollable);
135
104
  this.firstElementIntersection = signalElementIntersection(this.firstElement, { root: this.scrollable });
136
105
  this.firstElementVisibility = signal(null);
137
106
  this.lastElementIntersection = signalElementIntersection(this.lastElement, { root: this.scrollable });
138
107
  this.lastElementVisibility = signal(null);
108
+ this.allScrollableChildren = signalElementChildren(this.scrollableContainer);
109
+ this.scrollableChildren = computed(() => this.allScrollableChildren().filter((c) => !isScrollableChildIgnored(c)));
110
+ this._disableSnapping$ = new Subject();
111
+ this.scrollableContentIntersections = signalElementIntersection(this.scrollableChildren, {
112
+ root: this.scrollable,
113
+ threshold: ELEMENT_INTERSECTION_THRESHOLD,
114
+ });
115
+ this.scrollableContentIntersections$ = toObservable(this.scrollableContentIntersections);
116
+ this.manualActiveNavigationIndex = signal(null);
139
117
  this.canScroll = computed(() => {
140
118
  const dir = this.direction();
141
119
  if (dir === 'horizontal') {
@@ -147,7 +125,7 @@ export class ScrollableComponent {
147
125
  if (!this.canScroll()) {
148
126
  return true;
149
127
  }
150
- const intersection = this.firstElementIntersection();
128
+ const intersection = this.firstElementIntersection()[0];
151
129
  if (!intersection) {
152
130
  return this.firstElementVisibility()?.inline ?? true;
153
131
  }
@@ -157,20 +135,44 @@ export class ScrollableComponent {
157
135
  if (!this.canScroll()) {
158
136
  return true;
159
137
  }
160
- const intersection = this.lastElementIntersection();
138
+ const intersection = this.lastElementIntersection()[0];
161
139
  if (!intersection) {
162
140
  return this.lastElementVisibility()?.inline ?? true;
163
141
  }
164
142
  return intersection.isIntersecting;
165
143
  });
166
144
  this.enableOverlayAnimations = signal(false);
167
- this.hostAttributes = signalHostAttributes({
145
+ this._initialScrollableNavigation = signal([]);
146
+ this.scrollableNavigation = computed(() => {
147
+ const allIntersections = this.scrollableContentIntersections();
148
+ const manualActiveNavigationIndex = this.manualActiveNavigationIndex();
149
+ const initialScrollableNavigation = this._initialScrollableNavigation();
150
+ if (!allIntersections.length) {
151
+ return initialScrollableNavigation;
152
+ }
153
+ const highestIntersection = allIntersections.reduce((prev, curr) => {
154
+ if (prev && prev.intersectionRatio > curr.intersectionRatio) {
155
+ return prev;
156
+ }
157
+ return curr;
158
+ }, allIntersections[0]);
159
+ if (!highestIntersection) {
160
+ return [];
161
+ }
162
+ return allIntersections.map((i, index) => ({
163
+ isActive: manualActiveNavigationIndex !== null
164
+ ? manualActiveNavigationIndex === index
165
+ : i === highestIntersection && highestIntersection.intersectionRatio > 0,
166
+ element: i.target,
167
+ }));
168
+ });
169
+ this.hostAttributeBindings = signalHostAttributes({
168
170
  'item-size': this.itemSize,
169
171
  direction: this.direction,
170
172
  'render-scrollbars': this.renderScrollbars,
171
173
  'sticky-buttons': this.stickyButtons,
172
174
  });
173
- this.hostClasses = signalHostClasses({
175
+ this.hostClassBindings = signalHostClasses({
174
176
  'et-scrollable--can-scroll': this.canScroll,
175
177
  'et-scrollable--is-at-start': this.isAtStart,
176
178
  'et-scrollable--is-at-end': this.isAtEnd,
@@ -188,8 +190,8 @@ export class ScrollableComponent {
188
190
  if (firstActive && !this.disableActiveElementScrolling()) {
189
191
  const offsetTop = firstActive.elementRef.nativeElement.offsetTop - scrollable.offsetTop;
190
192
  const offsetLeft = firstActive.elementRef.nativeElement.offsetLeft - scrollable.offsetLeft;
191
- scrollable.scrollLeft = offsetLeft;
192
- scrollable.scrollTop = offsetTop;
193
+ scrollable.scrollLeft = offsetLeft - this.scrollMargin();
194
+ scrollable.scrollTop = offsetTop - this.scrollMargin();
193
195
  }
194
196
  this.firstElementVisibility.set(isElementVisible({
195
197
  container: scrollable,
@@ -202,6 +204,23 @@ export class ScrollableComponent {
202
204
  // We need to wait one frame before enabling animations to prevent a animation from playing during initial render.
203
205
  nextFrame(() => this.enableOverlayAnimations.set(true));
204
206
  }, { allowSignalWrites: true });
207
+ effect(() => {
208
+ const elementList = this.scrollableChildren();
209
+ const scrollable = this.scrollable()?.nativeElement;
210
+ const renderNavigation = this.renderNavigation();
211
+ if (!elementList || !scrollable || !renderNavigation) {
212
+ return;
213
+ }
214
+ const firstVisibleElement = elementList.find((e) => isElementVisible({ container: scrollable, element: e }));
215
+ if (!firstVisibleElement) {
216
+ return;
217
+ }
218
+ const initialNavigationStuff = elementList.map((e) => ({
219
+ isActive: e === firstVisibleElement,
220
+ element: e,
221
+ }));
222
+ this._initialScrollableNavigation.set(initialNavigationStuff);
223
+ }, { allowSignalWrites: true });
205
224
  effect(() => {
206
225
  const isAtStart = this.isAtStart();
207
226
  const isAtEnd = this.isAtEnd();
@@ -212,9 +231,25 @@ export class ScrollableComponent {
212
231
  isAtStart: !!isAtStart,
213
232
  });
214
233
  });
215
- }
216
- ngAfterContentInit() {
217
- this._setupScrollListening();
234
+ effect(() => {
235
+ const enableSnapping = this.snap();
236
+ if (enableSnapping) {
237
+ this._enableSnapping();
238
+ }
239
+ else {
240
+ this._disableSnapping();
241
+ }
242
+ });
243
+ this.scrollableContentIntersections$
244
+ .pipe(takeUntilDestroyed(), debounceTime(10), tap((entries) => {
245
+ this.intersectionChange.emit(entries.map((i, index) => ({
246
+ index,
247
+ element: i.target,
248
+ intersectionRatio: i.intersectionRatio,
249
+ isIntersecting: i.isIntersecting,
250
+ })));
251
+ }))
252
+ .subscribe();
218
253
  }
219
254
  scrollOneContainerSize(direction) {
220
255
  const scrollElement = this.scrollable()?.nativeElement;
@@ -222,38 +257,129 @@ export class ScrollableComponent {
222
257
  return;
223
258
  }
224
259
  const parent = this._elementRef.nativeElement;
225
- const scrollableSize = this.direction() === 'horizontal' ? parent.clientWidth : parent.clientHeight;
226
- const currentScroll = this.direction() === 'horizontal' ? scrollElement.scrollLeft : scrollElement.scrollTop;
227
- scrollElement.scrollTo({
228
- [this.direction() === 'horizontal' ? 'left' : 'top']: currentScroll + (direction === 'start' ? -scrollableSize : scrollableSize),
229
- behavior: 'smooth',
230
- });
260
+ const isSnappingEnabled = this.snap();
261
+ if (isSnappingEnabled) {
262
+ // If snapping is enabled we want to scroll to a position where no further snapping will happen after the scroll.
263
+ const allIntersections = this.scrollableContentIntersections();
264
+ const intersections = getFirstAndLastPartialIntersection(allIntersections);
265
+ const relevantIntersection = direction === 'start' ? intersections?.first : intersections?.last;
266
+ if (!relevantIntersection)
267
+ return;
268
+ const nextIndex = relevantIntersection.intersection.intersectionRatio !== 1
269
+ ? relevantIntersection.index
270
+ : direction === 'start'
271
+ ? relevantIntersection.index - 1
272
+ : relevantIntersection.index + 1;
273
+ const element = allIntersections[nextIndex]?.target ||
274
+ relevantIntersection.intersection.target;
275
+ this.scrollToElement({
276
+ element: element,
277
+ origin: direction === 'end' ? 'start' : 'end',
278
+ });
279
+ }
280
+ else {
281
+ // Just scroll one size of the scrollable container.
282
+ const scrollableSize = this.direction() === 'horizontal' ? parent.clientWidth : parent.clientHeight;
283
+ const currentScroll = this.direction() === 'horizontal' ? scrollElement.scrollLeft : scrollElement.scrollTop;
284
+ scrollElement.scrollTo({
285
+ [this.direction() === 'horizontal' ? 'left' : 'top']: currentScroll + (direction === 'start' ? -scrollableSize : scrollableSize),
286
+ behavior: 'smooth',
287
+ });
288
+ }
231
289
  }
232
290
  scrollOneItemSize(direction) {
233
- const elements = this._latestVisibilityStates$.value;
234
- if (!elements.length) {
291
+ const allIntersections = this.scrollableContentIntersections();
292
+ const scrollElement = this.scrollable()?.nativeElement;
293
+ if (!allIntersections.length) {
235
294
  if (isDevMode()) {
236
295
  console.warn('No elements found to scroll to. Make sure to apply the isElement directive to the elements you want to scroll to.');
237
296
  }
238
297
  return;
239
298
  }
240
- const el = direction === 'start' ? this.previousPartialIntersection : this.nextPartialIntersection;
241
- if (!el) {
299
+ const intersections = getFirstAndLastPartialIntersection(allIntersections);
300
+ if (!intersections || !scrollElement)
242
301
  return;
302
+ // Means the current element is bigger than the scrollable container.
303
+ // In this case we should scroll to the start of the current element. If we are already there we should scroll to the end of the previous element.
304
+ // This applies to the other direction as well.
305
+ const isFirstAndLastIntersectionEqual = intersections.first.intersection === intersections.last.intersection;
306
+ const scrollableRect = scrollElement.getBoundingClientRect();
307
+ if (isFirstAndLastIntersectionEqual) {
308
+ const intersection = intersections.first.intersection.target.getBoundingClientRect();
309
+ const isStartOfElementVisible = this.direction() === 'horizontal'
310
+ ? intersection.left >= scrollableRect.left
311
+ : intersection.top >= scrollableRect.top;
312
+ const isEndOfElementVisible = this.direction() === 'horizontal'
313
+ ? intersection.right <= scrollableRect.right
314
+ : intersection.bottom <= scrollableRect.bottom;
315
+ if (!isStartOfElementVisible || !isEndOfElementVisible) {
316
+ if (direction === 'start') {
317
+ if (isStartOfElementVisible) {
318
+ // to the end of the previous element
319
+ const previousIndex = intersections.first.index - 1;
320
+ const elementToScrollTo = allIntersections[previousIndex]?.target;
321
+ if (!elementToScrollTo)
322
+ return;
323
+ this.scrollToElement({
324
+ element: elementToScrollTo,
325
+ origin: 'end',
326
+ });
327
+ }
328
+ else {
329
+ // to the start of the current element
330
+ this.scrollToElement({
331
+ element: intersections.first.intersection.target,
332
+ origin: 'start',
333
+ });
334
+ }
335
+ }
336
+ else {
337
+ if (isEndOfElementVisible) {
338
+ // to the start of the next element
339
+ const nextIndex = intersections.last.index + 1;
340
+ const elementToScrollTo = allIntersections[nextIndex]?.target;
341
+ if (!elementToScrollTo)
342
+ return;
343
+ this.scrollToElement({
344
+ element: elementToScrollTo,
345
+ origin: 'start',
346
+ });
347
+ }
348
+ else {
349
+ // to the end of the current element
350
+ this.scrollToElement({
351
+ element: intersections.last.intersection.target,
352
+ origin: 'end',
353
+ });
354
+ }
355
+ }
356
+ return;
357
+ }
358
+ }
359
+ const data = direction === 'start' ? intersections.first : intersections.last;
360
+ let elementToScrollTo = data.intersection.target;
361
+ if (data.intersection.intersectionRatio === 1) {
362
+ if (direction === 'start' && data.index === 0) {
363
+ return;
364
+ }
365
+ if (direction === 'end' && data.index === allIntersections.length - 1) {
366
+ return;
367
+ }
368
+ const nextIndex = direction === 'start' ? data.index - 1 : data.index + 1;
369
+ elementToScrollTo = allIntersections[nextIndex]?.target;
243
370
  }
371
+ if (!elementToScrollTo)
372
+ return;
244
373
  this.scrollToElement({
245
- element: el?.element,
246
- direction: this.direction() === 'horizontal' ? 'inline' : 'block',
374
+ element: elementToScrollTo,
247
375
  origin: direction,
248
- ...(this.direction() === 'horizontal'
249
- ? { scrollInlineMargin: this.scrollMargin() }
250
- : { scrollBlockMargin: this.scrollMargin() }),
251
376
  });
252
377
  }
253
378
  scrollToElement(options) {
254
379
  const scrollElement = this.scrollable()?.nativeElement;
255
380
  scrollToElement({
256
381
  container: scrollElement,
382
+ direction: this.direction() === 'horizontal' ? 'inline' : 'block',
257
383
  ...(this.direction() === 'horizontal'
258
384
  ? { scrollInlineMargin: this.scrollMargin() }
259
385
  : { scrollBlockMargin: this.scrollMargin() }),
@@ -261,7 +387,7 @@ export class ScrollableComponent {
261
387
  });
262
388
  }
263
389
  scrollToElementByIndex(options) {
264
- const elements = this.elementList()?.toArray() ?? [];
390
+ const elements = this.scrollableChildren();
265
391
  if (!elements.length) {
266
392
  if (isDevMode()) {
267
393
  console.warn('No elements found to scroll to. Make sure to apply the isElement directive to the elements you want to scroll to.');
@@ -269,7 +395,7 @@ export class ScrollableComponent {
269
395
  return;
270
396
  }
271
397
  const scrollElement = this.scrollable()?.nativeElement;
272
- const element = elements[options.index]?.elementRef.nativeElement;
398
+ const element = elements[options.index];
273
399
  scrollToElement({
274
400
  container: scrollElement,
275
401
  element,
@@ -279,6 +405,18 @@ export class ScrollableComponent {
279
405
  ...options,
280
406
  });
281
407
  }
408
+ scrollToElementViaNavigation(elementIndex, element) {
409
+ this.manualActiveNavigationIndex.set(elementIndex);
410
+ this.scrollToElement({
411
+ element,
412
+ });
413
+ const scrollElement = this.scrollable()?.nativeElement;
414
+ if (!scrollElement)
415
+ return;
416
+ fromEvent(scrollElement, 'scroll')
417
+ .pipe(debounceTime(50), take(1), tap(() => this.manualActiveNavigationIndex.set(null)))
418
+ .subscribe();
419
+ }
282
420
  setIsCursorDragging(isDragging) {
283
421
  this._isCursorDragging$.next(isDragging);
284
422
  }
@@ -290,7 +428,7 @@ export class ScrollableComponent {
290
428
  this.scrollOneItemSize('start');
291
429
  }
292
430
  }
293
- scrollToStartEnd() {
431
+ scrollToEndDirection() {
294
432
  if (this.scrollMode() === 'container') {
295
433
  this.scrollOneContainerSize('end');
296
434
  }
@@ -298,95 +436,85 @@ export class ScrollableComponent {
298
436
  this.scrollOneItemSize('end');
299
437
  }
300
438
  }
301
- _setupScrollListening() {
302
- const scrollElement = this.scrollable()?.nativeElement;
303
- const elements = this.elementList();
304
- if (!scrollElement || !elements) {
305
- return;
306
- }
307
- let isSnapping = false;
308
- let snapTimeout = 0;
309
- merge(fromEvent(scrollElement, 'wheel'), fromEvent(scrollElement, 'touchstart'))
310
- .pipe(takeUntil(this._destroy$), tap(() => {
311
- isSnapping = false;
312
- }))
313
- .subscribe();
314
- merge(fromEvent(scrollElement, 'scroll'), this._isCursorDragging$, elements.changes.pipe(startWith(elements)) ?? of(null))
315
- .pipe(debounceTime(300), takeUntil(this._destroy$), tap(() => {
316
- const els = elements
317
- ?.toArray()
318
- .map((e) => e?.elementRef.nativeElement)
319
- .filter((e) => !!e) ?? [];
320
- if (!els.length) {
321
- this._latestVisibilityStates$.next([]);
439
+ _enableSnapping() {
440
+ combineLatest([this.scrollableContentIntersections$, this._isCursorDragging$])
441
+ .pipe(filter(([, isDragging]) => !isDragging), map(([intersections]) => intersections), debounceTime(150), tap((allIntersections) => {
442
+ const scrollElement = this.scrollable()?.nativeElement;
443
+ if (!scrollElement)
322
444
  return;
323
- }
324
- const states = getElementVisibleStates({
325
- elements: els,
326
- container: scrollElement,
327
- });
328
- const prop = this.direction() === 'horizontal' ? 'inlineIntersection' : 'blockIntersection';
329
- const stateClass = `et-element--is-intersecting`;
330
- for (const state of states) {
331
- if (state[prop] === 100) {
332
- state.element.classList.add(stateClass);
445
+ const intersections = getFirstAndLastPartialIntersection(allIntersections);
446
+ if (!intersections)
447
+ return;
448
+ const isFirstAndLastIntersectionEqual = intersections.first.intersection === intersections.last.intersection;
449
+ const scrollableRect = scrollElement.getBoundingClientRect();
450
+ if (isFirstAndLastIntersectionEqual) {
451
+ const intersection = intersections.first.intersection.target.getBoundingClientRect();
452
+ const isStartOfElementVisible = this.direction() === 'horizontal'
453
+ ? intersection.left >= scrollableRect.left
454
+ : intersection.top >= scrollableRect.top;
455
+ const isEndOfElementVisible = this.direction() === 'horizontal'
456
+ ? intersection.right <= scrollableRect.right
457
+ : intersection.bottom <= scrollableRect.bottom;
458
+ // Don't snap if neither the start nor the end of the current element is visible.
459
+ // Otherwise this would result in parts of the element being inaccessible.
460
+ if (!isStartOfElementVisible && !isEndOfElementVisible)
461
+ return;
462
+ // If the start of the element is visible we should snap to the start.
463
+ if (isStartOfElementVisible) {
464
+ this.scrollToElement({
465
+ element: intersections.first.intersection.target,
466
+ origin: 'start',
467
+ });
468
+ return;
333
469
  }
334
- else {
335
- state.element.classList.remove(stateClass);
470
+ // If the end of the element is visible we should snap to the end.
471
+ if (isEndOfElementVisible) {
472
+ this.scrollToElement({
473
+ element: intersections.last.intersection.target,
474
+ origin: 'end',
475
+ });
476
+ return;
336
477
  }
337
478
  }
338
- const intersectionChanges = states.map((s, i) => {
339
- const state = {
340
- element: s.element,
341
- intersectionRatio: s[prop] / 100,
342
- isIntersecting: s[prop] === 100,
343
- index: i,
344
- };
345
- return state;
346
- });
347
- this.intersectionChange.emit(intersectionChanges);
348
- this._latestVisibilityStates$.next(intersectionChanges);
349
- if (isSnapping || this._isCursorDragging$.value || !this.snap())
350
- return;
351
- const prev = this.previousPartialIntersection;
352
- const next = this.nextPartialIntersection;
353
- const skipSnap = !prev ||
354
- !next ||
355
- prev.intersectionRatio === 0 ||
356
- next.intersectionRatio === 0 ||
357
- prev.intersectionRatio === next.intersectionRatio;
358
- if (skipSnap)
359
- return;
360
- const highestIntersecting = prev.intersectionRatio > next.intersectionRatio ? prev : next;
361
- const fullIntersectionIndex = this.highestVisibleIntersection?.index;
362
- if (fullIntersectionIndex === undefined)
363
- return;
364
- const highestIntersectingIndex = highestIntersecting.index;
365
- const origin = highestIntersectingIndex > fullIntersectionIndex ? 'end' : 'start';
366
- scrollToElement({
367
- container: scrollElement,
368
- element: highestIntersecting.element,
369
- direction: this.direction() === 'horizontal' ? 'inline' : 'block',
370
- origin,
371
- scrollBlockMargin: this.direction() === 'horizontal' ? 0 : this.scrollMargin(),
372
- scrollInlineMargin: this.direction() === 'horizontal' ? this.scrollMargin() : 0,
373
- });
374
- isSnapping = true;
375
- window.clearTimeout(snapTimeout);
376
- snapTimeout = window.setTimeout(() => {
377
- isSnapping = false;
378
- }, 1000);
379
- }))
479
+ else if ((this.direction() === 'horizontal' &&
480
+ intersections.biggest.intersection.boundingClientRect.width > scrollableRect.width) ||
481
+ (this.direction() === 'vertical' &&
482
+ intersections.biggest.intersection.boundingClientRect.height > scrollableRect.height)) {
483
+ // If the current element is bigger than the scrollable container we should snap to the start of the current element if the scroll direction is forward
484
+ // and to the end of the current element if the scroll direction is backwards.
485
+ const origin = intersections.biggest.index === intersections.first.index ? 'end' : 'start';
486
+ this.scrollToElement({
487
+ element: intersections.biggest.intersection.target,
488
+ origin,
489
+ });
490
+ }
491
+ else {
492
+ // No special case. Just snap to the biggest intersection.
493
+ this.scrollToElement({
494
+ element: intersections.biggest.intersection.target,
495
+ });
496
+ }
497
+ }), takeUntil(this._disableSnapping$))
380
498
  .subscribe();
381
499
  }
382
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.0.2", ngImport: i0, type: ScrollableComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
383
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "17.0.2", type: ScrollableComponent, isStandalone: true, selector: "et-scrollable", inputs: { _itemSize: ["itemSize", "_itemSize"], _direction: ["direction", "_direction"], _scrollableRole: ["scrollableRole", "_scrollableRole"], _scrollableClass: ["scrollableClass", "_scrollableClass"], _renderMasks: ["renderMasks", "_renderMasks", booleanAttribute], _renderButtons: ["renderButtons", "_renderButtons", booleanAttribute], _renderScrollbars: ["renderScrollbars", "_renderScrollbars", booleanAttribute], _stickyButtons: ["stickyButtons", "_stickyButtons", booleanAttribute], _cursorDragScroll: ["cursorDragScroll", "_cursorDragScroll", booleanAttribute], _disableActiveElementScrolling: ["disableActiveElementScrolling", "_disableActiveElementScrolling", booleanAttribute], _scrollMode: ["scrollMode", "_scrollMode"], _snap: ["snap", "_snap", booleanAttribute], _scrollMargin: ["scrollMargin", "_scrollMargin", numberAttribute] }, outputs: { scrollStateChange: "scrollStateChange", intersectionChange: "intersectionChange" }, host: { classAttribute: "et-scrollable" }, queries: [{ propertyName: "_activeElementList", predicate: IS_ACTIVE_ELEMENT, descendants: true }, { propertyName: "_elementList", predicate: IS_ELEMENT, descendants: true }], viewQueries: [{ propertyName: "_scrollable", first: true, predicate: ["scrollable"], descendants: true, static: true }, { propertyName: "_firstElement", first: true, predicate: ["firstElement"], descendants: true, static: true }, { propertyName: "_lastElement", first: true, predicate: ["lastElement"], descendants: true, static: true }], ngImport: i0, template: "<div\n #scrollable\n [attr.role]=\"scrollableRole() ?? undefined\"\n [etCursorDragScroll]=\"cursorDragScroll()\"\n [allowedDirection]=\"direction()\"\n (cursorDragStart)=\"setIsCursorDragging(true)\"\n (cursorDragEnd)=\"setIsCursorDragging(false)\"\n class=\"et-scrollable-container-outer\"\n>\n <div [ngClass]=\"scrollableClass()\" class=\"et-scrollable-container\">\n <div #firstElement class=\"et-scroll-observer-first-element\"></div>\n <ng-content />\n <div #lastElement class=\"et-scroll-observer-last-element\"></div>\n </div>\n</div>\n\n@if (renderMasks()) {\n <div class=\"et-scrollable-masks\">\n <div class=\"et-scrollable-mask et-scrollable-mask--start\"></div>\n <div class=\"et-scrollable-mask et-scrollable-mask--end\"></div>\n </div>\n}\n\n@if (renderButtons()) {\n <div class=\"et-scrollable-buttons\">\n <button\n (click)=\"scrollToStartDirection()\"\n class=\"et-scrollable-button et-scrollable-button--start\"\n aria-hidden=\"true\"\n type=\"button\"\n tabindex=\"-1\"\n >\n <et-chevron-icon />\n </button>\n <button\n (click)=\"scrollToStartEnd()\"\n class=\"et-scrollable-button et-scrollable-button--end\"\n aria-hidden=\"true\"\n type=\"button\"\n tabindex=\"-1\"\n >\n <et-chevron-icon />\n </button>\n </div>\n}\n", styles: [".et-scrollable{--mask: #121212 0, transparent 100%;--mask-size: 25px;--_auto-size: min-content;--_flow: column;display:grid;position:relative}.et-scrollable[item-size=same]{--_auto-size: 1fr}.et-scrollable[item-size=full]{--_auto-size: 100%}.et-scrollable[render-scrollbars=false] .et-scrollable-container-outer{scrollbar-width:none}.et-scrollable[render-scrollbars=false] .et-scrollable-container-outer::-webkit-scrollbar{display:none}.et-scrollable[direction=horizontal] .et-scrollable-container-outer{overflow-x:auto;overflow-y:hidden}.et-scrollable[direction=horizontal] .et-scrollable-container{grid-auto-columns:var(--_auto-size)}.et-scrollable[direction=horizontal] .et-scrollable-mask,.et-scrollable[direction=horizontal] .et-scrollable-button{inline-size:var(--mask-size);block-size:100%}.et-scrollable[direction=horizontal] .et-scrollable-mask--start,.et-scrollable[direction=horizontal] .et-scrollable-button--start{inset-block-start:0;inset-inline:0 0}.et-scrollable[direction=horizontal] .et-scrollable-mask--end,.et-scrollable[direction=horizontal] .et-scrollable-button--end{inset-block-start:0;inset-inline:calc(100% - 40px) 0}.et-scrollable[direction=horizontal] .et-scrollable-mask--start{background:linear-gradient(to right,var(--mask))}.et-scrollable[direction=horizontal] .et-scrollable-mask--end{background:linear-gradient(to left,var(--mask));inset-inline:calc(100% - var(--mask-size)) 100%}.et-scrollable[direction=horizontal] .et-scrollable-button--start{inset-block-start:calc(50% - 20px);transform:rotate(-90deg)}.et-scrollable[direction=horizontal] .et-scrollable-button--end{inset-block-start:calc(50% - 20px);transform:rotate(90deg)}.et-scrollable[direction=vertical]{--_flow: row}.et-scrollable[direction=vertical] .et-scrollable-container-outer{overflow-x:hidden;overflow-y:auto}.et-scrollable[direction=vertical] .et-scrollable-container{grid-auto-rows:var(--_auto-size)}.et-scrollable[direction=vertical] .et-scrollable-mask,.et-scrollable[direction=vertical] .et-scrollable-button{block-size:var(--mask-size);inline-size:100%}.et-scrollable[direction=vertical] .et-scrollable-mask--start,.et-scrollable[direction=vertical] .et-scrollable-button--start{inset-block-start:0;inset-inline-start:0}.et-scrollable[direction=vertical] .et-scrollable-mask--end,.et-scrollable[direction=vertical] .et-scrollable-button--end{inset-block-end:0;inset-inline-start:0}.et-scrollable[direction=vertical] .et-scrollable-mask--start{background:linear-gradient(to bottom,var(--mask))}.et-scrollable[direction=vertical] .et-scrollable-mask--end{background:linear-gradient(to top,var(--mask))}.et-scrollable[direction=vertical] .et-scrollable-button--start{inset-inline-start:calc(50% - 20px);transform:rotate(0)}.et-scrollable[direction=vertical] .et-scrollable-button--end{inset-inline-start:calc(50% - 20px);transform:rotate(180deg)}.et-scrollable:not(.et-scrollable--is-at-start) .et-scrollable-masks .et-scrollable-mask--start,.et-scrollable:not(.et-scrollable--is-at-start) .et-scrollable-buttons .et-scrollable-button--start{opacity:1}.et-scrollable:not(.et-scrollable--is-at-start) .et-scrollable-buttons .et-scrollable-button--start{pointer-events:all}.et-scrollable:not(.et-scrollable--is-at-end) .et-scrollable-masks .et-scrollable-mask--end,.et-scrollable:not(.et-scrollable--is-at-end) .et-scrollable-buttons .et-scrollable-button--end{opacity:1}.et-scrollable:not(.et-scrollable--is-at-end) .et-scrollable-buttons .et-scrollable-button--end{pointer-events:all}.et-scrollable .et-scrollable-container-outer{overflow:auto;display:grid;grid-row:1/1;grid-column:1/1}.et-scrollable .et-scroll-observer-first-element,.et-scrollable .et-scroll-observer-last-element{position:absolute;block-size:100%;inline-size:1px;pointer-events:none}.et-scrollable .et-scroll-observer-first-element{inset-inline-start:1px}.et-scrollable .et-scroll-observer-last-element{inset-inline-end:1px}.et-scrollable .et-scrollable-container{display:grid;grid-auto-flow:var(--_flow);position:relative}.et-scrollable .et-scrollable-masks,.et-scrollable .et-scrollable-buttons{grid-row:1/1;grid-column:1/1;pointer-events:none}.et-scrollable .et-scrollable-masks .et-scrollable-mask,.et-scrollable .et-scrollable-masks .et-scrollable-button,.et-scrollable .et-scrollable-buttons .et-scrollable-mask,.et-scrollable .et-scrollable-buttons .et-scrollable-button{position:absolute;opacity:0}.et-scrollable.et-scrollable--can-scroll.et-scrollable--enable-overlay-animations .et-scrollable-mask,.et-scrollable.et-scrollable--can-scroll.et-scrollable--enable-overlay-animations .et-scrollable-button{transition:opacity .3s var(--ease-5)}.et-scrollable .et-scrollable-buttons .et-scrollable-button{background:transparent;border:none;padding:12px;inline-size:40px;block-size:40px;border-radius:4px;cursor:pointer}.et-scrollable .et-scrollable-buttons .et-scrollable-button .et-chevron-icon{pointer-events:none}.et-scrollable .et-scrollable-buttons .et-scrollable-button .et-scrollable-button--start{inset-inline:0 0}.et-scrollable .et-scrollable-buttons .et-scrollable-button .et-scrollable-button--end{inset-inline:calc(100% - 40px) 0}.et-scrollable[sticky-buttons=true]{--_sticky-margin: 10%}.et-scrollable[sticky-buttons=true] .et-scrollable-button{position:sticky}.et-scrollable[sticky-buttons=true][direction=horizontal] .et-scrollable-buttons{margin-block:var(--_sticky-margin)}.et-scrollable[sticky-buttons=true][direction=vertical] .et-scrollable-buttons{margin-inline:var(--_sticky-margin)}.et-scrollable[sticky-buttons=true][direction=vertical] .et-scrollable-buttons .et-scrollable-button--end{inset-block-start:100%}\n"], dependencies: [{ kind: "directive", type: CursorDragScrollDirective, selector: "[etCursorDragScroll]", inputs: ["etCursorDragScroll", "allowedDirection"], outputs: ["cursorDragStart", "cursorDragMove", "cursorDragEnd"], exportAs: ["etCursorDragScroll"] }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "component", type: ChevronIconComponent, selector: "et-chevron-icon" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
500
+ _disableSnapping() {
501
+ this._disableSnapping$.next();
502
+ }
503
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.0.3", ngImport: i0, type: ScrollableComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
504
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "17.0.3", type: ScrollableComponent, isStandalone: true, selector: "et-scrollable", inputs: { _itemSize: ["itemSize", "_itemSize"], _direction: ["direction", "_direction"], _scrollableRole: ["scrollableRole", "_scrollableRole"], _scrollableClass: ["scrollableClass", "_scrollableClass"], _renderNavigation: ["renderNavigation", "_renderNavigation", booleanAttribute], _renderMasks: ["renderMasks", "_renderMasks", booleanAttribute], _renderButtons: ["renderButtons", "_renderButtons", booleanAttribute], _renderScrollbars: ["renderScrollbars", "_renderScrollbars", booleanAttribute], _stickyButtons: ["stickyButtons", "_stickyButtons", booleanAttribute], _cursorDragScroll: ["cursorDragScroll", "_cursorDragScroll", booleanAttribute], _disableActiveElementScrolling: ["disableActiveElementScrolling", "_disableActiveElementScrolling", booleanAttribute], _scrollMode: ["scrollMode", "_scrollMode"], _snap: ["snap", "_snap", booleanAttribute], _scrollMargin: ["scrollMargin", "_scrollMargin", numberAttribute] }, outputs: { scrollStateChange: "scrollStateChange", intersectionChange: "intersectionChange" }, host: { classAttribute: "et-scrollable" }, queries: [{ propertyName: "_activeElementList", predicate: IS_ACTIVE_ELEMENT, descendants: true }], viewQueries: [{ propertyName: "_scrollable", first: true, predicate: ["scrollable"], descendants: true, static: true }, { propertyName: "_scrollableContainer", first: true, predicate: ["scrollableContainer"], descendants: true, static: true }, { propertyName: "_firstElement", first: true, predicate: ["firstElement"], descendants: true, static: true }, { propertyName: "_lastElement", first: true, predicate: ["lastElement"], descendants: true, static: true }], ngImport: i0, template: "<div class=\"et-scrollable-wrapper\">\n <div\n #scrollable\n [attr.role]=\"scrollableRole() ?? undefined\"\n [etCursorDragScroll]=\"cursorDragScroll()\"\n [allowedDirection]=\"direction()\"\n (cursorDragStart)=\"setIsCursorDragging(true)\"\n (cursorDragEnd)=\"setIsCursorDragging(false)\"\n class=\"et-scrollable-container-outer\"\n >\n <div #scrollableContainer [ngClass]=\"scrollableClass()\" class=\"et-scrollable-container\">\n <div #firstElement class=\"et-scroll-observer-first-element\" etScrollableIgnoreChild></div>\n <ng-content />\n <div #lastElement class=\"et-scroll-observer-last-element\" etScrollableIgnoreChild></div>\n </div>\n </div>\n\n @if (renderMasks()) {\n <div class=\"et-scrollable-masks\">\n <div class=\"et-scrollable-mask et-scrollable-mask--start\"></div>\n <div class=\"et-scrollable-mask et-scrollable-mask--end\"></div>\n </div>\n }\n\n @if (renderButtons()) {\n <div class=\"et-scrollable-buttons\">\n <button\n (click)=\"scrollToStartDirection()\"\n class=\"et-scrollable-button et-scrollable-button--start\"\n aria-hidden=\"true\"\n type=\"button\"\n tabindex=\"-1\"\n >\n <et-chevron-icon />\n </button>\n <button\n (click)=\"scrollToEndDirection()\"\n class=\"et-scrollable-button et-scrollable-button--end\"\n aria-hidden=\"true\"\n type=\"button\"\n tabindex=\"-1\"\n >\n <et-chevron-icon />\n </button>\n </div>\n }\n</div>\n\n@if (renderNavigation()) {\n <div class=\"et-scrollable-navigation\" aria-hidden=\"true\">\n @for (item of scrollableNavigation(); track i; let i = $index) {\n <button\n [class.et-scrollable-navigation-item--active]=\"item.isActive\"\n (click)=\"scrollToElementViaNavigation(i, item.element)\"\n class=\"et-scrollable-navigation-item\"\n ></button>\n }\n </div>\n}\n", styles: [".et-scrollable{--mask: #121212 0, transparent 100%;--mask-size: 25px;--_auto-size: min-content;--_flow: column;display:block}.et-scrollable .et-scrollable-wrapper{display:grid;position:relative}.et-scrollable[item-size=same]{--_auto-size: 1fr}.et-scrollable[item-size=full]{--_auto-size: 100%}.et-scrollable[render-scrollbars=false] .et-scrollable-container-outer{scrollbar-width:none}.et-scrollable[render-scrollbars=false] .et-scrollable-container-outer::-webkit-scrollbar{display:none}.et-scrollable[direction=horizontal] .et-scrollable-container-outer{overflow-x:auto;overflow-y:hidden}.et-scrollable[direction=horizontal] .et-scrollable-container{grid-auto-columns:var(--_auto-size)}.et-scrollable[direction=horizontal] .et-scrollable-mask,.et-scrollable[direction=horizontal] .et-scrollable-button{inline-size:var(--mask-size);block-size:100%}.et-scrollable[direction=horizontal] .et-scrollable-mask--start,.et-scrollable[direction=horizontal] .et-scrollable-button--start{inset-block-start:0;inset-inline:0 0}.et-scrollable[direction=horizontal] .et-scrollable-mask--end,.et-scrollable[direction=horizontal] .et-scrollable-button--end{inset-block-start:0;inset-inline:calc(100% - 40px) 0}.et-scrollable[direction=horizontal] .et-scrollable-mask--start{background:linear-gradient(to right,var(--mask))}.et-scrollable[direction=horizontal] .et-scrollable-mask--end{background:linear-gradient(to left,var(--mask));inset-inline:calc(100% - var(--mask-size)) 100%}.et-scrollable[direction=horizontal] .et-scrollable-button--start{inset-block-start:calc(50% - 20px);transform:rotate(-90deg)}.et-scrollable[direction=horizontal] .et-scrollable-button--end{inset-block-start:calc(50% - 20px);transform:rotate(90deg)}.et-scrollable[direction=vertical]{--_flow: row}.et-scrollable[direction=vertical] .et-scrollable-container-outer{overflow-x:hidden;overflow-y:auto}.et-scrollable[direction=vertical] .et-scrollable-container{grid-auto-rows:var(--_auto-size)}.et-scrollable[direction=vertical] .et-scrollable-mask,.et-scrollable[direction=vertical] .et-scrollable-button{block-size:var(--mask-size);inline-size:100%}.et-scrollable[direction=vertical] .et-scrollable-mask--start,.et-scrollable[direction=vertical] .et-scrollable-button--start{inset-block-start:0;inset-inline-start:0}.et-scrollable[direction=vertical] .et-scrollable-mask--end,.et-scrollable[direction=vertical] .et-scrollable-button--end{inset-block-end:0;inset-inline-start:0}.et-scrollable[direction=vertical] .et-scrollable-mask--start{background:linear-gradient(to bottom,var(--mask))}.et-scrollable[direction=vertical] .et-scrollable-mask--end{background:linear-gradient(to top,var(--mask))}.et-scrollable[direction=vertical] .et-scrollable-button--start{inset-inline-start:calc(50% - 20px);transform:rotate(0)}.et-scrollable[direction=vertical] .et-scrollable-button--end{inset-inline-start:calc(50% - 20px);transform:rotate(180deg)}.et-scrollable:not(.et-scrollable--is-at-start) .et-scrollable-masks .et-scrollable-mask--start,.et-scrollable:not(.et-scrollable--is-at-start) .et-scrollable-buttons .et-scrollable-button--start{opacity:1}.et-scrollable:not(.et-scrollable--is-at-start) .et-scrollable-buttons .et-scrollable-button--start{pointer-events:all}.et-scrollable:not(.et-scrollable--is-at-end) .et-scrollable-masks .et-scrollable-mask--end,.et-scrollable:not(.et-scrollable--is-at-end) .et-scrollable-buttons .et-scrollable-button--end{opacity:1}.et-scrollable:not(.et-scrollable--is-at-end) .et-scrollable-buttons .et-scrollable-button--end{pointer-events:all}.et-scrollable .et-scrollable-container-outer{overflow:auto;display:grid;position:relative;grid-row:1/1;grid-column:1/1}.et-scrollable .et-scroll-observer-first-element,.et-scrollable .et-scroll-observer-last-element{position:absolute;block-size:100%;inline-size:1px;pointer-events:none}.et-scrollable .et-scroll-observer-first-element{inset-inline-start:1px}.et-scrollable .et-scroll-observer-last-element{inset-inline-end:1px}.et-scrollable .et-scrollable-container{display:grid;grid-auto-flow:var(--_flow);position:relative}.et-scrollable .et-scrollable-masks,.et-scrollable .et-scrollable-buttons{grid-row:1/1;grid-column:1/1;pointer-events:none}.et-scrollable .et-scrollable-masks .et-scrollable-mask,.et-scrollable .et-scrollable-masks .et-scrollable-button,.et-scrollable .et-scrollable-buttons .et-scrollable-mask,.et-scrollable .et-scrollable-buttons .et-scrollable-button{position:absolute;opacity:0}.et-scrollable.et-scrollable--can-scroll.et-scrollable--enable-overlay-animations .et-scrollable-mask,.et-scrollable.et-scrollable--can-scroll.et-scrollable--enable-overlay-animations .et-scrollable-button{transition:opacity .3s var(--ease-5)}.et-scrollable .et-scrollable-buttons .et-scrollable-button{background:transparent;border:none;padding:12px;inline-size:40px;block-size:40px;border-radius:4px;cursor:pointer}.et-scrollable .et-scrollable-buttons .et-scrollable-button .et-chevron-icon{pointer-events:none}.et-scrollable .et-scrollable-buttons .et-scrollable-button .et-scrollable-button--start{inset-inline:0 0}.et-scrollable .et-scrollable-buttons .et-scrollable-button .et-scrollable-button--end{inset-inline:calc(100% - 40px) 0}.et-scrollable[sticky-buttons=true]{--_sticky-margin: 10%}.et-scrollable[sticky-buttons=true] .et-scrollable-button{position:sticky}.et-scrollable[sticky-buttons=true][direction=horizontal] .et-scrollable-buttons{margin-block:var(--_sticky-margin)}.et-scrollable[sticky-buttons=true][direction=vertical] .et-scrollable-buttons{margin-inline:var(--_sticky-margin)}.et-scrollable[sticky-buttons=true][direction=vertical] .et-scrollable-buttons .et-scrollable-button--end{inset-block-start:100%}.et-scrollable .et-scrollable-navigation{display:flex;justify-content:center;gap:10px;margin-block-start:10px}.et-scrollable .et-scrollable-navigation .et-scrollable-navigation-item{all:unset;inline-size:10px;block-size:10px;display:block;background-color:#4b4b4b;border-radius:50%;cursor:pointer}.et-scrollable .et-scrollable-navigation .et-scrollable-navigation-item.et-scrollable-navigation-item--active{background-color:#c6c6c6}\n"], dependencies: [{ kind: "directive", type: CursorDragScrollDirective, selector: "[etCursorDragScroll]", inputs: ["etCursorDragScroll", "allowedDirection"], outputs: ["cursorDragStart", "cursorDragMove", "cursorDragEnd"], exportAs: ["etCursorDragScroll"] }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "component", type: ChevronIconComponent, selector: "et-chevron-icon" }, { kind: "directive", type: ScrollableIgnoreChildDirective, selector: "[etScrollableIgnoreChild]", inputs: ["etScrollableIgnoreChild"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
384
505
  }
385
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.2", ngImport: i0, type: ScrollableComponent, decorators: [{
506
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.3", ngImport: i0, type: ScrollableComponent, decorators: [{
386
507
  type: Component,
387
- args: [{ selector: 'et-scrollable', standalone: true, encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, imports: [CursorDragScrollDirective, ObserveScrollStateDirective, NgClass, LetDirective, ChevronIconComponent], host: {
508
+ args: [{ selector: 'et-scrollable', standalone: true, encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, imports: [
509
+ CursorDragScrollDirective,
510
+ ObserveScrollStateDirective,
511
+ NgClass,
512
+ LetDirective,
513
+ ChevronIconComponent,
514
+ ScrollableIgnoreChildDirective,
515
+ ], host: {
388
516
  class: 'et-scrollable',
389
- }, template: "<div\n #scrollable\n [attr.role]=\"scrollableRole() ?? undefined\"\n [etCursorDragScroll]=\"cursorDragScroll()\"\n [allowedDirection]=\"direction()\"\n (cursorDragStart)=\"setIsCursorDragging(true)\"\n (cursorDragEnd)=\"setIsCursorDragging(false)\"\n class=\"et-scrollable-container-outer\"\n>\n <div [ngClass]=\"scrollableClass()\" class=\"et-scrollable-container\">\n <div #firstElement class=\"et-scroll-observer-first-element\"></div>\n <ng-content />\n <div #lastElement class=\"et-scroll-observer-last-element\"></div>\n </div>\n</div>\n\n@if (renderMasks()) {\n <div class=\"et-scrollable-masks\">\n <div class=\"et-scrollable-mask et-scrollable-mask--start\"></div>\n <div class=\"et-scrollable-mask et-scrollable-mask--end\"></div>\n </div>\n}\n\n@if (renderButtons()) {\n <div class=\"et-scrollable-buttons\">\n <button\n (click)=\"scrollToStartDirection()\"\n class=\"et-scrollable-button et-scrollable-button--start\"\n aria-hidden=\"true\"\n type=\"button\"\n tabindex=\"-1\"\n >\n <et-chevron-icon />\n </button>\n <button\n (click)=\"scrollToStartEnd()\"\n class=\"et-scrollable-button et-scrollable-button--end\"\n aria-hidden=\"true\"\n type=\"button\"\n tabindex=\"-1\"\n >\n <et-chevron-icon />\n </button>\n </div>\n}\n", styles: [".et-scrollable{--mask: #121212 0, transparent 100%;--mask-size: 25px;--_auto-size: min-content;--_flow: column;display:grid;position:relative}.et-scrollable[item-size=same]{--_auto-size: 1fr}.et-scrollable[item-size=full]{--_auto-size: 100%}.et-scrollable[render-scrollbars=false] .et-scrollable-container-outer{scrollbar-width:none}.et-scrollable[render-scrollbars=false] .et-scrollable-container-outer::-webkit-scrollbar{display:none}.et-scrollable[direction=horizontal] .et-scrollable-container-outer{overflow-x:auto;overflow-y:hidden}.et-scrollable[direction=horizontal] .et-scrollable-container{grid-auto-columns:var(--_auto-size)}.et-scrollable[direction=horizontal] .et-scrollable-mask,.et-scrollable[direction=horizontal] .et-scrollable-button{inline-size:var(--mask-size);block-size:100%}.et-scrollable[direction=horizontal] .et-scrollable-mask--start,.et-scrollable[direction=horizontal] .et-scrollable-button--start{inset-block-start:0;inset-inline:0 0}.et-scrollable[direction=horizontal] .et-scrollable-mask--end,.et-scrollable[direction=horizontal] .et-scrollable-button--end{inset-block-start:0;inset-inline:calc(100% - 40px) 0}.et-scrollable[direction=horizontal] .et-scrollable-mask--start{background:linear-gradient(to right,var(--mask))}.et-scrollable[direction=horizontal] .et-scrollable-mask--end{background:linear-gradient(to left,var(--mask));inset-inline:calc(100% - var(--mask-size)) 100%}.et-scrollable[direction=horizontal] .et-scrollable-button--start{inset-block-start:calc(50% - 20px);transform:rotate(-90deg)}.et-scrollable[direction=horizontal] .et-scrollable-button--end{inset-block-start:calc(50% - 20px);transform:rotate(90deg)}.et-scrollable[direction=vertical]{--_flow: row}.et-scrollable[direction=vertical] .et-scrollable-container-outer{overflow-x:hidden;overflow-y:auto}.et-scrollable[direction=vertical] .et-scrollable-container{grid-auto-rows:var(--_auto-size)}.et-scrollable[direction=vertical] .et-scrollable-mask,.et-scrollable[direction=vertical] .et-scrollable-button{block-size:var(--mask-size);inline-size:100%}.et-scrollable[direction=vertical] .et-scrollable-mask--start,.et-scrollable[direction=vertical] .et-scrollable-button--start{inset-block-start:0;inset-inline-start:0}.et-scrollable[direction=vertical] .et-scrollable-mask--end,.et-scrollable[direction=vertical] .et-scrollable-button--end{inset-block-end:0;inset-inline-start:0}.et-scrollable[direction=vertical] .et-scrollable-mask--start{background:linear-gradient(to bottom,var(--mask))}.et-scrollable[direction=vertical] .et-scrollable-mask--end{background:linear-gradient(to top,var(--mask))}.et-scrollable[direction=vertical] .et-scrollable-button--start{inset-inline-start:calc(50% - 20px);transform:rotate(0)}.et-scrollable[direction=vertical] .et-scrollable-button--end{inset-inline-start:calc(50% - 20px);transform:rotate(180deg)}.et-scrollable:not(.et-scrollable--is-at-start) .et-scrollable-masks .et-scrollable-mask--start,.et-scrollable:not(.et-scrollable--is-at-start) .et-scrollable-buttons .et-scrollable-button--start{opacity:1}.et-scrollable:not(.et-scrollable--is-at-start) .et-scrollable-buttons .et-scrollable-button--start{pointer-events:all}.et-scrollable:not(.et-scrollable--is-at-end) .et-scrollable-masks .et-scrollable-mask--end,.et-scrollable:not(.et-scrollable--is-at-end) .et-scrollable-buttons .et-scrollable-button--end{opacity:1}.et-scrollable:not(.et-scrollable--is-at-end) .et-scrollable-buttons .et-scrollable-button--end{pointer-events:all}.et-scrollable .et-scrollable-container-outer{overflow:auto;display:grid;grid-row:1/1;grid-column:1/1}.et-scrollable .et-scroll-observer-first-element,.et-scrollable .et-scroll-observer-last-element{position:absolute;block-size:100%;inline-size:1px;pointer-events:none}.et-scrollable .et-scroll-observer-first-element{inset-inline-start:1px}.et-scrollable .et-scroll-observer-last-element{inset-inline-end:1px}.et-scrollable .et-scrollable-container{display:grid;grid-auto-flow:var(--_flow);position:relative}.et-scrollable .et-scrollable-masks,.et-scrollable .et-scrollable-buttons{grid-row:1/1;grid-column:1/1;pointer-events:none}.et-scrollable .et-scrollable-masks .et-scrollable-mask,.et-scrollable .et-scrollable-masks .et-scrollable-button,.et-scrollable .et-scrollable-buttons .et-scrollable-mask,.et-scrollable .et-scrollable-buttons .et-scrollable-button{position:absolute;opacity:0}.et-scrollable.et-scrollable--can-scroll.et-scrollable--enable-overlay-animations .et-scrollable-mask,.et-scrollable.et-scrollable--can-scroll.et-scrollable--enable-overlay-animations .et-scrollable-button{transition:opacity .3s var(--ease-5)}.et-scrollable .et-scrollable-buttons .et-scrollable-button{background:transparent;border:none;padding:12px;inline-size:40px;block-size:40px;border-radius:4px;cursor:pointer}.et-scrollable .et-scrollable-buttons .et-scrollable-button .et-chevron-icon{pointer-events:none}.et-scrollable .et-scrollable-buttons .et-scrollable-button .et-scrollable-button--start{inset-inline:0 0}.et-scrollable .et-scrollable-buttons .et-scrollable-button .et-scrollable-button--end{inset-inline:calc(100% - 40px) 0}.et-scrollable[sticky-buttons=true]{--_sticky-margin: 10%}.et-scrollable[sticky-buttons=true] .et-scrollable-button{position:sticky}.et-scrollable[sticky-buttons=true][direction=horizontal] .et-scrollable-buttons{margin-block:var(--_sticky-margin)}.et-scrollable[sticky-buttons=true][direction=vertical] .et-scrollable-buttons{margin-inline:var(--_sticky-margin)}.et-scrollable[sticky-buttons=true][direction=vertical] .et-scrollable-buttons .et-scrollable-button--end{inset-block-start:100%}\n"] }]
517
+ }, template: "<div class=\"et-scrollable-wrapper\">\n <div\n #scrollable\n [attr.role]=\"scrollableRole() ?? undefined\"\n [etCursorDragScroll]=\"cursorDragScroll()\"\n [allowedDirection]=\"direction()\"\n (cursorDragStart)=\"setIsCursorDragging(true)\"\n (cursorDragEnd)=\"setIsCursorDragging(false)\"\n class=\"et-scrollable-container-outer\"\n >\n <div #scrollableContainer [ngClass]=\"scrollableClass()\" class=\"et-scrollable-container\">\n <div #firstElement class=\"et-scroll-observer-first-element\" etScrollableIgnoreChild></div>\n <ng-content />\n <div #lastElement class=\"et-scroll-observer-last-element\" etScrollableIgnoreChild></div>\n </div>\n </div>\n\n @if (renderMasks()) {\n <div class=\"et-scrollable-masks\">\n <div class=\"et-scrollable-mask et-scrollable-mask--start\"></div>\n <div class=\"et-scrollable-mask et-scrollable-mask--end\"></div>\n </div>\n }\n\n @if (renderButtons()) {\n <div class=\"et-scrollable-buttons\">\n <button\n (click)=\"scrollToStartDirection()\"\n class=\"et-scrollable-button et-scrollable-button--start\"\n aria-hidden=\"true\"\n type=\"button\"\n tabindex=\"-1\"\n >\n <et-chevron-icon />\n </button>\n <button\n (click)=\"scrollToEndDirection()\"\n class=\"et-scrollable-button et-scrollable-button--end\"\n aria-hidden=\"true\"\n type=\"button\"\n tabindex=\"-1\"\n >\n <et-chevron-icon />\n </button>\n </div>\n }\n</div>\n\n@if (renderNavigation()) {\n <div class=\"et-scrollable-navigation\" aria-hidden=\"true\">\n @for (item of scrollableNavigation(); track i; let i = $index) {\n <button\n [class.et-scrollable-navigation-item--active]=\"item.isActive\"\n (click)=\"scrollToElementViaNavigation(i, item.element)\"\n class=\"et-scrollable-navigation-item\"\n ></button>\n }\n </div>\n}\n", styles: [".et-scrollable{--mask: #121212 0, transparent 100%;--mask-size: 25px;--_auto-size: min-content;--_flow: column;display:block}.et-scrollable .et-scrollable-wrapper{display:grid;position:relative}.et-scrollable[item-size=same]{--_auto-size: 1fr}.et-scrollable[item-size=full]{--_auto-size: 100%}.et-scrollable[render-scrollbars=false] .et-scrollable-container-outer{scrollbar-width:none}.et-scrollable[render-scrollbars=false] .et-scrollable-container-outer::-webkit-scrollbar{display:none}.et-scrollable[direction=horizontal] .et-scrollable-container-outer{overflow-x:auto;overflow-y:hidden}.et-scrollable[direction=horizontal] .et-scrollable-container{grid-auto-columns:var(--_auto-size)}.et-scrollable[direction=horizontal] .et-scrollable-mask,.et-scrollable[direction=horizontal] .et-scrollable-button{inline-size:var(--mask-size);block-size:100%}.et-scrollable[direction=horizontal] .et-scrollable-mask--start,.et-scrollable[direction=horizontal] .et-scrollable-button--start{inset-block-start:0;inset-inline:0 0}.et-scrollable[direction=horizontal] .et-scrollable-mask--end,.et-scrollable[direction=horizontal] .et-scrollable-button--end{inset-block-start:0;inset-inline:calc(100% - 40px) 0}.et-scrollable[direction=horizontal] .et-scrollable-mask--start{background:linear-gradient(to right,var(--mask))}.et-scrollable[direction=horizontal] .et-scrollable-mask--end{background:linear-gradient(to left,var(--mask));inset-inline:calc(100% - var(--mask-size)) 100%}.et-scrollable[direction=horizontal] .et-scrollable-button--start{inset-block-start:calc(50% - 20px);transform:rotate(-90deg)}.et-scrollable[direction=horizontal] .et-scrollable-button--end{inset-block-start:calc(50% - 20px);transform:rotate(90deg)}.et-scrollable[direction=vertical]{--_flow: row}.et-scrollable[direction=vertical] .et-scrollable-container-outer{overflow-x:hidden;overflow-y:auto}.et-scrollable[direction=vertical] .et-scrollable-container{grid-auto-rows:var(--_auto-size)}.et-scrollable[direction=vertical] .et-scrollable-mask,.et-scrollable[direction=vertical] .et-scrollable-button{block-size:var(--mask-size);inline-size:100%}.et-scrollable[direction=vertical] .et-scrollable-mask--start,.et-scrollable[direction=vertical] .et-scrollable-button--start{inset-block-start:0;inset-inline-start:0}.et-scrollable[direction=vertical] .et-scrollable-mask--end,.et-scrollable[direction=vertical] .et-scrollable-button--end{inset-block-end:0;inset-inline-start:0}.et-scrollable[direction=vertical] .et-scrollable-mask--start{background:linear-gradient(to bottom,var(--mask))}.et-scrollable[direction=vertical] .et-scrollable-mask--end{background:linear-gradient(to top,var(--mask))}.et-scrollable[direction=vertical] .et-scrollable-button--start{inset-inline-start:calc(50% - 20px);transform:rotate(0)}.et-scrollable[direction=vertical] .et-scrollable-button--end{inset-inline-start:calc(50% - 20px);transform:rotate(180deg)}.et-scrollable:not(.et-scrollable--is-at-start) .et-scrollable-masks .et-scrollable-mask--start,.et-scrollable:not(.et-scrollable--is-at-start) .et-scrollable-buttons .et-scrollable-button--start{opacity:1}.et-scrollable:not(.et-scrollable--is-at-start) .et-scrollable-buttons .et-scrollable-button--start{pointer-events:all}.et-scrollable:not(.et-scrollable--is-at-end) .et-scrollable-masks .et-scrollable-mask--end,.et-scrollable:not(.et-scrollable--is-at-end) .et-scrollable-buttons .et-scrollable-button--end{opacity:1}.et-scrollable:not(.et-scrollable--is-at-end) .et-scrollable-buttons .et-scrollable-button--end{pointer-events:all}.et-scrollable .et-scrollable-container-outer{overflow:auto;display:grid;position:relative;grid-row:1/1;grid-column:1/1}.et-scrollable .et-scroll-observer-first-element,.et-scrollable .et-scroll-observer-last-element{position:absolute;block-size:100%;inline-size:1px;pointer-events:none}.et-scrollable .et-scroll-observer-first-element{inset-inline-start:1px}.et-scrollable .et-scroll-observer-last-element{inset-inline-end:1px}.et-scrollable .et-scrollable-container{display:grid;grid-auto-flow:var(--_flow);position:relative}.et-scrollable .et-scrollable-masks,.et-scrollable .et-scrollable-buttons{grid-row:1/1;grid-column:1/1;pointer-events:none}.et-scrollable .et-scrollable-masks .et-scrollable-mask,.et-scrollable .et-scrollable-masks .et-scrollable-button,.et-scrollable .et-scrollable-buttons .et-scrollable-mask,.et-scrollable .et-scrollable-buttons .et-scrollable-button{position:absolute;opacity:0}.et-scrollable.et-scrollable--can-scroll.et-scrollable--enable-overlay-animations .et-scrollable-mask,.et-scrollable.et-scrollable--can-scroll.et-scrollable--enable-overlay-animations .et-scrollable-button{transition:opacity .3s var(--ease-5)}.et-scrollable .et-scrollable-buttons .et-scrollable-button{background:transparent;border:none;padding:12px;inline-size:40px;block-size:40px;border-radius:4px;cursor:pointer}.et-scrollable .et-scrollable-buttons .et-scrollable-button .et-chevron-icon{pointer-events:none}.et-scrollable .et-scrollable-buttons .et-scrollable-button .et-scrollable-button--start{inset-inline:0 0}.et-scrollable .et-scrollable-buttons .et-scrollable-button .et-scrollable-button--end{inset-inline:calc(100% - 40px) 0}.et-scrollable[sticky-buttons=true]{--_sticky-margin: 10%}.et-scrollable[sticky-buttons=true] .et-scrollable-button{position:sticky}.et-scrollable[sticky-buttons=true][direction=horizontal] .et-scrollable-buttons{margin-block:var(--_sticky-margin)}.et-scrollable[sticky-buttons=true][direction=vertical] .et-scrollable-buttons{margin-inline:var(--_sticky-margin)}.et-scrollable[sticky-buttons=true][direction=vertical] .et-scrollable-buttons .et-scrollable-button--end{inset-block-start:100%}.et-scrollable .et-scrollable-navigation{display:flex;justify-content:center;gap:10px;margin-block-start:10px}.et-scrollable .et-scrollable-navigation .et-scrollable-navigation-item{all:unset;inline-size:10px;block-size:10px;display:block;background-color:#4b4b4b;border-radius:50%;cursor:pointer}.et-scrollable .et-scrollable-navigation .et-scrollable-navigation-item.et-scrollable-navigation-item--active{background-color:#c6c6c6}\n"] }]
390
518
  }], ctorParameters: () => [], propDecorators: { _itemSize: [{
391
519
  type: Input,
392
520
  args: [{ alias: 'itemSize' }]
@@ -399,6 +527,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.2", ngImpor
399
527
  }], _scrollableClass: [{
400
528
  type: Input,
401
529
  args: [{ alias: 'scrollableClass' }]
530
+ }], _renderNavigation: [{
531
+ type: Input,
532
+ args: [{ transform: booleanAttribute, alias: 'renderNavigation' }]
402
533
  }], _renderMasks: [{
403
534
  type: Input,
404
535
  args: [{ transform: booleanAttribute, alias: 'renderMasks' }]
@@ -433,6 +564,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.2", ngImpor
433
564
  }], _scrollable: [{
434
565
  type: ViewChild,
435
566
  args: ['scrollable', { static: true }]
567
+ }], _scrollableContainer: [{
568
+ type: ViewChild,
569
+ args: ['scrollableContainer', { static: true }]
436
570
  }], _firstElement: [{
437
571
  type: ViewChild,
438
572
  args: ['firstElement', { static: true }]
@@ -442,8 +576,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.2", ngImpor
442
576
  }], _activeElementList: [{
443
577
  type: ContentChildren,
444
578
  args: [IS_ACTIVE_ELEMENT, { descendants: true }]
445
- }], _elementList: [{
446
- type: ContentChildren,
447
- args: [IS_ELEMENT, { descendants: true }]
448
579
  }] } });
449
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2Nyb2xsYWJsZS5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi8uLi8uLi9saWJzL2Nkay9zcmMvbGliL2NvbXBvbmVudHMvc2Nyb2xsYWJsZS9jb21wb25lbnRzL3Njcm9sbGFibGUvc2Nyb2xsYWJsZS5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi8uLi8uLi8uLi8uLi8uLi9saWJzL2Nkay9zcmMvbGliL2NvbXBvbmVudHMvc2Nyb2xsYWJsZS9jb21wb25lbnRzL3Njcm9sbGFibGUvc2Nyb2xsYWJsZS5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsT0FBTyxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDMUMsT0FBTyxFQUVMLHVCQUF1QixFQUN2QixTQUFTLEVBQ1QsZUFBZSxFQUNmLFVBQVUsRUFDVixZQUFZLEVBQ1osS0FBSyxFQUNMLE1BQU0sRUFDTixTQUFTLEVBQ1QsaUJBQWlCLEVBQ2pCLGdCQUFnQixFQUNoQixRQUFRLEVBQ1IsTUFBTSxFQUNOLE1BQU0sRUFDTixTQUFTLEVBQ1QsZUFBZSxFQUNmLE1BQU0sR0FDUCxNQUFNLGVBQWUsQ0FBQztBQUN2QixPQUFPLEVBRUwseUJBQXlCLEVBQ3pCLGlCQUFpQixFQUNqQixVQUFVLEVBR1YsWUFBWSxFQUVaLDJCQUEyQixFQUczQixjQUFjLEVBQ2QsYUFBYSxFQUNiLHVCQUF1QixFQUN2QixnQkFBZ0IsRUFDaEIsU0FBUyxFQUNULGVBQWUsRUFDZix5QkFBeUIsRUFDekIsd0JBQXdCLEVBQ3hCLG9CQUFvQixFQUNwQixpQkFBaUIsR0FDbEIsTUFBTSxlQUFlLENBQUM7QUFDdkIsT0FBTyxFQUFFLGVBQWUsRUFBRSxZQUFZLEVBQUUsU0FBUyxFQUFFLEtBQUssRUFBRSxFQUFFLEVBQUUsU0FBUyxFQUFFLFNBQVMsRUFBRSxHQUFHLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFDdEcsT0FBTyxF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YyxFQUFFO2dCQU9uRCxpQkFBaUI7c0JBRHpCLE1BQU07Z0JBSUUsa0JBQWtCO3NCQUQxQixNQUFNO2dCQUlLLFdBQVc7c0JBRHRCLFNBQVM7dUJBQUMsWUFBWSxFQUFFLEVBQUUsTUFBTSxFQUFFLElBQUksRUFBRTtnQkFPN0IsYUFBYTtzQkFEeEIsU0FBUzt1QkFBQyxjQUFjLEVBQUUsRUFBRSxNQUFNLEVBQUUsSUFBSSxFQUFFO2dCQU8vQixZQUFZO3NCQUR2QixTQUFTO3VCQUFDLGFBQWEsRUFBRSxFQUFFLE1BQU0sRUFBRSxJQUFJLEVBQUU7Z0JBTzlCLGtCQUFrQjtzQkFEN0IsZUFBZTt1QkFBQyxpQkFBaUIsRUFBRSxFQUFFLFdBQVcsRUFBRSxJQUFJLEVBQUU7Z0JBTzdDLFlBQVk7c0JBRHZCLGVBQWU7dUJBQUMsVUFBVSxFQUFFLEVBQUUsV0FBVyxFQUFFLElBQUksRUFBRSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IE5nQ2xhc3MgfSBmcm9tICdAYW5ndWxhci9jb21tb24nO1xuaW1wb3J0IHtcbiAgQWZ0ZXJDb250ZW50SW5pdCxcbiAgQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3ksXG4gIENvbXBvbmVudCxcbiAgQ29udGVudENoaWxkcmVuLFxuICBFbGVtZW50UmVmLFxuICBFdmVudEVtaXR0ZXIsXG4gIElucHV0LFxuICBPdXRwdXQsXG4gIFZpZXdDaGlsZCxcbiAgVmlld0VuY2Fwc3VsYXRpb24sXG4gIGJvb2xlYW5BdHRyaWJ1dGUsXG4gIGNvbXB1dGVkLFxuICBlZmZlY3QsXG4gIGluamVjdCxcbiAgaXNEZXZNb2RlLFxuICBudW1iZXJBdHRyaWJ1dGUsXG4gIHNpZ25hbCxcbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQge1xuICBDdXJyZW50RWxlbWVudFZpc2liaWxpdHksXG4gIEN1cnNvckRyYWdTY3JvbGxEaXJlY3RpdmUsXG4gIElTX0FDVElWRV9FTEVNRU5ULFxuICBJU19FTEVNRU5ULFxuICBJc0FjdGl2ZUVsZW1lbnREaXJlY3RpdmUsXG4gIElzRWxlbWVudERpcmVjdGl2ZSxcbiAgTGV0RGlyZWN0aXZlLFxuICBOZ0NsYXNzVHlwZSxcbiAgT2JzZXJ2ZVNjcm9sbFN0YXRlRGlyZWN0aXZlLFxuICBTY3JvbGxPYnNlcnZlclNjcm9sbFN0YXRlLFxuICBTY3JvbGxUb0VsZW1lbnRPcHRpb25zLFxuICBUeXBlZFF1ZXJ5TGlzdCxcbiAgY3JlYXRlRGVzdHJveSxcbiAgZ2V0RWxlbWVudFZpc2libGVTdGF0ZXMsXG4gIGlzRWxlbWVudFZpc2libGUsXG4gIG5leHRGcmFtZSxcbiAgc2Nyb2xsVG9FbGVtZW50LFxuICBzaWduYWxFbGVtZW50SW50ZXJzZWN0aW9uLFxuICBzaWduYWxFbGVtZW50U2Nyb2xsU3RhdGUsXG4gIHNpZ25hbEhvc3RBdHRyaWJ1dGVzLFxuICBzaWduYWxIb3N0Q2xhc3Nlcyxcbn0gZnJvbSAnQGV0aGxldGUvY29yZSc7XG5pbXBvcnQgeyBCZWhhdmlvclN1YmplY3QsIGRlYm91bmNlVGltZSwgZnJvbUV2ZW50LCBtZXJnZSwgb2YsIHN0YXJ0V2l0aCwgdGFrZVVudGlsLCB0YXAgfSBmcm9tICdyeGpzJztcbmltcG9ydCB7IENoZXZyb25JY29uQ29tcG9uZW50IH0gZnJvbSAnLi4vLi4vLi4vaWNvbnMnO1xuaW1wb3J0IHsgU2Nyb2xsYWJsZUludGVyc2VjdGlvbkNoYW5nZSwgU2Nyb2xsYWJsZVNjcm9sbE1vZGUgfSBmcm9tICcuLi8uLi90eXBlcyc7XG5cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ2V0LXNjcm9sbGFibGUnLFxuICB0ZW1wbGF0ZVVybDogJy4vc2Nyb2xsYWJsZS5jb21wb25lbnQuaHRtbCcsXG4gIHN0eWxlVXJsczogWycuL3Njcm9sbGFibGUuY29tcG9uZW50LnNjc3MnXSxcbiAgc3RhbmRhbG9uZTogdHJ1ZSxcbiAgZW5jYXBzdWxhdGlvbjogVmlld0VuY2Fwc3VsYXRpb24uTm9uZSxcbiAgY2hhbmdlRGV0ZWN0aW9uOiBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneS5PblB1c2gsXG4gIGltcG9ydHM6IFtDdXJzb3JEcmFnU2Nyb2xsRGlyZWN0aXZlLCBPYnNlcnZlU2Nyb2xsU3RhdGVEaXJlY3RpdmUsIE5nQ2xhc3MsIExldERpcmVjdGl2ZSwgQ2hldnJvbkljb25Db21wb25lbnRdLFxuICBob3N0OiB7XG4gICAgY2xhc3M6ICdldC1zY3JvbGxhYmxlJyxcbiAgfSxcbn0pXG5leHBvcnQgY2xhc3MgU2Nyb2xsYWJsZUNvbXBvbmVudCBpbXBsZW1lbnRzIEFmdGVyQ29udGVudEluaXQge1xuICBwcml2YXRlIHJlYWRvbmx5IF9kZXN0cm95JCA9IGNyZWF0ZURlc3Ryb3koKTtcbiAgcHJpdmF0ZSByZWFkb25seSBfZWxlbWVudFJlZiA9IGluamVjdDxFbGVtZW50UmVmPEhUTUxFbGVtZW50Pj4oRWxlbWVudFJlZik7XG5cbiAgcHJpdmF0ZSByZWFkb25seSBfaXNDdXJzb3JEcmFnZ2luZyQgPSBuZXcgQmVoYXZpb3JTdWJqZWN0PGJvb2xlYW4+KGZhbHNlKTtcbiAgcHJpdmF0ZSByZWFkb25seSBfbGF0ZXN0VmlzaWJpbGl0eVN0YXRlcyQgPSBuZXcgQmVoYXZpb3JTdWJqZWN0PFNjcm9sbGFibGVJbnRlcnNlY3Rpb25DaGFuZ2VbXT4oW10pO1xuXG4gIEBJbnB1dCh7IGFsaWFzOiAnaXRlbVNpemUnIH0pXG4gIHNldCBfaXRlbVNpemUodjogJ2F1dG8nIHwgJ3NhbWUnIHwgJ2Z1bGwnKSB7XG4gICAgdGhpcy5pdGVtU2l6ZS5zZXQodik7XG4gIH1cbiAgcmVhZG9ubHkgaXRlbVNpemUgPSBzaWduYWw8J2F1dG8nIHwgJ3NhbWUnIHwgJ2Z1bGwnPignYXV0bycpO1xuXG4gIEBJbnB1dCh7IGFsaWFzOiAnZGlyZWN0aW9uJyB9KVxuICBzZXQgX2RpcmVjdGlvbih2OiAnaG9yaXpvbnRhbCcgfCAndmVydGljYWwnKSB7XG4gICAgdGhpcy5kaXJlY3Rpb24uc2V0KHYpO1xuICB9XG4gIHJlYWRvbmx5IGRpcmVjdGlvbiA9IHNpZ25hbDwnaG9yaXpvbnRhbCcgfCAndmVydGljYWwnPignaG9yaXpvbnRhbCcpO1xuXG4gIEBJbnB1dCh7IGFsaWFzOiAnc2Nyb2xsYWJsZVJvbGUnIH0pXG4gIHNldCBfc2Nyb2xsYWJsZVJvbGUodjogc3RyaW5nIHwgbnVsbCkge1xuICAgIHRoaXMuc2Nyb2xsYWJsZVJvbGUuc2V0KHYpO1xuICB9XG4gIHJlYWRvbmx5IHNjcm9sbGFibGVSb2xlID0gc2lnbmFsPHN0cmluZyB8IG51bGw+KG51bGwpO1xuXG4gIEBJbnB1dCh7IGFsaWFzOiAnc2Nyb2xsYWJsZUNsYXNzJyB9KVxuICBzZXQgX3Njcm9sbGFibGVDbGFzcyh2OiBOZ0NsYXNzVHlwZSB8IG51bGwpIHtcbiAgICB0aGlzLnNjcm9sbGFibGVDbGFzcy5zZXQodik7XG4gIH1cbiAgcmVhZG9ubHkgc2Nyb2xsYWJsZUNsYXNzID0gc2lnbmFsPE5nQ2xhc3NUeXBlIHwgbnVsbD4obnVsbCk7XG5cbiAgQElucHV0KHsgdHJhbnNmb3JtOiBib29sZWFuQXR0cmlidXRlLCBhbGlhczogJ3JlbmRlck1hc2tzJyB9KVxuICBzZXQgX3JlbmRlck1hc2tzKHY6IGJvb2xlYW4pIHtcbiAgICB0aGlzLnJlbmRlck1hc2tzLnNldCh2KTtcbiAgfVxuICByZWFkb25seSByZW5kZXJNYXNrcyA9IHNpZ25hbCh0cnVlKTtcblxuICBASW5wdXQoeyB0cmFuc2Zvcm06IGJvb2xlYW5BdHRyaWJ1dGUsIGFsaWFzOiAncmVuZGVyQnV0dG9ucycgfSlcbiAgc2V0IF9yZW5kZXJCdXR0b25zKHY6IGJvb2xlYW4pIHtcbiAgICB0aGlzLnJlbmRlckJ1dHRvbnMuc2V0KHYpO1xuICB9XG4gIHJlYWRvbmx5IHJlbmRlckJ1dHRvbnMgPSBzaWduYWwodHJ1ZSk7XG5cbiAgQElucHV0KHsgdHJhbnNmb3JtOiBib29sZWFuQXR0cmlidXRlLCBhbGlhczogJ3JlbmRlclNjcm9sbGJhcnMnIH0pXG4gIHNldCBfcmVuZGVyU2Nyb2xsYmFycyh2OiBib29sZWFuKSB7XG4gICAgdGhpcy5yZW5kZXJTY3JvbGxiYXJzLnNldCh2KTtcbiAgfVxuICByZWFkb25seSByZW5kZXJTY3JvbGxiYXJzID0gc2lnbmFsKGZhbHNlKTtcblxuICBASW5wdXQoeyB0cmFuc2Zvcm06IGJvb2xlYW5BdHRyaWJ1dGUsIGFsaWFzOiAnc3RpY2t5QnV0dG9ucycgfSlcbiAgc2V0IF9zdGlja3lCdXR0b25zKHY6IGJvb2xlYW4pIHtcbiAgICB0aGlzLnN0aWNreUJ1dHRvbnMuc2V0KHYpO1xuICB9XG4gIHJlYWRvbmx5IHN0aWNreUJ1dHRvbnMgPSBzaWduYWwoZmFsc2UpO1xuXG4gIEBJbnB1dCh7IHRyYW5zZm9ybTogYm9vbGVhbkF0dHJpYnV0ZSwgYWxpYXM6ICdjdXJzb3JEcmFnU2Nyb2xsJyB9KVxuICBzZXQgX2N1cnNvckRyYWdTY3JvbGwodjogYm9vbGVhbikge1xuICAgIHRoaXMuY3Vyc29yRHJhZ1Njcm9sbC5zZXQodik7XG4gIH1cbiAgcmVhZG9ubHkgY3Vyc29yRHJhZ1Njcm9sbCA9IHNpZ25hbCh0cnVlKTtcblxuICBASW5wdXQoeyB0cmFuc2Zvcm06IGJvb2xlYW5BdHRyaWJ1dGUsIGFsaWFzOiAnZGlzYWJsZUFjdGl2ZUVsZW1lbnRTY3JvbGxpbmcnIH0pXG4gIHNldCBfZGlzYWJsZUFjdGl2ZUVsZW1lbnRTY3JvbGxpbmcodjogYm9vbGVhbikge1xuICAgIHRoaXMuZGlzYWJsZUFjdGl2ZUVsZW1lbnRTY3JvbGxpbmcuc2V0KHYpO1xuICB9XG4gIHJlYWRvbmx5IGRpc2FibGVBY3RpdmVFbGVtZW50U2Nyb2xsaW5nID0gc2lnbmFsKGZhbHNlKTtcblxuICBASW5wdXQoeyBhbGlhczogJ3Njcm9sbE1vZGUnIH0pXG4gIHNldCBfc2Nyb2xsTW9kZSh2OiBTY3JvbGxhYmxlU2Nyb2xsTW9kZSkge1xuICAgIHRoaXMuc2Nyb2xsTW9kZS5zZXQodik7XG4gIH1cbiAgcmVhZG9ubHkgc2Nyb2xsTW9kZSA9IHNpZ25hbDxTY3JvbGxhYmxlU2Nyb2xsTW9kZT4oJ2NvbnRhaW5lcicpO1xuXG4gIEBJbnB1dCh7IHRyYW5zZm9ybTogYm9vbGVhbkF0dHJpYnV0ZSwgYWxpYXM6ICdzbmFwJyB9KVxuICBzZXQgX3NuYXAodjogYm9vbGVhbikge1xuICAgIHRoaXMuc25hcC5zZXQodik7XG4gIH1cbiAgcmVhZG9ubHkgc25hcCA9IHNpZ25hbChmYWxzZSk7XG5cbiAgQElucHV0KHsgdHJhbnNmb3JtOiBudW1iZXJBdHRyaWJ1dGUsIGFsaWFzOiAnc2Nyb2xsTWFyZ2luJyB9KVxuICBzZXQgX3Njcm9sbE1hcmdpbih2OiBudW1iZXIpIHtcbiAgICB0aGlzLnNjcm9sbE1hcmdpbi5zZXQodik7XG4gIH1cbiAgcmVhZG9ubHkgc2Nyb2xsTWFyZ2luID0gc2lnbmFsKDApO1xuXG4gIEBPdXRwdXQoKVxuICByZWFkb25seSBzY3JvbGxTdGF0ZUNoYW5nZSA9IG5ldyBFdmVudEVtaXR0ZXI8U2Nyb2xsT2JzZXJ2ZXJTY3JvbGxTdGF0ZT4oKTtcblxuICBAT3V0cHV0KClcbiAgcmVhZG9ubHkgaW50ZXJzZWN0aW9uQ2hhbmdlID0gbmV3IEV2ZW50RW1pdHRlcjxTY3JvbGxhYmxlSW50ZXJzZWN0aW9uQ2hhbmdlW10+KCk7XG5cbiAgQFZpZXdDaGlsZCgnc2Nyb2xsYWJsZScsIHsgc3RhdGljOiB0cnVlIH0pXG4gIHByaXZhdGUgc2V0IF9zY3JvbGxhYmxlKGU6IEVsZW1lbnRSZWY8SFRNTEVsZW1lbnQ+KSB7XG4gICAgdGhpcy5zY3JvbGxhYmxlLnNldChlKTtcbiAgfVxuICByZWFkb25seSBzY3JvbGxhYmxlID0gc2lnbmFsPEVsZW1lbnRSZWY8SFRNTEVsZW1lbnQ+IHwgbnVsbD4obnVsbCk7XG5cbiAgQFZpZXdDaGlsZCgnZmlyc3RFbGVtZW50JywgeyBzdGF0aWM6IHRydWUgfSlcbiAgcHJpdmF0ZSBzZXQgX2ZpcnN0RWxlbWVudChlOiBFbGVtZW50UmVmPEhUTUxFbGVtZW50Pikge1xuICAgIHRoaXMuZmlyc3RFbGVtZW50LnNldChlKTtcbiAgfVxuICByZWFkb25seSBmaXJzdEVsZW1lbnQgPSBzaWduYWw8RWxlbWVudFJlZjxIVE1MRWxlbWVudD4gfCBudWxsPihudWxsKTtcblxuICBAVmlld0NoaWxkKCdsYXN0RWxlbWVudCcsIHsgc3RhdGljOiB0cnVlIH0pXG4gIHByaXZhdGUgc2V0IF9sYXN0RWxlbWVudChlOiBFbGVtZW50UmVmPEhUTUxFbGVtZW50Pikge1xuICAgIHRoaXMubGFzdEVsZW1lbnQuc2V0KGUpO1xuICB9XG4gIHJlYWRvbmx5IGxhc3RFbGVtZW50ID0gc2lnbmFsPEVsZW1lbnRSZWY8SFRNTEVsZW1lbnQ+IHwgbnVsbD4obnVsbCk7XG5cbiAgQENvbnRlbnRDaGlsZHJlbihJU19BQ1RJVkVfRUxFTUVOVCwgeyBkZXNjZW5kYW50czogdHJ1ZSB9KVxuICBwcml2YXRlIHNldCBfYWN0aXZlRWxlbWVudExpc3QoZTogVHlwZWRRdWVyeUxpc3Q8SXNBY3RpdmVFbGVtZW50RGlyZWN0aXZlPikge1xuICAgIHRoaXMuYWN0aXZlRWxlbWVudExpc3Quc2V0KGUpO1xuICB9XG4gIHJlYWRvbmx5IGFjdGl2ZUVsZW1lbnRMaXN0ID0gc2lnbmFsPFR5cGVkUXVlcnlMaXN0PElzQWN0aXZlRWxlbWVudERpcmVjdGl2ZT4gfCBudWxsPihudWxsKTtcblxuICBAQ29udGVudENoaWxkcmVuKElTX0VMRU1FTlQsIHsgZGVzY2VuZGFudHM6IHRydWUgfSlcbiAgcHJpdmF0ZSBzZXQgX2VsZW1lbnRMaXN0KGU6IFR5cGVkUXVlcnlMaXN0PElzRWxlbWVudERpcmVjdGl2ZT4pIHtcbiAgICB0aGlzLmVsZW1lbnRMaXN0LnNldChlKTtcbiAgfVxuICByZWFkb25seSBlbGVtZW50TGlzdCA9IHNpZ25hbDxUeXBlZFF1ZXJ5TGlzdDxJc0VsZW1lbnREaXJlY3RpdmU+IHwgbnVsbD4obnVsbCk7XG5cbiAgZ2V0IGhpZ2hlc3RWaXNpYmxlSW50ZXJzZWN0aW9uKCkge1xuICAgIGNvbnN0IGVsZW1lbnRzID0gdGhpcy5fbGF0ZXN0VmlzaWJpbGl0eVN0YXRlcyQudmFsdWU7XG5cbiAgICBpZiAoIWVsZW1lbnRzLmxlbmd0aCkge1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuXG4gICAgcmV0dXJuIGVsZW1lbnRzLnJlZHVjZSgocHJldiwgY3VycikgPT4ge1xuICAgICAgaWYgKCFwcmV2KSB7XG4gICAgICAgIHJldHVybiBjdXJyO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gY3Vyci5pbnRlcnNlY3Rpb25SYXRpbyA+IHByZXYuaW50ZXJzZWN0aW9uUmF0aW8gPyBjdXJyIDogcHJldjtcbiAgICB9KTtcbiAgfVxuXG4gIGdldCBuZXh0UGFydGlhbEludGVyc2VjdGlvbigpIHtcbiAgICBjb25zdCBlbGVtZW50cyA9IHRoaXMuX2xhdGVzdFZpc2liaWxpdHlTdGF0ZXMkLnZhbHVlO1xuXG4gICAgaWYgKCFlbGVtZW50cy5sZW5ndGgpIHtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cblxuICAgIGNvbnN0IGhpZ2hlc3RWaXNpYmxlSW50ZXJzZWN0aW9uID0gdGhpcy5oaWdoZXN0VmlzaWJsZUludGVyc2VjdGlvbjtcblxuICAgIGlmICghaGlnaGVzdFZpc2libGVJbnRlcnNlY3Rpb24pIHtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cblxuICAgIGNvbnN0IG5leHRJbmRleCA9IGVsZW1lbnRzLnNsaWNlKGhpZ2hlc3RWaXNpYmxlSW50ZXJzZWN0aW9uLmluZGV4KS5maW5kSW5kZXgoKGUpID0+ICFlLmlzSW50ZXJzZWN0aW5nKTtcblxuICAgIGlmIChuZXh0SW5kZXggPT09IC0xKSB7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG5cbiAgICBjb25zdCBuZXh0RWxlbWVudCA9IGVsZW1lbnRzW2hpZ2hlc3RWaXNpYmxlSW50ZXJzZWN0aW9uLmluZGV4ICsgbmV4dEluZGV4XTtcblxuICAgIHJldHVybiBuZXh0RWxlbWVudCB8fCBudWxsO1xuICB9XG5cbiAgZ2V0IHByZXZpb3VzUGFydGlhbEludGVyc2VjdGlvbigpIHtcbiAgICBjb25zdCBlbGVtZW50cyA9IHRoaXMuX2xhdGVzdFZpc2liaWxpdHlTdGF0ZXMkLnZhbHVlO1xuXG4gICAgaWYgKCFlbGVtZW50cy5sZW5ndGgpIHtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cblxuICAgIGNvbnN0IGhpZ2hlc3RWaXNpYmxlSW50ZXJzZWN0aW9uID0gdGhpcy5oaWdoZXN0VmlzaWJsZUludGVyc2VjdGlvbjtcblxuICAgIGlmICghaGlnaGVzdFZpc2libGVJbnRlcnNlY3Rpb24pIHtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cblxuICAgIGNvbnN0IHByZXZpb3VzSW5kZXggPSBlbGVtZW50c1xuICAgICAgLnNsaWNlKDAsIGhpZ2hlc3RWaXNpYmxlSW50ZXJzZWN0aW9uLmluZGV4KVxuICAgICAgLnJldmVyc2UoKVxuICAgICAgLmZpbmRJbmRleCgoZSkgPT4gIWUuaXNJbnRlcnNlY3RpbmcpO1xuXG4gICAgaWYgKHByZXZpb3VzSW5kZXggPT09IC0xKSB7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG5cbiAgICBjb25zdCBwcmV2aW91c0VsZW1lbnQgPSBlbGVtZW50c1toaWdoZXN0VmlzaWJsZUludGVyc2VjdGlvbi5pbmRleCAtIHByZXZpb3VzSW5kZXggLSAxXTtcblxuICAgIHJldHVybiBwcmV2aW91c0VsZW1lbnQgfHwgbnVsbDtcbiAgfVxuXG4gIHByb3RlY3RlZCByZWFkb25seSBjb250YWluZXJTY3JvbGxTdGF0ZSA9IHNpZ25hbEVsZW1lbnRTY3JvbGxTdGF0ZSh0aGlzLnNjcm9sbGFibGUpO1xuICBwcm90ZWN0ZWQgcmVhZG9ubHkgZmlyc3RFbGVtZW50SW50ZXJzZWN0aW9uID0gc2lnbmFsRWxlbWVudEludGVyc2VjdGlvbih0aGlzLmZpcnN0RWxlbWVudCwgeyByb290OiB0aGlzLnNjcm9sbGFibGUgfSk7XG4gIHByb3RlY3RlZCByZWFkb25seSBmaXJzdEVsZW1lbnRWaXNpYmlsaXR5ID0gc2lnbmFsPEN1cnJlbnRFbGVtZW50VmlzaWJpbGl0eSB8IG51bGw+KG51bGwpO1xuICBwcm90ZWN0ZWQgcmVhZG9ubHkgbGFzdEVsZW1lbnRJbnRlcnNlY3Rpb24gPSBzaWduYWxFbGVtZW50SW50ZXJzZWN0aW9uKHRoaXMubGFzdEVsZW1lbnQsIHsgcm9vdDogdGhpcy5zY3JvbGxhYmxlIH0pO1xuICBwcm90ZWN0ZWQgcmVhZG9ubHkgbGFzdEVsZW1lbnRWaXNpYmlsaXR5ID0gc2lnbmFsPEN1cnJlbnRFbGVtZW50VmlzaWJpbGl0eSB8IG51bGw+KG51bGwpO1xuXG4gIHByb3RlY3RlZCByZWFkb25seSBjYW5TY3JvbGwgPSBjb21wdXRlZCgoKSA9PiB7XG4gICAgY29uc3QgZGlyID0gdGhpcy5kaXJlY3Rpb24oKTtcblxuICAgIGlmIChkaXIgPT09ICdob3Jpem9udGFsJykge1xuICAgICAgcmV0dXJuIHRoaXMuY29udGFpbmVyU2Nyb2xsU3RhdGUoKS5jYW5TY3JvbGxIb3Jpem9udGFsbHk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXMuY29udGFpbmVyU2Nyb2xsU3RhdGUoKS5jYW5TY3JvbGxWZXJ0aWNhbGx5O1xuICB9KTtcblxuICBwcm90ZWN0ZWQgcmVhZG9ubHkgaXNBdFN0YXJ0ID0gY29tcHV0ZWQoKCkgPT4ge1xuICAgIGlmICghdGhpcy5jYW5TY3JvbGwoKSkge1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuXG4gICAgY29uc3QgaW50ZXJzZWN0aW9uID0gdGhpcy5maXJzdEVsZW1lbnRJbnRlcnNlY3Rpb24oKTtcblxuICAgIGlmICghaW50ZXJzZWN0aW9uKSB7XG4gICAgICByZXR1cm4gdGhpcy5maXJzdEVsZW1lbnRWaXNpYmlsaXR5KCk/LmlubGluZSA/PyB0cnVlO1xuICAgIH1cblxuICAgIHJldHVybiBpbnRlcnNlY3Rpb24uaXNJbnRlcnNlY3Rpbmc7XG4gIH0pO1xuICBwcm90ZWN0ZWQgcmVhZG9ubHkgaXNBdEVuZCA9IGNvbXB1dGVkKCgpID0+IHtcbiAgICBpZiAoIXRoaXMuY2FuU2Nyb2xsKCkpIHtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cblxuICAgIGNvbnN0IGludGVyc2VjdGlvbiA9IHRoaXMubGFzdEVsZW1lbnRJbnRlcnNlY3Rpb24oKTtcblxuICAgIGlmICghaW50ZXJzZWN0aW9uKSB7XG4gICAgICByZXR1cm4gdGhpcy5sYXN0RWxlbWVudFZpc2liaWxpdHkoKT8uaW5saW5lID8/IHRydWU7XG4gICAgfVxuXG4gICAgcmV0dXJuIGludGVyc2VjdGlvbi5pc0ludGVyc2VjdGluZztcbiAgfSk7XG5cbiAgcHJvdGVjdGVkIHJlYWRvbmx5IGVuYWJsZU92ZXJsYXlBbmltYXRpb25zID0gc2lnbmFsKGZhbHNlKTtcblxuICBwcm90ZWN0ZWQgcmVhZG9ubHkgaG9zdEF0dHJpYnV0ZXMgPSBzaWduYWxIb3N0QXR0cmlidXRlcyh7XG4gICAgJ2l0ZW0tc2l6ZSc6IHRoaXMuaXRlbVNpemUsXG4gICAgZGlyZWN0aW9uOiB0aGlzLmRpcmVjdGlvbixcbiAgICAncmVuZGVyLXNjcm9sbGJhcnMnOiB0aGlzLnJlbmRlclNjcm9sbGJhcnMsXG4gICAgJ3N0aWNreS1idXR0b25zJzogdGhpcy5zdGlja3lCdXR0b25zLFxuICB9KTtcblxuICBwcm90ZWN0ZWQgcmVhZG9ubHkgaG9zdENsYXNzZXMgPSBzaWduYWxIb3N0Q2xhc3Nlcyh7XG4gICAgJ2V0LXNjcm9sbGFibGUtLWNhbi1zY3JvbGwnOiB0aGlzLmNhblNjcm9sbCxcbiAgICAnZXQtc2Nyb2xsYWJsZS0taXMtYXQtc3RhcnQnOiB0aGlzLmlzQXRTdGFydCxcbiAgICAnZXQtc2Nyb2xsYWJsZS0taXMtYXQtZW5kJzogdGhpcy5pc0F0RW5kLFxuICAgICdldC1zY3JvbGxhYmxlLS1lbmFibGUtb3ZlcmxheS1hbmltYXRpb25zJzogdGhpcy5lbmFibGVPdmVybGF5QW5pbWF0aW9ucyxcbiAgfSk7XG5cbiAgY29uc3RydWN0b3IoKSB7XG4gICAgZWZmZWN0KFxuICAgICAgKCkgPT4ge1xuICAgICAgICBjb25zdCBzY3JvbGxhYmxlID0gdGhpcy5zY3JvbGxhYmxlKCk/Lm5hdGl2ZUVsZW1lbnQ7XG4gICAgICAgIGNvbnN0IGZpcnN0RWxlbWVudCA9IHRoaXMuZmlyc3RFbGVtZW50KCk/Lm5hdGl2ZUVsZW1lbnQ7XG4gICAgICAgIGNvbnN0IGxhc3RFbGVtZW50ID0gdGhpcy5sYXN0RWxlbWVudCgpPy5uYXRpdmVFbGVtZW50O1xuICAgICAgICBjb25zdCBhY3RpdmVFbGVtZW50TGlzdCA9IHRoaXMuYWN0aXZlRWxlbWVudExpc3QoKT8udG9BcnJheSgpO1xuXG4gICAgICAgIGlmICghc2Nyb2xsYWJsZSB8fCAhZmlyc3RFbGVtZW50IHx8ICFsYXN0RWxlbWVudCB8fCAhYWN0aXZlRWxlbWVudExpc3QpIHtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBmaXJzdEFjdGl2ZSA9IGFjdGl2ZUVsZW1lbnRMaXN0LmZpbmQoKGEpID0+IGEuaXNBY3RpdmVFbGVtZW50KTtcblxuICAgICAgICBpZiAoZmlyc3RBY3RpdmUgJiYgIXRoaXMuZGlzYWJsZUFjdGl2ZUVsZW1lbnRTY3JvbGxpbmcoKSkge1xuICAgICAgICAgIGNvbnN0IG9mZnNldFRvcCA9IGZpcnN0QWN0aXZlLmVsZW1lbnRSZWYubmF0aXZlRWxlbWVudC5vZmZzZXRUb3AgLSBzY3JvbGxhYmxlLm9mZnNldFRvcDtcbiAgICAgICAgICBjb25zdCBvZmZzZXRMZWZ0ID0gZmlyc3RBY3RpdmUuZWxlbWVudFJlZi5uYXRpdmVFbGVtZW50Lm9mZnNldExlZnQgLSBzY3JvbGxhYmxlLm9mZnNldExlZnQ7XG4gICAgICAgICAgc2Nyb2xsYWJsZS5zY3JvbGxMZWZ0ID0gb2Zmc2V0TGVmdDtcbiAgICAgICAgICBzY3JvbGxhYmxlLnNjcm9sbFRvcCA9IG9mZnNldFRvcDtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuZmlyc3RFbGVtZW50VmlzaWJpbGl0eS5zZXQoXG4gICAgICAgICAgaXNFbGVtZW50VmlzaWJsZSh7XG4gICAgICAgICAgICBjb250YWluZXI6IHNjcm9sbGFibGUsXG4gICAgICAgICAgICBlbGVtZW50OiBmaXJzdEVsZW1lbnQsXG4gICAgICAgICAgfSksXG4gICAgICAgICk7XG5cbiAgICAgICAgdGhpcy5sYXN0RWxlbWVudFZpc2liaWxpdHkuc2V0KFxuICAgICAgICAgIGlzRWxlbWVudFZpc2libGUoe1xuICAgICAgICAgICAgY29udGFpbmVyOiBzY3JvbGxhYmxlLFxuICAgICAgICAgICAgZWxlbWVudDogbGFzdEVsZW1lbnQsXG4gICAgICAgICAgfSksXG4gICAgICAgICk7XG5cbiAgICAgICAgLy8gV2UgbmVlZCB0byB3YWl0IG9uZSBmcmFtZSBiZWZvcmUgZW5hYmxpbmcgYW5pbWF0aW9ucyB0byBwcmV2ZW50IGEgYW5pbWF0aW9uIGZyb20gcGxheWluZyBkdXJpbmcgaW5pdGlhbCByZW5kZXIuXG4gICAgICAgIG5leHRGcmFtZSgoKSA9PiB0aGlzLmVuYWJsZU92ZXJsYXlBbmltYXRpb25zLnNldCh0cnVlKSk7XG4gICAgICB9LFxuICAgICAgeyBhbGxvd1NpZ25hbFdyaXRlczogdHJ1ZSB9LFxuICAgICk7XG5cbiAgICBlZmZlY3QoKCkgPT4ge1xuICAgICAgY29uc3QgaXNBdFN0YXJ0ID0gdGhpcy5pc0F0U3RhcnQoKTtcbiAgICAgIGNvbnN0IGlzQXRFbmQgPSB0aGlzLmlzQXRFbmQoKTtcbiAgICAgIGNvbnN0IGNhblNjcm9sbCA9IHRoaXMuY2FuU2Nyb2xsKCk7XG5cbiAgICAgIHRoaXMuc2Nyb2xsU3RhdGVDaGFuZ2UuZW1pdCh7XG4gICAgICAgIGNhblNjcm9sbCxcbiAgICAgICAgaXNBdEVuZDogISFpc0F0RW5kLFxuICAgICAgICBpc0F0U3RhcnQ6ICEhaXNBdFN0YXJ0LFxuICAgICAgfSk7XG4gICAgfSk7XG4gIH1cblxuICBuZ0FmdGVyQ29udGVudEluaXQoKTogdm9pZCB7XG4gICAgdGhpcy5fc2V0dXBTY3JvbGxMaXN0ZW5pbmcoKTtcbiAgfVxuXG4gIHNjcm9sbE9uZUNvbnRhaW5lclNpemUoZGlyZWN0aW9uOiAnc3RhcnQnIHwgJ2VuZCcpIHtcbiAgICBjb25zdCBzY3JvbGxFbGVtZW50ID0gdGhpcy5zY3JvbGxhYmxlKCk/Lm5hdGl2ZUVsZW1lbnQ7XG5cbiAgICBpZiAoIXNjcm9sbEVsZW1lbnQpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCBwYXJlbnQgPSB0aGlzLl9lbGVtZW50UmVmLm5hdGl2ZUVsZW1lbnQ7XG5cbiAgICBjb25zdCBzY3JvbGxhYmxlU2l6ZSA9IHRoaXMuZGlyZWN0aW9uKCkgPT09ICdob3Jpem9udGFsJyA/IHBhcmVudC5jbGllbnRXaWR0aCA6IHBhcmVudC5jbGllbnRIZWlnaHQ7XG4gICAgY29uc3QgY3VycmVudFNjcm9sbCA9IHRoaXMuZGlyZWN0aW9uKCkgPT09ICdob3Jpem9udGFsJyA/IHNjcm9sbEVsZW1lbnQuc2Nyb2xsTGVmdCA6IHNjcm9sbEVsZW1lbnQuc2Nyb2xsVG9wO1xuXG4gICAgc2Nyb2xsRWxlbWVudC5zY3JvbGxUbyh7XG4gICAgICBbdGhpcy5kaXJlY3Rpb24oKSA9PT0gJ2hvcml6b250YWwnID8gJ2xlZnQnIDogJ3RvcCddOlxuICAgICAgICBjdXJyZW50U2Nyb2xsICsgKGRpcmVjdGlvbiA9PT0gJ3N0YXJ0JyA/IC1zY3JvbGxhYmxlU2l6ZSA6IHNjcm9sbGFibGVTaXplKSxcbiAgICAgIGJlaGF2aW9yOiAnc21vb3RoJyxcbiAgICB9KTtcbiAgfVxuXG4gIHNjcm9sbE9uZUl0ZW1TaXplKGRpcmVjdGlvbjogJ3N0YXJ0JyB8ICdlbmQnKSB7XG4gICAgY29uc3QgZWxlbWVudHMgPSB0aGlzLl9sYXRlc3RWaXNpYmlsaXR5U3RhdGVzJC52YWx1ZTtcblxuICAgIGlmICghZWxlbWVudHMubGVuZ3RoKSB7XG4gICAgICBpZiAoaXNEZXZNb2RlKCkpIHtcbiAgICAgICAgY29uc29sZS53YXJuKFxuICAgICAgICAgICdObyBlbGVtZW50cyBmb3VuZCB0byBzY3JvbGwgdG8uIE1ha2Ugc3VyZSB0byBhcHBseSB0aGUgaXNFbGVtZW50IGRpcmVjdGl2ZSB0byB0aGUgZWxlbWVudHMgeW91IHdhbnQgdG8gc2Nyb2xsIHRvLicsXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc3QgZWwgPSBkaXJlY3Rpb24gPT09ICdzdGFydCcgPyB0aGlzLnByZXZpb3VzUGFydGlhbEludGVyc2VjdGlvbiA6IHRoaXMubmV4dFBhcnRpYWxJbnRlcnNlY3Rpb247XG5cbiAgICBpZiAoIWVsKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdGhpcy5zY3JvbGxUb0VsZW1lbnQoe1xuICAgICAgZWxlbWVudDogZWw/LmVsZW1lbnQsXG4gICAgICBkaXJlY3Rpb246IHRoaXMuZGlyZWN0aW9uKCkgPT09ICdob3Jpem9udGFsJyA/ICdpbmxpbmUnIDogJ2Jsb2NrJyxcbiAgICAgIG9yaWdpbjogZGlyZWN0aW9uLFxuICAgICAgLi4uKHRoaXMuZGlyZWN0aW9uKCkgPT09ICdob3Jpem9udGFsJ1xuICAgICAgICA/IHsgc2Nyb2xsSW5saW5lTWFyZ2luOiB0aGlzLnNjcm9sbE1hcmdpbigpIH1cbiAgICAgICAgOiB7IHNjcm9sbEJsb2NrTWFyZ2luOiB0aGlzLnNjcm9sbE1hcmdpbigpIH0pLFxuICAgIH0pO1xuICB9XG5cbiAgc2Nyb2xsVG9FbGVtZW50KG9wdGlvbnM6IE9taXQ8U2Nyb2xsVG9FbGVtZW50T3B0aW9ucywgJ2NvbnRhaW5lcic+KSB7XG4gICAgY29uc3Qgc2Nyb2xsRWxlbWVudCA9IHRoaXMuc2Nyb2xsYWJsZSgpPy5uYXRpdmVFbGVtZW50O1xuXG4gICAgc2Nyb2xsVG9FbGVtZW50KHtcbiAgICAgIGNvbnRhaW5lcjogc2Nyb2xsRWxlbWVudCxcbiAgICAgIC4uLih0aGlzLmRpcmVjdGlvbigpID09PSAnaG9yaXpvbnRhbCdcbiAgICAgICAgPyB7IHNjcm9sbElubGluZU1hcmdpbjogdGhpcy5zY3JvbGxNYXJnaW4oKSB9XG4gICAgICAgIDogeyBzY3JvbGxCbG9ja01hcmdpbjogdGhpcy5zY3JvbGxNYXJnaW4oKSB9KSxcbiAgICAgIC4uLm9wdGlvbnMsXG4gICAgfSk7XG4gIH1cblxuICBzY3JvbGxUb0VsZW1lbnRCeUluZGV4KG9wdGlvbnM6IE9taXQ8U2Nyb2xsVG9FbGVtZW50T3B0aW9ucywgJ2NvbnRhaW5lcic+ICYgeyBpbmRleDogbnVtYmVyIH0pIHtcbiAgICBjb25zdCBlbGVtZW50cyA9IHRoaXMuZWxlbWVudExpc3QoKT8udG9BcnJheSgpID8/IFtdO1xuXG4gICAgaWYgKCFlbGVtZW50cy5sZW5ndGgpIHtcbiAgICAgIGlmIChpc0Rldk1vZGUoKSkge1xuICAgICAgICBjb25zb2xlLndhcm4oXG4gICAgICAgICAgJ05vIGVsZW1lbnRzIGZvdW5kIHRvIHNjcm9sbCB0by4gTWFrZSBzdXJlIHRvIGFwcGx5IHRoZSBpc0VsZW1lbnQgZGlyZWN0aXZlIHRvIHRoZSBlbGVtZW50cyB5b3Ugd2FudCB0byBzY3JvbGwgdG8uJyxcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCBzY3JvbGxFbGVtZW50ID0gdGhpcy5zY3JvbGxhYmxlKCk/Lm5hdGl2ZUVsZW1lbnQ7XG4gICAgY29uc3QgZWxlbWVudCA9IGVsZW1lbnRzW29wdGlvbnMuaW5kZXhdPy5lbGVtZW50UmVmLm5hdGl2ZUVsZW1lbnQ7XG5cbiAgICBzY3JvbGxUb0VsZW1lbnQoe1xuICAgICAgY29udGFpbmVyOiBzY3JvbGxFbGVtZW50LFxuICAgICAgZWxlbWVudCxcbiAgICAgIC4uLih0aGlzLmRpcmVjdGlvbigpID09PSAnaG9yaXpvbnRhbCdcbiAgICAgICAgPyB7IHNjcm9sbElubGluZU1hcmdpbjogdGhpcy5zY3JvbGxNYXJnaW4oKSB9XG4gICAgICAgIDogeyBzY3JvbGxCbG9ja01hcmdpbjogdGhpcy5zY3JvbGxNYXJnaW4oKSB9KSxcbiAgICAgIC4uLm9wdGlvbnMsXG4gICAgfSk7XG4gIH1cblxuICBwcm90ZWN0ZWQgc2V0SXNDdXJzb3JEcmFnZ2luZyhpc0RyYWdnaW5nOiBib29sZWFuKSB7XG4gICAgdGhpcy5faXNDdXJzb3JEcmFnZ2luZyQubmV4dChpc0RyYWdnaW5nKTtcbiAgfVxuXG4gIHByb3RlY3RlZCBzY3JvbGxUb1N0YXJ0RGlyZWN0aW9uKCkge1xuICAgIGlmICh0aGlzLnNjcm9sbE1vZGUoKSA9PT0gJ2NvbnRhaW5lcicpIHtcbiAgICAgIHRoaXMuc2Nyb2xsT25lQ29udGFpbmVyU2l6ZSgnc3RhcnQnKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5zY3JvbGxPbmVJdGVtU2l6ZSgnc3RhcnQnKTtcbiAgICB9XG4gIH1cblxuICBwcm90ZWN0ZWQgc2Nyb2xsVG9TdGFydEVuZCgpIHtcbiAgICBpZiAodGhpcy5zY3JvbGxNb2RlKCkgPT09ICdjb250YWluZXInKSB7XG4gICAgICB0aGlzLnNjcm9sbE9uZUNvbnRhaW5lclNpemUoJ2VuZCcpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLnNjcm9sbE9uZUl0ZW1TaXplKCdlbmQnKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIF9zZXR1cFNjcm9sbExpc3RlbmluZygpIHtcbiAgICBjb25zdCBzY3JvbGxFbGVtZW50ID0gdGhpcy5zY3JvbGxhYmxlKCk/Lm5hdGl2ZUVsZW1lbnQ7XG4gICAgY29uc3QgZWxlbWVudHMgPSB0aGlzLmVsZW1lbnRMaXN0KCk7XG5cbiAgICBpZiAoIXNjcm9sbEVsZW1lbnQgfHwgIWVsZW1lbnRzKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgbGV0IGlzU25hcHBpbmcgPSBmYWxzZTtcbiAgICBsZXQgc25hcFRpbWVvdXQgPSAwO1xuXG4gICAgbWVyZ2UoZnJvbUV2ZW50PFdoZWVsRXZlbnQ+KHNjcm9sbEVsZW1lbnQsICd3aGVlbCcpLCBmcm9tRXZlbnQ8VG91Y2hFdmVudD4oc2Nyb2xsRWxlbWVudCwgJ3RvdWNoc3RhcnQnKSlcbiAgICAgIC5waXBlKFxuICAgICAgICB0YWtlVW50aWwodGhpcy5fZGVzdHJveSQpLFxuICAgICAgICB0YXAoKCkgPT4ge1xuICAgICAgICAgIGlzU25hcHBpbmcgPSBmYWxzZTtcbiAgICAgICAgfSksXG4gICAgICApXG4gICAgICAuc3Vic2NyaWJlKCk7XG5cbiAgICBtZXJnZShcbiAgICAgIGZyb21FdmVudChzY3JvbGxFbGVtZW50LCAnc2Nyb2xsJyksXG4gICAgICB0aGlzLl9pc0N1cnNvckRyYWdnaW5nJCxcbiAgICAgIGVsZW1lbnRzLmNoYW5nZXMucGlwZShzdGFydFdpdGgoZWxlbWVudHMpKSA/PyBvZihudWxsKSxcbiAgICApXG4gICAgICAucGlwZShcbiAgICAgICAgZGVib3VuY2VUaW1lKDMwMCksXG4gICAgICAgIHRha2VVbnRpbCh0aGlzLl9kZXN0cm95JCksXG4gICAgICAgIHRhcCgoKSA9PiB7XG4gICAgICAgICAgY29uc3QgZWxzID1cbiAgICAgICAgICAgIGVsZW1lbnRzXG4gICAgICAgICAgICAgID8udG9BcnJheSgpXG4gICAgICAgICAgICAgIC5tYXAoKGUpID0+IGU/LmVsZW1lbnRSZWYubmF0aXZlRWxlbWVudClcbiAgICAgICAgICAgICAgLmZpbHRlcigoZSk6IGUgaXMgSFRNTEVsZW1lbnQgPT4gISFlKSA/PyBbXTtcblxuICAgICAgICAgIGlmICghZWxzLmxlbmd0aCkge1xuICAgICAgICAgICAgdGhpcy5fbGF0ZXN0VmlzaWJpbGl0eVN0YXRlcyQubmV4dChbXSk7XG5cbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBjb25zdCBzdGF0ZXMgPSBnZXRFbGVtZW50VmlzaWJsZVN0YXRlcyh7XG4gICAgICAgICAgICBlbGVtZW50czogZWxzLFxuICAgICAgICAgICAgY29udGFpbmVyOiBzY3JvbGxFbGVtZW50LFxuICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgY29uc3QgcHJvcCA9IHRoaXMuZGlyZWN0aW9uKCkgPT09ICdob3Jpem9udGFsJyA/ICdpbmxpbmVJbnRlcnNlY3Rpb24nIDogJ2Jsb2NrSW50ZXJzZWN0aW9uJztcbiAgICAgICAgICBjb25zdCBzdGF0ZUNsYXNzID0gYGV0LWVsZW1lbnQtLWlzLWludGVyc2VjdGluZ2A7XG5cbiAgICAgICAgICBmb3IgKGNvbnN0IHN0YXRlIG9mIHN0YXRlcykge1xuICAgICAgICAgICAgaWYgKHN0YXRlW3Byb3BdID09PSAxMDApIHtcbiAgICAgICAgICAgICAgc3RhdGUuZWxlbWVudC5jbGFzc0xpc3QuYWRkKHN0YXRlQ2xhc3MpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgc3RhdGUuZWxlbWVudC5jbGFzc0xpc3QucmVtb3ZlKHN0YXRlQ2xhc3MpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cblxuICAgICAgICAgIGNvbnN0IGludGVyc2VjdGlvbkNoYW5nZXMgPSBzdGF0ZXMubWFwKChzLCBpKSA9PiB7XG4gICAgICAgICAgICBjb25zdCBzdGF0ZTogU2Nyb2xsYWJsZUludGVyc2VjdGlvbkNoYW5nZSA9IHtcbiAgICAgICAgICAgICAgZWxlbWVudDogcy5lbGVtZW50LFxuICAgICAgICAgICAgICBpbnRlcnNlY3Rpb25SYXRpbzogc1twcm9wXSAvIDEwMCxcbiAgICAgICAgICAgICAgaXNJbnRlcnNlY3Rpbmc6IHNbcHJvcF0gPT09IDEwMCxcbiAgICAgICAgICAgICAgaW5kZXg6IGksXG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICByZXR1cm4gc3RhdGU7XG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgICB0aGlzLmludGVyc2VjdGlvbkNoYW5nZS5lbWl0KGludGVyc2VjdGlvbkNoYW5nZXMpO1xuXG4gICAgICAgICAgdGhpcy5fbGF0ZXN0VmlzaWJpbGl0eVN0YXRlcyQubmV4dChpbnRlcnNlY3Rpb25DaGFuZ2VzKTtcblxuICAgICAgICAgIGlmIChpc1NuYXBwaW5nIHx8IHRoaXMuX2lzQ3Vyc29yRHJhZ2dpbmckLnZhbHVlIHx8ICF0aGlzLnNuYXAoKSkgcmV0dXJuO1xuXG4gICAgICAgICAgY29uc3QgcHJldiA9IHRoaXMucHJldmlvdXNQYXJ0aWFsSW50ZXJzZWN0aW9uO1xuICAgICAgICAgIGNvbnN0IG5leHQgPSB0aGlzLm5leHRQYXJ0aWFsSW50ZXJzZWN0aW9uO1xuICAgICAgICAgIGNvbnN0IHNraXBTbmFwID1cbiAgICAgICAgICAgICFwcmV2IHx8XG4gICAgICAgICAgICAhbmV4dCB8fFxuICAgICAgICAgICAgcHJldi5pbnRlcnNlY3Rpb25SYXRpbyA9PT0gMCB8fFxuICAgICAgICAgICAgbmV4dC5pbnRlcnNlY3Rpb25SYXRpbyA9PT0gMCB8fFxuICAgICAgICAgICAgcHJldi5pbnRlcnNlY3Rpb25SYXRpbyA9PT0gbmV4dC5pbnRlcnNlY3Rpb25SYXRpbztcblxuICAgICAgICAgIGlmIChza2lwU25hcCkgcmV0dXJuO1xuXG4gICAgICAgICAgY29uc3QgaGlnaGVzdEludGVyc2VjdGluZyA9IHByZXYuaW50ZXJzZWN0aW9uUmF0aW8gPiBuZXh0LmludGVyc2VjdGlvblJhdGlvID8gcHJldiA6IG5leHQ7XG4gICAgICAgICAgY29uc3QgZnVsbEludGVyc2VjdGlvbkluZGV4ID0gdGhpcy5oaWdoZXN0VmlzaWJsZUludGVyc2VjdGlvbj8uaW5kZXg7XG5cbiAgICAgICAgICBpZiAoZnVsbEludGVyc2VjdGlvbkluZGV4ID09PSB1bmRlZmluZWQpIHJldHVybjtcblxuICAgICAgICAgIGNvbnN0IGhpZ2hlc3RJbnRlcnNlY3RpbmdJbmRleCA9IGhpZ2hlc3RJbnRlcnNlY3RpbmcuaW5kZXg7XG4gICAgICAgICAgY29uc3Qgb3JpZ2luID0gaGlnaGVzdEludGVyc2VjdGluZ0luZGV4ID4gZnVsbEludGVyc2VjdGlvbkluZGV4ID8gJ2VuZCcgOiAnc3RhcnQnO1xuXG4gICAgICAgICAgc2Nyb2xsVG9FbGVtZW50KHtcbiAgICAgICAgICAgIGNvbnRhaW5lcjogc2Nyb2xsRWxlbWVudCxcbiAgICAgICAgICAgIGVsZW1lbnQ6IGhpZ2hlc3RJbnRlcnNlY3RpbmcuZWxlbWVudCxcbiAgICAgICAgICAgIGRpcmVjdGlvbjogdGhpcy5kaXJlY3Rpb24oKSA9PT0gJ2hvcml6b250YWwnID8gJ2lubGluZScgOiAnYmxvY2snLFxuICAgICAgICAgICAgb3JpZ2luLFxuICAgICAgICAgICAgc2Nyb2xsQmxvY2tNYXJnaW46IHRoaXMuZGlyZWN0aW9uKCkgPT09ICdob3Jpem9udGFsJyA/IDAgOiB0aGlzLnNjcm9sbE1hcmdpbigpLFxuICAgICAgICAgICAgc2Nyb2xsSW5saW5lTWFyZ2luOiB0aGlzLmRpcmVjdGlvbigpID09PSAnaG9yaXpvbnRhbCcgPyB0aGlzLnNjcm9sbE1hcmdpbigpIDogMCxcbiAgICAgICAgICB9KTtcblxuICAgICAgICAgIGlzU25hcHBpbmcgPSB0cnVlO1xuXG4gICAgICAgICAgd2luZG93LmNsZWFyVGltZW91dChzbmFwVGltZW91dCk7XG5cbiAgICAgICAgICBzbmFwVGltZW91dCA9IHdpbmRvdy5zZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgICAgIGlzU25hcHBpbmcgPSBmYWxzZTtcbiAgICAgICAgICB9LCAxMDAwKTtcbiAgICAgICAgfSksXG4gICAgICApXG4gICAgICAuc3Vic2NyaWJlKCk7XG4gIH1cbn1cbiIsIjxkaXZcbiAgI3Njcm9sbGFibGVcbiAgW2F0dHIucm9sZV09XCJzY3JvbGxhYmxlUm9sZSgpID8/IHVuZGVmaW5lZFwiXG4gIFtldEN1cnNvckRyYWdTY3JvbGxdPVwiY3Vyc29yRHJhZ1Njcm9sbCgpXCJcbiAgW2FsbG93ZWREaXJlY3Rpb25dPVwiZGlyZWN0aW9uKClcIlxuICAoY3Vyc29yRHJhZ1N0YXJ0KT1cInNldElzQ3Vyc29yRHJhZ2dpbmcodHJ1ZSlcIlxuICAoY3Vyc29yRHJhZ0VuZCk9XCJzZXRJc0N1cnNvckRyYWdnaW5nKGZhbHNlKVwiXG4gIGNsYXNzPVwiZXQtc2Nyb2xsYWJsZS1jb250YWluZXItb3V0ZXJcIlxuPlxuICA8ZGl2IFtuZ0NsYXNzXT1cInNjcm9sbGFibGVDbGFzcygpXCIgY2xhc3M9XCJldC1zY3JvbGxhYmxlLWNvbnRhaW5lclwiPlxuICAgIDxkaXYgI2ZpcnN0RWxlbWVudCBjbGFzcz1cImV0LXNjcm9sbC1vYnNlcnZlci1maXJzdC1lbGVtZW50XCI+PC9kaXY+XG4gICAgPG5nLWNvbnRlbnQgLz5cbiAgICA8ZGl2ICNsYXN0RWxlbWVudCBjbGFzcz1cImV0LXNjcm9sbC1vYnNlcnZlci1sYXN0LWVsZW1lbnRcIj48L2Rpdj5cbiAgPC9kaXY+XG48L2Rpdj5cblxuQGlmIChyZW5kZXJNYXNrcygpKSB7XG4gIDxkaXYgY2xhc3M9XCJldC1zY3JvbGxhYmxlLW1hc2tzXCI+XG4gICAgPGRpdiBjbGFzcz1cImV0LXNjcm9sbGFibGUtbWFzayBldC1zY3JvbGxhYmxlLW1hc2stLXN0YXJ0XCI+PC9kaXY+XG4gICAgPGRpdiBjbGFzcz1cImV0LXNjcm9sbGFibGUtbWFzayBldC1zY3JvbGxhYmxlLW1hc2stLWVuZFwiPjwvZGl2PlxuICA8L2Rpdj5cbn1cblxuQGlmIChyZW5kZXJCdXR0b25zKCkpIHtcbiAgPGRpdiBjbGFzcz1cImV0LXNjcm9sbGFibGUtYnV0dG9uc1wiPlxuICAgIDxidXR0b25cbiAgICAgIChjbGljayk9XCJzY3JvbGxUb1N0YXJ0RGlyZWN0aW9uKClcIlxuICAgICAgY2xhc3M9XCJldC1zY3JvbGxhYmxlLWJ1dHRvbiBldC1zY3JvbGxhYmxlLWJ1dHRvbi0tc3RhcnRcIlxuICAgICAgYXJpYS1oaWRkZW49XCJ0cnVlXCJcbiAgICAgIHR5cGU9XCJidXR0b25cIlxuICAgICAgdGFiaW5kZXg9XCItMVwiXG4gICAgPlxuICAgICAgPGV0LWNoZXZyb24taWNvbiAvPlxuICAgIDwvYnV0dG9uPlxuICAgIDxidXR0b25cbiAgICAgIChjbGljayk9XCJzY3JvbGxUb1N0YXJ0RW5kKClcIlxuICAgICAgY2xhc3M9XCJldC1zY3JvbGxhYmxlLWJ1dHRvbiBldC1zY3JvbGxhYmxlLWJ1dHRvbi0tZW5kXCJcbiAgICAgIGFyaWEtaGlkZGVuPVwidHJ1ZVwiXG4gICAgICB0eXBlPVwiYnV0dG9uXCJcbiAgICAgIHRhYmluZGV4PVwiLTFcIlxuICAgID5cbiAgICAgIDxldC1jaGV2cm9uLWljb24gLz5cbiAgICA8L2J1dHRvbj5cbiAgPC9kaXY+XG59XG4iXX0=
580
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2Nyb2xsYWJsZS5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi8uLi8uLi9saWJzL2Nkay9zcmMvbGliL2NvbXBvbmVudHMvc2Nyb2xsYWJsZS9jb21wb25lbnRzL3Njcm9sbGFibGUvc2Nyb2xsYWJsZS5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi8uLi8uLi8uLi8uLi8uLi9saWJzL2Nkay9zcmMvbGliL2NvbXBvbmVudHMvc2Nyb2xsYWJsZS9jb21wb25lbnRzL3Njcm9sbGFibGUvc2Nyb2xsYWJsZS5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsT0FBTyxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDMUMsT0FBTyxFQUNMLHVCQUF1QixFQUN2QixTQUFTLEVBQ1QsZUFBZSxFQUNmLFVBQVUsRUFDVixZQUFZLEVBQ1osS0FBSyxFQUNMLE1BQU0sRUFDTixTQUFTLEVBQ1QsaUJBQWlCLEVBQ2pCLGdCQUFnQixFQUNoQixRQUFRLEVBQ1IsTUFBTSxFQUNOLE1BQU0sRUFDTixTQUFTLEVBQ1QsZUFBZSxFQUNmLE1BQU0sR0FDUCxNQUFNLGVBQWUsQ0FBQztBQUN2QixPQUFPLEVBQUUsa0JBQWtCLEVBQUUsWUFBWSxFQUFFLE1BQU0sNEJBQTRCLENBQUM7QUFDOUUsT0FBTyxFQUVMLHlCQUF5QixFQUN6QixpQkFBaUIsRUFFakIsWUFBWSxFQUVaLDJCQUEyQixFQUczQixjQUFjLEVBQ2Qsa0NBQWtDLEVBQ2xDLGdCQUFnQixFQUNoQixTQUFTLEVBQ1QsZUFBZSxFQUNmLHFCQUFxQixFQUNyQix5QkFBeUIsRUFDekIsd0JBQXdCLEVBQ3hCLG9CQUFvQixFQUNwQixpQkFBaUIsR0FDbEIsTUFBTSxlQUFlLENBQUM7QUFDdkIsT0FBTyxFQUNMLGVBQWUsRUFDZixPQUFPLEVBQ1AsYUFBYSxFQUNiLFlBQVksRUFDWixNQUFNLEVBQ04sU0FBUyxFQUNU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ZUFBZSxFQUFFO2dCQU8xRCxpQkFBaUI7c0JBRHBCLEtBQUs7dUJBQUMsRUFBRSxTQUFTLEVBQUUsZ0JBQWdCLEVBQUUsS0FBSyxFQUFFLGtCQUFrQixFQUFFO2dCQU83RCw4QkFBOEI7c0JBRGpDLEtBQUs7dUJBQUMsRUFBRSxTQUFTLEVBQUUsZ0JBQWdCLEVBQUUsS0FBSyxFQUFFLCtCQUErQixFQUFFO2dCQU8xRSxXQUFXO3NCQURkLEtBQUs7dUJBQUMsRUFBRSxLQUFLLEVBQUUsWUFBWSxFQUFFO2dCQU8xQixLQUFLO3NCQURSLEtBQUs7dUJBQUMsRUFBRSxTQUFTLEVBQUUsZ0JBQWdCLEVBQUUsS0FBSyxFQUFFLE1BQU0sRUFBRTtnQkFPakQsYUFBYTtzQkFEaEIsS0FBSzt1QkFBQyxFQUFFLFNBQVMsRUFBRSxlQUFlLEVBQUUsS0FBSyxFQUFFLGNBQWMsRUFBRTtnQkFPbkQsaUJBQWlCO3NCQUR6QixNQUFNO2dCQUlFLGtCQUFrQjtzQkFEMUIsTUFBTTtnQkFJSyxXQUFXO3NCQUR0QixTQUFTO3VCQUFDLFlBQVksRUFBRSxFQUFFLE1BQU0sRUFBRSxJQUFJLEVBQUU7Z0JBTzdCLG9CQUFvQjtzQkFEL0IsU0FBUzt1QkFBQyxxQkFBcUIsRUFBRSxFQUFFLE1BQU0sRUFBRSxJQUFJLEVBQUU7Z0JBT3RDLGFBQWE7c0JBRHhCLFNBQVM7dUJBQUMsY0FBYyxFQUFFLEVBQUUsTUFBTSxFQUFFLElBQUksRUFBRTtnQkFPL0IsWUFBWTtzQkFEdkIsU0FBUzt1QkFBQyxhQUFhLEVBQUUsRUFBRSxNQUFNLEVBQUUsSUFBSSxFQUFFO2dCQU85QixrQkFBa0I7c0JBRDdCLGVBQWU7dUJBQUMsaUJBQWlCLEVBQUUsRUFBRSxXQUFXLEVBQUUsSUFBSSxFQUFFIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgTmdDbGFzcyB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbic7XG5pbXBvcnQge1xuICBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneSxcbiAgQ29tcG9uZW50LFxuICBDb250ZW50Q2hpbGRyZW4sXG4gIEVsZW1lbnRSZWYsXG4gIEV2ZW50RW1pdHRlcixcbiAgSW5wdXQsXG4gIE91dHB1dCxcbiAgVmlld0NoaWxkLFxuICBWaWV3RW5jYXBzdWxhdGlvbixcbiAgYm9vbGVhbkF0dHJpYnV0ZSxcbiAgY29tcHV0ZWQsXG4gIGVmZmVjdCxcbiAgaW5qZWN0LFxuICBpc0Rldk1vZGUsXG4gIG51bWJlckF0dHJpYnV0ZSxcbiAgc2lnbmFsLFxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IHRha2VVbnRpbERlc3Ryb3llZCwgdG9PYnNlcnZhYmxlIH0gZnJvbSAnQGFuZ3VsYXIvY29yZS9yeGpzLWludGVyb3AnO1xuaW1wb3J0IHtcbiAgQ3VycmVudEVsZW1lbnRWaXNpYmlsaXR5LFxuICBDdXJzb3JEcmFnU2Nyb2xsRGlyZWN0aXZlLFxuICBJU19BQ1RJVkVfRUxFTUVOVCxcbiAgSXNBY3RpdmVFbGVtZW50RGlyZWN0aXZlLFxuICBMZXREaXJlY3RpdmUsXG4gIE5nQ2xhc3NUeXBlLFxuICBPYnNlcnZlU2Nyb2xsU3RhdGVEaXJlY3RpdmUsXG4gIFNjcm9sbE9ic2VydmVyU2Nyb2xsU3RhdGUsXG4gIFNjcm9sbFRvRWxlbWVudE9wdGlvbnMsXG4gIFR5cGVkUXVlcnlMaXN0LFxuICBnZXRGaXJzdEFuZExhc3RQYXJ0aWFsSW50ZXJzZWN0aW9uLFxuICBpc0VsZW1lbnRWaXNpYmxlLFxuICBuZXh0RnJhbWUsXG4gIHNjcm9sbFRvRWxlbWVudCxcbiAgc2lnbmFsRWxlbWVudENoaWxkcmVuLFxuICBzaWduYWxFbGVtZW50SW50ZXJzZWN0aW9uLFxuICBzaWduYWxFbGVtZW50U2Nyb2xsU3RhdGUsXG4gIHNpZ25hbEhvc3RBdHRyaWJ1dGVzLFxuICBzaWduYWxIb3N0Q2xhc3Nlcyxcbn0gZnJvbSAnQGV0aGxldGUvY29yZSc7XG5pbXBvcnQge1xuICBCZWhhdmlvclN1YmplY3QsXG4gIFN1YmplY3QsXG4gIGNvbWJpbmVMYXRlc3QsXG4gIGRlYm91bmNlVGltZSxcbiAgZmlsdGVyLFxuICBmcm9tRXZlbnQsXG4gIG1hcCxcbiAgdGFrZSxcbiAgdGFrZVVudGlsLFxuICB0YXAsXG59IGZyb20gJ3J4anMnO1xuaW1wb3J0IHsgQ2hldnJvbkljb25Db21wb25lbnQgfSBmcm9tICcuLi8uLi8uLi9pY29ucyc7XG5pbXBvcnQgeyBTY3JvbGxhYmxlSWdub3JlQ2hpbGREaXJlY3RpdmUsIGlzU2Nyb2xsYWJsZUNoaWxkSWdub3JlZCB9IGZyb20gJy4uLy4uL2RpcmVjdGl2ZXMnO1xuaW1wb3J0IHsgU2Nyb2xsYWJsZUludGVyc2VjdGlvbkNoYW5nZSwgU2Nyb2xsYWJsZVNjcm9sbE1vZGUgfSBmcm9tICcuLi8uLi90eXBlcyc7XG5cbi8vIFRocmVzaG9sZHMgZm9yIHRoZSBpbnRlcnNlY3Rpb24gb2JzZXJ2ZXIuXG5jb25zdCBFTEVNRU5UX0lOVEVSU0VDVElPTl9USFJFU0hPTEQgPSBbXG4gIC8vIFdlIHVzZSA1MSBzdGVwcyB0byBnZXQgYSAyJSBzdGVwIHNpemUuXG4gIC4uLkFycmF5LmZyb20oeyBsZW5ndGg6IDUxIH0sIChfLCBpKSA9PiBpIC8gNTApLFxuXG4gIC8vIEFkZGl0aW9uYWwgc3RlcHMgbmVlZGVkIHNpbmNlIGRpc3BsYXkgc2NhbGluZyBjYW4gY2F1c2UgdGhlIGludGVyc2VjdGlvbiByYXRpbyB0byBiZSBzbGlnaHRseSBvZmYuXG4gIDAuMDEsXG4gIDAuMDA1LFxuICAwLjAwMSxcbiAgMC45OSxcbiAgMC45OTUsXG4gIDAuOTk5LFxuXTtcblxuaW50ZXJmYWNlIFNjcm9sbGFibGVOYXZpZ2F0aW9uSXRlbSB7XG4gIGlzQWN0aXZlOiBib29sZWFuO1xuICBlbGVtZW50OiBIVE1MRWxlbWVudDtcbn1cblxuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAnZXQtc2Nyb2xsYWJsZScsXG4gIHRlbXBsYXRlVXJsOiAnLi9zY3JvbGxhYmxlLmNvbXBvbmVudC5odG1sJyxcbiAgc3R5bGVVcmxzOiBbJy4vc2Nyb2xsYWJsZS5jb21wb25lbnQuc2NzcyddLFxuICBzdGFuZGFsb25lOiB0cnVlLFxuICBlbmNhcHN1bGF0aW9uOiBWaWV3RW5jYXBzdWxhdGlvbi5Ob25lLFxuICBjaGFuZ2VEZXRlY3Rpb246IENoYW5nZURldGVjdGlvblN0cmF0ZWd5Lk9uUHVzaCxcbiAgaW1wb3J0czogW1xuICAgIEN1cnNvckRyYWdTY3JvbGxEaXJlY3RpdmUsXG4gICAgT2JzZXJ2ZVNjcm9sbFN0YXRlRGlyZWN0aXZlLFxuICAgIE5nQ2xhc3MsXG4gICAgTGV0RGlyZWN0aXZlLFxuICAgIENoZXZyb25JY29uQ29tcG9uZW50LFxuICAgIFNjcm9sbGFibGVJZ25vcmVDaGlsZERpcmVjdGl2ZSxcbiAgXSxcbiAgaG9zdDoge1xuICAgIGNsYXNzOiAnZXQtc2Nyb2xsYWJsZScsXG4gIH0sXG59KVxuZXhwb3J0IGNsYXNzIFNjcm9sbGFibGVDb21wb25lbnQge1xuICBwcml2YXRlIHJlYWRvbmx5IF9lbGVtZW50UmVmID0gaW5qZWN0PEVsZW1lbnRSZWY8SFRNTEVsZW1lbnQ+PihFbGVtZW50UmVmKTtcbiAgcHJpdmF0ZSByZWFkb25seSBfaXNDdXJzb3JEcmFnZ2luZyQgPSBuZXcgQmVoYXZpb3JTdWJqZWN0PGJvb2xlYW4+KGZhbHNlKTtcblxuICBASW5wdXQoeyBhbGlhczogJ2l0ZW1TaXplJyB9KVxuICBzZXQgX2l0ZW1TaXplKHY6ICdhdXRvJyB8ICdzYW1lJyB8ICdmdWxsJykge1xuICAgIHRoaXMuaXRlbVNpemUuc2V0KHYpO1xuICB9XG4gIHJlYWRvbmx5IGl0ZW1TaXplID0gc2lnbmFsPCdhdXRvJyB8ICdzYW1lJyB8ICdmdWxsJz4oJ2F1dG8nKTtcblxuICBASW5wdXQoeyBhbGlhczogJ2RpcmVjdGlvbicgfSlcbiAgc2V0IF9kaXJlY3Rpb24odjogJ2hvcml6b250YWwnIHwgJ3ZlcnRpY2FsJykge1xuICAgIHRoaXMuZGlyZWN0aW9uLnNldCh2KTtcbiAgfVxuICByZWFkb25seSBkaXJlY3Rpb24gPSBzaWduYWw8J2hvcml6b250YWwnIHwgJ3ZlcnRpY2FsJz4oJ2hvcml6b250YWwnKTtcblxuICBASW5wdXQoeyBhbGlhczogJ3Njcm9sbGFibGVSb2xlJyB9KVxuICBzZXQgX3Njcm9sbGFibGVSb2xlKHY6IHN0cmluZyB8IG51bGwpIHtcbiAgICB0aGlzLnNjcm9sbGFibGVSb2xlLnNldCh2KTtcbiAgfVxuICByZWFkb25seSBzY3JvbGxhYmxlUm9sZSA9IHNpZ25hbDxzdHJpbmcgfCBudWxsPihudWxsKTtcblxuICBASW5wdXQoeyBhbGlhczogJ3Njcm9sbGFibGVDbGFzcycgfSlcbiAgc2V0IF9zY3JvbGxhYmxlQ2xhc3ModjogTmdDbGFzc1R5cGUgfCBudWxsKSB7XG4gICAgdGhpcy5zY3JvbGxhYmxlQ2xhc3Muc2V0KHYpO1xuICB9XG4gIHJlYWRvbmx5IHNjcm9sbGFibGVDbGFzcyA9IHNpZ25hbDxOZ0NsYXNzVHlwZSB8IG51bGw+KG51bGwpO1xuXG4gIEBJbnB1dCh7IHRyYW5zZm9ybTogYm9vbGVhbkF0dHJpYnV0ZSwgYWxpYXM6ICdyZW5kZXJOYXZpZ2F0aW9uJyB9KVxuICBzZXQgX3JlbmRlck5hdmlnYXRpb24odjogYm9vbGVhbikge1xuICAgIHRoaXMucmVuZGVyTmF2aWdhdGlvbi5zZXQodik7XG4gIH1cbiAgcmVhZG9ubHkgcmVuZGVyTmF2aWdhdGlvbiA9IHNpZ25hbChmYWxzZSk7XG5cbiAgQElucHV0KHsgdHJhbnNmb3JtOiBib29sZWFuQXR0cmlidXRlLCBhbGlhczogJ3JlbmRlck1hc2tzJyB9KVxuICBzZXQgX3JlbmRlck1hc2tzKHY6IGJvb2xlYW4pIHtcbiAgICB0aGlzLnJlbmRlck1hc2tzLnNldCh2KTtcbiAgfVxuICByZWFkb25seSByZW5kZXJNYXNrcyA9IHNpZ25hbCh0cnVlKTtcblxuICBASW5wdXQoeyB0cmFuc2Zvcm06IGJvb2xlYW5BdHRyaWJ1dGUsIGFsaWFzOiAncmVuZGVyQnV0dG9ucycgfSlcbiAgc2V0IF9yZW5kZXJCdXR0b25zKHY6IGJvb2xlYW4pIHtcbiAgICB0aGlzLnJlbmRlckJ1dHRvbnMuc2V0KHYpO1xuICB9XG4gIHJlYWRvbmx5IHJlbmRlckJ1dHRvbnMgPSBzaWduYWwodHJ1ZSk7XG5cbiAgQElucHV0KHsgdHJhbnNmb3JtOiBib29sZWFuQXR0cmlidXRlLCBhbGlhczogJ3JlbmRlclNjcm9sbGJhcnMnIH0pXG4gIHNldCBfcmVuZGVyU2Nyb2xsYmFycyh2OiBib29sZWFuKSB7XG4gICAgdGhpcy5yZW5kZXJTY3JvbGxiYXJzLnNldCh2KTtcbiAgfVxuICByZWFkb25seSByZW5kZXJTY3JvbGxiYXJzID0gc2lnbmFsKGZhbHNlKTtcblxuICBASW5wdXQoeyB0cmFuc2Zvcm06IGJvb2xlYW5BdHRyaWJ1dGUsIGFsaWFzOiAnc3RpY2t5QnV0dG9ucycgfSlcbiAgc2V0IF9zdGlja3lCdXR0b25zKHY6IGJvb2xlYW4pIHtcbiAgICB0aGlzLnN0aWNreUJ1dHRvbnMuc2V0KHYpO1xuICB9XG4gIHJlYWRvbmx5IHN0aWNreUJ1dHRvbnMgPSBzaWduYWwoZmFsc2UpO1xuXG4gIEBJbnB1dCh7IHRyYW5zZm9ybTogYm9vbGVhbkF0dHJpYnV0ZSwgYWxpYXM6ICdjdXJzb3JEcmFnU2Nyb2xsJyB9KVxuICBzZXQgX2N1cnNvckRyYWdTY3JvbGwodjogYm9vbGVhbikge1xuICAgIHRoaXMuY3Vyc29yRHJhZ1Njcm9sbC5zZXQodik7XG4gIH1cbiAgcmVhZG9ubHkgY3Vyc29yRHJhZ1Njcm9sbCA9IHNpZ25hbCh0cnVlKTtcblxuICBASW5wdXQoeyB0cmFuc2Zvcm06IGJvb2xlYW5BdHRyaWJ1dGUsIGFsaWFzOiAnZGlzYWJsZUFjdGl2ZUVsZW1lbnRTY3JvbGxpbmcnIH0pXG4gIHNldCBfZGlzYWJsZUFjdGl2ZUVsZW1lbnRTY3JvbGxpbmcodjogYm9vbGVhbikge1xuICAgIHRoaXMuZGlzYWJsZUFjdGl2ZUVsZW1lbnRTY3JvbGxpbmcuc2V0KHYpO1xuICB9XG4gIHJlYWRvbmx5IGRpc2FibGVBY3RpdmVFbGVtZW50U2Nyb2xsaW5nID0gc2lnbmFsKGZhbHNlKTtcblxuICBASW5wdXQoeyBhbGlhczogJ3Njcm9sbE1vZGUnIH0pXG4gIHNldCBfc2Nyb2xsTW9kZSh2OiBTY3JvbGxhYmxlU2Nyb2xsTW9kZSkge1xuICAgIHRoaXMuc2Nyb2xsTW9kZS5zZXQodik7XG4gIH1cbiAgcmVhZG9ubHkgc2Nyb2xsTW9kZSA9IHNpZ25hbDxTY3JvbGxhYmxlU2Nyb2xsTW9kZT4oJ2NvbnRhaW5lcicpO1xuXG4gIEBJbnB1dCh7IHRyYW5zZm9ybTogYm9vbGVhbkF0dHJpYnV0ZSwgYWxpYXM6ICdzbmFwJyB9KVxuICBzZXQgX3NuYXAodjogYm9vbGVhbikge1xuICAgIHRoaXMuc25hcC5zZXQodik7XG4gIH1cbiAgcmVhZG9ubHkgc25hcCA9IHNpZ25hbChmYWxzZSk7XG5cbiAgQElucHV0KHsgdHJhbnNmb3JtOiBudW1iZXJBdHRyaWJ1dGUsIGFsaWFzOiAnc2Nyb2xsTWFyZ2luJyB9KVxuICBzZXQgX3Njcm9sbE1hcmdpbih2OiBudW1iZXIpIHtcbiAgICB0aGlzLnNjcm9sbE1hcmdpbi5zZXQodik7XG4gIH1cbiAgcmVhZG9ubHkgc2Nyb2xsTWFyZ2luID0gc2lnbmFsKDApO1xuXG4gIEBPdXRwdXQoKVxuICByZWFkb25seSBzY3JvbGxTdGF0ZUNoYW5nZSA9IG5ldyBFdmVudEVtaXR0ZXI8U2Nyb2xsT2JzZXJ2ZXJTY3JvbGxTdGF0ZT4oKTtcblxuICBAT3V0cHV0KClcbiAgcmVhZG9ubHkgaW50ZXJzZWN0aW9uQ2hhbmdlID0gbmV3IEV2ZW50RW1pdHRlcjxTY3JvbGxhYmxlSW50ZXJzZWN0aW9uQ2hhbmdlW10+KCk7XG5cbiAgQFZpZXdDaGlsZCgnc2Nyb2xsYWJsZScsIHsgc3RhdGljOiB0cnVlIH0pXG4gIHByaXZhdGUgc2V0IF9zY3JvbGxhYmxlKGU6IEVsZW1lbnRSZWY8SFRNTEVsZW1lbnQ+KSB7XG4gICAgdGhpcy5zY3JvbGxhYmxlLnNldChlKTtcbiAgfVxuICByZWFkb25seSBzY3JvbGxhYmxlID0gc2lnbmFsPEVsZW1lbnRSZWY8SFRNTEVsZW1lbnQ+IHwgbnVsbD4obnVsbCk7XG5cbiAgQFZpZXdDaGlsZCgnc2Nyb2xsYWJsZUNvbnRhaW5lcicsIHsgc3RhdGljOiB0cnVlIH0pXG4gIHByaXZhdGUgc2V0IF9zY3JvbGxhYmxlQ29udGFpbmVyKGU6IEVsZW1lbnRSZWY8SFRNTEVsZW1lbnQ+KSB7XG4gICAgdGhpcy5zY3JvbGxhYmxlQ29udGFpbmVyLnNldChlKTtcbiAgfVxuICByZWFkb25seSBzY3JvbGxhYmxlQ29udGFpbmVyID0gc2lnbmFsPEVsZW1lbnRSZWY8SFRNTEVsZW1lbnQ+IHwgbnVsbD4obnVsbCk7XG5cbiAgQFZpZXdDaGlsZCgnZmlyc3RFbGVtZW50JywgeyBzdGF0aWM6IHRydWUgfSlcbiAgcHJpdmF0ZSBzZXQgX2ZpcnN0RWxlbWVudChlOiBFbGVtZW50UmVmPEhUTUxFbGVtZW50Pikge1xuICAgIHRoaXMuZmlyc3RFbGVtZW50LnNldChlKTtcbiAgfVxuICByZWFkb25seSBmaXJzdEVsZW1lbnQgPSBzaWduYWw8RWxlbWVudFJlZjxIVE1MRWxlbWVudD4gfCBudWxsPihudWxsKTtcblxuICBAVmlld0NoaWxkKCdsYXN0RWxlbWVudCcsIHsgc3RhdGljOiB0cnVlIH0pXG4gIHByaXZhdGUgc2V0IF9sYXN0RWxlbWVudChlOiBFbGVtZW50UmVmPEhUTUxFbGVtZW50Pikge1xuICAgIHRoaXMubGFzdEVsZW1lbnQuc2V0KGUpO1xuICB9XG4gIHJlYWRvbmx5IGxhc3RFbGVtZW50ID0gc2lnbmFsPEVsZW1lbnRSZWY8SFRNTEVsZW1lbnQ+IHwgbnVsbD4obnVsbCk7XG5cbiAgQENvbnRlbnRDaGlsZHJlbihJU19BQ1RJVkVfRUxFTUVOVCwgeyBkZXNjZW5kYW50czogdHJ1ZSB9KVxuICBwcml2YXRlIHNldCBfYWN0aXZlRWxlbWVudExpc3QoZTogVHlwZWRRdWVyeUxpc3Q8SXNBY3RpdmVFbGVtZW50RGlyZWN0aXZlPikge1xuICAgIHRoaXMuYWN0aXZlRWxlbWVudExpc3Quc2V0KGUpO1xuICB9XG4gIHJlYWRvbmx5IGFjdGl2ZUVsZW1lbnRMaXN0ID0gc2lnbmFsPFR5cGVkUXVlcnlMaXN0PElzQWN0aXZlRWxlbWVudERpcmVjdGl2ZT4gfCBudWxsPihudWxsKTtcblxuICBwcml2YXRlIHJlYWRvbmx5IGNvbnRhaW5lclNjcm9sbFN0YXRlID0gc2lnbmFsRWxlbWVudFNjcm9sbFN0YXRlKHRoaXMuc2Nyb2xsYWJsZSk7XG4gIHByaXZhdGUgcmVhZG9ubHkgZmlyc3RFbGVtZW50SW50ZXJzZWN0aW9uID0gc2lnbmFsRWxlbWVudEludGVyc2VjdGlvbih0aGlzLmZpcnN0RWxlbWVudCwgeyByb290OiB0aGlzLnNjcm9sbGFibGUgfSk7XG4gIHByaXZhdGUgcmVhZG9ubHkgZmlyc3RFbGVtZW50VmlzaWJpbGl0eSA9IHNpZ25hbDxDdXJyZW50RWxlbWVudFZpc2liaWxpdHkgfCBudWxsPihudWxsKTtcbiAgcHJpdmF0ZSByZWFkb25seSBsYXN0RWxlbWVudEludGVyc2VjdGlvbiA9IHNpZ25hbEVsZW1lbnRJbnRlcnNlY3Rpb24odGhpcy5sYXN0RWxlbWVudCwgeyByb290OiB0aGlzLnNjcm9sbGFibGUgfSk7XG4gIHByaXZhdGUgcmVhZG9ubHkgbGFzdEVsZW1lbnRWaXNpYmlsaXR5ID0gc2lnbmFsPEN1cnJlbnRFbGVtZW50VmlzaWJpbGl0eSB8IG51bGw+KG51bGwpO1xuXG4gIHByaXZhdGUgcmVhZG9ubHkgYWxsU2Nyb2xsYWJsZUNoaWxkcmVuID0gc2lnbmFsRWxlbWVudENoaWxkcmVuKHRoaXMuc2Nyb2xsYWJsZUNvbnRhaW5lcik7XG4gIHByaXZhdGUgcmVhZG9ubHkgc2Nyb2xsYWJsZUNoaWxkcmVuID0gY29tcHV0ZWQoKCkgPT5cbiAgICB0aGlzLmFsbFNjcm9sbGFibGVDaGlsZHJlbigpLmZpbHRlcigoYykgPT4gIWlzU2Nyb2xsYWJsZUNoaWxkSWdub3JlZChjKSksXG4gICk7XG5cbiAgcHJpdmF0ZSByZWFkb25seSBfZGlzYWJsZVNuYXBwaW5nJCA9IG5ldyBTdWJqZWN0PHZvaWQ+KCk7XG5cbiAgcHJpdmF0ZSByZWFkb25seSBzY3JvbGxhYmxlQ29udGVudEludGVyc2VjdGlvbnMgPSBzaWduYWxFbGVtZW50SW50ZXJzZWN0aW9uKHRoaXMuc2Nyb2xsYWJsZUNoaWxkcmVuLCB7XG4gICAgcm9vdDogdGhpcy5zY3JvbGxhYmxlLFxuICAgIHRocmVzaG9sZDogRUxFTUVOVF9JTlRFUlNFQ1RJT05fVEhSRVNIT0xELFxuICB9KTtcblxuICBwcml2YXRlIHJlYWRvbmx5IHNjcm9sbGFibGVDb250ZW50SW50ZXJzZWN0aW9ucyQgPSB0b09ic2VydmFibGUodGhpcy5zY3JvbGxhYmxlQ29udGVudEludGVyc2VjdGlvbnMpO1xuXG4gIHByaXZhdGUgcmVhZG9ubHkgbWFudWFsQWN0aXZlTmF2aWdhdGlvbkluZGV4ID0gc2lnbmFsPG51bWJlciB8IG51bGw+KG51bGwpO1xuXG4gIHByaXZhdGUgcmVhZG9ubHkgY2FuU2Nyb2xsID0gY29tcHV0ZWQoKCkgPT4ge1xuICAgIGNvbnN0IGRpciA9IHRoaXMuZGlyZWN0aW9uKCk7XG5cbiAgICBpZiAoZGlyID09PSAnaG9yaXpvbnRhbCcpIHtcbiAgICAgIHJldHVybiB0aGlzLmNvbnRhaW5lclNjcm9sbFN0YXRlKCkuY2FuU2Nyb2xsSG9yaXpvbnRhbGx5O1xuICAgIH1cblxuICAgIHJldHVybiB0aGlzLmNvbnRhaW5lclNjcm9sbFN0YXRlKCkuY2FuU2Nyb2xsVmVydGljYWxseTtcbiAgfSk7XG5cbiAgcHJpdmF0ZSByZWFkb25seSBpc0F0U3RhcnQgPSBjb21wdXRlZCgoKSA9PiB7XG4gICAgaWYgKCF0aGlzLmNhblNjcm9sbCgpKSB7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG5cbiAgICBjb25zdCBpbnRlcnNlY3Rpb24gPSB0aGlzLmZpcnN0RWxlbWVudEludGVyc2VjdGlvbigpWzBdO1xuXG4gICAgaWYgKCFpbnRlcnNlY3Rpb24pIHtcbiAgICAgIHJldHVybiB0aGlzLmZpcnN0RWxlbWVudFZpc2liaWxpdHkoKT8uaW5saW5lID8/IHRydWU7XG4gICAgfVxuXG4gICAgcmV0dXJuIGludGVyc2VjdGlvbi5pc0ludGVyc2VjdGluZztcbiAgfSk7XG4gIHByaXZhdGUgcmVhZG9ubHkgaXNBdEVuZCA9IGNvbXB1dGVkKCgpID0+IHtcbiAgICBpZiAoIXRoaXMuY2FuU2Nyb2xsKCkpIHtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cblxuICAgIGNvbnN0IGludGVyc2VjdGlvbiA9IHRoaXMubGFzdEVsZW1lbnRJbnRlcnNlY3Rpb24oKVswXTtcblxuICAgIGlmICghaW50ZXJzZWN0aW9uKSB7XG4gICAgICByZXR1cm4gdGhpcy5sYXN0RWxlbWVudFZpc2liaWxpdHkoKT8uaW5saW5lID8/IHRydWU7XG4gICAgfVxuXG4gICAgcmV0dXJuIGludGVyc2VjdGlvbi5pc0ludGVyc2VjdGluZztcbiAgfSk7XG5cbiAgcHJpdmF0ZSByZWFkb25seSBlbmFibGVPdmVybGF5QW5pbWF0aW9ucyA9IHNpZ25hbChmYWxzZSk7XG5cbiAgcHJpdmF0ZSByZWFkb25seSBfaW5pdGlhbFNjcm9sbGFibGVOYXZpZ2F0aW9uID0gc2lnbmFsPFNjcm9sbGFibGVOYXZpZ2F0aW9uSXRlbVtdPihbXSk7XG5cbiAgcHJvdGVjdGVkIHJlYWRvbmx5IHNjcm9sbGFibGVOYXZpZ2F0aW9uID0gY29tcHV0ZWQ8U2Nyb2xsYWJsZU5hdmlnYXRpb25JdGVtW10+KCgpID0+IHtcbiAgICBjb25zdCBhbGxJbnRlcnNlY3Rpb25zID0gdGhpcy5zY3JvbGxhYmxlQ29udGVudEludGVyc2VjdGlvbnMoKTtcbiAgICBjb25zdCBtYW51YWxBY3RpdmVOYXZpZ2F0aW9uSW5kZXggPSB0aGlzLm1hbnVhbEFjdGl2ZU5hdmlnYXRpb25JbmRleCgpO1xuICAgIGNvbnN0IGluaXRpYWxTY3JvbGxhYmxlTmF2aWdhdGlvbiA9IHRoaXMuX2luaXRpYWxTY3JvbGxhYmxlTmF2aWdhdGlvbigpO1xuXG4gICAgaWYgKCFhbGxJbnRlcnNlY3Rpb25zLmxlbmd0aCkge1xuICAgICAgcmV0dXJuIGluaXRpYWxTY3JvbGxhYmxlTmF2aWdhdGlvbjtcbiAgICB9XG5cbiAgICBjb25zdCBoaWdoZXN0SW50ZXJzZWN0aW9uID0gYWxsSW50ZXJzZWN0aW9ucy5yZWR1Y2UoKHByZXYsIGN1cnIpID0+IHtcbiAgICAgIGlmIChwcmV2ICYmIHByZXYuaW50ZXJzZWN0aW9uUmF0aW8gPiBjdXJyLmludGVyc2VjdGlvblJhdGlvKSB7XG4gICAgICAgIHJldHVybiBwcmV2O1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gY3VycjtcbiAgICB9LCBhbGxJbnRlcnNlY3Rpb25zWzBdKTtcblxuICAgIGlmICghaGlnaGVzdEludGVyc2VjdGlvbikge1xuICAgICAgcmV0dXJuIFtdO1xuICAgIH1cblxuICAgIHJldHVybiBhbGxJbnRlcnNlY3Rpb25zLm1hcCgoaSwgaW5kZXgpID0+ICh7XG4gICAgICBpc0FjdGl2ZTpcbiAgICAgICAgbWFudWFsQWN0aXZlTmF2aWdhdGlvbkluZGV4ICE9PSBudWxsXG4gICAgICAgICAgPyBtYW51YWxBY3RpdmVOYXZpZ2F0aW9uSW5kZXggPT09IGluZGV4XG4gICAgICAgICAgOiBpID09PSBoaWdoZXN0SW50ZXJzZWN0aW9uICYmIGhpZ2hlc3RJbnRlcnNlY3Rpb24uaW50ZXJzZWN0aW9uUmF0aW8gPiAwLFxuICAgICAgZWxlbWVudDogaS50YXJnZXQgYXMgSFRNTEVsZW1lbnQsXG4gICAgfSkpO1xuICB9KTtcblxuICByZWFkb25seSBob3N0QXR0cmlidXRlQmluZGluZ3MgPSBzaWduYWxIb3N0QXR0cmlidXRlcyh7XG4gICAgJ2l0ZW0tc2l6ZSc6IHRoaXMuaXRlbVNpemUsXG4gICAgZGlyZWN0aW9uOiB0aGlzLmRpcmVjdGlvbixcbiAgICAncmVuZGVyLXNjcm9sbGJhcnMnOiB0aGlzLnJlbmRlclNjcm9sbGJhcnMsXG4gICAgJ3N0aWNreS1idXR0b25zJzogdGhpcy5zdGlja3lCdXR0b25zLFxuICB9KTtcblxuICByZWFkb25seSBob3N0Q2xhc3NCaW5kaW5ncyA9IHNpZ25hbEhvc3RDbGFzc2VzKHtcbiAgICAnZXQtc2Nyb2xsYWJsZS0tY2FuLXNjcm9sbCc6IHRoaXMuY2FuU2Nyb2xsLFxuICAgICdldC1zY3JvbGxhYmxlLS1pcy1hdC1zdGFydCc6IHRoaXMuaXNBdFN0YXJ0LFxuICAgICdldC1zY3JvbGxhYmxlLS1pcy1hdC1lbmQnOiB0aGlzLmlzQXRFbmQsXG4gICAgJ2V0LXNjcm9sbGFibGUtLWVuYWJsZS1vdmVybGF5LWFuaW1hdGlvbnMnOiB0aGlzLmVuYWJsZU92ZXJsYXlBbmltYXRpb25zLFxuICB9KTtcblxuICBjb25zdHJ1Y3RvcigpIHtcbiAgICBlZmZlY3QoXG4gICAgICAoKSA9PiB7XG4gICAgICAgIGNvbnN0IHNjcm9sbGFibGUgPSB0aGlzLnNjcm9sbGFibGUoKT8ubmF0aXZlRWxlbWVudDtcbiAgICAgICAgY29uc3QgZmlyc3RFbGVtZW50ID0gdGhpcy5maXJzdEVsZW1lbnQoKT8ubmF0aXZlRWxlbWVudDtcbiAgICAgICAgY29uc3QgbGFzdEVsZW1lbnQgPSB0aGlzLmxhc3RFbGVtZW50KCk/Lm5hdGl2ZUVsZW1lbnQ7XG4gICAgICAgIGNvbnN0IGFjdGl2ZUVsZW1lbnRMaXN0ID0gdGhpcy5hY3RpdmVFbGVtZW50TGlzdCgpPy50b0FycmF5KCk7XG5cbiAgICAgICAgaWYgKCFzY3JvbGxhYmxlIHx8ICFmaXJzdEVsZW1lbnQgfHwgIWxhc3RFbGVtZW50IHx8ICFhY3RpdmVFbGVtZW50TGlzdCkge1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IGZpcnN0QWN0aXZlID0gYWN0aXZlRWxlbWVudExpc3QuZmluZCgoYSkgPT4gYS5pc0FjdGl2ZUVsZW1lbnQpO1xuXG4gICAgICAgIGlmIChmaXJzdEFjdGl2ZSAmJiAhdGhpcy5kaXNhYmxlQWN0aXZlRWxlbWVudFNjcm9sbGluZygpKSB7XG4gICAgICAgICAgY29uc3Qgb2Zmc2V0VG9wID0gZmlyc3RBY3RpdmUuZWxlbWVudFJlZi5uYXRpdmVFbGVtZW50Lm9mZnNldFRvcCAtIHNjcm9sbGFibGUub2Zmc2V0VG9wO1xuICAgICAgICAgIGNvbnN0IG9mZnNldExlZnQgPSBmaXJzdEFjdGl2ZS5lbGVtZW50UmVmLm5hdGl2ZUVsZW1lbnQub2Zmc2V0TGVmdCAtIHNjcm9sbGFibGUub2Zmc2V0TGVmdDtcbiAgICAgICAgICBzY3JvbGxhYmxlLnNjcm9sbExlZnQgPSBvZmZzZXRMZWZ0IC0gdGhpcy5zY3JvbGxNYXJnaW4oKTtcbiAgICAgICAgICBzY3JvbGxhYmxlLnNjcm9sbFRvcCA9IG9mZnNldFRvcCAtIHRoaXMuc2Nyb2xsTWFyZ2luKCk7XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLmZpcnN0RWxlbWVudFZpc2liaWxpdHkuc2V0KFxuICAgICAgICAgIGlzRWxlbWVudFZpc2libGUoe1xuICAgICAgICAgICAgY29udGFpbmVyOiBzY3JvbGxhYmxlLFxuICAgICAgICAgICAgZWxlbWVudDogZmlyc3RFbGVtZW50LFxuICAgICAgICAgIH0pLFxuICAgICAgICApO1xuXG4gICAgICAgIHRoaXMubGFzdEVsZW1lbnRWaXNpYmlsaXR5LnNldChcbiAgICAgICAgICBpc0VsZW1lbnRWaXNpYmxlKHtcbiAgICAgICAgICAgIGNvbnRhaW5lcjogc2Nyb2xsYWJsZSxcbiAgICAgICAgICAgIGVsZW1lbnQ6IGxhc3RFbGVtZW50LFxuICAgICAgICAgIH0pLFxuICAgICAgICApO1xuXG4gICAgICAgIC8vIFdlIG5lZWQgdG8gd2FpdCBvbmUgZnJhbWUgYmVmb3JlIGVuYWJsaW5nIGFuaW1hdGlvbnMgdG8gcHJldmVudCBhIGFuaW1hdGlvbiBmcm9tIHBsYXlpbmcgZHVyaW5nIGluaXRpYWwgcmVuZGVyLlxuICAgICAgICBuZXh0RnJhbWUoKCkgPT4gdGhpcy5lbmFibGVPdmVybGF5QW5pbWF0aW9ucy5zZXQodHJ1ZSkpO1xuICAgICAgfSxcbiAgICAgIHsgYWxsb3dTaWduYWxXcml0ZXM6IHRydWUgfSxcbiAgICApO1xuXG4gICAgZWZmZWN0KFxuICAgICAgKCkgPT4ge1xuICAgICAgICBjb25zdCBlbGVtZW50TGlzdCA9IHRoaXMuc2Nyb2xsYWJsZUNoaWxkcmVuKCk7XG4gICAgICAgIGNvbnN0IHNjcm9sbGFibGUgPSB0aGlzLnNjcm9sbGFibGUoKT8ubmF0aXZlRWxlbWVudDtcbiAgICAgICAgY29uc3QgcmVuZGVyTmF2aWdhdGlvbiA9IHRoaXMucmVuZGVyTmF2aWdhdGlvbigpO1xuXG4gICAgICAgIGlmICghZWxlbWVudExpc3QgfHwgIXNjcm9sbGFibGUgfHwgIXJlbmRlck5hdmlnYXRpb24pIHtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBmaXJzdFZpc2libGVFbGVtZW50ID0gZWxlbWVudExpc3QuZmluZCgoZSkgPT4gaXNFbGVtZW50VmlzaWJsZSh7IGNvbnRhaW5lcjogc2Nyb2xsYWJsZSwgZWxlbWVudDogZSB9KSk7XG5cbiAgICAgICAgaWYgKCFmaXJzdFZpc2libGVFbGVtZW50KSB7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgaW5pdGlhbE5hdmlnYXRpb25TdHVmZjogU2Nyb2xsYWJsZU5hdmlnYXRpb25JdGVtW10gPSBlbGVtZW50TGlzdC5tYXAoKGUpID0+ICh7XG4gICAgICAgICAgaXNBY3RpdmU6IGUgPT09IGZpcnN0VmlzaWJsZUVsZW1lbnQsXG4gICAgICAgICAgZWxlbWVudDogZSxcbiAgICAgICAgfSkpO1xuXG4gICAgICAgIHRoaXMuX2luaXRpYWxTY3JvbGxhYmxlTmF2aWdhdGlvbi5zZXQoaW5pdGlhbE5hdmlnYXRpb25TdHVmZik7XG4gICAgICB9LFxuICAgICAgeyBhbGxvd1NpZ25hbFdyaXRlczogdHJ1ZSB9LFxuICAgICk7XG5cbiAgICBlZmZlY3QoKCkgPT4ge1xuICAgICAgY29uc3QgaXNBdFN0YXJ0ID0gdGhpcy5pc0F0U3RhcnQoKTtcbiAgICAgIGNvbnN0IGlzQXRFbmQgPSB0aGlzLmlzQXRFbmQoKTtcbiAgICAgIGNvbnN0IGNhblNjcm9sbCA9IHRoaXMuY2FuU2Nyb2xsKCk7XG5cbiAgICAgIHRoaXMuc2Nyb2xsU3RhdGVDaGFuZ2UuZW1pdCh7XG4gICAgICAgIGNhblNjcm9sbCxcbiAgICAgICAgaXNBdEVuZDogISFpc0F0RW5kLFxuICAgICAgICBpc0F0U3RhcnQ6ICEhaXNBdFN0YXJ0LFxuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBlZmZlY3QoKCkgPT4ge1xuICAgICAgY29uc3QgZW5hYmxlU25hcHBpbmcgPSB0aGlzLnNuYXAoKTtcblxuICAgICAgaWYgKGVuYWJsZVNuYXBwaW5nKSB7XG4gICAgICAgIHRoaXMuX2VuYWJsZVNuYXBwaW5nKCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLl9kaXNhYmxlU25hcHBpbmcoKTtcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIHRoaXMuc2Nyb2xsYWJsZUNvbnRlbnRJbnRlcnNlY3Rpb25zJFxuICAgICAgLnBpcGUoXG4gICAgICAgIHRha2VVbnRpbERlc3Ryb3llZCgpLFxuICAgICAgICBkZWJvdW5jZVRpbWUoMTApLFxuICAgICAgICB0YXAoKGVudHJpZXMpID0+IHtcbiAgICAgICAgICB0aGlzLmludGVyc2VjdGlvbkNoYW5nZS5lbWl0KFxuICAgICAgICAgICAgZW50cmllcy5tYXAoKGksIGluZGV4KSA9PiAoe1xuICAgICAgICAgICAgICBpbmRleCxcbiAgICAgICAgICAgICAgZWxlbWVudDogaS50YXJnZXQgYXMgSFRNTEVsZW1lbnQsXG4gICAgICAgICAgICAgIGludGVyc2VjdGlvblJhdGlvOiBpLmludGVyc2VjdGlvblJhdGlvLFxuICAgICAgICAgICAgICBpc0ludGVyc2VjdGluZzogaS5pc0ludGVyc2VjdGluZyxcbiAgICAgICAgICAgIH0pKSxcbiAgICAgICAgICApO1xuICAgICAgICB9KSxcbiAgICAgIClcbiAgICAgIC5zdWJzY3JpYmUoKTtcbiAgfVxuXG4gIHNjcm9sbE9uZUNvbnRhaW5lclNpemUoZGlyZWN0aW9uOiAnc3RhcnQnIHwgJ2VuZCcpIHtcbiAgICBjb25zdCBzY3JvbGxFbGVtZW50ID0gdGhpcy5zY3JvbGxhYmxlKCk/Lm5hdGl2ZUVsZW1lbnQ7XG5cbiAgICBpZiAoIXNjcm9sbEVsZW1lbnQpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCBwYXJlbnQgPSB0aGlzLl9lbGVtZW50UmVmLm5hdGl2ZUVsZW1lbnQ7XG5cbiAgICBjb25zdCBpc1NuYXBwaW5nRW5hYmxlZCA9IHRoaXMuc25hcCgpO1xuXG4gICAgaWYgKGlzU25hcHBpbmdFbmFibGVkKSB7XG4gICAgICAvLyBJZiBzbmFwcGluZyBpcyBlbmFibGVkIHdlIHdhbnQgdG8gc2Nyb2xsIHRvIGEgcG9zaXRpb24gd2hlcmUgbm8gZnVydGhlciBzbmFwcGluZyB3aWxsIGhhcHBlbiBhZnRlciB0aGUgc2Nyb2xsLlxuICAgICAgY29uc3QgYWxsSW50ZXJzZWN0aW9ucyA9IHRoaXMuc2Nyb2xsYWJsZUNvbnRlbnRJbnRlcnNlY3Rpb25zKCk7XG4gICAgICBjb25zdCBpbnRlcnNlY3Rpb25zID0gZ2V0Rmlyc3RBbmRMYXN0UGFydGlhbEludGVyc2VjdGlvbihhbGxJbnRlcnNlY3Rpb25zKTtcbiAgICAgIGNvbnN0IHJlbGV2YW50SW50ZXJzZWN0aW9uID0gZGlyZWN0aW9uID09PSAnc3RhcnQnID8gaW50ZXJzZWN0aW9ucz8uZmlyc3QgOiBpbnRlcnNlY3Rpb25zPy5sYXN0O1xuXG4gICAgICBpZiAoIXJlbGV2YW50SW50ZXJzZWN0aW9uKSByZXR1cm47XG5cbiAgICAgIGNvbnN0IG5leHRJbmRleCA9XG4gICAgICAgIHJlbGV2YW50SW50ZXJzZWN0aW9uLmludGVyc2VjdGlvbi5pbnRlcnNlY3Rpb25SYXRpbyAhPT0gMVxuICAgICAgICAgID8gcmVsZXZhbnRJbnRlcnNlY3Rpb24uaW5kZXhcbiAgICAgICAgICA6IGRpcmVjdGlvbiA9PT0gJ3N0YXJ0J1xuICAgICAgICAgICAgPyByZWxldmFudEludGVyc2VjdGlvbi5pbmRleCAtIDFcbiAgICAgICAgICAgIDogcmVsZXZhbnRJbnRlcnNlY3Rpb24uaW5kZXggKyAxO1xuXG4gICAgICBjb25zdCBlbGVtZW50ID1cbiAgICAgICAgKGFsbEludGVyc2VjdGlvbnNbbmV4dEluZGV4XT8udGFyZ2V0IGFzIEhUTUxFbGVtZW50KSB8fFxuICAgICAgICAocmVsZXZhbnRJbnRlcnNlY3Rpb24uaW50ZXJzZWN0aW9uLnRhcmdldCBhcyBIVE1MRWxlbWVudCk7XG5cbiAgICAgIHRoaXMuc2Nyb2xsVG9FbGVtZW50KHtcbiAgICAgICAgZWxlbWVudDogZWxlbWVudCxcbiAgICAgICAgb3JpZ2luOiBkaXJlY3Rpb24gPT09ICdlbmQnID8gJ3N0YXJ0JyA6ICdlbmQnLFxuICAgICAgfSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIEp1c3Qgc2Nyb2xsIG9uZSBzaXplIG9mIHRoZSBzY3JvbGxhYmxlIGNvbnRhaW5lci5cbiAgICAgIGNvbnN0IHNjcm9sbGFibGVTaXplID0gdGhpcy5kaXJlY3Rpb24oKSA9PT0gJ2hvcml6b250YWwnID8gcGFyZW50LmNsaWVudFdpZHRoIDogcGFyZW50LmNsaWVudEhlaWdodDtcbiAgICAgIGNvbnN0IGN1cnJlbnRTY3JvbGwgPSB0aGlzLmRpcmVjdGlvbigpID09PSAnaG9yaXpvbnRhbCcgPyBzY3JvbGxFbGVtZW50LnNjcm9sbExlZnQgOiBzY3JvbGxFbGVtZW50LnNjcm9sbFRvcDtcblxuICAgICAgc2Nyb2xsRWxlbWVudC5zY3JvbGxUbyh7XG4gICAgICAgIFt0aGlzLmRpcmVjdGlvbigpID09PSAnaG9yaXpvbnRhbCcgPyAnbGVmdCcgOiAndG9wJ106XG4gICAgICAgICAgY3VycmVudFNjcm9sbCArIChkaXJlY3Rpb24gPT09ICdzdGFydCcgPyAtc2Nyb2xsYWJsZVNpemUgOiBzY3JvbGxhYmxlU2l6ZSksXG4gICAgICAgIGJlaGF2aW9yOiAnc21vb3RoJyxcbiAgICAgIH0pO1xuICAgIH1cbiAgfVxuXG4gIHNjcm9sbE9uZUl0ZW1TaXplKGRpcmVjdGlvbjogJ3N0YXJ0JyB8ICdlbmQnKSB7XG4gICAgY29uc3QgYWxsSW50ZXJzZWN0aW9ucyA9IHRoaXMuc2Nyb2xsYWJsZUNvbnRlbnRJbnRlcnNlY3Rpb25zKCk7XG4gICAgY29uc3Qgc2Nyb2xsRWxlbWVudCA9IHRoaXMuc2Nyb2xsYWJsZSgpPy5uYXRpdmVFbGVtZW50O1xuXG4gICAgaWYgKCFhbGxJbnRlcnNlY3Rpb25zLmxlbmd0aCkge1xuICAgICAgaWYgKGlzRGV2TW9kZSgpKSB7XG4gICAgICAgIGNvbnNvbGUud2FybihcbiAgICAgICAgICAnTm8gZWxlbWVudHMgZm91bmQgdG8gc2Nyb2xsIHRvLiBNYWtlIHN1cmUgdG8gYXBwbHkgdGhlIGlzRWxlbWVudCBkaXJlY3RpdmUgdG8gdGhlIGVsZW1lbnRzIHlvdSB3YW50IHRvIHNjcm9sbCB0by4nLFxuICAgICAgICApO1xuICAgICAgfVxuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IGludGVyc2VjdGlvbnMgPSBnZXRGaXJzdEFuZExhc3RQYXJ0aWFsSW50ZXJzZWN0aW9uKGFsbEludGVyc2VjdGlvbnMpO1xuXG4gICAgaWYgKCFpbnRlcnNlY3Rpb25zIHx8ICFzY3JvbGxFbGVtZW50KSByZXR1cm47XG5cbiAgICAvLyBNZWFucyB0aGUgY3VycmVudCBlbGVtZW50IGlzIGJpZ2dlciB0aGFuIHRoZSBzY3JvbGxhYmxlIGNvbnRhaW5lci5cbiAgICAvLyBJbiB0aGlzIGNhc2Ugd2Ugc2hvdWxkIHNjcm9sbCB0byB0aGUgc3RhcnQgb2YgdGhlIGN1cnJlbnQgZWxlbWVudC4gSWYgd2UgYXJlIGFscmVhZHkgdGhlcmUgd2Ugc2hvdWxkIHNjcm9sbCB0byB0aGUgZW5kIG9mIHRoZSBwcmV2aW91cyBlbGVtZW50LlxuICAgIC8vIFRoaXMgYXBwbGllcyB0byB0aGUgb3RoZXIgZGlyZWN0aW9uIGFzIHdlbGwuXG4gICAgY29uc3QgaXNGaXJzdEFuZExhc3RJbnRlcnNlY3Rpb25FcXVhbCA9IGludGVyc2VjdGlvbnMuZmlyc3QuaW50ZXJzZWN0aW9uID09PSBpbnRlcnNlY3Rpb25zLmxhc3QuaW50ZXJzZWN0aW9uO1xuICAgIGNvbnN0IHNjcm9sbGFibGVSZWN0ID0gc2Nyb2xsRWxlbWVudC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcblxuICAgIGlmIChpc0ZpcnN0QW5kTGFzdEludGVyc2VjdGlvbkVxdWFsKSB7XG4gICAgICBjb25zdCBpbnRlcnNlY3Rpb24gPSBpbnRlcnNlY3Rpb25zLmZpcnN0LmludGVyc2VjdGlvbi50YXJnZXQuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG4gICAgICBjb25zdCBpc1N0YXJ0T2ZFbGVtZW50VmlzaWJsZSA9XG4gICAgICAgIHRoaXMuZGlyZWN0aW9uKCkgPT09ICdob3Jpem9udGFsJ1xuICAgICAgICAgID8gaW50ZXJzZWN0aW9uLmxlZnQgPj0gc2Nyb2xsYWJsZVJlY3QubGVmdFxuICAgICAgICAgIDogaW50ZXJzZWN0aW9uLnRvcCA+PSBzY3JvbGxhYmxlUmVjdC50b3A7XG5cbiAgICAgIGNvbnN0IGlzRW5kT2ZFbGVtZW50VmlzaWJsZSA9XG4gICAgICAgIHRoaXMuZGlyZWN0aW9uKCkgPT09ICdob3Jpem9udGFsJ1xuICAgICAgICAgID8gaW50ZXJzZWN0aW9uLnJpZ2h0IDw9IHNjcm9sbGFibGVSZWN0LnJpZ2h0XG4gICAgICAgICAgOiBpbnRlcnNlY3Rpb24uYm90dG9tIDw9IHNjcm9sbGFibGVSZWN0LmJvdHRvbTtcblxuICAgICAgaWYgKCFpc1N0YXJ0T2ZFbGVtZW50VmlzaWJsZSB8fCAhaXNFbmRPZkVsZW1lbnRWaXNpYmxlKSB7XG4gICAgICAgIGlmIChkaXJlY3Rpb24gPT09ICdzdGFydCcpIHtcbiAgICAgICAgICBpZiAoaXNTdGFydE9mRWxlbWVudFZpc2libGUpIHtcbiAgICAgICAgICAgIC8vIHRvIHRoZSBlbmQgb2YgdGhlIHByZXZpb3VzIGVsZW1lbnRcbiAgICAgICAgICAgIGNvbnN0IHByZXZpb3VzSW5kZXggPSBpbnRlcnNlY3Rpb25zLmZpcnN0LmluZGV4IC0gMTtcbiAgICAgICAgICAgIGNvbnN0IGVsZW1lbnRUb1Njcm9sbFRvID0gYWxsSW50ZXJzZWN0aW9uc1twcmV2aW91c0luZGV4XT8udGFyZ2V0IGFzIEhUTUxFbGVtZW50O1xuXG4gICAgICAgICAgICBpZiAoIWVsZW1lbnRUb1Njcm9sbFRvKSByZXR1cm47XG5cbiAgICAgICAgICAgIHRoaXMuc2Nyb2xsVG9FbGVtZW50KHtcbiAgICAgICAgICAgICAgZWxlbWVudDogZWxlbWVudFRvU2Nyb2xsVG8sXG4gICAgICAgICAgICAgIG9yaWdpbjogJ2VuZCcsXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgLy8gdG8gdGhlIHN0YXJ0IG9mIHRoZSBjdXJyZW50IGVsZW1lbnRcbiAgICAgICAgICAgIHRoaXMuc2Nyb2xsVG9FbGVtZW50KHtcbiAgICAgICAgICAgICAgZWxlbWVudDogaW50ZXJzZWN0aW9ucy5maXJzdC5pbnRlcnNlY3Rpb24udGFyZ2V0IGFzIEhUTUxFbGVtZW50LFxuICAgICAgICAgICAgICBvcmlnaW46ICdzdGFydCcsXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgaWYgKGlzRW5kT2ZFbGVtZW50VmlzaWJsZSkge1xuICAgICAgICAgICAgLy8gdG8gdGhlIHN0YXJ0IG9mIHRoZSBuZXh0IGVsZW1lbnRcbiAgICAgICAgICAgIGNvbnN0IG5leHRJbmRleCA9IGludGVyc2VjdGlvbnMubGFzdC5pbmRleCArIDE7XG4gICAgICAgICAgICBjb25zdCBlbGVtZW50VG9TY3JvbGxUbyA9IGFsbEludGVyc2VjdGlvbnNbbmV4dEluZGV4XT8udGFyZ2V0IGFzIEhUTUxFbGVtZW50O1xuXG4gICAgICAgICAgICBpZiAoIWVsZW1lbnRUb1Njcm9sbFRvKSByZXR1cm47XG5cbiAgICAgICAgICAgIHRoaXMuc2Nyb2xsVG9FbGVtZW50KHtcbiAgICAgICAgICAgICAgZWxlbWVudDogZWxlbWVudFRvU2Nyb2xsVG8sXG4gICAgICAgICAgICAgIG9yaWdpbjogJ3N0YXJ0JyxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAvLyB0byB0aGUgZW5kIG9mIHRoZSBjdXJyZW50IGVsZW1lbnRcbiAgICAgICAgICAgIHRoaXMuc2Nyb2xsVG9FbGVtZW50KHtcbiAgICAgICAgICAgICAgZWxlbWVudDogaW50ZXJzZWN0aW9ucy5sYXN0LmludGVyc2VjdGlvbi50YXJnZXQgYXMgSFRNTEVsZW1lbnQsXG4gICAgICAgICAgICAgIG9yaWdpbjogJ2VuZCcsXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgfVxuXG4gICAgY29uc3QgZGF0YSA9IGRpcmVjdGlvbiA9PT0gJ3N0YXJ0JyA/IGludGVyc2VjdGlvbnMuZmlyc3QgOiBpbnRlcnNlY3Rpb25zLmxhc3Q7XG4gICAgbGV0IGVsZW1lbnRUb1Njcm9sbFRvID0gZGF0YS5pbnRlcnNlY3Rpb24udGFyZ2V0IGFzIEhUTUxFbGVtZW50O1xuXG4gICAgaWYgKGRhdGEuaW50ZXJzZWN0aW9uLmludGVyc2VjdGlvblJhdGlvID09PSAxKSB7XG4gICAgICBpZiAoZGlyZWN0aW9uID09PSAnc3RhcnQnICYmIGRhdGEuaW5kZXggPT09IDApIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBpZiAoZGlyZWN0aW9uID09PSAnZW5kJyAmJiBkYXRhLmluZGV4ID09PSBhbGxJbnRlcnNlY3Rpb25zLmxlbmd0aCAtIDEpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBjb25zdCBuZXh0SW5kZXggPSBkaXJlY3Rpb24gPT09ICdzdGFydCcgPyBkYXRhLmluZGV4IC0gMSA6IGRhdGEuaW5kZXggKyAxO1xuXG4gICAgICBlbGVtZW50VG9TY3JvbGxUbyA9IGFsbEludGVyc2VjdGlvbnNbbmV4dEluZGV4XT8udGFyZ2V0IGFzIEhUTUxFbGVtZW50O1xuICAgIH1cblxuICAgIGlmICghZWxlbWVudFRvU2Nyb2xsVG8pIHJldHVybjtcblxuICAgIHRoaXMuc2Nyb2xsVG9FbGVtZW50KHtcbiAgICAgIGVsZW1lbnQ6IGVsZW1lbnRUb1Njcm9sbFRvLFxuICAgICAgb3JpZ2luOiBkaXJlY3Rpb24sXG4gICAgfSk7XG4gIH1cblxuICBzY3JvbGxUb0VsZW1lbnQob3B0aW9uczogT21pdDxTY3JvbGxUb0VsZW1lbnRPcHRpb25zLCAnY29udGFpbmVyJz4pIHtcbiAgICBjb25zdCBzY3JvbGxFbGVtZW50ID0gdGhpcy5zY3JvbGxhYmxlKCk/Lm5hdGl2ZUVsZW1lbnQ7XG5cbiAgICBzY3JvbGxUb0VsZW1lbnQoe1xuICAgICAgY29udGFpbmVyOiBzY3JvbGxFbGVtZW50LFxuICAgICAgZGlyZWN0aW9uOiB0aGlzLmRpcmVjdGlvbigpID09PSAnaG9yaXpvbnRhbCcgPyAnaW5saW5lJyA6ICdibG9jaycsXG4gICAgICAuLi4odGhpcy5kaXJlY3Rpb24oKSA9PT0gJ2hvcml6b250YWwnXG4gICAgICAgID8geyBzY3JvbGxJbmxpbmVNYXJnaW46IHRoaXMuc2Nyb2xsTWFyZ2luKCkgfVxuICAgICAgICA6IHsgc2Nyb2xsQmxvY2tNYXJnaW46IHRoaXMuc2Nyb2xsTWFyZ2luKCkgfSksXG4gICAgICAuLi5vcHRpb25zLFxuICAgIH0pO1xuICB9XG5cbiAgc2Nyb2xsVG9FbGVtZW50QnlJbmRleChvcHRpb25zOiBPbWl0PFNjcm9sbFRvRWxlbWVudE9wdGlvbnMsICdjb250YWluZXInPiAmIHsgaW5kZXg6IG51bWJlciB9KSB7XG4gICAgY29uc3QgZWxlbWVudHMgPSB0aGlzLnNjcm9sbGFibGVDaGlsZHJlbigpO1xuXG4gICAgaWYgKCFlbGVtZW50cy5sZW5ndGgpIHtcbiAgICAgIGlmIChpc0Rldk1vZGUoKSkge1xuICAgICAgICBjb25zb2xlLndhcm4oXG4gICAgICAgICAgJ05vIGVsZW1lbnRzIGZvdW5kIHRvIHNjcm9sbCB0by4gTWFrZSBzdXJlIHRvIGFwcGx5IHRoZSBpc0VsZW1lbnQgZGlyZWN0aXZlIHRvIHRoZSBlbGVtZW50cyB5b3Ugd2FudCB0byBzY3JvbGwgdG8uJyxcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCBzY3JvbGxFbGVtZW50ID0gdGhpcy5zY3JvbGxhYmxlKCk/Lm5hdGl2ZUVsZW1lbnQ7XG4gICAgY29uc3QgZWxlbWVudCA9IGVsZW1lbnRzW29wdGlvbnMuaW5kZXhdO1xuXG4gICAgc2Nyb2xsVG9FbGVtZW50KHtcbiAgICAgIGNvbnRhaW5lcjogc2Nyb2xsRWxlbWVudCxcbiAgICAgIGVsZW1lbnQsXG4gICAgICAuLi4odGhpcy5kaXJlY3Rpb24oKSA9PT0gJ2hvcml6b250YWwnXG4gICAgICAgID8geyBzY3JvbGxJbmxpbmVNYXJnaW46IHRoaXMuc2Nyb2xsTWFyZ2luKCkgfVxuICAgICAgICA6IHsgc2Nyb2xsQmxvY2tNYXJnaW46IHRoaXMuc2Nyb2xsTWFyZ2luKCkgfSksXG4gICAgICAuLi5vcHRpb25zLFxuICAgIH0pO1xuICB9XG5cbiAgcHJvdGVjdGVkIHNjcm9sbFRvRWxlbWVudFZpYU5hdmlnYXRpb24oZWxlbWVudEluZGV4OiBudW1iZXIsIGVsZW1lbnQ6IEhUTUxFbGVtZW50KSB7XG4gICAgdGhpcy5tYW51YWxBY3RpdmVOYXZpZ2F0aW9uSW5kZXguc2V0KGVsZW1lbnRJbmRleCk7XG5cbiAgICB0aGlzLnNjcm9sbFRvRWxlbWVudCh7XG4gICAgICBlbGVtZW50LFxuICAgIH0pO1xuXG4gICAgY29uc3Qgc2Nyb2xsRWxlbWVudCA9IHRoaXMuc2Nyb2xsYWJsZSgpPy5uYXRpdmVFbGVtZW50O1xuXG4gICAgaWYgKCFzY3JvbGxFbGVtZW50KSByZXR1cm47XG5cbiAgICBmcm9tRXZlbnQoc2Nyb2xsRWxlbWVudCwgJ3Njcm9sbCcpXG4gICAgICAucGlwZShcbiAgICAgICAgZGVib3VuY2VUaW1lKDUwKSxcbiAgICAgICAgdGFrZSgxKSxcbiAgICAgICAgdGFwKCgpID0+IHRoaXMubWFudWFsQWN0aXZlTmF2aWdhdGlvbkluZGV4LnNldChudWxsKSksXG4gICAgICApXG4gICAgICAuc3Vic2NyaWJlKCk7XG4gIH1cblxuICBwcm90ZWN0ZWQgc2V0SXNDdXJzb3JEcmFnZ2luZyhpc0RyYWdnaW5nOiBib29sZWFuKSB7XG4gICAgdGhpcy5faXNDdXJzb3JEcmFnZ2luZyQubmV4dChpc0RyYWdnaW5nKTtcbiAgfVxuXG4gIHByb3RlY3RlZCBzY3JvbGxUb1N0YXJ0RGlyZWN0aW9uKCkge1xuICAgIGlmICh0aGlzLnNjcm9sbE1vZGUoKSA9PT0gJ2NvbnRhaW5lcicpIHtcbiAgICAgIHRoaXMuc2Nyb2xsT25lQ29udGFpbmVyU2l6ZSgnc3RhcnQnKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5zY3JvbGxPbmVJdGVtU2l6ZSgnc3RhcnQnKTtcbiAgICB9XG4gIH1cblxuICBwcm90ZWN0ZWQgc2Nyb2xsVG9FbmREaXJlY3Rpb24oKSB7XG4gICAgaWYgKHRoaXMuc2Nyb2xsTW9kZSgpID09PSAnY29udGFpbmVyJykge1xuICAgICAgdGhpcy5zY3JvbGxPbmVDb250YWluZXJTaXplKCdlbmQnKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5zY3JvbGxPbmVJdGVtU2l6ZSgnZW5kJyk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBfZW5hYmxlU25hcHBpbmcoKSB7XG4gICAgY29tYmluZUxhdGVzdChbdGhpcy5zY3JvbGxhYmxlQ29udGVudEludGVyc2VjdGlvbnMkLCB0aGlzLl9pc0N1cnNvckRyYWdnaW5nJF0pXG4gICAgICAucGlwZShcbiAgICAgICAgZmlsdGVyKChbLCBpc0RyYWdnaW5nXSkgPT4gIWlzRHJhZ2dpbmcpLFxuICAgICAgICBtYXAoKFtpbnRlcnNlY3Rpb25zXSkgPT4gaW50ZXJzZWN0aW9ucyksXG4gICAgICAgIGRlYm91bmNlVGltZSgxNTApLFxuICAgICAgICB0YXAoKGFsbEludGVyc2VjdGlvbnMpID0+IHtcbiAgICAgICAgICBjb25zdCBzY3JvbGxFbGVtZW50ID0gdGhpcy5zY3JvbGxhYmxlKCk/Lm5hdGl2ZUVsZW1lbnQ7XG5cbiAgICAgICAgICBpZiAoIXNjcm9sbEVsZW1lbnQpIHJldHVybjtcblxuICAgICAgICAgIGNvbnN0IGludGVyc2VjdGlvbnMgPSBnZXRGaXJzdEFuZExhc3RQYXJ0aWFsSW50ZXJzZWN0aW9uKGFsbEludGVyc2VjdGlvbnMpO1xuXG4gICAgICAgICAgaWYgKCFpbnRlcnNlY3Rpb25zKSByZXR1cm47XG5cbiAgICAgICAgICBjb25zdCBpc0ZpcnN0QW5kTGFzdEludGVyc2VjdGlvbkVxdWFsID0gaW50ZXJzZWN0aW9ucy5maXJzdC5pbnRlcnNlY3Rpb24gPT09IGludGVyc2VjdGlvbnMubGFzdC5pbnRlcnNlY3Rpb247XG4gICAgICAgICAgY29uc3Qgc2Nyb2xsYWJsZVJlY3QgPSBzY3JvbGxFbGVtZW50LmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuXG4gICAgICAgICAgaWYgKGlzRmlyc3RBbmRMYXN0SW50ZXJzZWN0aW9uRXF1YWwpIHtcbiAgICAgICAgICAgIGNvbnN0IGludGVyc2VjdGlvbiA9IGludGVyc2VjdGlvbnMuZmlyc3QuaW50ZXJzZWN0aW9uLnRhcmdldC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcbiAgICAgICAgICAgIGNvbnN0IGlzU3RhcnRPZkVsZW1lbnRWaXNpYmxlID1cbiAgICAgICAgICAgICAgdGhpcy5kaXJlY3Rpb24oKSA9PT0gJ2hvcml6b250YWwnXG4gICAgICAgICAgICAgICAgPyBpbnRlcnNlY3Rpb24ubGVmdCA+PSBzY3JvbGxhYmxlUmVjdC5sZWZ0XG4gICAgICAgICAgICAgICAgOiBpbnRlcnNlY3Rpb24udG9wID49IHNjcm9sbGFibGVSZWN0LnRvcDtcblxuICAgICAgICAgICAgY29uc3QgaXNFbmRPZkVsZW1lbnRWaXNpYmxlID1cbiAgICAgICAgICAgICAgdGhpcy5kaXJlY3Rpb24oKSA9PT0gJ2hvcml6b250YWwnXG4gICAgICAgICAgICAgICAgPyBpbnRlcnNlY3Rpb24ucmlnaHQgPD0gc2Nyb2xsYWJsZVJlY3QucmlnaHRcbiAgICAgICAgICAgICAgICA6IGludGVyc2VjdGlvbi5ib3R0b20gPD0gc2Nyb2xsYWJsZVJlY3QuYm90dG9tO1xuXG4gICAgICAgICAgICAvLyBEb24ndCBzbmFwIGlmIG5laXRoZXIgdGhlIHN0YXJ0IG5vciB0aGUgZW5kIG9mIHRoZSBjdXJyZW50IGVsZW1lbnQgaXMgdmlzaWJsZS5cbiAgICAgICAgICAgIC8vIE90aGVyd2lzZSB0aGlzIHdvdWxkIHJlc3VsdCBpbiBwYXJ0cyBvZiB0aGUgZWxlbWVudCBiZWluZyBpbmFjY2Vzc2libGUuXG4gICAgICAgICAgICBpZiAoIWlzU3RhcnRPZkVsZW1lbnRWaXNpYmxlICYmICFpc0VuZE9mRWxlbWVudFZpc2libGUpIHJldHVybjtcblxuICAgICAgICAgICAgLy8gSWYgdGhlIHN0YXJ0IG9mIHRoZSBlbGVtZW50IGlzIHZpc2libGUgd2Ugc2hvdWxkIHNuYXAgdG8gdGhlIHN0YXJ0LlxuICAgICAgICAgICAgaWYgKGlzU3RhcnRPZkVsZW1lbnRWaXNpYmxlKSB7XG4gICAgICAgICAgICAgIHRoaXMuc2Nyb2xsVG9FbGVtZW50KHtcbiAgICAgICAgICAgICAgICBlbGVtZW50OiBpbnRlcnNlY3Rpb25zLmZpcnN0LmludGVyc2VjdGlvbi50YXJnZXQgYXMgSFRNTEVsZW1lbnQsXG4gICAgICAgICAgICAgICAgb3JpZ2luOiAnc3RhcnQnLFxuICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAvLyBJZiB0aGUgZW5kIG9mIHRoZSBlbGVtZW50IGlzIHZpc2libGUgd2Ugc2hvdWxkIHNuYXAgdG8gdGhlIGVuZC5cbiAgICAgICAgICAgIGlmIChpc0VuZE9mRWxlbWVudFZpc2libGUpIHtcbiAgICAgICAgICAgICAgdGhpcy5zY3JvbGxUb0VsZW1lbnQoe1xuICAgICAgICAgICAgICAgIGVsZW1lbnQ6IGludGVyc2VjdGlvbnMubGFzdC5pbnRlcnNlY3Rpb24udGFyZ2V0IGFzIEhUTUxFbGVtZW50LFxuICAgICAgICAgICAgICAgIG9yaWdpbjogJ2VuZCcsXG4gICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSBlbHNlIGlmIChcbiAgICAgICAgICAgICh0aGlzLmRpcmVjdGlvbigpID09PSAnaG9yaXpvbnRhbCcgJiZcbiAgICAgICAgICAgICAgaW50ZXJzZWN0aW9ucy5iaWdnZXN0LmludGVyc2VjdGlvbi5ib3VuZGluZ0NsaWVudFJlY3Qud2lkdGggPiBzY3JvbGxhYmxlUmVjdC53aWR0aCkgfHxcbiAgICAgICAgICAgICh0aGlzLmRpcmVjdGlvbigpID09PSAndmVydGljYWwnICYmXG4gICAgICAgICAgICAgIGludGVyc2VjdGlvbnMuYmlnZ2VzdC5pbnRlcnNlY3Rpb24uYm91bmRpbmdDbGllbnRSZWN0LmhlaWdodCA+IHNjcm9sbGFibGVSZWN0LmhlaWdodClcbiAgICAgICAgICApIHtcbiAgICAgICAgICAgIC8vIElmIHRoZSBjdXJyZW50IGVsZW1lbnQgaXMgYmlnZ2VyIHRoYW4gdGhlIHNjcm9sbGFibGUgY29udGFpbmVyIHdlIHNob3VsZCBzbmFwIHRvIHRoZSBzdGFydCBvZiB0aGUgY3VycmVudCBlbGVtZW50IGlmIHRoZSBzY3JvbGwgZGlyZWN0aW9uIGlzIGZvcndhcmRcbiAgICAgICAgICAgIC8vIGFuZCB0byB0aGUgZW5kIG9mIHRoZSBjdXJyZW50IGVsZW1lbnQgaWYgdGhlIHNjcm9sbCBkaXJlY3Rpb24gaXMgYmFja3dhcmRzLlxuICAgICAgICAgICAgY29uc3Qgb3JpZ2luID0gaW50ZXJzZWN0aW9ucy5iaWdnZXN0LmluZGV4ID09PSBpbnRlcnNlY3Rpb25zLmZpcnN0LmluZGV4ID8gJ2VuZCcgOiAnc3RhcnQnO1xuXG4gICAgICAgICAgICB0aGlzLnNjcm9sbFRvRWxlbWVudCh7XG4gICAgICAgICAgICAgIGVsZW1lbnQ6IGludGVyc2VjdGlvbnMuYmlnZ2VzdC5pbnRlcnNlY3Rpb24udGFyZ2V0IGFzIEhUTUxFbGVtZW50LFxuICAgICAgICAgICAgICBvcmlnaW4sXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgLy8gTm8gc3BlY2lhbCBjYXNlLiBKdXN0IHNuYXAgdG8gdGhlIGJpZ2dlc3QgaW50ZXJzZWN0aW9uLlxuICAgICAgICAgICAgdGhpcy5zY3JvbGxUb0VsZW1lbnQoe1xuICAgICAgICAgICAgICBlbGVtZW50OiBpbnRlcnNlY3Rpb25zLmJpZ2dlc3QuaW50ZXJzZWN0aW9uLnRhcmdldCBhcyBIVE1MRWxlbWVudCxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgIH1cbiAgICAgICAgfSksXG4gICAgICAgIHRha2VVbnRpbCh0aGlzLl9kaXNhYmxlU25hcHBpbmckKSxcbiAgICAgIClcbiAgICAgIC5zdWJzY3JpYmUoKTtcbiAgfVxuXG4gIHByaXZhdGUgX2Rpc2FibGVTbmFwcGluZygpIHtcbiAgICB0aGlzLl9kaXNhYmxlU25hcHBpbmckLm5leHQoKTtcbiAgfVxufVxuIiwiPGRpdiBjbGFzcz1cImV0LXNjcm9sbGFibGUtd3JhcHBlclwiPlxuICA8ZGl2XG4gICAgI3Njcm9sbGFibGVcbiAgICBbYXR0ci5yb2xlXT1cInNjcm9sbGFibGVSb2xlKCkgPz8gdW5kZWZpbmVkXCJcbiAgICBbZXRDdXJzb3JEcmFnU2Nyb2xsXT1cImN1cnNvckRyYWdTY3JvbGwoKVwiXG4gICAgW2FsbG93ZWREaXJlY3Rpb25dPVwiZGlyZWN0aW9uKClcIlxuICAgIChjdXJzb3JEcmFnU3RhcnQpPVwic2V0SXNDdXJzb3JEcmFnZ2luZyh0cnVlKVwiXG4gICAgKGN1cnNvckRyYWdFbmQpPVwic2V0SXNDdXJzb3JEcmFnZ2luZyhmYWxzZSlcIlxuICAgIGNsYXNzPVwiZXQtc2Nyb2xsYWJsZS1jb250YWluZXItb3V0ZXJcIlxuICA+XG4gICAgPGRpdiAjc2Nyb2xsYWJsZUNvbnRhaW5lciBbbmdDbGFzc109XCJzY3JvbGxhYmxlQ2xhc3MoKVwiIGNsYXNzPVwiZXQtc2Nyb2xsYWJsZS1jb250YWluZXJcIj5cbiAgICAgIDxkaXYgI2ZpcnN0RWxlbWVudCBjbGFzcz1cImV0LXNjcm9sbC1vYnNlcnZlci1maXJzdC1lbGVtZW50XCIgZXRTY3JvbGxhYmxlSWdub3JlQ2hpbGQ+PC9kaXY+XG4gICAgICA8bmctY29udGVudCAvPlxuICAgICAgPGRpdiAjbGFzdEVsZW1lbnQgY2xhc3M9XCJldC1zY3JvbGwtb2JzZXJ2ZXItbGFzdC1lbGVtZW50XCIgZXRTY3JvbGxhYmxlSWdub3JlQ2hpbGQ+PC9kaXY+XG4gICAgPC9kaXY+XG4gIDwvZGl2PlxuXG4gIEBpZiAocmVuZGVyTWFza3MoKSkge1xuICAgIDxkaXYgY2xhc3M9XCJldC1zY3JvbGxhYmxlLW1hc2tzXCI+XG4gICAgICA8ZGl2IGNsYXNzPVwiZXQtc2Nyb2xsYWJsZS1tYXNrIGV0LXNjcm9sbGFibGUtbWFzay0tc3RhcnRcIj48L2Rpdj5cbiAgICAgIDxkaXYgY2xhc3M9XCJldC1zY3JvbGxhYmxlLW1hc2sgZXQtc2Nyb2xsYWJsZS1tYXNrLS1lbmRcIj48L2Rpdj5cbiAgICA8L2Rpdj5cbiAgfVxuXG4gIEBpZiAocmVuZGVyQnV0dG9ucygpKSB7XG4gICAgPGRpdiBjbGFzcz1cImV0LXNjcm9sbGFibGUtYnV0dG9uc1wiPlxuICAgICAgPGJ1dHRvblxuICAgICAgICAoY2xpY2spPVwic2Nyb2xsVG9TdGFydERpcmVjdGlvbigpXCJcbiAgICAgICAgY2xhc3M9XCJldC1zY3JvbGxhYmxlLWJ1dHRvbiBldC1zY3JvbGxhYmxlLWJ1dHRvbi0tc3RhcnRcIlxuICAgICAgICBhcmlhLWhpZGRlbj1cInRydWVcIlxuICAgICAgICB0eXBlPVwiYnV0dG9uXCJcbiAgICAgICAgdGFiaW5kZXg9XCItMVwiXG4gICAgICA+XG4gICAgICAgIDxldC1jaGV2cm9uLWljb24gLz5cbiAgICAgIDwvYnV0dG9uPlxuICAgICAgPGJ1dHRvblxuICAgICAgICAoY2xpY2spPVwic2Nyb2xsVG9FbmREaXJlY3Rpb24oKVwiXG4gICAgICAgIGNsYXNzPVwiZXQtc2Nyb2xsYWJsZS1idXR0b24gZXQtc2Nyb2xsYWJsZS1idXR0b24tLWVuZFwiXG4gICAgICAgIGFyaWEtaGlkZGVuPVwidHJ1ZVwiXG4gICAgICAgIHR5cGU9XCJidXR0b25cIlxuICAgICAgICB0YWJpbmRleD1cIi0xXCJcbiAgICAgID5cbiAgICAgICAgPGV0LWNoZXZyb24taWNvbiAvPlxuICAgICAgPC9idXR0b24+XG4gICAgPC9kaXY+XG4gIH1cbjwvZGl2PlxuXG5AaWYgKHJlbmRlck5hdmlnYXRpb24oKSkge1xuICA8ZGl2IGNsYXNzPVwiZXQtc2Nyb2xsYWJsZS1uYXZpZ2F0aW9uXCIgYXJpYS1oaWRkZW49XCJ0cnVlXCI+XG4gICAgQGZvciAoaXRlbSBvZiBzY3JvbGxhYmxlTmF2aWdhdGlvbigpOyB0cmFjayBpOyBsZXQgaSA9ICRpbmRleCkge1xuICAgICAgPGJ1dHRvblxuICAgICAgICBbY2xhc3MuZXQtc2Nyb2xsYWJsZS1uYXZpZ2F0aW9uLWl0ZW0tLWFjdGl2ZV09XCJpdGVtLmlzQWN0aXZlXCJcbiAgICAgICAgKGNsaWNrKT1cInNjcm9sbFRvRWxlbWVudFZpYU5hdmlnYXRpb24oaSwgaXRlbS5lbGVtZW50KVwiXG4gICAgICAgIGNsYXNzPVwiZXQtc2Nyb2xsYWJsZS1uYXZpZ2F0aW9uLWl0ZW1cIlxuICAgICAgPjwvYnV0dG9uPlxuICAgIH1cbiAgPC9kaXY+XG59XG4iXX0=