@recursyve/nice-ui-kit.v2 15.0.0-beta.131 → 16.0.0-beta.134

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 (400) hide show
  1. package/esm2022/lib/animations/defaults.mjs +32 -0
  2. package/{esm2020 → esm2022}/lib/api/interceptors/transform-response.interceptor.mjs +4 -4
  3. package/{esm2020 → esm2022}/lib/components/alert/alert.component.mjs +4 -4
  4. package/{esm2020 → esm2022}/lib/components/alert/alert.module.mjs +9 -9
  5. package/{esm2020 → esm2022}/lib/components/alert/alert.service.mjs +4 -4
  6. package/esm2022/lib/components/assets-carousel/assets-carousel.component.mjs +283 -0
  7. package/{esm2020 → esm2022}/lib/components/assets-carousel/assets-carousel.module.mjs +19 -19
  8. package/{esm2020 → esm2022}/lib/components/assets-carousel/directives/assets-carousel-active-content.directive.mjs +4 -4
  9. package/esm2022/lib/components/async-typeahead/async-typeahead.component.mjs +451 -0
  10. package/{esm2020 → esm2022}/lib/components/async-typeahead/async-typeahead.module.mjs +21 -21
  11. package/{esm2020 → esm2022}/lib/components/async-typeahead/providers/async-typeahead.service.mjs +4 -4
  12. package/{esm2020 → esm2022}/lib/components/base-form/base-form.component.mjs +4 -4
  13. package/{esm2020 → esm2022}/lib/components/base-form/base-form.module.mjs +5 -5
  14. package/{esm2020 → esm2022}/lib/components/base-form/form-submit.directive.mjs +4 -4
  15. package/{esm2020 → esm2022}/lib/components/card/card.component.mjs +4 -4
  16. package/{esm2020 → esm2022}/lib/components/card/card.module.mjs +5 -5
  17. package/{esm2020 → esm2022}/lib/components/carousel/carousel.component.mjs +4 -4
  18. package/esm2022/lib/components/carousel/carousel.module.mjs +40 -0
  19. package/{esm2020 → esm2022}/lib/components/carousel/picture-modal/picture-modal.component.mjs +4 -4
  20. package/{esm2020 → esm2022}/lib/components/carousel/picture-modal/picture-modal.service.mjs +4 -4
  21. package/{esm2020 → esm2022}/lib/components/carousel/pipe/carousel-layout.pipe.mjs +4 -4
  22. package/{esm2020 → esm2022}/lib/components/collapsable/collapsable.component.mjs +4 -4
  23. package/{esm2020 → esm2022}/lib/components/collapsable/collapsable.module.mjs +7 -7
  24. package/{esm2020 → esm2022}/lib/components/date-range-picker/components/header/header.component.mjs +4 -4
  25. package/{esm2020 → esm2022}/lib/components/date-range-picker/components/range-preset/range-preset.component.mjs +4 -4
  26. package/esm2022/lib/components/date-range-picker/date-range-picker.component.mjs +95 -0
  27. package/{esm2020 → esm2022}/lib/components/date-range-picker/date-range-picker.module.mjs +21 -21
  28. package/{esm2020 → esm2022}/lib/components/date-range-picker/providers/date-range-picker.service.mjs +4 -4
  29. package/{esm2020 → esm2022}/lib/components/drawer/drawer.component.mjs +4 -4
  30. package/{esm2020 → esm2022}/lib/components/drawer/drawer.module.mjs +7 -7
  31. package/{esm2020 → esm2022}/lib/components/drawer/drawer.service.mjs +4 -4
  32. package/{esm2020 → esm2022}/lib/components/export-bottom-sheet/export-bottom-sheet.component.mjs +4 -4
  33. package/esm2022/lib/components/export-bottom-sheet/export-bottom-sheet.module.mjs +45 -0
  34. package/{esm2020 → esm2022}/lib/components/export-bottom-sheet/providers/export-bottom-sheet.service.mjs +7 -7
  35. package/{esm2020 → esm2022}/lib/components/form-error/control-status.directive.mjs +4 -4
  36. package/esm2022/lib/components/form-error/form-error.component.mjs +53 -0
  37. package/{esm2020 → esm2022}/lib/components/form-error/form-error.module.mjs +5 -5
  38. package/esm2022/lib/components/horizontal-stepper/horizontal-stepper.component.mjs +34 -0
  39. package/{esm2020 → esm2022}/lib/components/horizontal-stepper/horizontal-stepper.module.mjs +9 -9
  40. package/{esm2020 → esm2022}/lib/components/horizontal-stepper/step.component.mjs +6 -6
  41. package/esm2022/lib/components/image-cropper/image-cropper.component.mjs +1269 -0
  42. package/{esm2020 → esm2022}/lib/components/image-cropper/image-cropper.module.mjs +5 -5
  43. package/{esm2020 → esm2022}/lib/components/layout/layout.component.mjs +4 -4
  44. package/{esm2020 → esm2022}/lib/components/layout/layout.module.mjs +5 -5
  45. package/{esm2020 → esm2022}/lib/components/loading-spinner/loading-spinner.component.mjs +4 -4
  46. package/{esm2020 → esm2022}/lib/components/loading-spinner/loading-spinner.module.mjs +9 -9
  47. package/{esm2020 → esm2022}/lib/components/loading-spinner/loading.directive.mjs +4 -4
  48. package/{esm2020 → esm2022}/lib/components/loading-toast/loading-toast.component.mjs +4 -4
  49. package/{esm2020 → esm2022}/lib/components/loading-toast/loading-toast.directive.mjs +4 -4
  50. package/{esm2020 → esm2022}/lib/components/loading-toast/loading-toast.module.mjs +5 -5
  51. package/{esm2020 → esm2022}/lib/components/loading-toast/loading-toast.service.mjs +4 -4
  52. package/{esm2020 → esm2022}/lib/components/lottie/lottie.component.mjs +4 -4
  53. package/{esm2020 → esm2022}/lib/components/lottie/lottie.module.mjs +5 -5
  54. package/{esm2020 → esm2022}/lib/components/navigation/components/hint-component-base.mjs +4 -4
  55. package/{esm2020 → esm2022}/lib/components/navigation/directives/show-hint.directive.mjs +4 -4
  56. package/esm2022/lib/components/navigation/horizontal/components/basic/basic.component.mjs +62 -0
  57. package/{esm2020 → esm2022}/lib/components/navigation/horizontal/components/branch/branch.component.mjs +7 -7
  58. package/{esm2020 → esm2022}/lib/components/navigation/horizontal/components/divider/divider.component.mjs +4 -4
  59. package/{esm2020 → esm2022}/lib/components/navigation/horizontal/components/spacer/spacer.component.mjs +4 -4
  60. package/esm2022/lib/components/navigation/horizontal/horizontal.component.mjs +50 -0
  61. package/esm2022/lib/components/navigation/navigation.component.mjs +83 -0
  62. package/esm2022/lib/components/navigation/navigation.module.mjs +108 -0
  63. package/{esm2020 → esm2022}/lib/components/navigation/navigation.service.mjs +4 -4
  64. package/{esm2020 → esm2022}/lib/components/navigation/pipes/should-hide.pipe.mjs +4 -4
  65. package/{esm2020 → esm2022}/lib/components/navigation/pipes/should-show-hint.pipe.mjs +4 -4
  66. package/esm2022/lib/components/navigation/pipes/translate-with-context.pipe.mjs +25 -0
  67. package/{esm2020 → esm2022}/lib/components/navigation/providers/hint.service.mjs +4 -4
  68. package/esm2022/lib/components/navigation/providers/translation-context.service.mjs +16 -0
  69. package/{esm2020 → esm2022}/lib/components/navigation/vertical/components/aside/aside.component.mjs +6 -6
  70. package/esm2022/lib/components/navigation/vertical/components/basic/basic.component.mjs +76 -0
  71. package/{esm2020 → esm2022}/lib/components/navigation/vertical/components/collapsable/collapsable.component.mjs +8 -8
  72. package/{esm2020 → esm2022}/lib/components/navigation/vertical/components/divider/divider.component.mjs +4 -4
  73. package/esm2022/lib/components/navigation/vertical/components/group/group.component.mjs +75 -0
  74. package/{esm2020 → esm2022}/lib/components/navigation/vertical/components/spacer/spacer.component.mjs +4 -4
  75. package/esm2022/lib/components/navigation/vertical/vertical.component.mjs +599 -0
  76. package/esm2022/lib/components/search-bar/search-bar.component.mjs +76 -0
  77. package/{esm2020 → esm2022}/lib/components/search-bar/search-bar.module.mjs +13 -13
  78. package/{esm2020 → esm2022}/lib/components/sweet-alert/sweet-alert.component.mjs +4 -4
  79. package/{esm2020 → esm2022}/lib/components/sweet-alert/sweet-alert.directive.mjs +4 -4
  80. package/{esm2020 → esm2022}/lib/components/sweet-alert/sweet-alert.module.mjs +5 -5
  81. package/{esm2020 → esm2022}/lib/components/sweet-alert/sweet-alert.service.mjs +4 -4
  82. package/{esm2020 → esm2022}/lib/components/toast/toast.component.mjs +4 -4
  83. package/{esm2020 → esm2022}/lib/components/toast/toast.module.mjs +5 -5
  84. package/{esm2020 → esm2022}/lib/components/toast/toast.service.mjs +4 -4
  85. package/esm2022/lib/components/toggle-button-group/toggle-button-group.component.mjs +134 -0
  86. package/{esm2020 → esm2022}/lib/components/toggle-button-group/toggle-button-group.module.mjs +7 -7
  87. package/{esm2020 → esm2022}/lib/components/toggle-button-group/toggle-button.component.mjs +4 -4
  88. package/esm2022/lib/components/translation-form/components/textarea/translation-form-textarea.component.mjs +38 -0
  89. package/esm2022/lib/components/translation-form/components/textfield/translation-form-textfield.component.mjs +26 -0
  90. package/{esm2020 → esm2022}/lib/components/translation-form/components/translation-form.component.mjs +4 -4
  91. package/{esm2020 → esm2022}/lib/components/translation-form/components/translation-form.module.mjs +19 -19
  92. package/{esm2020 → esm2022}/lib/components/translation-form/directives/translation-context.directive.mjs +4 -4
  93. package/{esm2020 → esm2022}/lib/components/translation-form/providers/nice-translation-form.service.mjs +4 -4
  94. package/{esm2020 → esm2022}/lib/components/translation-form/toggle/translation-toggle.component.mjs +4 -4
  95. package/{esm2020 → esm2022}/lib/components/translation-form/validators/require-for-languages.validator.mjs +4 -4
  96. package/{esm2020 → esm2022}/lib/components/typeahead/directives/options-scroll.directive.mjs +4 -4
  97. package/{esm2020 → esm2022}/lib/components/typeahead/directives/options-scroll.module.mjs +5 -5
  98. package/{esm2020 → esm2022}/lib/components/typeahead/typeahead.component.mjs +9 -9
  99. package/{esm2020 → esm2022}/lib/components/typeahead/typeahead.module.mjs +25 -25
  100. package/{esm2020 → esm2022}/lib/directives/autofocus/autofocus.directive.mjs +4 -4
  101. package/{esm2020 → esm2022}/lib/directives/autofocus/autofocus.module.mjs +5 -5
  102. package/{esm2020 → esm2022}/lib/directives/autogrow/autogrow.directive.mjs +4 -4
  103. package/{esm2020 → esm2022}/lib/directives/autogrow/autogrow.module.mjs +5 -5
  104. package/{esm2020 → esm2022}/lib/directives/chip-async-typeahead/chip-async-typeahead.directive.mjs +4 -4
  105. package/{esm2020 → esm2022}/lib/directives/chip-list/chip-list-items/chip-list-item-label.directive.mjs +4 -4
  106. package/{esm2020 → esm2022}/lib/directives/chip-list/chip-list-items/chip-list-items.component.mjs +4 -4
  107. package/{esm2020 → esm2022}/lib/directives/chip-list/chip-list.directive.mjs +4 -4
  108. package/{esm2020 → esm2022}/lib/directives/chip-list/chip-list.module.mjs +5 -5
  109. package/{esm2020 → esm2022}/lib/directives/draggable-list/draggable-list.directive.mjs +4 -4
  110. package/{esm2020 → esm2022}/lib/directives/draggable-list/draggable-list.module.mjs +5 -5
  111. package/{esm2020 → esm2022}/lib/directives/dropzone/dropzone.directive.mjs +4 -4
  112. package/{esm2020 → esm2022}/lib/directives/dropzone/dropzone.module.mjs +5 -5
  113. package/{esm2020 → esm2022}/lib/directives/image-error-placeholder/image-error-placeholder.directive.mjs +4 -4
  114. package/{esm2020 → esm2022}/lib/directives/image-error-placeholder/image-error-placeholder.module.mjs +5 -5
  115. package/{esm2020 → esm2022}/lib/directives/material/material.module.mjs +7 -7
  116. package/{esm2020 → esm2022}/lib/directives/material/nice-material-style.directive.mjs +4 -4
  117. package/{esm2020 → esm2022}/lib/directives/material/nice-rounded-style.directive.mjs +4 -4
  118. package/{esm2020 → esm2022}/lib/directives/modals/modal-on-click.directive.mjs +4 -4
  119. package/{esm2020 → esm2022}/lib/directives/modals/modal-opener.directive.mjs +4 -4
  120. package/{esm2020 → esm2022}/lib/directives/rerender/rerender.directive.mjs +4 -4
  121. package/{esm2020 → esm2022}/lib/directives/resolve/resolve.directive.mjs +4 -4
  122. package/{esm2020 → esm2022}/lib/directives/scroll-reset/scroll-reset.directive.mjs +4 -4
  123. package/{esm2020 → esm2022}/lib/directives/scroll-reset/scroll-reset.module.mjs +5 -5
  124. package/{esm2020 → esm2022}/lib/directives/scrollbar/scrollbar.directive.mjs +4 -4
  125. package/{esm2020 → esm2022}/lib/directives/scrollbar/scrollbar.module.mjs +5 -5
  126. package/{esm2020 → esm2022}/lib/directives/stop-propagation/click-stop-propagation.directive.mjs +4 -4
  127. package/{esm2020 → esm2022}/lib/directives/stop-propagation/stop-propagation.module.mjs +5 -5
  128. package/{esm2020 → esm2022}/lib/directives/window/prevent-close-window.directive.mjs +4 -4
  129. package/{esm2020 → esm2022}/lib/directives/window/window-directive.module.mjs +5 -5
  130. package/esm2022/lib/nice.module.mjs +124 -0
  131. package/{esm2020 → esm2022}/lib/pipes/boolean.pipe.mjs +4 -4
  132. package/{esm2020 → esm2022}/lib/pipes/capitalize-first-letter.pipe.mjs +4 -4
  133. package/{esm2020 → esm2022}/lib/pipes/ceil.pipe.mjs +4 -4
  134. package/{esm2020 → esm2022}/lib/pipes/entries.pipe.mjs +4 -4
  135. package/{esm2020 → esm2022}/lib/pipes/find-by-key.pipe.mjs +4 -4
  136. package/{esm2020 → esm2022}/lib/pipes/first-letter.pipe.mjs +4 -4
  137. package/{esm2020 → esm2022}/lib/pipes/floor.pipe.mjs +4 -4
  138. package/{esm2020 → esm2022}/lib/pipes/join-if-defined.pipe.mjs +4 -4
  139. package/{esm2020 → esm2022}/lib/pipes/link.pipe.mjs +4 -4
  140. package/{esm2020 → esm2022}/lib/pipes/localized-boolean.pipe.mjs +4 -4
  141. package/{esm2020 → esm2022}/lib/pipes/localized-currency.pipe.mjs +4 -4
  142. package/{esm2020 → esm2022}/lib/pipes/localized-date-only.pipe.mjs +4 -4
  143. package/{esm2020 → esm2022}/lib/pipes/localized-date.pipe.mjs +4 -4
  144. package/{esm2020 → esm2022}/lib/pipes/minutes-to-time.pipe.mjs +4 -4
  145. package/{esm2020 → esm2022}/lib/pipes/number-to-ordinal-indicator.pipe.mjs +4 -4
  146. package/{esm2020 → esm2022}/lib/pipes/pad.pipe.mjs +4 -4
  147. package/{esm2020 → esm2022}/lib/pipes/phone.pipe.mjs +4 -4
  148. package/{esm2020 → esm2022}/lib/pipes/pipes.module.mjs +72 -72
  149. package/{esm2020 → esm2022}/lib/pipes/postal-code.pipe.mjs +4 -4
  150. package/{esm2020 → esm2022}/lib/pipes/range.pipe.mjs +4 -4
  151. package/{esm2020 → esm2022}/lib/pipes/round.pipe.mjs +4 -4
  152. package/{esm2020 → esm2022}/lib/pipes/sanitize-bypass.pipe.mjs +4 -4
  153. package/{esm2020 → esm2022}/lib/pipes/seconds-to-time.pipe.mjs +4 -4
  154. package/{esm2020 → esm2022}/lib/pipes/track-by-prop.pipe.mjs +4 -4
  155. package/{esm2020 → esm2022}/lib/providers/config/config.module.mjs +5 -5
  156. package/{esm2020 → esm2022}/lib/providers/config/config.service.mjs +4 -4
  157. package/{esm2020 → esm2022}/lib/providers/media-watcher/media-watcher.module.mjs +7 -7
  158. package/{esm2020 → esm2022}/lib/providers/media-watcher/media-watcher.service.mjs +4 -4
  159. package/{esm2020 → esm2022}/lib/providers/overlay/dynamic-overlay-container.service.mjs +4 -4
  160. package/{esm2020 → esm2022}/lib/providers/overlay/dynamic-overlay.service.mjs +4 -4
  161. package/{esm2020 → esm2022}/lib/providers/splash-screen/splash-screen.module.mjs +7 -7
  162. package/{esm2020 → esm2022}/lib/providers/splash-screen/splash-screen.service.mjs +4 -4
  163. package/{esm2020 → esm2022}/lib/providers/utils/utils.module.mjs +5 -5
  164. package/{esm2020 → esm2022}/lib/providers/utils/utils.service.mjs +4 -4
  165. package/esm2022/lib/utils/regex.utils.mjs +11 -0
  166. package/{fesm2020 → fesm2022}/recursyve-nice-ui-kit.v2.mjs +948 -905
  167. package/fesm2022/recursyve-nice-ui-kit.v2.mjs.map +1 -0
  168. package/lib/components/alert/alert.component.d.ts +1 -1
  169. package/lib/components/assets-carousel/assets-carousel.component.d.ts +1 -1
  170. package/lib/components/async-typeahead/async-typeahead.component.d.ts +1 -1
  171. package/lib/components/base-form/base-form.component.d.ts +1 -1
  172. package/lib/components/base-form/form-submit.directive.d.ts +1 -1
  173. package/lib/components/card/card.component.d.ts +1 -1
  174. package/lib/components/carousel/carousel.component.d.ts +1 -1
  175. package/lib/components/collapsable/collapsable.component.d.ts +1 -1
  176. package/lib/components/date-range-picker/date-range-picker.component.d.ts +1 -1
  177. package/lib/components/drawer/drawer.component.d.ts +1 -1
  178. package/lib/components/form-error/form-error.component.d.ts +1 -1
  179. package/lib/components/image-cropper/image-cropper.component.d.ts +2 -2
  180. package/lib/components/loading-spinner/loading-spinner.component.d.ts +1 -1
  181. package/lib/components/loading-spinner/loading.directive.d.ts +1 -1
  182. package/lib/components/loading-toast/loading-toast.component.d.ts +1 -1
  183. package/lib/components/loading-toast/loading-toast.directive.d.ts +1 -1
  184. package/lib/components/lottie/lottie.component.d.ts +1 -1
  185. package/lib/components/navigation/directives/show-hint.directive.d.ts +1 -1
  186. package/lib/components/navigation/horizontal/components/basic/basic.component.d.ts +1 -1
  187. package/lib/components/navigation/horizontal/components/branch/branch.component.d.ts +1 -1
  188. package/lib/components/navigation/horizontal/components/divider/divider.component.d.ts +1 -1
  189. package/lib/components/navigation/horizontal/components/spacer/spacer.component.d.ts +1 -1
  190. package/lib/components/navigation/horizontal/horizontal.component.d.ts +4 -2
  191. package/lib/components/navigation/navigation.component.d.ts +3 -1
  192. package/lib/components/navigation/navigation.module.d.ts +12 -11
  193. package/lib/components/navigation/pipes/translate-with-context.pipe.d.ts +12 -0
  194. package/lib/components/navigation/providers/translation-context.service.d.ts +8 -0
  195. package/lib/components/navigation/vertical/components/aside/aside.component.d.ts +1 -1
  196. package/lib/components/navigation/vertical/components/basic/basic.component.d.ts +1 -1
  197. package/lib/components/navigation/vertical/components/collapsable/collapsable.component.d.ts +1 -1
  198. package/lib/components/navigation/vertical/components/divider/divider.component.d.ts +1 -1
  199. package/lib/components/navigation/vertical/components/group/group.component.d.ts +1 -1
  200. package/lib/components/navigation/vertical/components/spacer/spacer.component.d.ts +1 -1
  201. package/lib/components/navigation/vertical/vertical.component.d.ts +4 -2
  202. package/lib/components/search-bar/search-bar.component.d.ts +1 -1
  203. package/lib/components/sweet-alert/sweet-alert.directive.d.ts +1 -1
  204. package/lib/components/toggle-button-group/toggle-button-group.component.d.ts +1 -1
  205. package/lib/components/toggle-button-group/toggle-button.component.d.ts +1 -1
  206. package/lib/components/translation-form/components/textarea/translation-form-textarea.component.d.ts +1 -1
  207. package/lib/components/translation-form/components/translation-form.component.d.ts +1 -1
  208. package/lib/components/translation-form/validators/require-for-languages.validator.d.ts +1 -1
  209. package/lib/components/typeahead/directives/options-scroll.directive.d.ts +1 -1
  210. package/lib/components/typeahead/typeahead.component.d.ts +1 -1
  211. package/lib/directives/autogrow/autogrow.directive.d.ts +1 -1
  212. package/lib/directives/chip-list/chip-list-items/chip-list-items.component.d.ts +1 -1
  213. package/lib/directives/chip-list/chip-list.directive.d.ts +1 -1
  214. package/lib/directives/draggable-list/draggable-list.directive.d.ts +1 -1
  215. package/lib/directives/image-error-placeholder/image-error-placeholder.directive.d.ts +1 -1
  216. package/lib/directives/modals/modal-opener.directive.d.ts +1 -1
  217. package/lib/directives/rerender/rerender.directive.d.ts +1 -1
  218. package/lib/directives/resolve/resolve.directive.d.ts +1 -1
  219. package/lib/directives/scrollbar/scrollbar.directive.d.ts +1 -1
  220. package/package.json +12 -19
  221. package/esm2020/lib/animations/defaults.mjs +0 -32
  222. package/esm2020/lib/components/assets-carousel/assets-carousel.component.mjs +0 -283
  223. package/esm2020/lib/components/async-typeahead/async-typeahead.component.mjs +0 -451
  224. package/esm2020/lib/components/carousel/carousel.module.mjs +0 -41
  225. package/esm2020/lib/components/date-range-picker/date-range-picker.component.mjs +0 -95
  226. package/esm2020/lib/components/export-bottom-sheet/export-bottom-sheet.module.mjs +0 -45
  227. package/esm2020/lib/components/form-error/form-error.component.mjs +0 -53
  228. package/esm2020/lib/components/horizontal-stepper/horizontal-stepper.component.mjs +0 -34
  229. package/esm2020/lib/components/image-cropper/image-cropper.component.mjs +0 -1269
  230. package/esm2020/lib/components/navigation/horizontal/components/basic/basic.component.mjs +0 -62
  231. package/esm2020/lib/components/navigation/horizontal/horizontal.component.mjs +0 -46
  232. package/esm2020/lib/components/navigation/navigation.component.mjs +0 -76
  233. package/esm2020/lib/components/navigation/navigation.module.mjs +0 -105
  234. package/esm2020/lib/components/navigation/vertical/components/basic/basic.component.mjs +0 -76
  235. package/esm2020/lib/components/navigation/vertical/components/group/group.component.mjs +0 -75
  236. package/esm2020/lib/components/navigation/vertical/vertical.component.mjs +0 -595
  237. package/esm2020/lib/components/search-bar/search-bar.component.mjs +0 -76
  238. package/esm2020/lib/components/toggle-button-group/toggle-button-group.component.mjs +0 -134
  239. package/esm2020/lib/components/translation-form/components/textarea/translation-form-textarea.component.mjs +0 -38
  240. package/esm2020/lib/components/translation-form/components/textfield/translation-form-textfield.component.mjs +0 -26
  241. package/esm2020/lib/nice.module.mjs +0 -124
  242. package/esm2020/lib/utils/regex.utils.mjs +0 -11
  243. package/fesm2015/recursyve-nice-ui-kit.v2.mjs +0 -11867
  244. package/fesm2015/recursyve-nice-ui-kit.v2.mjs.map +0 -1
  245. package/fesm2020/recursyve-nice-ui-kit.v2.mjs.map +0 -1
  246. /package/{esm2020 → esm2022}/lib/animations/expand-collapse.mjs +0 -0
  247. /package/{esm2020 → esm2022}/lib/animations/fade.mjs +0 -0
  248. /package/{esm2020 → esm2022}/lib/animations/index.mjs +0 -0
  249. /package/{esm2020 → esm2022}/lib/animations/public-api.mjs +0 -0
  250. /package/{esm2020 → esm2022}/lib/animations/shake.mjs +0 -0
  251. /package/{esm2020 → esm2022}/lib/animations/slide.mjs +0 -0
  252. /package/{esm2020 → esm2022}/lib/animations/zoom.mjs +0 -0
  253. /package/{esm2020 → esm2022}/lib/api/exceptions/api.exception.mjs +0 -0
  254. /package/{esm2020 → esm2022}/lib/api/exceptions/exception.factory.mjs +0 -0
  255. /package/{esm2020 → esm2022}/lib/api/index.mjs +0 -0
  256. /package/{esm2020 → esm2022}/lib/api/nice.api.mjs +0 -0
  257. /package/{esm2020 → esm2022}/lib/api/public-api.mjs +0 -0
  258. /package/{esm2020 → esm2022}/lib/components/alert/alert.types.mjs +0 -0
  259. /package/{esm2020 → esm2022}/lib/components/alert/index.mjs +0 -0
  260. /package/{esm2020 → esm2022}/lib/components/alert/public-api.mjs +0 -0
  261. /package/{esm2020 → esm2022}/lib/components/assets-carousel/assets-carousel.constant.mjs +0 -0
  262. /package/{esm2020 → esm2022}/lib/components/assets-carousel/index.mjs +0 -0
  263. /package/{esm2020 → esm2022}/lib/components/assets-carousel/public-api.mjs +0 -0
  264. /package/{esm2020 → esm2022}/lib/components/async-typeahead/async-typeahead.constant.mjs +0 -0
  265. /package/{esm2020 → esm2022}/lib/components/async-typeahead/index.mjs +0 -0
  266. /package/{esm2020 → esm2022}/lib/components/async-typeahead/providers/async-typeahead.provider.mjs +0 -0
  267. /package/{esm2020 → esm2022}/lib/components/async-typeahead/public-api.mjs +0 -0
  268. /package/{esm2020 → esm2022}/lib/components/base-form/index.mjs +0 -0
  269. /package/{esm2020 → esm2022}/lib/components/base-form/nice-base.form.mjs +0 -0
  270. /package/{esm2020 → esm2022}/lib/components/base-form/public-api.mjs +0 -0
  271. /package/{esm2020 → esm2022}/lib/components/card/card.types.mjs +0 -0
  272. /package/{esm2020 → esm2022}/lib/components/card/index.mjs +0 -0
  273. /package/{esm2020 → esm2022}/lib/components/card/public-api.mjs +0 -0
  274. /package/{esm2020 → esm2022}/lib/components/carousel/index.mjs +0 -0
  275. /package/{esm2020 → esm2022}/lib/components/carousel/picture-modal/index.mjs +0 -0
  276. /package/{esm2020 → esm2022}/lib/components/carousel/picture-modal/public-api.mjs +0 -0
  277. /package/{esm2020 → esm2022}/lib/components/carousel/public-api.mjs +0 -0
  278. /package/{esm2020 → esm2022}/lib/components/collapsable/index.mjs +0 -0
  279. /package/{esm2020 → esm2022}/lib/components/collapsable/public-api.mjs +0 -0
  280. /package/{esm2020 → esm2022}/lib/components/date-range-picker/index.mjs +0 -0
  281. /package/{esm2020 → esm2022}/lib/components/date-range-picker/public-api.mjs +0 -0
  282. /package/{esm2020 → esm2022}/lib/components/drawer/drawer.types.mjs +0 -0
  283. /package/{esm2020 → esm2022}/lib/components/drawer/index.mjs +0 -0
  284. /package/{esm2020 → esm2022}/lib/components/drawer/public-api.mjs +0 -0
  285. /package/{esm2020 → esm2022}/lib/components/export-bottom-sheet/index.mjs +0 -0
  286. /package/{esm2020 → esm2022}/lib/components/export-bottom-sheet/models/export-strategy.model.mjs +0 -0
  287. /package/{esm2020 → esm2022}/lib/components/export-bottom-sheet/public-api.mjs +0 -0
  288. /package/{esm2020 → esm2022}/lib/components/form-error/index.mjs +0 -0
  289. /package/{esm2020 → esm2022}/lib/components/form-error/public-api.mjs +0 -0
  290. /package/{esm2020 → esm2022}/lib/components/horizontal-stepper/index.mjs +0 -0
  291. /package/{esm2020 → esm2022}/lib/components/horizontal-stepper/public-api.mjs +0 -0
  292. /package/{esm2020 → esm2022}/lib/components/image-cropper/index.mjs +0 -0
  293. /package/{esm2020 → esm2022}/lib/components/image-cropper/public-api.mjs +0 -0
  294. /package/{esm2020 → esm2022}/lib/components/image-cropper/resize-canvas.mjs +0 -0
  295. /package/{esm2020 → esm2022}/lib/components/index.mjs +0 -0
  296. /package/{esm2020 → esm2022}/lib/components/layout/index.mjs +0 -0
  297. /package/{esm2020 → esm2022}/lib/components/layout/public-api.mjs +0 -0
  298. /package/{esm2020 → esm2022}/lib/components/loading-spinner/index.mjs +0 -0
  299. /package/{esm2020 → esm2022}/lib/components/loading-spinner/loading.constant.mjs +0 -0
  300. /package/{esm2020 → esm2022}/lib/components/loading-spinner/public-api.mjs +0 -0
  301. /package/{esm2020 → esm2022}/lib/components/loading-toast/index.mjs +0 -0
  302. /package/{esm2020 → esm2022}/lib/components/loading-toast/loading-toast.constant.mjs +0 -0
  303. /package/{esm2020 → esm2022}/lib/components/loading-toast/public-api.mjs +0 -0
  304. /package/{esm2020 → esm2022}/lib/components/loading-toast/rxjs/show-loading-toast.operator.mjs +0 -0
  305. /package/{esm2020 → esm2022}/lib/components/lottie/index.mjs +0 -0
  306. /package/{esm2020 → esm2022}/lib/components/lottie/public-api.mjs +0 -0
  307. /package/{esm2020 → esm2022}/lib/components/navigation/index.mjs +0 -0
  308. /package/{esm2020 → esm2022}/lib/components/navigation/navigation.types.mjs +0 -0
  309. /package/{esm2020 → esm2022}/lib/components/navigation/providers/hide-item.resolver.mjs +0 -0
  310. /package/{esm2020 → esm2022}/lib/components/navigation/providers/hint.resolver.mjs +0 -0
  311. /package/{esm2020 → esm2022}/lib/components/navigation/public-api.mjs +0 -0
  312. /package/{esm2020 → esm2022}/lib/components/public-api.mjs +0 -0
  313. /package/{esm2020 → esm2022}/lib/components/search-bar/index.mjs +0 -0
  314. /package/{esm2020 → esm2022}/lib/components/search-bar/public-api.mjs +0 -0
  315. /package/{esm2020 → esm2022}/lib/components/sweet-alert/index.mjs +0 -0
  316. /package/{esm2020 → esm2022}/lib/components/sweet-alert/public-api.mjs +0 -0
  317. /package/{esm2020 → esm2022}/lib/components/sweet-alert/sweet-alert.constant.mjs +0 -0
  318. /package/{esm2020 → esm2022}/lib/components/toast/index.mjs +0 -0
  319. /package/{esm2020 → esm2022}/lib/components/toast/public-api.mjs +0 -0
  320. /package/{esm2020 → esm2022}/lib/components/toast/rxjs/show-success-or-error-toast.operator.mjs +0 -0
  321. /package/{esm2020 → esm2022}/lib/components/toast/rxjs/show-toast.operator.mjs +0 -0
  322. /package/{esm2020 → esm2022}/lib/components/toast/toast.constant.mjs +0 -0
  323. /package/{esm2020 → esm2022}/lib/components/toggle-button-group/index.mjs +0 -0
  324. /package/{esm2020 → esm2022}/lib/components/toggle-button-group/public-api.mjs +0 -0
  325. /package/{esm2020 → esm2022}/lib/components/translation-form/decorators/translation-form-group.decorator.mjs +0 -0
  326. /package/{esm2020 → esm2022}/lib/components/translation-form/index.mjs +0 -0
  327. /package/{esm2020 → esm2022}/lib/components/translation-form/public-api.mjs +0 -0
  328. /package/{esm2020 → esm2022}/lib/components/translation-form/translation.form.mjs +0 -0
  329. /package/{esm2020 → esm2022}/lib/components/typeahead/index.mjs +0 -0
  330. /package/{esm2020 → esm2022}/lib/components/typeahead/public-api.mjs +0 -0
  331. /package/{esm2020 → esm2022}/lib/directives/autofocus/index.mjs +0 -0
  332. /package/{esm2020 → esm2022}/lib/directives/autofocus/public-api.mjs +0 -0
  333. /package/{esm2020 → esm2022}/lib/directives/autogrow/index.mjs +0 -0
  334. /package/{esm2020 → esm2022}/lib/directives/autogrow/public-api.mjs +0 -0
  335. /package/{esm2020 → esm2022}/lib/directives/chip-async-typeahead/index.mjs +0 -0
  336. /package/{esm2020 → esm2022}/lib/directives/chip-async-typeahead/public-api.mjs +0 -0
  337. /package/{esm2020 → esm2022}/lib/directives/chip-list/chip-list.constant.mjs +0 -0
  338. /package/{esm2020 → esm2022}/lib/directives/chip-list/index.mjs +0 -0
  339. /package/{esm2020 → esm2022}/lib/directives/chip-list/public-api.mjs +0 -0
  340. /package/{esm2020 → esm2022}/lib/directives/draggable-list/index.mjs +0 -0
  341. /package/{esm2020 → esm2022}/lib/directives/draggable-list/public-api.mjs +0 -0
  342. /package/{esm2020 → esm2022}/lib/directives/dropzone/index.mjs +0 -0
  343. /package/{esm2020 → esm2022}/lib/directives/dropzone/public-api.mjs +0 -0
  344. /package/{esm2020 → esm2022}/lib/directives/image-error-placeholder/index.mjs +0 -0
  345. /package/{esm2020 → esm2022}/lib/directives/image-error-placeholder/public-api.mjs +0 -0
  346. /package/{esm2020 → esm2022}/lib/directives/index.mjs +0 -0
  347. /package/{esm2020 → esm2022}/lib/directives/material/index.mjs +0 -0
  348. /package/{esm2020 → esm2022}/lib/directives/material/public-api.mjs +0 -0
  349. /package/{esm2020 → esm2022}/lib/directives/modals/index.mjs +0 -0
  350. /package/{esm2020 → esm2022}/lib/directives/modals/public-api.mjs +0 -0
  351. /package/{esm2020 → esm2022}/lib/directives/public-api.mjs +0 -0
  352. /package/{esm2020 → esm2022}/lib/directives/rerender/index.mjs +0 -0
  353. /package/{esm2020 → esm2022}/lib/directives/rerender/public-api.mjs +0 -0
  354. /package/{esm2020 → esm2022}/lib/directives/resolve/index.mjs +0 -0
  355. /package/{esm2020 → esm2022}/lib/directives/resolve/public-api.mjs +0 -0
  356. /package/{esm2020 → esm2022}/lib/directives/scroll-reset/index.mjs +0 -0
  357. /package/{esm2020 → esm2022}/lib/directives/scroll-reset/public-api.mjs +0 -0
  358. /package/{esm2020 → esm2022}/lib/directives/scrollbar/index.mjs +0 -0
  359. /package/{esm2020 → esm2022}/lib/directives/scrollbar/public-api.mjs +0 -0
  360. /package/{esm2020 → esm2022}/lib/directives/scrollbar/scrollbar.types.mjs +0 -0
  361. /package/{esm2020 → esm2022}/lib/directives/stop-propagation/index.mjs +0 -0
  362. /package/{esm2020 → esm2022}/lib/directives/stop-propagation/public-api.mjs +0 -0
  363. /package/{esm2020 → esm2022}/lib/directives/window/index.mjs +0 -0
  364. /package/{esm2020 → esm2022}/lib/directives/window/public-api.mjs +0 -0
  365. /package/{esm2020 → esm2022}/lib/pipes/index.mjs +0 -0
  366. /package/{esm2020 → esm2022}/lib/pipes/public-api.mjs +0 -0
  367. /package/{esm2020 → esm2022}/lib/providers/config/config.constants.mjs +0 -0
  368. /package/{esm2020 → esm2022}/lib/providers/config/config.model.mjs +0 -0
  369. /package/{esm2020 → esm2022}/lib/providers/config/index.mjs +0 -0
  370. /package/{esm2020 → esm2022}/lib/providers/config/public-api.mjs +0 -0
  371. /package/{esm2020 → esm2022}/lib/providers/index.mjs +0 -0
  372. /package/{esm2020 → esm2022}/lib/providers/media-watcher/index.mjs +0 -0
  373. /package/{esm2020 → esm2022}/lib/providers/media-watcher/public-api.mjs +0 -0
  374. /package/{esm2020 → esm2022}/lib/providers/public-api.mjs +0 -0
  375. /package/{esm2020 → esm2022}/lib/providers/splash-screen/index.mjs +0 -0
  376. /package/{esm2020 → esm2022}/lib/providers/splash-screen/public-api.mjs +0 -0
  377. /package/{esm2020 → esm2022}/lib/providers/utils/index.mjs +0 -0
  378. /package/{esm2020 → esm2022}/lib/providers/utils/public-api.mjs +0 -0
  379. /package/{esm2020 → esm2022}/lib/types/constructor.mjs +0 -0
  380. /package/{esm2020 → esm2022}/lib/utils/array.utils.mjs +0 -0
  381. /package/{esm2020 → esm2022}/lib/utils/case.utils.mjs +0 -0
  382. /package/{esm2020 → esm2022}/lib/utils/colors.utils.mjs +0 -0
  383. /package/{esm2020 → esm2022}/lib/utils/date.utils.mjs +0 -0
  384. /package/{esm2020 → esm2022}/lib/utils/file.utils.mjs +0 -0
  385. /package/{esm2020 → esm2022}/lib/utils/font-awesome.utils.mjs +0 -0
  386. /package/{esm2020 → esm2022}/lib/utils/form-data.utils.mjs +0 -0
  387. /package/{esm2020 → esm2022}/lib/utils/http-status.utils.mjs +0 -0
  388. /package/{esm2020 → esm2022}/lib/utils/index.mjs +0 -0
  389. /package/{esm2020 → esm2022}/lib/utils/keyboard.utils.mjs +0 -0
  390. /package/{esm2020 → esm2022}/lib/utils/lexorank.utils.mjs +0 -0
  391. /package/{esm2020 → esm2022}/lib/utils/modal.utils.mjs +0 -0
  392. /package/{esm2020 → esm2022}/lib/utils/number.utils.mjs +0 -0
  393. /package/{esm2020 → esm2022}/lib/utils/object.utils.mjs +0 -0
  394. /package/{esm2020 → esm2022}/lib/utils/promise.utils.mjs +0 -0
  395. /package/{esm2020 → esm2022}/lib/utils/public-api.mjs +0 -0
  396. /package/{esm2020 → esm2022}/lib/utils/query-params.utils.mjs +0 -0
  397. /package/{esm2020 → esm2022}/lib/utils/type.utils.mjs +0 -0
  398. /package/{esm2020 → esm2022}/lib/utils/url.utils.mjs +0 -0
  399. /package/{esm2020 → esm2022}/public-api.mjs +0 -0
  400. /package/{esm2020 → esm2022}/recursyve-nice-ui-kit.v2.mjs +0 -0
@@ -0,0 +1,1269 @@
1
+ /**
2
+ * Adapted from https://github.com/A-l-y-l-e/Alyle-UI/tree/10.5.3/src/lib/image-cropper
3
+ */
4
+ import { normalizePassiveListenerOptions } from "@angular/cdk/platform";
5
+ import { ViewportRuler } from "@angular/cdk/scrolling";
6
+ import { DOCUMENT } from "@angular/common";
7
+ import { ChangeDetectionStrategy, ChangeDetectorRef, Component, ElementRef, EventEmitter, HostBinding, Inject, Input, NgZone, Output, Renderer2, ViewChild, ViewEncapsulation } from "@angular/core";
8
+ import { Observable, Subject } from "rxjs";
9
+ import { take, takeUntil } from "rxjs/operators";
10
+ import { resizeCanvas } from "./resize-canvas";
11
+ import * as i0 from "@angular/core";
12
+ import * as i1 from "@angular/cdk/scrolling";
13
+ import * as i2 from "@angular/common";
14
+ import * as i3 from "@angular/material/button";
15
+ import * as i4 from "@angular/material/icon";
16
+ const activeEventOptions = normalizePassiveListenerOptions({ passive: false });
17
+ /** Image Cropper Config */
18
+ export class ImgCropperConfig {
19
+ constructor() {
20
+ /** Cropper area width */
21
+ this.width = 250;
22
+ /** Cropper area height */
23
+ this.height = 200;
24
+ this.minWidth = 40;
25
+ this.minHeight = 40;
26
+ /**
27
+ * Set anti-aliased (default: true)
28
+ * @deprecated this is not necessary as the cropper will automatically resize the image
29
+ * to the best quality
30
+ */
31
+ this.antiAliased = true;
32
+ this.output = ImgResolution.Default;
33
+ }
34
+ }
35
+ /** Image output */
36
+ export var ImgResolution;
37
+ (function (ImgResolution) {
38
+ /**
39
+ * The output image will be equal to the initial size of the cropper area.
40
+ */
41
+ ImgResolution[ImgResolution["Default"] = 0] = "Default";
42
+ /** Just crop the image without resizing */
43
+ ImgResolution[ImgResolution["OriginalImage"] = 1] = "OriginalImage";
44
+ })(ImgResolution || (ImgResolution = {}));
45
+ /** Image output */
46
+ export var ImgCropperError;
47
+ (function (ImgCropperError) {
48
+ /** The loaded image exceeds the size limit set. */
49
+ ImgCropperError[ImgCropperError["Size"] = 0] = "Size";
50
+ /** The file loaded is not image. */
51
+ ImgCropperError[ImgCropperError["Type"] = 1] = "Type";
52
+ /** When the image has not been loaded. */
53
+ ImgCropperError[ImgCropperError["Other"] = 2] = "Other";
54
+ })(ImgCropperError || (ImgCropperError = {}));
55
+ export class NiceImageCropperComponent {
56
+ static { this.и = "NiceImageCropper"; }
57
+ set config(val) {
58
+ this._config = mergeDeep({}, new ImgCropperConfig(), val);
59
+ this._configPrimary = mergeDeep({}, this._config);
60
+ this._primaryAreaWidth = this.config.width;
61
+ this._primaryAreaHeight = this.config.height;
62
+ if (this._config.round
63
+ && this.config.width !== this.config.height) {
64
+ throw new Error(`${NiceImageCropperComponent.и}: Both width and height must be equal when using \`ImgCropperConfig.round = true\``);
65
+ }
66
+ const maxFileSize = this._config.maxFileSize;
67
+ if (maxFileSize) {
68
+ this.maxFileSize = maxFileSize;
69
+ }
70
+ }
71
+ get config() {
72
+ return this._config;
73
+ }
74
+ /** Set scale */
75
+ set scale(val) {
76
+ this.setScale(val);
77
+ }
78
+ get scale() {
79
+ return this._scale;
80
+ }
81
+ /** Get min scale */
82
+ get minScale() {
83
+ return this._minScale;
84
+ }
85
+ constructor(_renderer, _elementRef, cd, _ngZone, _document, viewPortRuler) {
86
+ this._renderer = _renderer;
87
+ this._elementRef = _elementRef;
88
+ this.cd = cd;
89
+ this._ngZone = _ngZone;
90
+ this._imgRect = {};
91
+ this._rotation = 0;
92
+ this.scaleChange = new EventEmitter();
93
+ /** Emits minimum supported image scale */
94
+ // tslint:disable-next-line:no-output-rename
95
+ this.minScaleChange = new EventEmitter();
96
+ /** Emits maximum supported image scale */
97
+ // tslint:disable-next-line:no-output-rename
98
+ this.maxScaleChange = new EventEmitter();
99
+ /** Emits when the image is loaded */
100
+ this.imageLoaded = new EventEmitter();
101
+ /** Emits when the cropper is ready to be interacted */
102
+ this.ready = new EventEmitter();
103
+ /** On crop new image */
104
+ this.cropped = new EventEmitter();
105
+ /** Emits when the cropper is cleaned */
106
+ this.cleaned = new EventEmitter();
107
+ /** Emit an error when the loaded image is not valid */
108
+ // tslint:disable-next-line: no-output-native
109
+ this.error = new EventEmitter();
110
+ /** Emits whenever the component is destroyed. */
111
+ this._destroy = new Subject();
112
+ this._pointerDown = (event) => {
113
+ // Don't do anything if the
114
+ // user is using anything other than the main mouse button.
115
+ if (this._isSliding || (!isTouchEvent(event) && event.button !== 0)) {
116
+ return;
117
+ }
118
+ this._ngZone.run(() => {
119
+ this._isSliding = true;
120
+ this.offset = {
121
+ x: this._imgRect.x,
122
+ y: this._imgRect.y,
123
+ left: this._imgRect.xc,
124
+ top: this._imgRect.yc
125
+ };
126
+ this._lastPointerEvent = event;
127
+ this._startPointerEvent = getGesturePointFromEvent(event);
128
+ event.preventDefault();
129
+ this._bindGlobalEvents(event);
130
+ });
131
+ };
132
+ /**
133
+ * Called when the user has moved their pointer after
134
+ * starting to drag.
135
+ */
136
+ this._pointerMove = (event) => {
137
+ if (this._isSliding) {
138
+ event.preventDefault();
139
+ this._lastPointerEvent = event;
140
+ let x;
141
+ let y;
142
+ const canvas = this._imgCanvas.nativeElement;
143
+ const scaleFix = this._scal3Fix;
144
+ const config = this.config;
145
+ const startP = this.offset;
146
+ const point = getGesturePointFromEvent(event);
147
+ const deltaX = point.x - this._startPointerEvent.x;
148
+ const deltaY = point.y - this._startPointerEvent.y;
149
+ if (!scaleFix || !startP) {
150
+ return;
151
+ }
152
+ const isMinScaleY = canvas.height * scaleFix < config.height && config.extraZoomOut;
153
+ const isMinScaleX = canvas.width * scaleFix < config.width && config.extraZoomOut;
154
+ const limitLeft = (config.width / 2 / scaleFix) >= startP.left - (deltaX / scaleFix);
155
+ const limitRight = (config.width / 2 / scaleFix) +
156
+ (canvas.width) - (startP.left - (deltaX / scaleFix)) <= config.width / scaleFix;
157
+ const limitTop = ((config.height / 2 / scaleFix) >= (startP.top - (deltaY / scaleFix)));
158
+ const limitBottom = (((config.height / 2 / scaleFix) + (canvas.height) - (startP.top - (deltaY / scaleFix))) <= (config.height / scaleFix));
159
+ // Limit for left
160
+ if ((limitLeft && !isMinScaleX) || (!limitLeft && isMinScaleX)) {
161
+ x = startP.x + (startP.left) - (config.width / 2 / scaleFix);
162
+ }
163
+ // Limit for right
164
+ if ((limitRight && !isMinScaleX) || (!limitRight && isMinScaleX)) {
165
+ x = startP.x + (startP.left) + (config.width / 2 / scaleFix) - canvas.width;
166
+ }
167
+ // Limit for top
168
+ if ((limitTop && !isMinScaleY) || (!limitTop && isMinScaleY)) {
169
+ y = startP.y + (startP.top) - (config.height / 2 / scaleFix);
170
+ }
171
+ // Limit for bottom
172
+ if ((limitBottom && !isMinScaleY) || (!limitBottom && isMinScaleY)) {
173
+ y = startP.y + (startP.top) + (config.height / 2 / scaleFix) - canvas.height;
174
+ }
175
+ // When press shiftKey, deprecated
176
+ // if (event.srcEvent && event.srcEvent.shiftKey) {
177
+ // if (Math.abs(event.deltaX) === Math.max(Math.abs(event.deltaX), Math.abs(event.deltaY))) {
178
+ // y = this.offset.top;
179
+ // } else {
180
+ // x = this.offset.left;
181
+ // }
182
+ // }
183
+ if (x === void 0) {
184
+ x = (deltaX / scaleFix) + (startP.x);
185
+ }
186
+ if (y === void 0) {
187
+ y = (deltaY / scaleFix) + (startP.y);
188
+ }
189
+ this._setStylesForContImg({
190
+ x, y
191
+ });
192
+ }
193
+ };
194
+ /** Called when the user has lifted their pointer. */
195
+ this._pointerUp = (event) => {
196
+ if (this._isSliding) {
197
+ event.preventDefault();
198
+ this._removeGlobalEvents();
199
+ this._isSliding = false;
200
+ this._startPointerEvent = null;
201
+ this._cropIfAutoCrop();
202
+ }
203
+ };
204
+ /** Called when the window has lost focus. */
205
+ this._windowBlur = () => {
206
+ // If the window is blurred while dragging we need to stop dragging because the
207
+ // browser won't dispatch the `mouseup` and `touchend` events anymore.
208
+ if (this._lastPointerEvent) {
209
+ this._pointerUp(this._lastPointerEvent);
210
+ }
211
+ };
212
+ this._document = _document;
213
+ viewPortRuler.change()
214
+ .pipe(takeUntil(this._destroy))
215
+ .subscribe(() => this._ngZone.run(() => this.updateCropperPosition()));
216
+ }
217
+ ngOnInit() {
218
+ this._ngZone.runOutsideAngular(() => {
219
+ const element = this._imgContainer.nativeElement;
220
+ element.addEventListener("mousedown", this._pointerDown, activeEventOptions);
221
+ element.addEventListener("touchstart", this._pointerDown, activeEventOptions);
222
+ });
223
+ }
224
+ ngOnDestroy() {
225
+ this._destroy.next();
226
+ this._destroy.complete();
227
+ const element = this._imgContainer.nativeElement;
228
+ this._lastPointerEvent = null;
229
+ this._removeGlobalEvents();
230
+ element.removeEventListener("mousedown", this._pointerDown, activeEventOptions);
231
+ element.removeEventListener("touchstart", this._pointerDown, activeEventOptions);
232
+ }
233
+ /** Load image with canvas */
234
+ _imgLoaded(imgElement) {
235
+ if (imgElement) {
236
+ this._img = imgElement;
237
+ const canvas = this._imgCanvas.nativeElement;
238
+ canvas.width = imgElement.width;
239
+ canvas.height = imgElement.height;
240
+ const ctx = canvas.getContext("2d");
241
+ ctx.clearRect(0, 0, imgElement.width, imgElement.height);
242
+ ctx.drawImage(imgElement, 0, 0);
243
+ /** set min scale */
244
+ this._updateMinScale(canvas);
245
+ this._updateMaxScale();
246
+ }
247
+ }
248
+ _setStylesForContImg(values) {
249
+ const newStyles = {};
250
+ if (values.x != null && values.y != null) {
251
+ const rootRect = this._rootRect();
252
+ const x = rootRect.width / 2 - (values.x);
253
+ const y = rootRect.height / 2 - (values.y);
254
+ this._imgRect.x = (values.x);
255
+ this._imgRect.y = (values.y);
256
+ this._imgRect.xc = (x);
257
+ this._imgRect.yc = (y);
258
+ }
259
+ newStyles.transform = `translate3d(${(this._imgRect.x)}px,${(this._imgRect.y)}px, 0)`;
260
+ newStyles.transform += `scale(${this._scal3Fix})`;
261
+ newStyles.transformOrigin = `${this._imgRect.xc}px ${this._imgRect.yc}px 0`;
262
+ newStyles["-webkit-transform"] = newStyles.transform;
263
+ newStyles["-webkit-transform-origin"] = newStyles.transformOrigin;
264
+ for (const key in newStyles) {
265
+ if (newStyles.hasOwnProperty(key)) {
266
+ this._renderer.setStyle(this._imgContainer.nativeElement, key, newStyles[key]);
267
+ }
268
+ }
269
+ }
270
+ /**
271
+ * Update area and image position only if needed,
272
+ * this is used when window resize
273
+ */
274
+ updateCropperPosition() {
275
+ if (this.isLoaded) {
276
+ this.updatePosition();
277
+ this._updateAreaIfNeeded();
278
+ }
279
+ }
280
+ /** Load Image from input event */
281
+ selectInputEvent(img) {
282
+ this._currentInputElement = img.target;
283
+ const _img = img.target;
284
+ if (_img.files && _img.files.length !== 1) {
285
+ return;
286
+ }
287
+ const fileSize = _img.files[0].size;
288
+ const fileName = _img.value.replace(/.*(\/|\\)/, "");
289
+ if (this.maxFileSize && fileSize > this.maxFileSize) {
290
+ const cropEvent = {
291
+ name: fileName,
292
+ type: _img.files[0].type,
293
+ size: fileSize,
294
+ error: ImgCropperError.Size
295
+ };
296
+ this.clean();
297
+ this.error.emit(cropEvent);
298
+ return;
299
+ }
300
+ new Observable(observer => {
301
+ const reader = new FileReader();
302
+ reader.onerror = err => observer.error(err);
303
+ reader.onabort = err => observer.error(err);
304
+ reader.onload = (ev) => setTimeout(() => {
305
+ observer.next(ev);
306
+ observer.complete();
307
+ });
308
+ reader.readAsDataURL(_img.files[0]);
309
+ })
310
+ .pipe(take(1), takeUntil(this._destroy))
311
+ .subscribe((loadEvent) => {
312
+ const originalDataURL = loadEvent.target.result;
313
+ this.loadImage({
314
+ name: fileName,
315
+ size: _img.files[0].size,
316
+ type: this.config.type || _img.files[0].type,
317
+ originalDataURL
318
+ });
319
+ this.cd.markForCheck();
320
+ }, () => {
321
+ const cropEvent = {
322
+ name: fileName,
323
+ size: fileSize,
324
+ error: ImgCropperError.Other,
325
+ errorMsg: "The File could not be loaded.",
326
+ type: _img.files[0].type
327
+ };
328
+ this.clean();
329
+ this.error.emit(cropEvent);
330
+ });
331
+ }
332
+ /** Set the size of the image, the values can be 0 between 1, where 1 is the original size */
333
+ setScale(size, noAutoCrop) {
334
+ // fix min scale
335
+ const newSize = size >= this.minScale && size <= 1 ? size : this.minScale;
336
+ // check
337
+ const changed = size != null && size !== this.scale && newSize !== this.scale;
338
+ this._scale = size;
339
+ if (!changed) {
340
+ return;
341
+ }
342
+ this._scal3Fix = newSize;
343
+ this._updateAbsoluteScale();
344
+ if (this.isLoaded) {
345
+ if (changed) {
346
+ const originPosition = { ...this._imgRect };
347
+ this.offset = {
348
+ x: originPosition.x,
349
+ y: originPosition.y,
350
+ left: originPosition.xc,
351
+ top: originPosition.yc
352
+ };
353
+ this._setStylesForContImg({});
354
+ this._simulatePointerMove();
355
+ }
356
+ else {
357
+ return;
358
+ }
359
+ }
360
+ else if (this.minScale) {
361
+ this._setStylesForContImg({
362
+ ...this._getCenterPoints()
363
+ });
364
+ }
365
+ else {
366
+ return;
367
+ }
368
+ this.scaleChange.emit(size);
369
+ if (!noAutoCrop) {
370
+ this._cropIfAutoCrop();
371
+ }
372
+ }
373
+ _getCenterPoints() {
374
+ const root = this._elementRef.nativeElement;
375
+ const img = this._imgCanvas.nativeElement;
376
+ const x = (root.offsetWidth - (img.width)) / 2;
377
+ const y = (root.offsetHeight - (img.height)) / 2;
378
+ return {
379
+ x,
380
+ y
381
+ };
382
+ }
383
+ /**
384
+ * Fit to screen
385
+ */
386
+ fitToScreen() {
387
+ const container = this._elementRef.nativeElement;
388
+ const min = {
389
+ width: container.offsetWidth,
390
+ height: container.offsetHeight
391
+ };
392
+ const { width, height } = this._img;
393
+ const minScale = {
394
+ width: min.width / width,
395
+ height: min.height / height
396
+ };
397
+ const result = Math.max(minScale.width, minScale.height);
398
+ this.setScale(result);
399
+ }
400
+ fit() {
401
+ this.setScale(this.minScale);
402
+ }
403
+ /**
404
+ * Simulate pointerMove with clientX = 0 and clientY = 0,
405
+ * this is used by `setScale` and `rotate`
406
+ */
407
+ _simulatePointerMove() {
408
+ this._isSliding = true;
409
+ this._startPointerEvent = {
410
+ x: 0,
411
+ y: 0
412
+ };
413
+ this._pointerMove({
414
+ clientX: 0,
415
+ clientY: 0,
416
+ type: "n",
417
+ preventDefault: () => { }
418
+ });
419
+ this._isSliding = false;
420
+ this._startPointerEvent = null;
421
+ }
422
+ _markForCheck() {
423
+ this.cd.markForCheck();
424
+ }
425
+ updatePosition(xOrigin, yOrigin) {
426
+ const hostRect = this._rootRect();
427
+ const areaRect = this._areaCropperRect();
428
+ const areaWidth = areaRect.width > hostRect.width
429
+ ? hostRect.width
430
+ : areaRect.width;
431
+ const areaHeight = areaRect.height > hostRect.height
432
+ ? hostRect.height
433
+ : areaRect.height;
434
+ let x;
435
+ let y;
436
+ if (xOrigin == null && yOrigin == null) {
437
+ xOrigin = this._imgRect.xc;
438
+ yOrigin = this._imgRect.yc;
439
+ }
440
+ x = (areaRect.left - hostRect.left);
441
+ y = (areaRect.top - hostRect.top);
442
+ x -= (xOrigin - (areaWidth / 2));
443
+ y -= (yOrigin - (areaHeight / 2));
444
+ this._setStylesForContImg({
445
+ x, y
446
+ });
447
+ }
448
+ _slideEnd() {
449
+ this._cropIfAutoCrop();
450
+ }
451
+ _cropIfAutoCrop() {
452
+ if (this.config.autoCrop) {
453
+ this.crop();
454
+ }
455
+ }
456
+ /** + */
457
+ zoomIn() {
458
+ const scale = this._scal3Fix + .05;
459
+ if (scale > this.minScale && scale <= this._maxScale) {
460
+ this.setScale(scale);
461
+ }
462
+ else {
463
+ this.setScale(this._maxScale);
464
+ }
465
+ }
466
+ /** Clean the img cropper */
467
+ clean() {
468
+ // fix choosing the same image does not load
469
+ if (this._currentInputElement) {
470
+ this._currentInputElement.value = "";
471
+ this._currentInputElement = null;
472
+ }
473
+ if (this.isLoaded) {
474
+ this._imgRect = {};
475
+ this.offset = undefined;
476
+ this.scale = undefined;
477
+ this._scal3Fix = undefined;
478
+ this._rotation = 0;
479
+ this._minScale = undefined;
480
+ this._isLoadedImg = false;
481
+ this.isLoaded = false;
482
+ this.isCropped = false;
483
+ this._currentLoadConfig = undefined;
484
+ this.config = this._configPrimary;
485
+ const canvas = this._imgCanvas.nativeElement;
486
+ canvas.width = 0;
487
+ canvas.height = 0;
488
+ this.cleaned.emit(null);
489
+ this.cd.markForCheck();
490
+ }
491
+ }
492
+ /** - */
493
+ zoomOut() {
494
+ const scale = this._scal3Fix - .05;
495
+ if (scale > this.minScale && scale <= this._maxScale) {
496
+ this.setScale(scale);
497
+ }
498
+ else {
499
+ this.fit();
500
+ }
501
+ }
502
+ center() {
503
+ const newStyles = {
504
+ ...this._getCenterPoints()
505
+ };
506
+ this._setStylesForContImg(newStyles);
507
+ this._cropIfAutoCrop();
508
+ }
509
+ /**
510
+ * load an image from a given configuration,
511
+ * or from the result of a cropped image
512
+ */
513
+ loadImage(config, fn) {
514
+ this.clean();
515
+ const _config = this._currentLoadConfig = typeof config === "string"
516
+ ? { originalDataURL: config }
517
+ : { ...config };
518
+ let src = _config.originalDataURL;
519
+ this._primaryAreaWidth = this._configPrimary.width;
520
+ this._primaryAreaHeight = this._configPrimary.height;
521
+ if (_config.areaWidth && _config.areaHeight) {
522
+ this.config.width = _config.areaWidth;
523
+ this.config.height = _config.areaHeight;
524
+ }
525
+ src = normalizeSVG(src);
526
+ const img = createHtmlImg(src);
527
+ const cropEvent = { ..._config };
528
+ new Observable(observer => {
529
+ img.onerror = err => observer.error(err);
530
+ img.onabort = err => observer.error(err);
531
+ img.onload = () => observer.next(null);
532
+ })
533
+ .pipe(take(1), takeUntil(this._destroy))
534
+ .subscribe(() => {
535
+ this._imgLoaded(img);
536
+ this._isLoadedImg = true;
537
+ this.imageLoaded.emit(cropEvent);
538
+ this.cd.markForCheck();
539
+ this._ngZone.runOutsideAngular(() => {
540
+ this._ngZone
541
+ .onStable
542
+ .asObservable()
543
+ .pipe(take(1), takeUntil(this._destroy))
544
+ .subscribe(() => setTimeout(() => this._ngZone.run(() => this._positionImg(cropEvent, fn))));
545
+ });
546
+ }, () => {
547
+ const error = {
548
+ name: _config.name,
549
+ error: ImgCropperError.Type,
550
+ type: _config.type,
551
+ size: _config.size
552
+ };
553
+ this.error.emit(error);
554
+ });
555
+ }
556
+ _updateAreaIfNeeded() {
557
+ if (!this._config.responsiveArea) {
558
+ return;
559
+ }
560
+ const rootRect = this._rootRect();
561
+ const areaRect = this._areaCropperRect();
562
+ const minWidth = this.config.minWidth || 1;
563
+ const minHeight = this.config.minHeight || 1;
564
+ if (!(areaRect.width > rootRect.width
565
+ || areaRect.height > rootRect.height
566
+ || areaRect.width < this._primaryAreaWidth
567
+ || areaRect.height < this._primaryAreaHeight)) {
568
+ return;
569
+ }
570
+ const areaWidthConf = Math.max(this.config.width, minWidth);
571
+ const areaWidthMax = Math.max(rootRect.width, minWidth);
572
+ const minHost = Math.min(Math.max(rootRect.width, minWidth), Math.max(rootRect.height, minHeight));
573
+ const currentScale = this._scal3Fix;
574
+ let newScale = 0;
575
+ const roundConf = this.config.round;
576
+ if (roundConf) {
577
+ this.config.width = this.config.height = minHost;
578
+ }
579
+ else {
580
+ if (areaWidthConf === areaRect.width) {
581
+ if (areaWidthMax > this._primaryAreaWidth) {
582
+ this.config.width = this._primaryAreaWidth;
583
+ this.config.height = (this._primaryAreaWidth * areaRect.height) / areaRect.width;
584
+ newScale = (currentScale * this._primaryAreaWidth) / areaRect.width;
585
+ }
586
+ else {
587
+ this.config.width = areaWidthMax;
588
+ this.config.height = (areaWidthMax * areaRect.height) / areaRect.width;
589
+ newScale = (currentScale * areaWidthMax) / areaRect.width;
590
+ }
591
+ this._updateMinScale();
592
+ this._updateMaxScale();
593
+ this.setScale(newScale, true);
594
+ this._markForCheck();
595
+ }
596
+ }
597
+ }
598
+ _updateAbsoluteScale() {
599
+ const scale = this._scal3Fix / (this.config.width / this._primaryAreaWidth);
600
+ this._absoluteScale = scale;
601
+ }
602
+ /**
603
+ * Load Image from URL
604
+ * @deprecated Use `loadImage` instead of `setImageUrl`
605
+ * @param src URL
606
+ * @param fn function that will be called before emit the event loaded
607
+ */
608
+ setImageUrl(src, fn) {
609
+ this.loadImage(src, fn);
610
+ }
611
+ _positionImg(cropEvent, fn) {
612
+ const loadConfig = this._currentLoadConfig;
613
+ this._updateMinScale(this._imgCanvas.nativeElement);
614
+ this._updateMaxScale();
615
+ this.isLoaded = false;
616
+ if (fn) {
617
+ fn();
618
+ }
619
+ else {
620
+ if (loadConfig.scale) {
621
+ this.setScale(loadConfig.scale, true);
622
+ }
623
+ else {
624
+ this.setScale(this.minScale, true);
625
+ }
626
+ this.rotate(loadConfig.rotation || 0);
627
+ this._updateAreaIfNeeded();
628
+ this._markForCheck();
629
+ this._ngZone.runOutsideAngular(() => {
630
+ this._ngZone
631
+ .onStable
632
+ .asObservable()
633
+ .pipe(take(1), takeUntil(this._destroy))
634
+ .subscribe(() => {
635
+ if (loadConfig.xOrigin != null && loadConfig.yOrigin != null) {
636
+ this.updatePosition(loadConfig.xOrigin, loadConfig.yOrigin);
637
+ }
638
+ this._updateAreaIfNeeded();
639
+ this.isLoaded = true;
640
+ this._cropIfAutoCrop();
641
+ this._ngZone.run(() => {
642
+ this._markForCheck();
643
+ this.ready.emit(cropEvent);
644
+ });
645
+ });
646
+ });
647
+ }
648
+ }
649
+ rotate(degrees) {
650
+ let validDegrees = _normalizeDegrees(degrees);
651
+ // If negative convert to positive
652
+ if (validDegrees < 0) {
653
+ validDegrees += 360;
654
+ }
655
+ const newRotation = _normalizeDegrees((this._rotation || 0) + validDegrees);
656
+ if (newRotation === this._rotation) {
657
+ return;
658
+ }
659
+ const degreesRad = validDegrees * Math.PI / 180;
660
+ const canvas = this._imgCanvas.nativeElement;
661
+ const canvasClon = createCanvasImg(canvas);
662
+ const ctx = canvas.getContext("2d");
663
+ this._rotation = newRotation;
664
+ // clear
665
+ ctx.clearRect(0, 0, canvasClon.width, canvasClon.height);
666
+ // rotate canvas image
667
+ const transform = `rotate(${validDegrees}deg) scale(${1 / this._scal3Fix})`;
668
+ const transformOrigin = `${this._imgRect.xc}px ${this._imgRect.yc}px 0`;
669
+ canvas.style.transform = transform;
670
+ // tslint:disable-next-line: deprecation
671
+ canvas.style.webkitTransform = transform;
672
+ canvas.style.transformOrigin = transformOrigin;
673
+ // tslint:disable-next-line: deprecation
674
+ canvas.style.webkitTransformOrigin = transformOrigin;
675
+ const { left, top } = canvas.getBoundingClientRect();
676
+ // save rect
677
+ const canvasRect = canvas.getBoundingClientRect();
678
+ // remove rotate styles
679
+ canvas.removeAttribute("style");
680
+ // set w & h
681
+ const w = canvasRect.width;
682
+ const h = canvasRect.height;
683
+ ctx.canvas.width = w;
684
+ ctx.canvas.height = h;
685
+ // clear
686
+ ctx.clearRect(0, 0, w, h);
687
+ // translate and rotate
688
+ ctx.translate(w / 2, h / 2);
689
+ ctx.rotate(degreesRad);
690
+ ctx.drawImage(canvasClon, -canvasClon.width / 2, -canvasClon.height / 2);
691
+ // Update min scale
692
+ this._updateMinScale(canvas);
693
+ this._updateMaxScale();
694
+ // set the minimum scale, only if necessary
695
+ if (this.scale < this.minScale) {
696
+ this.setScale(0, true);
697
+ } // ↑ no AutoCrop
698
+ const rootRect = this._rootRect();
699
+ this._setStylesForContImg({
700
+ x: (left - rootRect.left),
701
+ y: (top - rootRect.top)
702
+ });
703
+ // keep image inside the frame
704
+ const originPosition = { ...this._imgRect };
705
+ this.offset = {
706
+ x: originPosition.x,
707
+ y: originPosition.y,
708
+ left: originPosition.xc,
709
+ top: originPosition.yc
710
+ };
711
+ this._setStylesForContImg({});
712
+ this._simulatePointerMove();
713
+ this._cropIfAutoCrop();
714
+ }
715
+ _updateMinScale(canvas) {
716
+ if (!canvas) {
717
+ canvas = this._imgCanvas.nativeElement;
718
+ }
719
+ const config = this.config;
720
+ const minScale = (config.extraZoomOut ? Math.min : Math.max)(config.width / canvas.width, config.height / canvas.height);
721
+ this._minScale = minScale;
722
+ this.minScaleChange.emit(minScale);
723
+ }
724
+ _updateMaxScale() {
725
+ const maxScale = (this.config.width / this._primaryAreaWidth);
726
+ this._maxScale = maxScale;
727
+ this.maxScaleChange.emit(maxScale);
728
+ }
729
+ /**
730
+ * Resize & crop image
731
+ */
732
+ crop(config) {
733
+ const newConfig = config
734
+ ? mergeDeep({}, this.config || new ImgCropperConfig(), config) : this.config;
735
+ const cropEvent = this._imgCrop(newConfig);
736
+ this.cd.markForCheck();
737
+ return cropEvent;
738
+ }
739
+ /**
740
+ * @docs-private
741
+ */
742
+ _imgCrop(myConfig) {
743
+ const canvasElement = document.createElement("canvas");
744
+ const areaRect = this._areaCropperRect();
745
+ const canvasRect = this._canvasRect();
746
+ const scaleFix = this._scal3Fix;
747
+ const left = (areaRect.left - canvasRect.left) / scaleFix;
748
+ const top = (areaRect.top - canvasRect.top) / scaleFix;
749
+ const { output } = myConfig;
750
+ const currentImageLoadConfig = this._currentLoadConfig;
751
+ const area = {
752
+ width: myConfig.width,
753
+ height: myConfig.height
754
+ };
755
+ canvasElement.width = area.width / scaleFix;
756
+ canvasElement.height = area.height / scaleFix;
757
+ const ctx = canvasElement.getContext("2d");
758
+ if (myConfig.fill) {
759
+ ctx.fillStyle = myConfig.fill;
760
+ ctx.fillRect(0, 0, canvasElement.width, canvasElement.height);
761
+ }
762
+ ctx.drawImage(this._imgCanvas.nativeElement, -(left), -(top));
763
+ const result = canvasElement;
764
+ if (myConfig.output === ImgResolution.Default) {
765
+ resizeCanvas(result, this._configPrimary.width, this._configPrimary.height);
766
+ }
767
+ else if (typeof output === "object") {
768
+ if (output.width && output.height) {
769
+ resizeCanvas(result, output.width, output.height);
770
+ }
771
+ else if (output.width) {
772
+ const newHeight = area.height * output.width / area.width;
773
+ resizeCanvas(result, output.width, newHeight);
774
+ }
775
+ else if (output.height) {
776
+ const newWidth = area.width * output.height / area.height;
777
+ resizeCanvas(result, newWidth, output.height);
778
+ }
779
+ }
780
+ const type = currentImageLoadConfig.originalDataURL.startsWith("http")
781
+ ? currentImageLoadConfig.type || myConfig.type
782
+ : myConfig.type || currentImageLoadConfig.type;
783
+ const dataURL = result.toDataURL(type);
784
+ const cropEvent = {
785
+ dataURL,
786
+ type,
787
+ name: currentImageLoadConfig.name,
788
+ areaWidth: this._primaryAreaWidth,
789
+ areaHeight: this._primaryAreaHeight,
790
+ width: result.width,
791
+ height: result.height,
792
+ originalDataURL: currentImageLoadConfig.originalDataURL,
793
+ scale: this._absoluteScale,
794
+ rotation: this._rotation,
795
+ left: (areaRect.left - canvasRect.left) / this._scal3Fix,
796
+ top: (areaRect.top - canvasRect.top) / this._scal3Fix,
797
+ size: currentImageLoadConfig.size,
798
+ xOrigin: this._imgRect.xc,
799
+ yOrigin: this._imgRect.yc,
800
+ position: {
801
+ x: this._imgRect.xc,
802
+ y: this._imgRect.yc
803
+ }
804
+ };
805
+ this.isCropped = true;
806
+ this.cropped.emit(cropEvent);
807
+ return cropEvent;
808
+ }
809
+ _rootRect() {
810
+ return this._elementRef.nativeElement.getBoundingClientRect();
811
+ }
812
+ _areaCropperRect() {
813
+ return this._areaRef.nativeElement.getBoundingClientRect();
814
+ }
815
+ _canvasRect() {
816
+ return this._imgCanvas.nativeElement.getBoundingClientRect();
817
+ }
818
+ _bindGlobalEvents(triggerEvent) {
819
+ const element = this._document;
820
+ const isTouch = isTouchEvent(triggerEvent);
821
+ const moveEventName = isTouch ? "touchmove" : "mousemove";
822
+ const endEventName = isTouch ? "touchend" : "mouseup";
823
+ element.addEventListener(moveEventName, this._pointerMove, activeEventOptions);
824
+ element.addEventListener(endEventName, this._pointerUp, activeEventOptions);
825
+ if (isTouch) {
826
+ element.addEventListener("touchcancel", this._pointerUp, activeEventOptions);
827
+ }
828
+ const window = this._getWindow();
829
+ if (typeof window !== "undefined" && window) {
830
+ window.addEventListener("blur", this._windowBlur);
831
+ }
832
+ }
833
+ /** Removes any global event listeners that we may have added. */
834
+ _removeGlobalEvents() {
835
+ const element = this._document;
836
+ element.removeEventListener("mousemove", this._pointerMove, activeEventOptions);
837
+ element.removeEventListener("mouseup", this._pointerUp, activeEventOptions);
838
+ element.removeEventListener("touchmove", this._pointerMove, activeEventOptions);
839
+ element.removeEventListener("touchend", this._pointerUp, activeEventOptions);
840
+ element.removeEventListener("touchcancel", this._pointerUp, activeEventOptions);
841
+ const window = this._getWindow();
842
+ if (typeof window !== "undefined" && window) {
843
+ window.removeEventListener("blur", this._windowBlur);
844
+ }
845
+ }
846
+ /** Use defaultView of injected document if available or fallback to global window reference */
847
+ _getWindow() {
848
+ return this._document.defaultView || window;
849
+ }
850
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.0.5", ngImport: i0, type: NiceImageCropperComponent, deps: [{ token: i0.Renderer2 }, { token: i0.ElementRef }, { token: i0.ChangeDetectorRef }, { token: i0.NgZone }, { token: DOCUMENT }, { token: i1.ViewportRuler }], target: i0.ɵɵFactoryTarget.Component }); }
851
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.0.5", type: NiceImageCropperComponent, selector: "nice-img-cropper, nice-image-cropper", inputs: { config: "config", scale: "scale", maxFileSize: "maxFileSize" }, outputs: { scaleChange: "scaleChange", minScaleChange: "minScale", maxScaleChange: "maxScale", imageLoaded: "imageLoaded", ready: "ready", cropped: "cropped", cleaned: "cleaned", error: "error" }, viewQueries: [{ propertyName: "_imgContainer", first: true, predicate: ["_imgContainer"], descendants: true, static: true }, { propertyName: "_areaRef", first: true, predicate: ["_area"], descendants: true, read: ElementRef }, { propertyName: "_imgCanvas", first: true, predicate: ["_imgCanvas"], descendants: true, static: true }], ngImport: i0, template: "<!-- (selectstart): On Safari starting to slide temporarily triggers text selection mode which\nshow the wrong cursor. We prevent it by stopping the `selectstart` event. -->\n<div class=\"image-container\" #_imgContainer\n (selectstart)=\"$event.preventDefault()\"\n>\n <canvas #_imgCanvas></canvas>\n</div>\n<nice-cropper-area\n #_area\n *ngIf=\"_isLoadedImg\"\n [round]=\"!!config.round\"\n [resizableArea]=\"!!config.resizableArea\"\n [keepAspectRatio]=\"!!config.keepAspectRatio\"\n [ngStyle]=\"{\n width: config.width + 'px',\n height: config.height + 'px'\n }\"\n></nice-cropper-area>\n<button class=\"close-button\" mat-icon-button *ngIf=\"_isLoadedImg\" (click)=\"clean()\">\n <mat-icon>arrow_back</mat-icon>\n</button>\n", styles: ["nice-image-cropper,nice-img-cropper{-webkit-user-select:none;user-select:none;display:flex;overflow:hidden;position:relative;justify-content:center;align-items:center}nice-image-cropper .image-container,nice-img-cropper .image-container{cursor:move;position:absolute;top:0;left:0;display:flex;touch-action:none}nice-image-cropper .image-container>canvas,nice-img-cropper .image-container>canvas{display:block}nice-image-cropper .close-button,nice-img-cropper .close-button{position:absolute;top:8px;left:8px;background-color:#fff!important;border-radius:4px;height:20px;width:20px;min-height:20px}nice-image-cropper .close-button .mat-icon,nice-img-cropper .close-button .mat-icon{height:14px!important;width:14px!important;font-size:14px!important;line-height:14px!important}\n"], dependencies: [{ kind: "directive", type: i0.forwardRef(function () { return i2.NgIf; }), selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i0.forwardRef(function () { return i2.NgStyle; }), selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "component", type: i0.forwardRef(function () { return i3.MatIconButton; }), selector: "button[mat-icon-button]", inputs: ["disabled", "disableRipple", "color"], exportAs: ["matButton"] }, { kind: "component", type: i0.forwardRef(function () { return i4.MatIcon; }), selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: i0.forwardRef(function () { return NiceCropperAreaComponent; }), selector: "nice-cropper-area", inputs: ["keepAspectRatio", "round", "resizableArea"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
852
+ }
853
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.0.5", ngImport: i0, type: NiceImageCropperComponent, decorators: [{
854
+ type: Component,
855
+ args: [{ changeDetection: ChangeDetectionStrategy.OnPush, preserveWhitespaces: false, selector: "nice-img-cropper, nice-image-cropper", encapsulation: ViewEncapsulation.None, template: "<!-- (selectstart): On Safari starting to slide temporarily triggers text selection mode which\nshow the wrong cursor. We prevent it by stopping the `selectstart` event. -->\n<div class=\"image-container\" #_imgContainer\n (selectstart)=\"$event.preventDefault()\"\n>\n <canvas #_imgCanvas></canvas>\n</div>\n<nice-cropper-area\n #_area\n *ngIf=\"_isLoadedImg\"\n [round]=\"!!config.round\"\n [resizableArea]=\"!!config.resizableArea\"\n [keepAspectRatio]=\"!!config.keepAspectRatio\"\n [ngStyle]=\"{\n width: config.width + 'px',\n height: config.height + 'px'\n }\"\n></nice-cropper-area>\n<button class=\"close-button\" mat-icon-button *ngIf=\"_isLoadedImg\" (click)=\"clean()\">\n <mat-icon>arrow_back</mat-icon>\n</button>\n", styles: ["nice-image-cropper,nice-img-cropper{-webkit-user-select:none;user-select:none;display:flex;overflow:hidden;position:relative;justify-content:center;align-items:center}nice-image-cropper .image-container,nice-img-cropper .image-container{cursor:move;position:absolute;top:0;left:0;display:flex;touch-action:none}nice-image-cropper .image-container>canvas,nice-img-cropper .image-container>canvas{display:block}nice-image-cropper .close-button,nice-img-cropper .close-button{position:absolute;top:8px;left:8px;background-color:#fff!important;border-radius:4px;height:20px;width:20px;min-height:20px}nice-image-cropper .close-button .mat-icon,nice-img-cropper .close-button .mat-icon{height:14px!important;width:14px!important;font-size:14px!important;line-height:14px!important}\n"] }]
856
+ }], ctorParameters: function () { return [{ type: i0.Renderer2 }, { type: i0.ElementRef }, { type: i0.ChangeDetectorRef }, { type: i0.NgZone }, { type: undefined, decorators: [{
857
+ type: Inject,
858
+ args: [DOCUMENT]
859
+ }] }, { type: i1.ViewportRuler }]; }, propDecorators: { _imgContainer: [{
860
+ type: ViewChild,
861
+ args: ["_imgContainer", { static: true }]
862
+ }], _areaRef: [{
863
+ type: ViewChild,
864
+ args: ["_area", { read: ElementRef }]
865
+ }], _imgCanvas: [{
866
+ type: ViewChild,
867
+ args: ["_imgCanvas", { static: true }]
868
+ }], config: [{
869
+ type: Input
870
+ }], scale: [{
871
+ type: Input
872
+ }], maxFileSize: [{
873
+ type: Input
874
+ }], scaleChange: [{
875
+ type: Output
876
+ }], minScaleChange: [{
877
+ type: Output,
878
+ args: ["minScale"]
879
+ }], maxScaleChange: [{
880
+ type: Output,
881
+ args: ["maxScale"]
882
+ }], imageLoaded: [{
883
+ type: Output
884
+ }], ready: [{
885
+ type: Output
886
+ }], cropped: [{
887
+ type: Output
888
+ }], cleaned: [{
889
+ type: Output
890
+ }], error: [{
891
+ type: Output
892
+ }] } });
893
+ /**
894
+ * Normalize degrees for cropper rotation
895
+ * @docs-private
896
+ */
897
+ export function _normalizeDegrees(n) {
898
+ const de = n % 360;
899
+ if (de % 90) {
900
+ throw new Error(`LyCropper: Invalid \`${n}\` degree, only accepted values: 0, 90, 180, 270 & 360.`);
901
+ }
902
+ return de;
903
+ }
904
+ /**
905
+ * @docs-private
906
+ */
907
+ function createCanvasImg(img) {
908
+ // create a new canvas
909
+ const newCanvas = document.createElement("canvas");
910
+ const context = newCanvas.getContext("2d");
911
+ // set dimensions
912
+ newCanvas.width = img.width;
913
+ newCanvas.height = img.height;
914
+ // apply the old canvas to the new one
915
+ context.drawImage(img, 0, 0);
916
+ // return the new canvas
917
+ return newCanvas;
918
+ }
919
+ const DATA_IMAGE_SVG_PREFIX = "data:image/svg+xml;base64,";
920
+ function normalizeSVG(dataURL) {
921
+ if (window.atob && isSvgImage(dataURL)) {
922
+ const len = dataURL.length / 5;
923
+ const text = window.atob(dataURL.replace(DATA_IMAGE_SVG_PREFIX, ""));
924
+ const span = document.createElement("span");
925
+ span.innerHTML = text;
926
+ const svg = span.querySelector("svg");
927
+ span.setAttribute("style", "display:none");
928
+ document.body.appendChild(span);
929
+ const width = parseFloat(getComputedStyle(svg).width) || 1;
930
+ const height = parseFloat(getComputedStyle(svg).height) || 1;
931
+ const max = Math.max(width, height);
932
+ svg.setAttribute("width", `${len / (width / max)}px`);
933
+ svg.setAttribute("height", `${len / (height / max)}px`);
934
+ const result = DATA_IMAGE_SVG_PREFIX + window.btoa(span.innerHTML);
935
+ document.body.removeChild(span);
936
+ return result;
937
+ }
938
+ return dataURL;
939
+ }
940
+ function isSvgImage(dataUrl) {
941
+ return dataUrl.startsWith(DATA_IMAGE_SVG_PREFIX);
942
+ }
943
+ function createHtmlImg(src) {
944
+ const img = new Image();
945
+ img.crossOrigin = "anonymous";
946
+ img.src = src;
947
+ return img;
948
+ }
949
+ function getGesturePointFromEvent(event) {
950
+ // `touches` will be empty for start/end events so we have to fall back to `changedTouches`.
951
+ const point = isTouchEvent(event)
952
+ ? (event.touches[0] || event.changedTouches[0])
953
+ : event;
954
+ return {
955
+ x: point.clientX,
956
+ y: point.clientY
957
+ };
958
+ }
959
+ /** Returns whether an event is a touch event. */
960
+ function isTouchEvent(event) {
961
+ return event.type[0] === "t";
962
+ }
963
+ export function round(n) {
964
+ return Math.round(n);
965
+ }
966
+ /**
967
+ * Simple object check.
968
+ * @param item
969
+ */
970
+ function isObject(item) {
971
+ return (item && typeof item === "object" && !Array.isArray(item));
972
+ }
973
+ /**
974
+ * Deep merge two objects.
975
+ * @param target
976
+ * @param ...sources
977
+ */
978
+ export function mergeDeep(target, ...sources) {
979
+ if (!sources.length) {
980
+ return target;
981
+ }
982
+ const source = sources.shift();
983
+ if (isObject(target) && isObject(source)) {
984
+ for (const key in source) {
985
+ if (isObject(source[key])) {
986
+ if (!target[key]) {
987
+ Object.assign(target, { [key]: {} });
988
+ }
989
+ mergeDeep(target[key], source[key]);
990
+ }
991
+ else {
992
+ Object.assign(target, { [key]: source[key] });
993
+ }
994
+ }
995
+ }
996
+ return mergeDeep(target, ...sources);
997
+ }
998
+ /**
999
+ * We have the cropper area in the same file to fix the build
1000
+ */
1001
+ export class NiceCropperAreaComponent {
1002
+ constructor(_document, _elementRef, _cropper, _ngZone) {
1003
+ this._elementRef = _elementRef;
1004
+ this._cropper = _cropper;
1005
+ this._ngZone = _ngZone;
1006
+ this._pointerDown = (event) => {
1007
+ // Don't do anything if the
1008
+ // user is using anything other than the main mouse button.
1009
+ if (this._isSliding || (!isTouchEvent(event) && event.button !== 0)) {
1010
+ return;
1011
+ }
1012
+ event.preventDefault();
1013
+ this._ngZone.run(() => {
1014
+ this._isSliding = true;
1015
+ this._lastPointerEvent = event;
1016
+ this._startPointerEvent = getGesturePointFromEvent(event);
1017
+ this._startAreaRect = this._cropper._areaCropperRect();
1018
+ this._startImgRect = this._cropper._canvasRect();
1019
+ event.preventDefault();
1020
+ this._bindGlobalEvents(event);
1021
+ });
1022
+ };
1023
+ this._pointerMove = (event) => {
1024
+ if (this._isSliding) {
1025
+ event.preventDefault();
1026
+ this._lastPointerEvent = event;
1027
+ const element = this._elementRef.nativeElement;
1028
+ const { width, height, minWidth, minHeight } = this._cropper.config;
1029
+ const point = getGesturePointFromEvent(event);
1030
+ const deltaX = point.x - this._startPointerEvent.x;
1031
+ const deltaY = point.y - this._startPointerEvent.y;
1032
+ const startAreaRect = this._startAreaRect;
1033
+ const startImgRect = this._startImgRect;
1034
+ const isRound = this.round;
1035
+ const keepAspectRatio = this._cropper.config.keepAspectRatio || event.shiftKey;
1036
+ let newWidth = 0;
1037
+ let newHeight = 0;
1038
+ const rootRect = this._cropper._rootRect();
1039
+ if (isRound) {
1040
+ // The distance from the center of the cropper area to the pointer
1041
+ const originX = ((width / 2 / Math.sqrt(2)) + deltaX);
1042
+ const originY = ((height / 2 / Math.sqrt(2)) + deltaY);
1043
+ // Leg
1044
+ const side = Math.sqrt(originX ** 2 + originY ** 2);
1045
+ newWidth = newHeight = side * 2;
1046
+ }
1047
+ else if (keepAspectRatio) {
1048
+ newWidth = width + deltaX * 2;
1049
+ newHeight = height + deltaY * 2;
1050
+ if (width !== height) {
1051
+ if (width > height) {
1052
+ newHeight = height / (width / newWidth);
1053
+ }
1054
+ else if (height > width) {
1055
+ newWidth = width / (height / newHeight);
1056
+ }
1057
+ }
1058
+ else {
1059
+ newWidth = newHeight = Math.max(newWidth, newHeight);
1060
+ }
1061
+ }
1062
+ else {
1063
+ newWidth = width + deltaX * 2;
1064
+ newHeight = height + deltaY * 2;
1065
+ }
1066
+ // To min width
1067
+ if (newWidth < minWidth) {
1068
+ newWidth = minWidth;
1069
+ }
1070
+ // To min height
1071
+ if (newHeight < minHeight) {
1072
+ newHeight = minHeight;
1073
+ }
1074
+ // Do not overflow the cropper area
1075
+ const centerX = startAreaRect.x + startAreaRect.width / 2;
1076
+ const centerY = startAreaRect.y + startAreaRect.height / 2;
1077
+ const topOverflow = startImgRect.y > centerY - (newHeight / 2);
1078
+ const bottomOverflow = centerY + (newHeight / 2) > startImgRect.bottom;
1079
+ const minHeightOnOverflow = Math.min((centerY - startImgRect.y) * 2, (startImgRect.bottom - centerY) * 2);
1080
+ const leftOverflow = startImgRect.x > centerX - (newWidth / 2);
1081
+ const rightOverflow = centerX + (newWidth / 2) > startImgRect.right;
1082
+ const minWidthOnOverflow = Math.min((centerX - startImgRect.x) * 2, (startImgRect.right - centerX) * 2);
1083
+ const minOnOverflow = Math.min(minWidthOnOverflow, minHeightOnOverflow);
1084
+ if (round) {
1085
+ if (topOverflow || bottomOverflow || leftOverflow || rightOverflow) {
1086
+ newHeight = newWidth = minOnOverflow;
1087
+ }
1088
+ }
1089
+ else if (keepAspectRatio) {
1090
+ const newNewWidth = [];
1091
+ const newNewHeight = [];
1092
+ if ((topOverflow || bottomOverflow) && Math.min()) {
1093
+ newHeight = minHeightOnOverflow;
1094
+ newNewHeight.push(newHeight);
1095
+ newWidth = width / (height / minHeightOnOverflow);
1096
+ newNewWidth.push(newWidth);
1097
+ }
1098
+ if ((leftOverflow || rightOverflow)) {
1099
+ newWidth = minWidthOnOverflow;
1100
+ newNewWidth.push(newWidth);
1101
+ newHeight = height / (width / minWidthOnOverflow);
1102
+ newNewHeight.push(newHeight);
1103
+ }
1104
+ if (newNewWidth.length === 2) {
1105
+ newWidth = Math.min(...newNewWidth);
1106
+ }
1107
+ if (newNewHeight.length === 2) {
1108
+ newHeight = Math.min(...newNewHeight);
1109
+ }
1110
+ }
1111
+ else {
1112
+ if (topOverflow || bottomOverflow) {
1113
+ newHeight = minHeightOnOverflow;
1114
+ }
1115
+ if (leftOverflow || rightOverflow) {
1116
+ newWidth = minWidthOnOverflow;
1117
+ }
1118
+ }
1119
+ // Do not overflow the container
1120
+ if (round) {
1121
+ const min = Math.min(rootRect.width, rootRect.height);
1122
+ if (newWidth > min) {
1123
+ newWidth = newHeight = min;
1124
+ }
1125
+ else if (newHeight > min) {
1126
+ newWidth = newHeight = min;
1127
+ }
1128
+ }
1129
+ else if (keepAspectRatio) {
1130
+ if (newWidth > rootRect.width) {
1131
+ newWidth = rootRect.width;
1132
+ newHeight = height / (width / rootRect.width);
1133
+ }
1134
+ else if (newHeight > rootRect.height) {
1135
+ newWidth = width / (height / rootRect.height);
1136
+ newHeight = rootRect.height;
1137
+ }
1138
+ }
1139
+ else {
1140
+ if (newWidth > rootRect.width) {
1141
+ newWidth = rootRect.width;
1142
+ }
1143
+ else if (newHeight > rootRect.height) {
1144
+ newHeight = rootRect.height;
1145
+ }
1146
+ }
1147
+ // round values
1148
+ newWidth = Math.round(newWidth);
1149
+ newHeight = Math.round(newHeight);
1150
+ element.style.width = `${newWidth}px`;
1151
+ element.style.height = `${newHeight}px`;
1152
+ this._currentWidth = newWidth;
1153
+ this._currentHeight = newHeight;
1154
+ }
1155
+ };
1156
+ /** Called when the user has lifted their pointer. */
1157
+ this._pointerUp = (event) => {
1158
+ if (this._isSliding) {
1159
+ event.preventDefault();
1160
+ this._removeGlobalEvents();
1161
+ this._cropper._primaryAreaWidth = this._cropper.config.width = this._currentWidth;
1162
+ this._cropper._primaryAreaHeight = this._cropper.config.height = this._currentHeight;
1163
+ this._cropper.config = this._cropper.config;
1164
+ this._cropper._updateMinScale();
1165
+ this._isSliding = false;
1166
+ this._startPointerEvent = null;
1167
+ }
1168
+ };
1169
+ /** Called when the window has lost focus. */
1170
+ this._windowBlur = () => {
1171
+ // If the window is blurred while dragging we need to stop dragging because the
1172
+ // browser won't dispatch the `mouseup` and `touchend` events anymore.
1173
+ if (this._lastPointerEvent) {
1174
+ this._pointerUp(this._lastPointerEvent);
1175
+ }
1176
+ };
1177
+ this._document = _document;
1178
+ }
1179
+ set resizableArea(val) {
1180
+ if (val !== this._resizableArea) {
1181
+ this._resizableArea = val;
1182
+ Promise.resolve(null).then(() => {
1183
+ if (val) {
1184
+ this._removeResizableArea();
1185
+ this._addResizableArea();
1186
+ }
1187
+ else {
1188
+ this._removeResizableArea();
1189
+ }
1190
+ });
1191
+ }
1192
+ }
1193
+ get resizableArea() {
1194
+ return this._resizableArea;
1195
+ }
1196
+ ngOnDestroy() {
1197
+ this._removeResizableArea();
1198
+ }
1199
+ _addResizableArea() {
1200
+ this._ngZone.runOutsideAngular(() => {
1201
+ const element = this._resizer.nativeElement;
1202
+ element.addEventListener("mousedown", this._pointerDown, activeEventOptions);
1203
+ element.addEventListener("touchstart", this._pointerDown, activeEventOptions);
1204
+ });
1205
+ }
1206
+ _removeResizableArea() {
1207
+ const element = this._resizer?.nativeElement;
1208
+ if (element) {
1209
+ this._lastPointerEvent = null;
1210
+ this._removeGlobalEvents();
1211
+ element.removeEventListener("mousedown", this._pointerDown, activeEventOptions);
1212
+ element.removeEventListener("touchstart", this._pointerDown, activeEventOptions);
1213
+ }
1214
+ }
1215
+ _bindGlobalEvents(triggerEvent) {
1216
+ const element = this._document;
1217
+ const isTouch = isTouchEvent(triggerEvent);
1218
+ const moveEventName = isTouch ? "touchmove" : "mousemove";
1219
+ const endEventName = isTouch ? "touchend" : "mouseup";
1220
+ element.addEventListener(moveEventName, this._pointerMove, activeEventOptions);
1221
+ element.addEventListener(endEventName, this._pointerUp, activeEventOptions);
1222
+ if (isTouch) {
1223
+ element.addEventListener("touchcancel", this._pointerUp, activeEventOptions);
1224
+ }
1225
+ const window = this._getWindow();
1226
+ if (typeof window !== "undefined" && window) {
1227
+ window.addEventListener("blur", this._windowBlur);
1228
+ }
1229
+ }
1230
+ /** Removes any global event listeners that we may have added. */
1231
+ _removeGlobalEvents() {
1232
+ const element = this._document;
1233
+ element.removeEventListener("mousemove", this._pointerMove, activeEventOptions);
1234
+ element.removeEventListener("mouseup", this._pointerUp, activeEventOptions);
1235
+ element.removeEventListener("touchmove", this._pointerMove, activeEventOptions);
1236
+ element.removeEventListener("touchend", this._pointerUp, activeEventOptions);
1237
+ element.removeEventListener("touchcancel", this._pointerUp, activeEventOptions);
1238
+ const window = this._getWindow();
1239
+ if (typeof window !== "undefined" && window) {
1240
+ window.removeEventListener("blur", this._windowBlur);
1241
+ }
1242
+ }
1243
+ /** Use defaultView of injected document if available or fallback to global window reference */
1244
+ _getWindow() {
1245
+ return this._document.defaultView || window;
1246
+ }
1247
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.0.5", ngImport: i0, type: NiceCropperAreaComponent, deps: [{ token: DOCUMENT }, { token: i0.ElementRef }, { token: NiceImageCropperComponent }, { token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Component }); }
1248
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.0.5", type: NiceCropperAreaComponent, selector: "nice-cropper-area", inputs: { keepAspectRatio: "keepAspectRatio", round: "round", resizableArea: "resizableArea" }, host: { properties: { "class.round": "this.round" } }, viewQueries: [{ propertyName: "_resizer", first: true, predicate: ["resizer"], descendants: true }], ngImport: i0, template: "<div class=\"resizer\" #resizer *ngIf=\"resizableArea\"></div>\n", styles: ["nice-cropper-area{pointer-events:none;box-shadow:0 0 0 20000px #0006;margin:auto;position:absolute;inset:0}nice-cropper-area.round{border-radius:50%}nice-cropper-area:before,nice-cropper-area:after{position:absolute;inset:0;content:\"\"}nice-cropper-area:before{width:0;height:0;margin:auto;border-radius:50%;background:#fff;border:solid 2px rgb(255,255,255)}nice-cropper-area:after{border:solid 2px rgb(255,255,255);border-radius:inherit}nice-cropper-area .resizer{width:10px;height:10px;background:#fff;border-radius:3px;position:absolute;touch-action:none;bottom:0;pointer-events:all}nice-cropper-area .resizer:before{content:\"\";width:20px;height:20px;transform:translate(-25%,-25%)}\n"], dependencies: [{ kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
1249
+ }
1250
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.0.5", ngImport: i0, type: NiceCropperAreaComponent, decorators: [{
1251
+ type: Component,
1252
+ args: [{ selector: "nice-cropper-area", encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"resizer\" #resizer *ngIf=\"resizableArea\"></div>\n", styles: ["nice-cropper-area{pointer-events:none;box-shadow:0 0 0 20000px #0006;margin:auto;position:absolute;inset:0}nice-cropper-area.round{border-radius:50%}nice-cropper-area:before,nice-cropper-area:after{position:absolute;inset:0;content:\"\"}nice-cropper-area:before{width:0;height:0;margin:auto;border-radius:50%;background:#fff;border:solid 2px rgb(255,255,255)}nice-cropper-area:after{border:solid 2px rgb(255,255,255);border-radius:inherit}nice-cropper-area .resizer{width:10px;height:10px;background:#fff;border-radius:3px;position:absolute;touch-action:none;bottom:0;pointer-events:all}nice-cropper-area .resizer:before{content:\"\";width:20px;height:20px;transform:translate(-25%,-25%)}\n"] }]
1253
+ }], ctorParameters: function () { return [{ type: undefined, decorators: [{
1254
+ type: Inject,
1255
+ args: [DOCUMENT]
1256
+ }] }, { type: i0.ElementRef }, { type: NiceImageCropperComponent }, { type: i0.NgZone }]; }, propDecorators: { _resizer: [{
1257
+ type: ViewChild,
1258
+ args: ["resizer"]
1259
+ }], keepAspectRatio: [{
1260
+ type: Input
1261
+ }], round: [{
1262
+ type: Input
1263
+ }, {
1264
+ type: HostBinding,
1265
+ args: ["class.round"]
1266
+ }], resizableArea: [{
1267
+ type: Input
1268
+ }] } });
1269
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW1hZ2UtY3JvcHBlci5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9uaWNlLXVpLWtpdC12Mi9zcmMvbGliL2NvbXBvbmVudHMvaW1hZ2UtY3JvcHBlci9pbWFnZS1jcm9wcGVyLmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL25pY2UtdWkta2l0LXYyL3NyYy9saWIvY29tcG9uZW50cy9pbWFnZS1jcm9wcGVyL2ltYWdlLWNyb3BwZXIudGVtcGxhdGUuaHRtbCIsIi4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL25pY2UtdWkta2l0LXYyL3NyYy9saWIvY29tcG9uZW50cy9pbWFnZS1jcm9wcGVyL2ltYWdlLWNyb3BwZXItYXJlYS50ZW1wbGF0ZS5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOztHQUVHO0FBRUgsT0FBTyxFQUFFLCtCQUErQixFQUFFLE1BQU0sdUJBQXVCLENBQUM7QUFDeEUsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLHdCQUF3QixDQUFDO0FBQ3ZELE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUMzQyxPQUFPLEVBQ0gsdUJBQXVCLEVBQ3ZCLGlCQUFpQixFQUNqQixTQUFTLEVBQ1QsVUFBVSxFQUNWLFlBQVksRUFBRSxXQUFXLEVBQ3pCLE1BQU0sRUFDTixLQUFLLEVBQ0wsTUFBTSxFQUdOLE1BQU0sRUFDTixTQUFTLEVBQ1QsU0FBUyxFQUNULGlCQUFpQixFQUNwQixNQUFNLGVBQWUsQ0FBQztBQUN2QixPQUFPLEVBQUUsVUFBVSxFQUFFLE9BQU8sRUFBRSxNQUFNLE1BQU0sQ0FBQztBQUMzQyxPQUFPLEVBQUUsSUFBSSxFQUFFLFNBQVMsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBQ2pELE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQzs7Ozs7O0FBRS9DLE1BQU0sa0JBQWtCLEdBQUcsK0JBQStCLENBQUMsRUFBRSxPQUFPLEVBQUUsS0FBSyxFQUFFLENBQUMsQ0FBQztBQUUvRSwyQkFBMkI7QUFDM0IsTUFBTSxPQUFPLGdCQUFnQjtJQUE3QjtRQUNJLHlCQUF5QjtRQUN6QixVQUFLLEdBQUcsR0FBRyxDQUFDO1FBQ1osMEJBQTBCO1FBQzFCLFdBQU0sR0FBRyxHQUFHLENBQUM7UUFDYixhQUFRLEdBQUcsRUFBRSxDQUFDO1FBQ2QsY0FBUyxHQUFHLEVBQUUsQ0FBQztRQUtmOzs7O1dBSUc7UUFDSCxnQkFBVyxHQUFHLElBQUksQ0FBQztRQUVuQixXQUFNLEdBQStCLGFBQWEsQ0FBQyxPQUFPLENBQUM7SUFtQy9ELENBQUM7Q0FBQTtBQW1CRCxtQkFBbUI7QUFDbkIsTUFBTSxDQUFOLElBQVksYUFPWDtBQVBELFdBQVksYUFBYTtJQUNyQjs7T0FFRztJQUNILHVEQUFPLENBQUE7SUFDUCwyQ0FBMkM7SUFDM0MsbUVBQWEsQ0FBQTtBQUNqQixDQUFDLEVBUFcsYUFBYSxLQUFiLGFBQWEsUUFPeEI7QUFFRCxtQkFBbUI7QUFDbkIsTUFBTSxDQUFOLElBQVksZUFPWDtBQVBELFdBQVksZUFBZTtJQUN2QixtREFBbUQ7SUFDbkQscURBQUksQ0FBQTtJQUNKLG9DQUFvQztJQUNwQyxxREFBSSxDQUFBO0lBQ0osMENBQTBDO0lBQzFDLHVEQUFLLENBQUE7QUFDVCxDQUFDLEVBUFcsZUFBZSxLQUFmLGVBQWUsUUFPMUI7QUFrR0QsTUFBTSxPQUFPLHlCQUF5QjthQUNsQixNQUFDLEdBQUcsa0JBQWtCLENBQUM7SUFzRHZDLElBQ1csTUFBTSxDQUFDLEdBQXFCO1FBQ25DLElBQUksQ0FBQyxPQUFPLEdBQUcsU0FBUyxDQUFDLEVBQUUsRUFBRSxJQUFJLGdCQUFnQixFQUFFLEVBQUUsR0FBRyxDQUFDLENBQUM7UUFDMUQsSUFBSSxDQUFDLGNBQWMsR0FBRyxTQUFTLENBQUMsRUFBRSxFQUFFLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQztRQUNsRCxJQUFJLENBQUMsaUJBQWlCLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUM7UUFDM0MsSUFBSSxDQUFDLGtCQUFrQixHQUFHLElBQUksQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDO1FBQzdDLElBQ0ksSUFBSSxDQUFDLE9BQU8sQ0FBQyxLQUFLO2VBQ2YsSUFBSSxDQUFDLE1BQU0sQ0FBQyxLQUFLLEtBQUssSUFBSSxDQUFDLE1BQU0sQ0FBQyxNQUFNLEVBQzdDO1lBQ0UsTUFBTSxJQUFJLEtBQUssQ0FBQyxHQUFHLHlCQUF5QixDQUFDLENBQUMsb0ZBQW9GLENBQUMsQ0FBQztTQUN2STtRQUNELE1BQU0sV0FBVyxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsV0FBVyxDQUFDO1FBQzdDLElBQUksV0FBVyxFQUFFO1lBQ2IsSUFBSSxDQUFDLFdBQVcsR0FBRyxXQUFXLENBQUM7U0FDbEM7SUFDTCxDQUFDO0lBQ0QsSUFBVyxNQUFNO1FBQ2IsT0FBTyxJQUFJLENBQUMsT0FBTyxDQUFDO0lBQ3hCLENBQUM7SUFDRCxnQkFBZ0I7SUFDaEIsSUFDVyxLQUFLLENBQUMsR0FBdUI7UUFDcEMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQUMsQ0FBQztJQUN2QixDQUFDO0lBQ0QsSUFBVyxLQUFLO1FBQ1osT0FBTyxJQUFJLENBQUMsTUFBTSxDQUFDO0lBQ3ZCLENBQUM7SUFTRCxvQkFBb0I7SUFDcEIsSUFBVyxRQUFRO1FBQ2YsT0FBTyxJQUFJLENBQUMsU0FBUyxDQUFDO0lBQzFCLENBQUM7SUE0Q0QsWUFDWSxTQUFvQixFQUNuQixXQUFvQyxFQUNyQyxFQUFxQixFQUNyQixPQUFlLEVBQ0wsU0FBYyxFQUNoQyxhQUE0QjtRQUxwQixjQUFTLEdBQVQsU0FBUyxDQUFXO1FBQ25CLGdCQUFXLEdBQVgsV0FBVyxDQUF5QjtRQUNyQyxPQUFFLEdBQUYsRUFBRSxDQUFtQjtRQUNyQixZQUFPLEdBQVAsT0FBTyxDQUFRO1FBMUhuQixhQUFRLEdBQVksRUFBUyxDQUFDO1FBQzlCLGNBQVMsR0FBRyxDQUFDLENBQUM7UUE0RUwsZ0JBQVcsR0FBRyxJQUFJLFlBQVksRUFBVSxDQUFDO1FBRTFELDBDQUEwQztRQUMxQyw0Q0FBNEM7UUFFM0IsbUJBQWMsR0FBRyxJQUFJLFlBQVksRUFBVSxDQUFDO1FBRTdELDBDQUEwQztRQUMxQyw0Q0FBNEM7UUFFM0IsbUJBQWMsR0FBRyxJQUFJLFlBQVksRUFBVSxDQUFDO1FBRTdELHFDQUFxQztRQUVwQixnQkFBVyxHQUFHLElBQUksWUFBWSxFQUFtQixDQUFDO1FBRW5FLHVEQUF1RDtRQUV0QyxVQUFLLEdBQUcsSUFBSSxZQUFZLEVBQW1CLENBQUM7UUFFN0Qsd0JBQXdCO1FBRVAsWUFBTyxHQUFHLElBQUksWUFBWSxFQUFtQixDQUFDO1FBRS9ELHdDQUF3QztRQUV2QixZQUFPLEdBQUcsSUFBSSxZQUFZLEVBQVEsQ0FBQztRQUVwRCx1REFBdUQ7UUFDdkQsNkNBQTZDO1FBRTVCLFVBQUssR0FBRyxJQUFJLFlBQVksRUFBd0IsQ0FBQztRQUlsRSxpREFBaUQ7UUFDaEMsYUFBUSxHQUFHLElBQUksT0FBTyxFQUFRLENBQUM7UUFzT3hDLGlCQUFZLEdBQUcsQ0FBQyxLQUE4QixFQUFFLEVBQUU7WUFDdEQsMkJBQTJCO1lBQzNCLDJEQUEyRDtZQUMzRCxJQUFJLElBQUksQ0FBQyxVQUFVLElBQUksQ0FBQyxDQUFDLFlBQVksQ0FBQyxLQUFLLENBQUMsSUFBSSxLQUFLLENBQUMsTUFBTSxLQUFLLENBQUMsQ0FBQyxFQUFFO2dCQUNqRSxPQUFPO2FBQ1Y7WUFFRCxJQUFJLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxHQUFHLEVBQUU7Z0JBQ2xCLElBQUksQ0FBQyxVQUFVLEdBQUcsSUFBSSxDQUFDO2dCQUN2QixJQUFJLENBQUMsTUFBTSxHQUFHO29CQUNWLENBQUMsRUFBRSxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUM7b0JBQ2xCLENBQUMsRUFBRSxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUM7b0JBQ2xCLElBQUksRUFBRSxJQUFJLENBQUMsUUFBUSxDQUFDLEVBQUU7b0JBQ3RCLEdBQUcsRUFBRSxJQUFJLENBQUMsUUFBUSxDQUFDLEVBQUU7aUJBQ3hCLENBQUM7Z0JBQ0YsSUFBSSxDQUFDLGlCQUFpQixHQUFHLEtBQUssQ0FBQztnQkFDL0IsSUFBSSxDQUFDLGtCQUFrQixHQUFHLHdCQUF3QixDQUFDLEtBQUssQ0FBQyxDQUFDO2dCQUMxRCxLQUFLLENBQUMsY0FBYyxFQUFFLENBQUM7Z0JBQ3ZCLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxLQUFLLENBQUMsQ0FBQztZQUNsQyxDQUFDLENBQUMsQ0FBQztRQUVQLENBQUMsQ0FBQTtRQTBCRDs7O1dBR0c7UUFDSyxpQkFBWSxHQUFHLENBQUMsS0FBOEIsRUFBRSxFQUFFO1lBQ3RELElBQUksSUFBSSxDQUFDLFVBQVUsRUFBRTtnQkFDakIsS0FBSyxDQUFDLGNBQWMsRUFBRSxDQUFDO2dCQUN2QixJQUFJLENBQUMsaUJBQWlCLEdBQUcsS0FBSyxDQUFDO2dCQUMvQixJQUFJLENBQXFCLENBQUM7Z0JBQzFCLElBQUksQ0FBcUIsQ0FBQztnQkFDMUIsTUFBTSxNQUFNLEdBQUcsSUFBSSxDQUFDLFVBQVUsQ0FBQyxhQUFhLENBQUM7Z0JBQzdDLE1BQU0sUUFBUSxHQUFHLElBQUksQ0FBQyxTQUFTLENBQUM7Z0JBQ2hDLE1BQU0sTUFBTSxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUM7Z0JBQzNCLE1BQU0sTUFBTSxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUM7Z0JBQzNCLE1BQU0sS0FBSyxHQUFHLHdCQUF3QixDQUFDLEtBQUssQ0FBQyxDQUFDO2dCQUM5QyxNQUFNLE1BQU0sR0FBRyxLQUFLLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxDQUFDLENBQUM7Z0JBQ25ELE1BQU0sTUFBTSxHQUFHLEtBQUssQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLGtCQUFrQixDQUFDLENBQUMsQ0FBQztnQkFDbkQsSUFBSSxDQUFDLFFBQVEsSUFBSSxDQUFDLE1BQU0sRUFBRTtvQkFDdEIsT0FBTztpQkFDVjtnQkFFRCxNQUFNLFdBQVcsR0FBRyxNQUFNLENBQUMsTUFBTSxHQUFHLFFBQVEsR0FBRyxNQUFNLENBQUMsTUFBTSxJQUFJLE1BQU0sQ0FBQyxZQUFZLENBQUM7Z0JBQ3BGLE1BQU0sV0FBVyxHQUFHLE1BQU0sQ0FBQyxLQUFLLEdBQUcsUUFBUSxHQUFHLE1BQU0sQ0FBQyxLQUFLLElBQUksTUFBTSxDQUFDLFlBQVksQ0FBQztnQkFFbEYsTUFBTSxTQUFTLEdBQUcsQ0FBQyxNQUFNLENBQUMsS0FBSyxHQUFHLENBQUMsR0FBRyxRQUFRLENBQUMsSUFBSSxNQUFNLENBQUMsSUFBSSxHQUFHLENBQUMsTUFBTSxHQUFHLFFBQVEsQ0FBQyxDQUFDO2dCQUNyRixNQUFNLFVBQVUsR0FBRyxDQUFDLE1BQU0sQ0FBQyxLQUFLLEdBQUcsQ0FBQyxHQUFHLFFBQVEsQ0FBQztvQkFDNUMsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxNQUFNLENBQUMsSUFBSSxHQUFHLENBQUMsTUFBTSxHQUFHLFFBQVEsQ0FBQyxDQUFDLElBQUksTUFBTSxDQUFDLEtBQUssR0FBRyxRQUFRLENBQUM7Z0JBQ3BGLE1BQU0sUUFBUSxHQUFHLENBQUMsQ0FBQyxNQUFNLENBQUMsTUFBTSxHQUFHLENBQUMsR0FBRyxRQUFRLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxHQUFHLEdBQUcsQ0FBQyxNQUFNLEdBQUcsUUFBUSxDQUFDLENBQUMsQ0FBQyxDQUFDO2dCQUN4RixNQUFNLFdBQVcsR0FBRyxDQUNoQixDQUFDLENBQUMsTUFBTSxDQUFDLE1BQU0sR0FBRyxDQUFDLEdBQUcsUUFBUSxDQUFDLEdBQUcsQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxNQUFNLENBQUMsR0FBRyxHQUFHLENBQUMsTUFBTSxHQUFHLFFBQVEsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxNQUFNLEdBQUcsUUFBUSxDQUFDLENBQ3hILENBQUM7Z0JBRUYsaUJBQWlCO2dCQUNqQixJQUFJLENBQUMsU0FBUyxJQUFJLENBQUMsV0FBVyxDQUFDLElBQUksQ0FBQyxDQUFDLFNBQVMsSUFBSSxXQUFXLENBQUMsRUFBRTtvQkFDNUQsQ0FBQyxHQUFHLE1BQU0sQ0FBQyxDQUFDLEdBQUcsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxNQUFNLENBQUMsS0FBSyxHQUFHLENBQUMsR0FBRyxRQUFRLENBQUMsQ0FBQztpQkFDaEU7Z0JBRUQsa0JBQWtCO2dCQUNsQixJQUFJLENBQUMsVUFBVSxJQUFJLENBQUMsV0FBVyxDQUFDLElBQUksQ0FBQyxDQUFDLFVBQVUsSUFBSSxXQUFXLENBQUMsRUFBRTtvQkFDOUQsQ0FBQyxHQUFHLE1BQU0sQ0FBQyxDQUFDLEdBQUcsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxNQUFNLENBQUMsS0FBSyxHQUFHLENBQUMsR0FBRyxRQUFRLENBQUMsR0FBRyxNQUFNLENBQUMsS0FBSyxDQUFDO2lCQUMvRTtnQkFFRCxnQkFBZ0I7Z0JBQ2hCLElBQUksQ0FBQyxRQUFRLElBQUksQ0FBQyxXQUFXLENBQUMsSUFBSSxDQUFDLENBQUMsUUFBUSxJQUFJLFdBQVcsQ0FBQyxFQUFFO29CQUMxRCxDQUFDLEdBQUcsTUFBTSxDQUFDLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxNQUFNLEdBQUcsQ0FBQyxHQUFHLFFBQVEsQ0FBQyxDQUFDO2lCQUNoRTtnQkFFRCxtQkFBbUI7Z0JBQ25CLElBQUksQ0FBQyxXQUFXLElBQUksQ0FBQyxXQUFXLENBQUMsSUFBSSxDQUFDLENBQUMsV0FBVyxJQUFJLFdBQVcsQ0FBQyxFQUFFO29CQUNoRSxDQUFDLEdBQUcsTUFBTSxDQUFDLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxNQUFNLEdBQUcsQ0FBQyxHQUFHLFFBQVEsQ0FBQyxHQUFHLE1BQU0sQ0FBQyxNQUFNLENBQUM7aUJBQ2hGO2dCQUVELGtDQUFrQztnQkFDbEMsbURBQW1EO2dCQUNuRCwrRkFBK0Y7Z0JBQy9GLDJCQUEyQjtnQkFDM0IsYUFBYTtnQkFDYiw0QkFBNEI7Z0JBQzVCLE1BQU07Z0JBQ04sSUFBSTtnQkFFSixJQUFJLENBQUMsS0FBSyxLQUFLLENBQUMsRUFBRTtvQkFBRSxDQUFDLEdBQUcsQ0FBQyxNQUFNLEdBQUcsUUFBUSxDQUFDLEdBQUcsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUM7aUJBQUU7Z0JBQzNELElBQUksQ0FBQyxLQUFLLEtBQUssQ0FBQyxFQUFFO29CQUFFLENBQUMsR0FBRyxDQUFDLE1BQU0sR0FBRyxRQUFRLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQztpQkFBRTtnQkFDM0QsSUFBSSxDQUFDLG9CQUFvQixDQUFDO29CQUN0QixDQUFDLEVBQUUsQ0FBQztpQkFDUCxDQUFDLENBQUM7YUFDTjtRQUNMLENBQUMsQ0FBQTtRQTZiRCxxREFBcUQ7UUFDN0MsZUFBVSxHQUFHLENBQUMsS0FBOEIsRUFBRSxFQUFFO1lBQ3BELElBQUksSUFBSSxDQUFDLFVBQVUsRUFBRTtnQkFDakIsS0FBSyxDQUFDLGNBQWMsRUFBRSxDQUFDO2dCQUN2QixJQUFJLENBQUMsbUJBQW1CLEVBQUUsQ0FBQztnQkFDM0IsSUFBSSxDQUFDLFVBQVUsR0FBRyxLQUFLLENBQUM7Z0JBQ3hCLElBQUksQ0FBQyxrQkFBa0IsR0FBRyxJQUFJLENBQUM7Z0JBQy9CLElBQUksQ0FBQyxlQUFlLEVBQUUsQ0FBQzthQUMxQjtRQUNMLENBQUMsQ0FBQTtRQUVELDZDQUE2QztRQUNyQyxnQkFBVyxHQUFHLEdBQUcsRUFBRTtZQUN2QiwrRUFBK0U7WUFDL0Usc0VBQXNFO1lBQ3RFLElBQUksSUFBSSxDQUFDLGlCQUFpQixFQUFFO2dCQUN4QixJQUFJLENBQUMsVUFBVSxDQUFDLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxDQUFDO2FBQzNDO1FBQ0wsQ0FBQyxDQUFBO1FBMXhCRyxJQUFJLENBQUMsU0FBUyxHQUFHLFNBQVMsQ0FBQztRQUMzQixhQUFhLENBQUMsTUFBTSxFQUFFO2FBQ2pCLElBQUksQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDO2FBQzlCLFNBQVMsQ0FBQyxHQUFHLEVBQUUsQ0FDWixJQUFJLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxJQUFJLENBQUMscUJBQXFCLEVBQUUsQ0FBQyxDQUN2RCxDQUFDO0lBQ1YsQ0FBQztJQUVNLFFBQVE7UUFDWCxJQUFJLENBQUMsT0FBTyxDQUFDLGlCQUFpQixDQUFDLEdBQUcsRUFBRTtZQUNoQyxNQUFNLE9BQU8sR0FBRyxJQUFJLENBQUMsYUFBYSxDQUFDLGFBQWEsQ0FBQztZQUNqRCxPQUFPLENBQUMsZ0JBQWdCLENBQUMsV0FBVyxFQUFFLElBQUksQ0FBQyxZQUFZLEVBQUUsa0JBQWtCLENBQUMsQ0FBQztZQUM3RSxPQUFPLENBQUMsZ0JBQWdCLENBQUMsWUFBWSxFQUFFLElBQUksQ0FBQyxZQUFZLEVBQUUsa0JBQWtCLENBQUMsQ0FBQztRQUNsRixDQUFDLENBQUMsQ0FBQztJQUNQLENBQUM7SUFFTSxXQUFXO1FBQ2QsSUFBSSxDQUFDLFFBQVEsQ0FBQyxJQUFJLEVBQUUsQ0FBQztRQUNyQixJQUFJLENBQUMsUUFBUSxDQUFDLFFBQVEsRUFBRSxDQUFDO1FBQ3pCLE1BQU0sT0FBTyxHQUFHLElBQUksQ0FBQyxhQUFhLENBQUMsYUFBYSxDQUFDO1FBQ2pELElBQUksQ0FBQyxpQkFBaUIsR0FBRyxJQUFJLENBQUM7UUFDOUIsSUFBSSxDQUFDLG1CQUFtQixFQUFFLENBQUM7UUFDM0IsT0FBTyxDQUFDLG1CQUFtQixDQUFDLFdBQVcsRUFBRSxJQUFJLENBQUMsWUFBWSxFQUFFLGtCQUFrQixDQUFDLENBQUM7UUFDaEYsT0FBTyxDQUFDLG1CQUFtQixDQUFDLFlBQVksRUFBRSxJQUFJLENBQUMsWUFBWSxFQUFFLGtCQUFrQixDQUFDLENBQUM7SUFDckYsQ0FBQztJQUVELDZCQUE2QjtJQUNyQixVQUFVLENBQUMsVUFBNEI7UUFDM0MsSUFBSSxVQUFVLEVBQUU7WUFDWixJQUFJLENBQUMsSUFBSSxHQUFHLFVBQVUsQ0FBQztZQUN2QixNQUFNLE1BQU0sR0FBRyxJQUFJLENBQUMsVUFBVSxDQUFDLGFBQWEsQ0FBQztZQUM3QyxNQUFNLENBQUMsS0FBSyxHQUFHLFVBQVUsQ0FBQyxLQUFLLENBQUM7WUFDaEMsTUFBTSxDQUFDLE1BQU0sR0FBRyxVQUFVLENBQUMsTUFBTSxDQUFDO1lBQ2xDLE1BQU0sR0FBRyxHQUFHLE1BQU0sQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLENBQUM7WUFDcEMsR0FBRyxDQUFDLFNBQVMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLFVBQVUsQ0FBQyxLQUFLLEVBQUUsVUFBVSxDQUFDLE1BQU0sQ0FBQyxDQUFDO1lBQ3pELEdBQUcsQ0FBQyxTQUFTLENBQUMsVUFBVSxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQztZQUVoQyxvQkFBb0I7WUFDcEIsSUFBSSxDQUFDLGVBQWUsQ0FBQyxNQUFNLENBQUMsQ0FBQztZQUM3QixJQUFJLENBQUMsZUFBZSxFQUFFLENBQUM7U0FDMUI7SUFDTCxDQUFDO0lBRU8sb0JBQW9CLENBQUMsTUFBa0M7UUFDM0QsTUFBTSxTQUFTLEdBQUcsRUFBVSxDQUFDO1FBQzdCLElBQUksTUFBTSxDQUFDLENBQUMsSUFBSSxJQUFJLElBQUksTUFBTSxDQUFDLENBQUMsSUFBSSxJQUFJLEVBQUU7WUFDdEMsTUFBTSxRQUFRLEdBQUcsSUFBSSxDQUFDLFNBQVMsRUFBRSxDQUFDO1lBQ2xDLE1BQU0sQ0FBQyxHQUFHLFFBQVEsQ0FBQyxLQUFLLEdBQUcsQ0FBQyxHQUFHLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQzFDLE1BQU0sQ0FBQyxHQUFHLFFBQVEsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxHQUFHLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBRTNDLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQyxHQUFHLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQzdCLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQyxHQUFHLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQzdCLElBQUksQ0FBQyxRQUFRLENBQUMsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDdkIsSUFBSSxDQUFDLFFBQVEsQ0FBQyxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQztTQUUxQjtRQUNELFNBQVMsQ0FBQyxTQUFTLEdBQUcsZUFBZSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxRQUFRLENBQUM7UUFDdEYsU0FBUyxDQUFDLFNBQVMsSUFBSSxTQUFTLElBQUksQ0FBQyxTQUFTLEdBQUcsQ0FBQztRQUNsRCxTQUFTLENBQUMsZUFBZSxHQUFHLEdBQUcsSUFBSSxDQUFDLFFBQVEsQ0FBQyxFQUFFLE1BQU0sSUFBSSxDQUFDLFFBQVEsQ0FBQyxFQUFFLE1BQU0sQ0FBQztRQUM1RSxTQUFTLENBQUMsbUJBQW1CLENBQUMsR0FBRyxTQUFTLENBQUMsU0FBUyxDQUFDO1FBQ3JELFNBQVMsQ0FBQywwQkFBMEIsQ0FBQyxHQUFHLFNBQVMsQ0FBQyxlQUFlLENBQUM7UUFDbEUsS0FBSyxNQUFNLEdBQUcsSUFBSSxTQUFTLEVBQUU7WUFDekIsSUFBSSxTQUFTLENBQUMsY0FBYyxDQUFDLEdBQUcsQ0FBQyxFQUFFO2dCQUMvQixJQUFJLENBQUMsU0FBUyxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsYUFBYSxDQUFDLGFBQWEsRUFBRSxHQUFHLEVBQUUsU0FBUyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUM7YUFDbEY7U0FDSjtJQUNMLENBQUM7SUFDRDs7O09BR0c7SUFDSSxxQkFBcUI7UUFDeEIsSUFBSSxJQUFJLENBQUMsUUFBUSxFQUFFO1lBQ2YsSUFBSSxDQUFDLGNBQWMsRUFBRSxDQUFDO1lBQ3RCLElBQUksQ0FBQyxtQkFBbUIsRUFBRSxDQUFDO1NBQzlCO0lBQ0wsQ0FBQztJQUVELGtDQUFrQztJQUMzQixnQkFBZ0IsQ0FBQyxHQUFVO1FBQzlCLElBQUksQ0FBQyxvQkFBb0IsR0FBRyxHQUFHLENBQUMsTUFBMEIsQ0FBQztRQUMzRCxNQUFNLElBQUksR0FBRyxHQUFHLENBQUMsTUFBMEIsQ0FBQztRQUM1QyxJQUFJLElBQUksQ0FBQyxLQUFLLElBQUksSUFBSSxDQUFDLEtBQUssQ0FBQyxNQUFNLEtBQUssQ0FBQyxFQUFFO1lBQ3ZDLE9BQU87U0FDVjtRQUNELE1BQU0sUUFBUSxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDO1FBQ3BDLE1BQU0sUUFBUSxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLFdBQVcsRUFBRSxFQUFFLENBQUMsQ0FBQztRQUVyRCxJQUFJLElBQUksQ0FBQyxXQUFXLElBQUksUUFBUSxHQUFHLElBQUksQ0FBQyxXQUFXLEVBQUU7WUFDakQsTUFBTSxTQUFTLEdBQXlCO2dCQUNwQyxJQUFJLEVBQUUsUUFBUTtnQkFDZCxJQUFJLEVBQUUsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJO2dCQUN4QixJQUFJLEVBQUUsUUFBUTtnQkFDZCxLQUFLLEVBQUUsZUFBZSxDQUFDLElBQUk7YUFDOUIsQ0FBQztZQUNGLElBQUksQ0FBQyxLQUFLLEVBQUUsQ0FBQztZQUNiLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLFNBQWlDLENBQUMsQ0FBQztZQUNuRCxPQUFPO1NBQ1Y7UUFFRCxJQUFJLFVBQVUsQ0FBZ0IsUUFBUSxDQUFDLEVBQUU7WUFFckMsTUFBTSxNQUFNLEdBQUcsSUFBSSxVQUFVLEVBQUUsQ0FBQztZQUVoQyxNQUFNLENBQUMsT0FBTyxHQUFHLEdBQUcsQ0FBQyxFQUFFLENBQUMsUUFBUSxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQztZQUM1QyxNQUFNLENBQUMsT0FBTyxHQUFHLEdBQUcsQ0FBQyxFQUFFLENBQUMsUUFBUSxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQztZQUM1QyxNQUFNLENBQUMsTUFBTSxHQUFHLENBQUMsRUFBRSxFQUFFLEVBQUUsQ0FBQyxVQUFVLENBQUMsR0FBRyxFQUFFO2dCQUNwQyxRQUFRLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxDQUFDO2dCQUNsQixRQUFRLENBQUMsUUFBUSxFQUFFLENBQUM7WUFDeEIsQ0FBQyxDQUFDLENBQUM7WUFFSCxNQUFNLENBQUMsYUFBYSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUN4QyxDQUFDLENBQUM7YUFDRyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxFQUFFLFNBQVMsQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUM7YUFDdkMsU0FBUyxDQUNOLENBQUMsU0FBUyxFQUFFLEVBQUU7WUFDVixNQUFNLGVBQWUsR0FBSSxTQUFTLENBQUMsTUFBcUIsQ0FBQyxNQUFnQixDQUFDO1lBRTFFLElBQUksQ0FBQyxTQUFTLENBQUM7Z0JBQ1gsSUFBSSxFQUFFLFFBQVE7Z0JBQ2QsSUFBSSxFQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSTtnQkFDeEIsSUFBSSxFQUFFLElBQUksQ0FBQyxNQUFNLENBQUMsSUFBSSxJQUFJLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSTtnQkFDNUMsZUFBZTthQUNsQixDQUFDLENBQUM7WUFFSCxJQUFJLENBQUMsRUFBRSxDQUFDLFlBQVksRUFBRSxDQUFDO1FBQzNCLENBQUMsRUFDRCxHQUFHLEVBQUU7WUFDRCxNQUFNLFNBQVMsR0FBeUI7Z0JBQ3BDLElBQUksRUFBRSxRQUFRO2dCQUNkLElBQUksRUFBRSxRQUFRO2dCQUNkLEtBQUssRUFBRSxlQUFlLENBQUMsS0FBSztnQkFDNUIsUUFBUSxFQUFFLCtCQUErQjtnQkFDekMsSUFBSSxFQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSTthQUMzQixDQUFDO1lBQ0YsSUFBSSxDQUFDLEtBQUssRUFBRSxDQUFDO1lBQ2IsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsU0FBaUMsQ0FBQyxDQUFDO1FBQ3ZELENBQUMsQ0FDSixDQUFDO0lBRVYsQ0FBQztJQUVELDZGQUE2RjtJQUN0RixRQUFRLENBQUMsSUFBYSxFQUFFLFVBQW9CO1FBQy9DLGdCQUFnQjtRQUNoQixNQUFNLE9BQU8sR0FBRyxJQUFJLElBQUksSUFBSSxDQUFDLFFBQVEsSUFBSSxJQUFJLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUM7UUFFMUUsUUFBUTtRQUNSLE1BQU0sT0FBTyxHQUFHLElBQUksSUFBSSxJQUFJLElBQUksSUFBSSxLQUFLLElBQUksQ0FBQyxLQUFLLElBQUksT0FBTyxLQUFLLElBQUksQ0FBQyxLQUFLLENBQUM7UUFDOUUsSUFBSSxDQUFDLE1BQU0sR0FBRyxJQUFJLENBQUM7UUFDbkIsSUFBSSxDQUFDLE9BQU8sRUFBRTtZQUNWLE9BQU87U0FDVjtRQUNELElBQUksQ0FBQyxTQUFTLEdBQUcsT0FBTyxDQUFDO1FBQ3pCLElBQUksQ0FBQyxvQkFBb0IsRUFBRSxDQUFDO1FBQzVCLElBQUksSUFBSSxDQUFDLFFBQVEsRUFBRTtZQUNmLElBQUksT0FBTyxFQUFFO2dCQUNULE1BQU0sY0FBYyxHQUFHLEVBQUMsR0FBRyxJQUFJLENBQUMsUUFBUSxFQUFDLENBQUM7Z0JBQzFDLElBQUksQ0FBQyxNQUFNLEdBQUc7b0JBQ1YsQ0FBQyxFQUFFLGNBQWMsQ0FBQyxDQUFDO29CQUNuQixDQUFDLEVBQUUsY0FBYyxDQUFDLENBQUM7b0JBQ25CLElBQUksRUFBRSxjQUFjLENBQUMsRUFBRTtvQkFDdkIsR0FBRyxFQUFFLGNBQWMsQ0FBQyxFQUFFO2lCQUN6QixDQUFDO2dCQUNGLElBQUksQ0FBQyxvQkFBb0IsQ0FBQyxFQUFFLENBQUMsQ0FBQztnQkFDOUIsSUFBSSxDQUFDLG9CQUFvQixFQUFFLENBQUM7YUFDL0I7aUJBQU07Z0JBQ0gsT0FBTzthQUNWO1NBQ0o7YUFBTSxJQUFJLElBQUksQ0FBQyxRQUFRLEVBQUU7WUFDdEIsSUFBSSxDQUFDLG9CQUFvQixDQUFDO2dCQUN0QixHQUFHLElBQUksQ0FBQyxnQkFBZ0IsRUFBRTthQUM3QixDQUFDLENBQUM7U0FDTjthQUFNO1lBQ0gsT0FBTztTQUNWO1FBRUQsSUFBSSxDQUFDLFdBQVcsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDNUIsSUFBSSxDQUFDLFVBQVUsRUFBRTtZQUNiLElBQUksQ0FBQyxlQUFlLEVBQUUsQ0FBQztTQUMxQjtJQUVMLENBQUM7SUFFTyxnQkFBZ0I7UUFDcEIsTUFBTSxJQUFJLEdBQUcsSUFBSSxDQUFDLFdBQVcsQ0FBQyxhQUE0QixDQUFDO1FBQzNELE1BQU0sR0FBRyxHQUFHLElBQUksQ0FBQyxVQUFVLENBQUMsYUFBYSxDQUFDO1FBQzFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLFdBQVcsR0FBRyxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQztRQUMvQyxNQUFNLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxZQUFZLEdBQUcsQ0FBQyxHQUFHLENBQUMsTUFBTSxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUM7UUFDakQsT0FBTztZQUNILENBQUM7WUFDRCxDQUFDO1NBQ0osQ0FBQztJQUNOLENBQUM7SUFFRDs7T0FFRztJQUNJLFdBQVc7UUFDZCxNQUFNLFNBQVMsR0FBRyxJQUFJLENBQUMsV0FBVyxDQUFDLGFBQTRCLENBQUM7UUFDaEUsTUFBTSxHQUFHLEdBQUc7WUFDUixLQUFLLEVBQUUsU0FBUyxDQUFDLFdBQVc7WUFDNUIsTUFBTSxFQUFFLFNBQVMsQ0FBQyxZQUFZO1NBQ2pDLENBQUM7UUFDRixNQUFNLEVBQUUsS0FBSyxFQUFFLE1BQU0sRUFBRSxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUM7UUFDcEMsTUFBTSxRQUFRLEdBQUc7WUFDYixLQUFLLEVBQUUsR0FBRyxDQUFDLEtBQUssR0FBRyxLQUFLO1lBQ3hCLE1BQU0sRUFBRSxHQUFHLENBQUMsTUFBTSxHQUFHLE1BQU07U0FDOUIsQ0FBQztRQUNGLE1BQU0sTUFBTSxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsUUFBUSxDQUFDLEtBQUssRUFBRSxRQUFRLENBQUMsTUFBTSxDQUFDLENBQUM7UUFDekQsSUFBSSxDQUFDLFFBQVEsQ0FBQyxNQUFNLENBQUMsQ0FBQztJQUMxQixDQUFDO0lBRU0sR0FBRztRQUNOLElBQUksQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDO0lBQ2pDLENBQUM7SUF5QkQ7OztPQUdHO0lBQ0ssb0JBQW9CO1FBQ3hCLElBQUksQ0FBQyxVQUFVLEdBQUcsSUFBSSxDQUFDO1FBQ3ZCLElBQUksQ0FBQyxrQkFBa0IsR0FBRztZQUN0QixDQUFDLEVBQUUsQ0FBQztZQUNKLENBQUMsRUFBRSxDQUFDO1NBQ1AsQ0FBQztRQUNGLElBQUksQ0FBQyxZQUFZLENBQUM7WUFDZCxPQUFPLEVBQUUsQ0FBQztZQUNWLE9BQU8sRUFBRSxDQUFDO1lBQ1YsSUFBSSxFQUFFLEdBQUc7WUFDVCxjQUFjLEVBQUUsR0FBRyxFQUFFLEdBQUUsQ0FBQztTQUNiLENBQUMsQ0FBQztRQUNqQixJQUFJLENBQUMsVUFBVSxHQUFHLEtBQUssQ0FBQztRQUN4QixJQUFJLENBQUMsa0JBQWtCLEdBQUcsSUFBSSxDQUFDO0lBQ25DLENBQUM7SUFFTSxhQUFhO1FBQ2hCLElBQUksQ0FBQyxFQUFFLENBQUMsWUFBWSxFQUFFLENBQUM7SUFDM0IsQ0FBQztJQXlFTSxjQUFjLENBQUMsT0FBZ0IsRUFBRSxPQUFnQjtRQUNwRCxNQUFNLFFBQVEsR0FBRyxJQUFJLENBQUMsU0FBUyxFQUFFLENBQUM7UUFDbEMsTUFBTSxRQUFRLEdBQUcsSUFBSSxDQUFDLGdCQUFnQixFQUFFLENBQUM7UUFDekMsTUFBTSxTQUFTLEdBQUcsUUFBUSxDQUFDLEtBQUssR0FBRyxRQUFRLENBQUMsS0FBSztZQUM3QyxDQUFDLENBQUMsUUFBUSxDQUFDLEtBQUs7WUFDaEIsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxLQUFLLENBQUM7UUFDckIsTUFBTSxVQUFVLEdBQUcsUUFBUSxDQUFDLE1BQU0sR0FBRyxRQUFRLENBQUMsTUFBTTtZQUNoRCxDQUFDLENBQUMsUUFBUSxDQUFDLE1BQU07WUFDakIsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxNQUFNLENBQUM7UUFDdEIsSUFBSSxDQUFTLENBQUM7UUFDZCxJQUFJLENBQVMsQ0FBQztRQUNkLElBQUksT0FBTyxJQUFJLElBQUksSUFBSSxPQUFPLElBQUksSUFBSSxFQUFFO1lBQ3BDLE9BQU8sR0FBRyxJQUFJLENBQUMsUUFBUSxDQUFDLEVBQUUsQ0FBQztZQUMzQixPQUFPLEdBQUcsSUFBSSxDQUFDLFFBQVEsQ0FBQyxFQUFFLENBQUM7U0FDOUI7UUFDRCxDQUFDLEdBQUcsQ0FBQyxRQUFRLENBQUMsSUFBSSxHQUFHLFFBQVEsQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUNwQyxDQUFDLEdBQUcsQ0FBQyxRQUFRLENBQUMsR0FBRyxHQUFHLFFBQVEsQ0FBQyxHQUFHLENBQUMsQ0FBQztRQUNsQyxDQUFDLElBQUksQ0FBQyxPQUFPLEdBQUcsQ0FBQyxTQUFTLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUNqQyxDQUFDLElBQUksQ0FBQyxPQUFPLEdBQUcsQ0FBQyxVQUFVLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUVsQyxJQUFJLENBQUMsb0JBQW9CLENBQUM7WUFDdEIsQ0FBQyxFQUFFLENBQUM7U0FDUCxDQUFDLENBQUM7SUFDUCxDQUFDO0lBRU0sU0FBUztRQUNaLElBQUksQ0FBQyxlQUFlLEVBQUUsQ0FBQztJQUMzQixDQUFDO0lBRU8sZUFBZTtRQUNuQixJQUFJLElBQUksQ0FBQyxNQUFNLENBQUMsUUFBUSxFQUFFO1lBQ3RCLElBQUksQ0FBQyxJQUFJLEVBQUUsQ0FBQztTQUNmO0lBQ0wsQ0FBQztJQUVELFFBQVE7SUFDRCxNQUFNO1FBQ1QsTUFBTSxLQUFLLEdBQUcsSUFBSSxDQUFDLFNBQVMsR0FBRyxHQUFHLENBQUM7UUFDbkMsSUFBSSxLQUFLLEdBQUcsSUFBSSxDQUFDLFFBQVEsSUFBSSxLQUFLLElBQUksSUFBSSxDQUFDLFNBQVMsRUFBRTtZQUNsRCxJQUFJLENBQUMsUUFBUSxDQUFDLEtBQUssQ0FBQyxDQUFDO1NBQ3hCO2FBQU07WUFDSCxJQUFJLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQztTQUNqQztJQUNMLENBQUM7SUFFRCw0QkFBNEI7SUFDckIsS0FBSztRQUNSLDRDQUE0QztRQUM1QyxJQUFJLElBQUksQ0FBQyxvQkFBb0IsRUFBRTtZQUMzQixJQUFJLENBQUMsb0JBQW9CLENBQUMsS0FBSyxHQUFHLEVBQUUsQ0FBQztZQUNyQyxJQUFJLENBQUMsb0JBQW9CLEdBQUcsSUFBSSxDQUFDO1NBQ3BDO1FBQ0QsSUFBSSxJQUFJLENBQUMsUUFBUSxFQUFFO1lBQ2YsSUFBSSxDQUFDLFFBQVEsR0FBRyxFQUFVLENBQUM7WUFDM0IsSUFBSSxDQUFDLE1BQU0sR0FBRyxTQUFTLENBQUM7WUFDeEIsSUFBSSxDQUFDLEtBQUssR0FBRyxTQUFnQixDQUFDO1lBQzlCLElBQUksQ0FBQyxTQUFTLEdBQUcsU0FBUyxDQUFDO1lBQzNCLElBQUksQ0FBQyxTQUFTLEdBQUcsQ0FBQyxDQUFDO1lBQ25CLElBQUksQ0FBQyxTQUFTLEdBQUcsU0FBUyxDQUFDO1lBQzNCLElBQUksQ0FBQyxZQUFZLEdBQUcsS0FBSyxDQUFDO1lBQzFCLElBQUksQ0FBQyxRQUFRLEdBQUcsS0FBSyxDQUFDO1lBQ3RCLElBQUksQ0FBQyxTQUFTLEdBQUcsS0FBSyxDQUFDO1lBQ3ZCLElBQUksQ0FBQyxrQkFBa0IsR0FBRyxTQUFTLENBQUM7WUFDcEMsSUFBSSxDQUFDLE1BQU0sR0FBRyxJQUFJLENBQUMsY0FBYyxDQUFDO1lBQ2xDLE1BQU0sTUFBTSxHQUFHLElBQUksQ0FBQyxVQUFVLENBQUMsYUFBYSxDQUFDO1lBQzdDLE1BQU0sQ0FBQyxLQUFLLEdBQUcsQ0FBQyxDQUFDO1lBQ2pCLE1BQU0sQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDO1lBQ2xCLElBQUksQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDO1lBQ3hCLElBQUksQ0FBQyxFQUFFLENBQUMsWUFBWSxFQUFFLENBQUM7U0FDMUI7SUFDTCxDQUFDO0lBRUQsUUFBUTtJQUNELE9BQU87UUFDVixNQUFNLEtBQUssR0FBRyxJQUFJLENBQUMsU0FBUyxHQUFHLEdBQUcsQ0FBQztRQUNuQyxJQUFJLEtBQUssR0FBRyxJQUFJLENBQUMsUUFBUSxJQUFJLEtBQUssSUFBSSxJQUFJLENBQUMsU0FBUyxFQUFFO1lBQ2xELElBQUksQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDLENBQUM7U0FDeEI7YUFBTTtZQUNILElBQUksQ0FBQyxHQUFHLEVBQUUsQ0FBQztTQUNkO0lBQ0wsQ0FBQztJQUNNLE1BQU07UUFDVCxNQUFNLFNBQVMsR0FBRztZQUNkLEdBQUcsSUFBSSxDQUFDLGdCQUFnQixFQUFFO1NBQzdCLENBQUM7UUFDRixJQUFJLENBQUMsb0JBQW9CLENBQUMsU0FBUyxDQUFDLENBQUM7UUFDckMsSUFBSSxDQUFDLGVBQWUsRUFBRSxDQUFDO0lBQzNCLENBQUM7SUFDRDs7O09BR0c7SUFDSSxTQUFTLENBQUMsTUFBdUMsRUFBRSxFQUFlO1FBQ3JFLElBQUksQ0FBQyxLQUFLLEVBQUUsQ0FBQztRQUNiLE1BQU0sT0FBTyxHQUFHLElBQUksQ0FBQyxrQkFBa0IsR0FBRyxPQUFPLE1BQU0sS0FBSyxRQUFRO1lBQ2hFLENBQUMsQ0FBQyxFQUFFLGVBQWUsRUFBRSxNQUFNLEVBQUU7WUFDN0IsQ0FBQyxDQUFDLEVBQUUsR0FBRyxNQUFNLEVBQUUsQ0FBQztRQUNwQixJQUFJLEdBQUcsR0FBRyxPQUFPLENBQUMsZUFBZSxDQUFDO1FBQ2xDLElBQUksQ0FBQyxpQkFBaUIsR0FBRyxJQUFJLENBQUMsY0FBYyxDQUFDLEtBQUssQ0FBQztRQUNuRCxJQUFJLENBQUMsa0JBQWtCLEdBQUcsSUFBSSxDQUFDLGNBQWMsQ0FBQyxNQUFNLENBQUM7UUFDckQsSUFBSSxPQUFPLENBQUMsU0FBUyxJQUFJLE9BQU8sQ0FBQyxVQUFVLEVBQUU7WUFDekMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxLQUFLLEdBQUcsT0FBTyxDQUFDLFNBQVMsQ0FBQztZQUN0QyxJQUFJLENBQUMsTUFBTSxDQUFDLE1BQU0sR0FBRyxPQUFPLENBQUMsVUFBVSxDQUFDO1NBQzNDO1FBQ0QsR0FBRyxHQUFHLFlBQVksQ0FBQyxHQUFHLENBQUMsQ0FBQztRQUV4QixNQUFNLEdBQUcsR0FBRyxhQUFhLENBQUMsR0FBRyxDQUFDLENBQUM7UUFFL0IsTUFBTSxTQUFTLEdBQUcsRUFBRSxHQUFHLE9BQU8sRUFBcUIsQ0FBQztRQUVwRCxJQUFJLFVBQVUsQ0FBTyxRQUFRLENBQUMsRUFBRTtZQUU1QixHQUFHLENBQUMsT0FBTyxHQUFHLEdBQUcsQ0FBQyxFQUFFLENBQUMsUUFBUSxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQztZQUN6QyxHQUFHLENBQUMsT0FBTyxHQUFHLEdBQUcsQ0FBQyxFQUFFLENBQUMsUUFBUSxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQztZQUN6QyxHQUFHLENBQUMsTUFBTSxHQUFHLEdBQUcsRUFBRSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDM0MsQ0FBQyxDQUFDO2FBQ0csSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsRUFBRSxTQUFTLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDO2FBQ3ZDLFNBQVMsQ0FDTixHQUFHLEVBQUU7WUFDRCxJQUFJLENBQUMsVUFBVSxDQUFDLEdBQUcsQ0FBQyxDQUFDO1lBQ3JCLElBQUksQ0FBQyxZQUFZLEdBQUcsSUFBSSxDQUFDO1lBQ3pCLElBQUksQ0FBQyxXQUFXLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxDQUFDO1lBQ2pDLElBQUksQ0FBQyxFQUFFLENBQUMsWUFBWSxFQUFFLENBQUM7WUFDdkIsSUFBSSxDQUFDLE9BQU8sQ0FBQyxpQkFBaUIsQ0FBQyxHQUFHLEVBQUU7Z0JBQ2hDLElBQUksQ0FBQyxPQUFPO3FCQUNQLFFBQVE7cUJBQ1IsWUFBWSxFQUFFO3FCQUNkLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLEVBQUUsU0FBUyxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQztxQkFDdkMsU0FBUyxDQUNOLEdBQUcsRUFBRSxDQUFDLFVBQVUsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLFNBQVMsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQ25GLENBQUM7WUFDVixDQUFDLENBQUMsQ0FBQztRQUNQLENBQUMsRUFDRCxHQUFHLEVBQUU7WUFDRCxNQUFNLEtBQUssR0FBeUI7Z0JBQ2hDLElBQUksRUFBRSxPQUFPLENBQUMsSUFBSTtnQkFDbEIsS0FBSyxFQUFFLGVBQWUsQ0FBQyxJQUFJO2dCQUMzQixJQUFJLEVBQUUsT0FBTyxDQUFDLElBQUk7Z0JBQ2xCLElBQUksRUFBRSxPQUFPLENBQUMsSUFBSTthQUNyQixDQUFDO1lBQ0YsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDM0IsQ0FBQyxDQUNKLENBQUM7SUFDVixDQUFDO0lBRU8sbUJBQW1CO1FBQ3ZCLElBQUksQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLGNBQWMsRUFBRTtZQUM5QixPQUFPO1NBQ1Y7UUFFRCxNQUFNLFFBQVEsR0FBRyxJQUFJLENBQUMsU0FBUyxFQUFFLENBQUM7UUFDbEMsTUFBTSxRQUFRLEdBQUcsSUFBSSxDQUFDLGdCQUFnQixFQUFFLENBQUM7UUFDekMsTUFBTSxRQUFRLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQyxRQUFRLElBQUksQ0FBQyxDQUFDO1FBQzNDLE1BQU0sU0FBUyxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUMsU0FBUyxJQUFJLENBQUMsQ0FBQztRQUM3QyxJQUFJLENBQUMsQ0FDRCxRQUFRLENBQUMsS0FBSyxHQUFHLFFBQVEsQ0FBQyxLQUFLO2VBQzVCLFFBQVEsQ0FBQyxNQUFNLEdBQUcsUUFBUSxDQUFDLE1BQU07ZUFDakMsUUFBUSxDQUFDLEtBQUssR0FBRyxJQUFJLENBQUMsaUJBQWlCO2VBQ3ZDLFFBQVEsQ0FBQyxNQUFNLEdBQUcsSUFBSSxDQUFDLGtCQUFrQixDQUMvQyxFQUFFO1lBQ0MsT0FBTztTQUNWO1FBQ0QsTUFBTSxhQUFhLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLEtBQUssRUFBRSxRQUFRLENBQUMsQ0FBQztRQUM1RCxNQUFNLFlBQVksR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLFFBQVEsQ0FBQyxLQUFLLEVBQUUsUUFBUSxDQUFDLENBQUM7UUFDeEQsTUFBTSxPQUFPLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FDcEIsSUFBSSxDQUFDLEdBQUcsQ0FBQyxRQUFRLENBQUMsS0FBSyxFQUFFLFFBQVEsQ0FBQyxFQUFFLElBQUksQ0FBQyxHQUFHLENBQUMsUUFBUSxDQUFDLE1BQU0sRUFBRSxTQUFTLENBQUMsQ0FDM0UsQ0FBQztRQUNGLE1BQU0sWUFBWSxHQUFHLElBQUksQ0FBQyxTQUFTLENBQUM7UUFDcEMsSUFBSSxRQUFRLEdBQUcsQ0FBQyxDQUFDO1FBQ2pCLE1BQU0sU0FBUyxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDO1FBRXBDLElBQUksU0FBUyxFQUFFO1lBQ1gsSUFBSSxDQUFDLE1BQU0sQ0FBQyxLQUFLLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQyxNQUFNLEdBQUcsT0FBTyxDQUFDO1NBQ3BEO2FBQU07WUFDSCxJQUFJLGFBQWEsS0FBSyxRQUFRLENBQUMsS0FBSyxFQUFFO2dCQUNsQyxJQUFJLFlBQVksR0FBRyxJQUFJLENBQUMsaUJBQWlCLEVBQUU7b0JBQ3ZDLElBQUksQ0FBQyxNQUFNLENBQUMsS0FBSyxHQUFHLElBQUksQ0FBQyxpQkFBaUIsQ0FBQztvQkFDM0MsSUFBSSxDQUFDLE1BQU0sQ0FBQyxNQUFNLEdBQUcsQ0FBQyxJQUFJLENBQUMsaUJBQWlCLEdBQUcsUUFBUSxDQUFDLE1BQU0sQ0FBQyxHQUFHLFFBQVEsQ0FBQyxLQUFLLENBQUM7b0JBQ2pGLFFBQVEsR0FBRyxDQUFDLFlBQVksR0FBRyxJQUFJLENBQUMsaUJBQWlCLENBQUMsR0FBRyxRQUFRLENBQUMsS0FBSyxDQUFDO2lCQUN2RTtxQkFBTTtvQkFDSCxJQUFJLENBQUMsTUFBTSxDQUFDLEtBQUssR0FBRyxZQUFZLENBQUM7b0JBQ2pDLElBQUksQ0FBQyxNQUFNLENBQUMsTUFBTSxHQUFHLENBQUMsWUFBWSxHQUFHLFFBQVEsQ0FBQyxNQUFNLENBQUMsR0FBRyxRQUFRLENBQUMsS0FBSyxDQUFDO29CQUN2RSxRQUFRLEdBQUcsQ0FBQyxZQUFZLEdBQUcsWUFBWSxDQUFDLEdBQUcsUUFBUSxDQUFDLEtBQUssQ0FBQztpQkFDN0Q7Z0JBQ0QsSUFBSSxDQUFDLGVBQWUsRUFBRSxDQUFDO2dCQUN2QixJQUFJLENBQUMsZUFBZSxFQUFFLENBQUM7Z0JBQ3ZCLElBQUksQ0FBQyxRQUFRLENBQUMsUUFBUSxFQUFFLElBQUksQ0FBQyxDQUFDO2dCQUM5QixJQUFJLENBQUMsYUFBYSxFQUFFLENBQUM7YUFDeEI7U0FDSjtJQUNMLENBQUM7SUFFTyxvQkFBb0I7UUFDeEIsTUFBTSxLQUFLLEdBQUcsSUFBSSxDQUFDLFNBQVMsR0FBRyxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsS0FBSyxHQUFHLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxDQUFDO1FBQzVFLElBQUksQ0FBQyxjQUFjLEdBQUcsS0FBSyxDQUFDO0lBQ2hDLENBQUM7SUFFRDs7Ozs7T0FLRztJQUNJLFdBQVcsQ0FBQyxHQUFXLEVBQUUsRUFBZTtRQUMzQyxJQUFJLENBQUMsU0FBUyxDQUFDLEdBQUcsRUFBRSxFQUFFLENBQUMsQ0FBQztJQUM1QixDQUFDO0lBRU8sWUFBWSxDQUFDLFNBQTBCLEVBQUUsRUFBZTtRQUM1RCxNQUFNLFVBQVUsR0FBRyxJQUFJLENBQUMsa0JBQWtCLENBQUM7UUFDM0MsSUFBSSxDQUFDLGVBQWUsQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLGFBQWEsQ0FBQyxDQUFDO1FBQ3BELElBQUksQ0FBQyxlQUFlLEVBQUUsQ0FBQztRQUN2QixJQUFJLENBQUMsUUFBUSxHQUFHLEtBQUssQ0FBQztRQUN0QixJQUFJLEVBQUUsRUFBRTtZQUNKLEVBQUUsRUFBRSxDQUFDO1NBQ1I7YUFBTTtZQUNILElBQUksVUFBVSxDQUFDLEtBQUssRUFBRTtnQkFDbEIsSUFBSSxDQUFDLFFBQVEsQ0FBQyxVQUFVLENBQUMsS0FBSyxFQUFFLElBQUksQ0FBQyxDQUFDO2FBQ3pDO2lCQUFNO2dCQUNILElBQUksQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLFFBQVEsRUFBRSxJQUFJLENBQUMsQ0FBQzthQUN0QztZQUNELElBQUksQ0FBQyxNQUFNLENBQUMsVUFBVSxDQUFDLFFBQVEsSUFBSSxDQUFDLENBQUMsQ0FBQztZQUN0QyxJQUFJLENBQUMsbUJBQW1CLEVBQUUsQ0FBQztZQUMzQixJQUFJLENBQUMsYUFBYSxFQUFFLENBQUM7WUFDckIsSUFBSSxDQUFDLE9BQU8sQ0FBQyxpQkFBaUIsQ0FBQyxHQUFHLEVBQUU7Z0JBQ2hDLElBQUksQ0FBQyxPQUFPO3FCQUNQLFFBQVE7cUJBQ1IsWUFBWSxFQUFFO3FCQUNkLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLEVBQUUsU0FBUyxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQztxQkFDdkMsU0FBUyxDQUFDLEdBQUcsRUFBRTtvQkFDWixJQUFJLFVBQVUsQ0FBQyxPQUFPLElBQUksSUFBSSxJQUFJLFVBQVUsQ0FBQyxPQUFPLElBQUksSUFBSSxFQUFFO3dCQUMxRCxJQUFJLENBQUMsY0FBYyxDQUFDLFVBQVUsQ0FBQyxPQUFPLEVBQUUsVUFBVSxDQUFDLE9BQU8sQ0FBQyxDQUFDO3FCQUMvRDtvQkFDRCxJQUFJLENBQUMsbUJBQW1CLEVBQUUsQ0FBQztvQkFDM0IsSUFBSSxDQUFDLFFBQVEsR0FBRyxJQUFJLENBQUM7b0JBQ3JCLElBQUksQ0FBQyxlQUFlLEVBQUUsQ0FBQztvQkFDdkIsSUFBSSxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsR0FBRyxFQUFFO3dCQUNsQixJQUFJLENBQUMsYUFBYSxFQUFFLENBQUM7d0JBQ3JCLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxDQUFDO29CQUMvQixDQUFDLENBQUMsQ0FBQztnQkFDUCxDQUFDLENBQUMsQ0FBQztZQUNYLENBQUMsQ0FBQyxDQUFDO1NBQ047SUFDTCxDQUFDO0lBRU0sTUFBTSxDQUFDLE9BQWU7UUFDekIsSUFBSSxZQUFZLEdBQUcsaUJBQWlCLENBQUMsT0FBTyxDQUFDLENBQUM7UUFDOUMsa0NBQWtDO1FBQ2xDLElBQUksWUFBWSxHQUFHLENBQUMsRUFBRTtZQUNsQixZQUFZLElBQUksR0FBRyxDQUFDO1NBQ3ZCO1FBQ0QsTUFBTSxXQUFXLEdBQUcsaUJBQWlCLENBQUMsQ0FBQyxJQUFJLENBQUMsU0FBUyxJQUFJLENBQUMsQ0FBQyxHQUFHLFlBQVksQ0FBQyxDQUFDO1FBQzVFLElBQUksV0FBVyxLQUFLLElBQUksQ0FBQyxTQUFTLEVBQUU7WUFDaEMsT0FBTztTQUNWO1FBQ0QsTUFBTSxVQUFVLEdBQUcsWUFBWSxHQUFHLElBQUksQ0FBQyxFQUFFLEdBQUcsR0FBRyxDQUFDO1FBQ2hELE1BQU0sTUFBTSxHQUFHLElBQUksQ0FBQyxVQUFVLENBQUMsYUFBYSxDQUFDO1FBQzdDLE1BQU0sVUFBVSxHQUFHLGVBQWUsQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUMzQyxNQUFNLEdBQUcsR0FBRyxNQUFNLENBQUMsVUFBVSxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQ3BDLElBQUksQ0FBQyxTQUFTLEdBQUcsV0FBVyxDQUFDO1FBRTdCLFFBQVE7UUFDUixHQUFHLENBQUMsU0FBUyxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsVUFBVSxDQUFDLEtBQUssRUFBRSxVQUFVLENBQUMsTUFBTSxDQUFDLENBQUM7UUFFekQsc0JBQXNCO1FBQ3RCLE1BQU0sU0FBUyxHQUFHLFVBQVUsWUFBWSxjQUFjLENBQUMsR0FBRyxJQUFJLENBQUMsU0FBUyxHQUFHLENBQUM7UUFDNUUsTUFBTSxlQUFlLEdBQUcsR0FBRyxJQUFJLENBQUMsUUFBUSxDQUFDLEVBQUUsTUFBTSxJQUFJLENBQUMsUUFBUSxDQUFDLEVBQUUsTUFBTSxDQUFDO1FBQ3hFLE1BQU0sQ0FBQyxLQUFLLENBQUMsU0FBUyxHQUFHLFNBQVMsQ0FBQztRQUNuQyx3Q0FBd0M7UUFDeEMsTUFBTSxDQUFDLEtBQUssQ0FBQyxlQUFlLEdBQUcsU0FBUyxDQUFDO1FBQ3pDLE1BQU0sQ0FBQyxLQUFLLENBQUMsZUFBZSxHQUFHLGVBQWUsQ0FBQztRQUMvQyx3Q0FBd0M7UUFDeEMsTUFBTSxDQUFDLEtBQUssQ0FBQyxxQkFBcUIsR0FBRyxlQUFlLENBQUM7UUFFckQsTUFBTSxFQUFFLElBQUksRUFBRSxHQUFHLEVBQUUsR0FBRyxNQUFNLENBQUMscUJBQXFCLEVBQWEsQ0FBQztRQUVoRSxZQUFZO1FBQ1osTUFBTSxVQUFVLEdBQUcsTUFBTSxDQUFDLHFCQUFxQixFQUFFLENBQUM7UUFFbEQsdUJBQXVCO1FBQ3ZCLE1BQU0sQ0FBQyxlQUFlLENBQUMsT0FBTyxDQUFDLENBQUM7UUFFaEMsWUFBWTtRQUNaLE1BQU0sQ0FBQyxHQUFHLFVBQVUsQ0FBQyxLQUFLLENBQUM7UUFDM0IsTUFBTSxDQUFDLEdBQUcsVUFBVSxDQUFDLE1BQU0sQ0FBQztRQUM1QixHQUFHLENBQUMsTUFBTSxDQUFDLEtBQUssR0FBRyxDQUFDLENBQUM7UUFDckIsR0FBRyxDQUFDLE1BQU0sQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDO1FBRXRCLFFBQVE7UUFDUixHQUFHLENBQUMsU0FBUyxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO1FBRTFCLHVCQUF1QjtRQUN2QixHQUFHLENBQUMsU0FBUyxDQUFDLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDO1FBQzVCLEdBQUcsQ0FBQyxNQUFNLENBQUMsVUFBVSxDQUFDLENBQUM7UUFDdkIsR0FBRyxDQUFDLFNBQVMsQ0FBQyxVQUFVLEVBQUUsQ0FBQyxVQUFVLENBQUMsS0FBSyxHQUFHLENBQUMsRUFBRSxDQUFDLFVBQVUsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDLENBQUM7UUFFekUsbUJBQW1CO1FBQ25CLElBQUksQ0FBQyxlQUFlLENBQUMsTUFBTSxDQUFDLENBQUM7UUFDN0IsSUFBSSxDQUFDLGVBQWUsRUFBRSxDQUFDO1FBRXZCLDJDQUEyQztRQUMzQyxJQUFJLElBQUksQ0FBQyxLQUFLLEdBQUcsSUFBSSxDQUFDLFFBQVEsRUFBRTtZQUM1QixJQUFJLENBQUMsUUFBUSxDQUFDLENBQUMsRUFBRSxJQUFJLENBQUMsQ0FBQztTQUMxQixDQUFDLCtCQUErQjtRQUVqQyxNQUFNLFFBQVEsR0FBRyxJQUFJLENBQUMsU0FBUyxFQUFFLENBQUM7UUFFbEMsSUFBSSxDQUFDLG9CQUFvQixDQUFDO1lBQ3RCLENBQUMsRUFBRSxDQUFDLElBQUksR0FBRyxRQUFRLENBQUMsSUFBSSxDQUFDO1lBQ3pCLENBQUMsRUFBRSxDQUFDLEdBQUcsR0FBRyxRQUFRLENBQUMsR0FBRyxDQUFDO1NBQzFCLENBQUMsQ0FBQztRQUVILDhCQUE4QjtRQUM5QixNQUFNLGNBQWMsR0FBRyxFQUFDLEdBQUcsSUFBSSxDQUFDLFFBQVEsRUFBQyxDQUFDO1FBQzFDLElBQUksQ0FBQyxNQUFNLEdBQUc7WUFDVixDQUFDLEVBQUUsY0FBYyxDQUFDLENBQUM7WUFDbkIsQ0FBQyxFQUFFLGNBQWMsQ0FBQyxDQUFDO1lBQ25CLElBQUksRUFBRSxjQUFjLENBQUMsRUFBRTtZQUN2QixHQUFHLEVBQUUsY0FBYyxDQUFDLEVBQUU7U0FDekIsQ0FBQztRQUNGLElBQUksQ0FBQyxvQkFBb0IsQ0FBQyxFQUFFLENBQUMsQ0FBQztRQUM5QixJQUFJLENBQUMsb0JBQW9CLEVBQUUsQ0FBQztRQUU1QixJQUFJLENBQUMsZUFBZSxFQUFFLENBQUM7SUFDM0IsQ0FBQztJQUVNLGVBQWUsQ0FBQyxNQUEwQjtRQUM3QyxJQUFJLENBQUMsTUFBTSxFQUFFO1lBQ1QsTUFBTSxHQUFHLElBQUksQ0FBQyxVQUFVLENBQUMsYUFBYSxDQUFDO1NBQzFDO1FBQ0QsTUFBTSxNQUFNLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQztRQUMzQixNQUFNLFFBQVEsR0FBRyxDQUFDLE1BQU0sQ0FBQyxZQUFZLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FDeEQsTUFBTSxDQUFDLEtBQUssR0FBRyxNQUFNLENBQUMsS0FBSyxFQUMzQixNQUFNLENBQUMsTUFBTSxHQUFHLE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUNuQyxJQUFJLENBQUMsU0FBUyxHQUFHLFFBQVEsQ0FBQztRQUMxQixJQUFJLENBQUMsY0FBYyxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQztJQUN2QyxDQUFDO0lBRU8sZUFBZTtRQUNuQixNQUFNLFFBQVEsR0FBRyxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsS0FBSyxHQUFHLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxDQUFDO1FBQzlELElBQUksQ0FBQyxTQUFTLEdBQUcsUUFBUSxDQUFDO1FBQzFCLElBQUksQ0FBQyxjQUFjLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDO0lBQ3ZDLENBQUM7SUFFRDs7T0FFRztJQUNJLElBQUksQ0FBQyxNQUF5QjtRQUNqQyxNQUFNLFNBQVMsR0FBRyxNQUFNO1lBQ3BCLENBQUMsQ0FBQyxTQUFTLENBQUMsRUFBRyxFQUFFLElBQUksQ0FBQyxNQUFNLElBQUksSUFBSSxnQkFBZ0IsRUFBRSxFQUFFLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDO1FBQ2xGLE1BQU0sU0FBUyxHQUFHLElBQUksQ0FBQyxRQUFRLENBQUMsU0FBUyxDQUFDLENBQUM7UUFDM0MsSUFBSSxDQUFDLEVBQUUsQ0FBQyxZQUFZLEVBQUUsQ0FBQztRQUN2QixPQUFPLFNBQVMsQ0FBQztJQUNyQixDQUFDO0lBRUQ7O09BRUc7SUFDSyxRQUFRLENBQUMsUUFBMEI7UUFDdkMsTUFBTSxhQUFhLEdBQXNCLFFBQVEsQ0FBQyxhQUFhLENBQUMsUUFBUSxDQUFDLENBQUM7UUFDMUUsTUFBTSxRQUFRLEdBQUcsSUFBSSxDQUFDLGdCQUFnQixFQUFFLENBQUM7UUFDekMsTUFBTSxVQUFVLEdBQUcsSUFBSSxDQUFDLFdBQVcsRUFBRSxDQUFDO1FBQ3RDLE1BQU0sUUFBUSxHQUFHLElBQUksQ0FBQyxTQUFTLENBQUM7UUFDaEMsTUFBTSxJQUFJLEdBQUcsQ0FBQyxRQUFRLENBQUMsSUFBSSxHQUFHLFVBQVUsQ0FBQyxJQUFJLENBQUMsR0FBRyxRQUFRLENBQUM7UUFDMUQsTUFBTSxHQUFHLEdBQUcsQ0FBQyxRQUFRLENBQUMsR0FBRyxHQUFHLFVBQVUsQ0FBQyxHQUFHLENBQUMsR0FBRyxRQUFRLENBQUM7UUFDdkQsTUFBTSxFQUFFLE1BQU0sRUFBRSxHQUFHLFFBQVEsQ0FBQztRQUM1QixNQUFNLHNCQUFzQixHQUFHLElBQUksQ0FBQyxrQkFBa0IsQ0FBQztRQUN2RCxNQUFNLElBQUksR0FBRztZQUNULEtBQUssRUFBRSxRQUFRLENBQUMsS0FBSztZQUNyQixNQUFNLEVBQUUsUUFBUSxDQUFDLE1BQU07U0FDMUIsQ0FBQztRQUNGLGFBQWEsQ0FBQyxLQUFLLEdBQUcsSUFBSSxDQUFDLEtBQUssR0FBRyxRQUFRLENBQUM7UUFDNUMsYUFBYSxDQUFDLE1BQU0sR0FBRyxJQUFJLENBQUMsTUFBTSxHQUFHLFFBQVEsQ0FBQztRQUM5QyxNQUFNLEdBQUcsR0FBRyxhQUFhLENBQUMsVUFBVSxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQzNDLElBQUksUUFBUSxDQUFDLElBQUksRUFBRTtZQUNmLEdBQUcsQ0FBQyxTQUFTLEdBQUcsUUFBUSxDQUFDLElBQUksQ0FBQztZQUM5QixHQUFHLENBQUMsUUFBUSxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsYUFBYSxDQUFDLEtBQUssRUFBRSxhQUFhLENBQUMsTUFBTSxDQUFDLENBQUM7U0FDakU7UUFDRCxHQUFHLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsYUFBYSxFQUN2QyxDQUFDLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUNsQixDQUFDO1FBQ0YsTUFBTSxNQUFNLEdBQUcsYUFBYSxDQUFDO1FBQzdCLElBQUksUUFBUSxDQUFDLE1BQU0sS0FBSyxhQUFhLENBQUMsT0FBTyxFQUFFO1lBQzNDLFlBQVksQ0FDUixNQUFNLEVBQ04sSUFBSSxDQUFDLGNBQWMsQ0FBQyxLQUFLLEVBQ3pCLElBQUksQ0FBQyxjQUFjLENBQUMsTUFBTSxDQUFDLENBQUM7U0FDbkM7YUFBTSxJQUFJLE9BQU8sTUFBTSxLQUFLLFFBQVEsRUFBRTtZQUNuQyxJQUFJLE1BQU0sQ0FBQyxLQUFLLElBQUksTUFBTSxDQUFDLE1BQU0sRUFBRTtnQkFDL0IsWUFBWSxDQUFDLE1BQU0sRUFBRSxNQUFNLENBQUMsS0FBSyxFQUFFLE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FBQzthQUNyRDtpQkFBTSxJQUFJLE1BQU0sQ0FBQyxLQUFLLEVBQUU7Z0JBQ3JCLE1BQU0sU0FBUyxHQUFHLElBQUksQ0FBQyxNQUFNLEdBQUcsTUFBTSxDQUFDLEtBQUssR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDO2dCQUMxRCxZQUFZLENBQUMsTUFBTSxFQUFFLE1BQU0sQ0FBQyxLQUFLLEVBQUUsU0FBUyxDQUFDLENBQUM7YUFDakQ7aUJBQU0sSUFBSSxNQUFNLENBQUMsTUFBTSxFQUFFO2dCQUN0QixNQUFNLFFBQVEsR0FBRyxJQUFJLENBQUMsS0FBSyxHQUFHLE1BQU0sQ0FBQyxNQUFNLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQztnQkFDMUQsWUFBWSxDQUFDLE1BQU0sRUFBRSxRQUFRLEVBQUUsTUFBTSxDQUFDLE1BQU0sQ0FBQyxDQUFDO2FBQ2pEO1NBQ0o7UUFDRCxNQUFNLElBQUksR0FBRyxzQkFBc0IsQ0FBQyxlQUFlLENBQUMsVUFBVSxDQUFDLE1BQU0sQ0FBQztZQUNsRSxDQUFDLENBQUMsc0JBQXNCLENBQUMsSUFBSSxJQUFJLFFBQVEsQ0FBQyxJQUFJO1lBQzlDLENBQUMsQ0FBQyxRQUFRLENBQUMsSUFBSSxJQUFJLHNCQUFzQixDQUFDLElBQUksQ0FBQztRQUNuRCxNQUFNLE9BQU8sR0FBRyxNQUFNLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQ3ZDLE1BQU0sU0FBUyxHQUFvQjtZQUMvQixPQUFPO1lBQ1AsSUFBSTtZQUNKLElBQUksRUFBRSxzQkFBc0IsQ0FBQyxJQUFJO1lBQ2pDLFNBQVMsRUFBRSxJQUFJLENBQUMsaUJBQWlCO1lBQ2pDLFVBQVUsRUFBRSxJQUFJLENBQUMsa0JBQWtCO1lBQ25DLEtBQUssRUFBRSxNQUFNLENBQUMsS0FBSztZQUNuQixNQUFNLEVBQUUsTUFBTSxDQUFDLE1BQU07WUFDckIsZUFBZSxFQUFFLHNCQUFzQixDQUFDLGVBQWU7WUFDdkQsS0FBSyxFQUFFLElBQUksQ0FBQyxjQUFjO1lBQzFCLFFBQVEsRUFBRSxJQUFJLENBQUMsU0FBUztZQUN4QixJQUFJLEVBQUUsQ0FBQyxRQUFRLENBQUMsSUFBSSxHQUFHLFVBQVUsQ0FBQyxJQUFJLENBQUMsR0FBRyxJQUFJLENBQUMsU0FBUztZQUN4RCxHQUFHLEVBQUUsQ0FBQyxRQUFRLENBQUMsR0FBRyxHQUFHLFVBQVUsQ0FBQyxHQUFHLENBQUMsR0FBRyxJQUFJLENBQUMsU0FBUztZQUNyRCxJQUFJLEVBQUUsc0JBQXNCLENBQUMsSUFBSTtZQUNqQyxPQUFPLEVBQUUsSUFBSSxDQUFDLFFBQVEsQ0FBQyxFQUFFO1lBQ3pCLE9BQU8sRUFBRSxJQUFJLENBQUMsUUFBUSxDQUFDLEVBQUU7WUFDekIsUUFBUSxFQUFFO2dCQUNOLENBQUMsRUFBRSxJQUFJLENBQUMsUUFBUSxDQUFDLEVBQUU7Z0JBQ25CLENBQUMsRUFBRSxJQUFJLENBQUMsUUFBUSxDQUFDLEVBQUU7YUFDdEI7U0FDSixDQUFDO1FBRUYsSUFBSSxDQUFDLFNBQVMsR0FBRyxJQUFJLENBQUM7UUFDdEIsSUFBSSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLENBQUM7UUFDN0IsT0FBTyxTQUFTLENBQUM7SUFDckIsQ0FBQztJQUVNLFNBQVM7UUFDWixPQUFPLElBQUksQ0FBQyxXQUFXLENBQUMsYUFBYSxDQUFDLHFCQUFxQixFQUFhLENBQUM7SUFDN0UsQ0FBQztJQUVNLGdCQUFnQjtRQUNuQixPQUFPLElBQUksQ0FBQyxRQUFRLENBQUMsYUFBYSxDQUFDLHFCQUFxQixFQUFhLENBQUM7SUFDMUUsQ0FBQztJQUVNLFdBQVc7UUFDZCxPQUFPLElBQUksQ0FBQyxVQUFVLENBQUMsYUFBYSxDQUFDLHFCQUFxQixFQUFFLENBQUM7SUFDakUsQ0FBQztJQXVCTyxpQkFBaUIsQ0FBQyxZQUFxQztRQUMzRCxNQUFNLE9BQU8sR0FBRyxJQUFJLENBQUMsU0FBUyxDQUFDO1FBQy9CLE1BQU0sT0FBTyxHQUFHLFlBQVksQ0FBQyxZQUFZLENBQUMsQ0FBQztRQUMzQyxNQUFNLGFBQWEsR0FBRyxPQUFPLENBQUMsQ0FBQyxDQUFDLFdBQVcsQ0FBQyxDQUFDLENBQUMsV0FBVyxDQUFDO1FBQzFELE1BQU0sWUFBWSxHQUFHLE9BQU8sQ0FBQyxDQUFDLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUM7UUFDdEQsT0FBTyxDQUFDLGdCQUFnQixDQUFDLGFBQWEsRUFBRSxJQUFJLENBQUMsWUFBWSxFQUFFLGtCQUFrQixDQUFDLENBQUM7UUFDL0UsT0FBTyxDQUFDLGdCQUFnQixDQUFDLFlBQVksRUFBRSxJQUFJLENBQUMsVUFBVSxFQUFFLGtCQUFrQixDQUFDLENBQUM7UUFFNUUsSUFBSSxPQUFPLEVBQUU7WUFDVCxPQUFPLENBQUMsZ0JBQWdCLENBQUMsYUFBYSxFQUFFLElBQUksQ0FBQyxVQUFVLEVBQUUsa0JBQWtCLENBQUMsQ0FBQztTQUNoRjtRQUVELE1BQU0sTUFBTSxHQUFHLElBQUksQ0FBQyxVQUFVLEVBQUUsQ0FBQztRQUVqQyxJQUFJLE9BQU8sTUFBTSxLQUFLLFdBQVcsSUFBSSxNQUFNLEVBQUU7WUFDekMsTUFBTSxDQUFDLGdCQUFnQixDQUFDLE1BQU0sRUFBRSxJQUFJLENBQUMsV0FBVyxDQUFDLENBQUM7U0FDckQ7SUFDTCxDQUFDO0lBRUQsaUVBQWlFO0lBQ3pELG1CQUFtQjtRQUN2QixNQUFNLE9BQU8sR0FBRyxJQUFJLENBQUMsU0FBUyxDQUFDO1FBQy9CLE9BQU8sQ0FBQyxtQkFBbUIsQ0FBQyxXQUFXLEVBQUUsSUFBSSxDQUFDLFlBQVksRUFBRSxrQkFBa0IsQ0FBQyxDQUFDO1FBQ2hGLE9BQU8sQ0FBQyxtQkFBbUIsQ0FBQyxTQUFTLEVBQUUsSUFBSSxDQUFDLFVBQVUsRUFBRSxrQkFBa0IsQ0FBQyxDQUFDO1FBQzVFLE9BQU8sQ0FBQyxtQkFBbUIsQ0FBQyxXQUFXLEVBQUUsSUFBSSxDQUFDLFlBQVksRUFBRSxrQkFBa0IsQ0FBQyxDQUFDO1FBQ2hGLE9BQU8sQ0FBQyxtQkFBbUIsQ0FBQyxVQUFVLEVBQUUsSUFBSSxDQUFDLFVBQVUsRUFBRSxrQkFBa0IsQ0FBQyxDQUFDO1FBQzdFLE9BQU8sQ0FBQyxtQkFBbUIsQ0FBQyxhQUFhLEVBQUUsSUFBSSxDQUFDLFVBQVUsRUFBRSxrQkFBa0IsQ0FBQyxDQUFDO1FBRWhGLE1BQU0sTUFBTSxHQUFHLElBQUksQ0FBQyxVQUFVLEVBQUUsQ0FBQztRQUVqQyxJQUFJLE9BQU8sTUFBTSxLQUFLLFdBQVcsSUFBSSxNQUFNLEVBQUU7WUFDekMsTUFBTSxDQUFDLG1CQUFtQixDQUFDLE1BQU0sRUFBRSxJQUFJLENBQUMsV0FBVyxDQUFDLENBQUM7U0FDeEQ7SUFDTCxDQUFDO0lBRUQsK0ZBQStGO0lBQ3ZGLFVBQVU7UUFDZCxPQUFPLElBQUksQ0FBQyxTQUFTLENBQUMsV0FBVyxJQUFJLE1BQU0sQ0FBQztJQUNoRCxDQUFDOzhHQXA5QlEseUJBQXlCLDRIQStJdEIsUUFBUTtrR0EvSVgseUJBQXlCLHdoQkFrRE4sVUFBVSxzSUM1UTFDLHd3QkFxQkEsOCtDRHd5Q2Esd0JBQXdCOzsyRkFubUN4Qix5QkFBeUI7a0JBUnJDLFNBQVM7c0NBQ1csdUJBQXVCLENBQUMsTUFBTSx1QkFDMUIsS0FBSyxZQUNoQixzQ0FBc0MsaUJBR2pDLGlCQUFpQixDQUFDLElBQUk7OzBCQWlKaEMsTUFBTTsyQkFBQyxRQUFRO3dFQS9GWixhQUFhO3NCQURwQixTQUFTO3VCQUFDLGVBQWUsRUFBRSxFQUFFLE1BQU0sRUFBRSxJQUFJLEVBQUU7Z0JBSXBDLFFBQVE7c0JBRGYsU0FBUzt1QkFBQyxPQUFPLEVBQUUsRUFBRSxJQUFJLEVBQUUsVUFBVSxFQUFFO2dCQUdoQyxVQUFVO3NCQURqQixTQUFTO3VCQUFDLFlBQVksRUFBRSxFQUFFLE1BQU0sRUFBRSxJQUFJLEVBQUU7Z0JBSTlCLE1BQU07c0JBRGhCLEtBQUs7Z0JBc0JLLEtBQUs7c0JBRGYsS0FBSztnQkFhQyxXQUFXO3NCQURqQixLQUFLO2dCQVNXLFdBQVc7c0JBRDNCLE1BQU07Z0JBTVUsY0FBYztzQkFEOUIsTUFBTTt1QkFBQyxVQUFVO2dCQU1ELGNBQWM7c0JBRDlCLE1BQU07dUJBQUMsVUFBVTtnQkFLRCxXQUFXO3NCQUQzQixNQUFNO2dCQUtVLEtBQUs7c0JBRHJCLE1BQU07Z0JBS1UsT0FBTztzQkFEdkIsTUFBTTtnQkFLVSxPQUFPO3NCQUR2QixNQUFNO2dCQU1VLEtBQUs7c0JBRHJCLE1BQU07O0FBeTFCWDs7O0dBR0c7QUFDSCxNQUFNLFVBQVUsaUJBQWlCLENBQUMsQ0FBUztJQUN2QyxNQUFNLEVBQUUsR0FBRyxDQUFDLEdBQUcsR0FBRyxDQUFDO0lBQ25CLElBQUksRUFBRSxHQUFHLEVBQUUsRUFBRTtRQUNULE1BQU0sSUFBSSxLQUFLLENBQUMsd0JBQXdCLENBQUMseURBQXlELENBQUMsQ0FBQztLQUN2RztJQUNELE9BQU8sRUFBRSxDQUFDO0FBQ2QsQ0FBQztBQUVEOztHQUVHO0FBQ0gsU0FBUyxlQUFlLENBQUMsR0FBeUM7SUFFOUQsc0JBQXNCO0lBQ3RCLE1BQU0sU0FBUyxHQUFHLFFBQVEsQ0FBQyxhQUFhLENBQUMsUUFBUSxDQUFDLENBQUM7SUFDbkQsTUFBTSxPQUFPLEdBQUcsU0FBUyxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUUzQyxpQkFBaUI7SUFDakIsU0FBUyxDQUFDLEtBQUssR0FBRyxHQUFHLENBQUMsS0FBSyxDQUFDO0lBQzVCLFNBQVMsQ0FBQyxNQUFNLEdBQUcsR0FBRyxDQUFDLE1BQU0sQ0FBQztJQUU5QixzQ0FBc0M7SUFDdEMsT0FBTyxDQUFDLFNBQVMsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO0lBRTdCLHdCQUF3QjtJQUN4QixPQUFPLFNBQVMsQ0FBQztBQUNyQixDQUFDO0FBR0QsTUFBTSxxQkFBcUIsR0FBRyw0QkFBNEIsQ0FBQztBQUUzRCxTQUFTLFlBQVksQ0FBQyxPQUFlO0lBQ2pDLElBQUksTUFBTSxDQUFDLElBQUksSUFBSSxVQUFVLENBQUMsT0FBTyxDQUFDLEVBQUU7UUFDcEMsTUFBTSxHQUFHLEdBQUcsT0FBTyxDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUM7UUFDL0IsTUFBTSxJQUFJLEdBQUcsTUFBTSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsT0FBTyxDQUFDLHFCQUFxQixFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUM7UUFDckUsTUFBTSxJQUFJLEdBQUcsUUFBUSxDQUFDLGFBQWEsQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUM1QyxJQUFJLENBQUMsU0FBUyxHQUFHLElBQUksQ0FBQztRQUN0QixNQUFNLEdBQUcsR0FBRyxJQUFJLENBQUMsYUFBYSxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQ3RDLElBQUksQ0FBQyxZQUFZLENBQUMsT0FBTyxFQUFFLGNBQWMsQ0FBQyxDQUFDO1FBQzNDLFFBQVEsQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQ2hDLE1BQU0sS0FBSyxHQUFHLFVBQVUsQ0FBQyxnQkFBZ0IsQ0FBQyxHQUFHLENBQUMsQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDM0QsTUFBTSxNQUFNLEdBQUcsVUFBVSxDQUFDLGdCQUFnQixDQUFDLEdBQUcsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUM3RCxNQUFNLEdBQUcsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLEtBQUssRUFBRSxNQUFNLENBQUMsQ0FBQztRQUVwQyxHQUFHLENBQUMsWUFBWSxDQUFDLE9BQU8sRUFBRSxHQUFHLEdBQUcsR0FBRyxDQUFDLEtBQUssR0FBRyxHQUFHLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDdEQsR0FBRyxDQUFDLFlBQVksQ0FBQyxRQUFRLEVBQUUsR0FBRyxHQUFHLEdBQUcsQ0FBQyxNQUFNLEdBQUcsR0FBRyxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQ3hELE1BQU0sTUFBTSxHQUFHLHFCQUFxQixHQUFHLE1BQU0sQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxDQUFDO1FBQ25FLFFBQVEsQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQ2hDLE9BQU8sTUFBTSxDQUFDO0tBQ2pCO0lBQ0QsT0FBTyxPQUFPLENBQUM7QUFDbkIsQ0FBQztBQUVELFNBQVMsVUFBVSxDQUFDLE9BQWU7SUFDL0IsT0FBTyxPQUFPLENBQUMsVUFBVSxDQUFDLHFCQUFxQixDQUFDLENBQUM7QUFDckQsQ0FBQztBQUVELFNBQVMsYUFBYSxDQUFDLEdBQVc7SUFDOUIsTUFBTSxHQUFHLEdBQUcsSUFBSSxLQUFLLEVBQUUsQ0FBQztJQUN4QixHQUFHLENBQUMsV0FBVyxHQUFHLFdBQVcsQ0FBQztJQUM5QixHQUFHLENBQUMsR0FBRyxHQUFHLEdBQUcsQ0FBQztJQUNkLE9BQU8sR0FBRyxDQUFDO0FBQ2YsQ0FBQztBQUdELFNBQVMsd0JBQXdCLENBQUMsS0FBOEI7SUFFNUQsNEZBQTRGO0lBQzVGLE1BQU0sS0FBSyxHQUFHLFlBQVksQ0FBQyxLQUFLLENBQUM7UUFDN0IsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsSUFBSSxLQUFLLENBQUMsY0FBYyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQy9DLENBQUMsQ0FBQyxLQUFLLENBQUM7SUFFWixPQUFPO1FBQ0gsQ0FBQyxFQUFFLEtBQUssQ0FBQyxPQUFPO1FBQ2hCLENBQUMsRUFBRSxLQUFLLENBQUMsT0FBTztLQUNuQixDQUFDO0FBQ04sQ0FBQztBQUVELGlEQUFpRDtBQUNqRCxTQUFTLFlBQVksQ0FBQyxLQUE4QjtJQUNoRCxPQUFPLEtBQUssQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLEtBQUssR0FBRyxDQUFDO0FBQ2pDLENBQUM7QUFFRCxNQUFNLFVBQVUsS0FBSyxDQUFDLENBQVM7SUFDM0IsT0FBTyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ3pCLENBQUM7QUFFRDs7O0dBR0c7QUFDSCxTQUFTLFFBQVEsQ0FBQyxJQUFJO0lBQ2xCLE9BQU8sQ0FBQyxJQUFJLElBQUksT0FBTyxJQUFJLEtBQUssUUFBUSxJQUFJLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDO0FBQ3RFLENBQUM7QUFPRDs7OztHQUlHO0FBQ0gsTUFBTSxVQUFVLFNBQVMsQ0FBQyxNQUFXLEVBQUUsR0FBRyxPQUFjO0lBQ3BELElBQUksQ0FBQyxPQUFPLENBQUMsTUFBTSxFQUFFO1FBQUUsT0FBTyxNQUFNLENBQUM7S0FBRTtJQUN2QyxNQUFNLE1BQU0sR0FBRyxPQUFPLENBQUMsS0FBSyxFQUFFLENBQUM7SUFFL0IsSUFBSSxRQUFRLENBQUMsTUFBTSxDQUFDLElBQUksUUFBUSxDQUFDLE1BQU0sQ0FBQyxFQUFFO1FBQ3RDLEtBQUssTUFBTSxHQUFHLElBQUksTUFBTSxFQUFFO1lBQ3RCLElBQUksUUFBUSxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQyxFQUFFO2dCQUN2QixJQUFJLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxFQUFFO29CQUFFLE1BQU0sQ0FBQyxNQUFNLENBQUMsTUFBTSxFQUFFLEVBQUUsQ0FBQyxHQUFHLENBQUMsRUFBRSxFQUFFLEVBQUUsQ0FBQyxDQUFDO2lCQUFFO2dCQUMzRCxTQUFTLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxFQUFFLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDO2FBQ3ZDO2lCQUFNO2dCQUNILE1BQU0sQ0FBQyxNQUFNLENBQUMsTUFBTSxFQUFFLEVBQUUsQ0FBQyxHQUFHLENBQUMsRUFBRSxNQUFNLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxDQUFDO2FBQ2pEO1NBQ0o7S0FDSjtJQUVELE9BQU8sU0FBUyxDQUFDLE1BQU0sRUFBRSxHQUFHLE9BQU8sQ0FBQyxDQUFDO0FBQ3pDLENBQUM7QUFHRDs7R0FFRztBQVNILE1BQU0sT0FBTyx3QkFBd0I7SUEwQmpDLFlBQ3NCLFNBQWMsRUFDZixXQUF1QixFQUN2QixRQUFtQyxFQUNuQyxPQUFlO1FBRmYsZ0JBQVcsR0FBWCxXQUFXLENBQVk7UUFDdkIsYUFBUSxHQUFSLFFBQVEsQ0FBMkI7UUFDbkMsWUFBTyxHQUFQLE9BQU8sQ0FBUTtRQStDNUIsaUJBQVksR0FBRyxDQUFDLEtBQThCLEVBQUUsRUFBRTtZQUN0RCwyQkFBMkI7WUFDM0IsMkRBQTJEO1lBQzNELElBQUksSUFBSSxDQUFDLFVBQVUsSUFBSSxDQUFDLENBQUMsWUFBWSxDQUFDLEtBQUssQ0FBQyxJQUFJLEtBQUssQ0FBQyxNQUFNLEtBQUssQ0FBQyxDQUFDLEVBQUU7Z0JBQ2pFLE9BQU87YUFDVjtZQUVELEtBQUssQ0FBQyxjQUFjLEVBQUUsQ0FBQztZQUV2QixJQUFJLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxHQUFHLEVBQUU7Z0JBQ2xCLElBQUksQ0FBQyxVQUFVLEdBQUcsSUFBSSxDQUFDO2dCQUN2QixJQUFJLENBQUMsaUJBQWlCLEdBQUcsS0FBSyxDQUFDO2dCQUMvQixJQUFJLENBQUMsa0JBQWtCLEdBQUcsd0JBQXdCLENBQUMsS0FBSyxDQUFDLENBQUM7Z0JBQzFELElBQUksQ0FBQyxjQUFjLEdBQUcsSUFBSSxDQUFDLFFBQVEsQ0FBQyxnQkFBZ0IsRUFBRSxDQUFDO2dCQUN2RCxJQUFJLENBQUMsYUFBYSxHQUFHLElBQUksQ0FBQyxRQUFRLENBQUMsV0FBVyxFQUFFLENBQUM7Z0JBQ2pELEtBQUssQ0FBQyxjQUFjLEVBQUUsQ0FBQztnQkFDdkIsSUFBSSxDQUFDLGlCQUFpQixDQUFDLEtBQUssQ0FBQyxDQUFDO1lBQ2xDLENBQUMsQ0FBQyxDQUFDO1FBQ1AsQ0FBQyxDQUFBO1FBRU8saUJBQVksR0FBRyxDQUFDLEtBQThCLEVBQUUsRUFBRTtZQUN0RCxJQUFJLElBQUksQ0FBQyxVQUFVLEVBQUU7Z0JBQ2pCLEtBQUssQ0FBQyxjQUFjLEVBQUUsQ0FBQztnQkFDdkIsSUFBSSxDQUFDLGlCQUFpQixHQUFHLEtBQUssQ0FBQztnQkFDL0IsTUFBTSxPQUFPLEdBQW1CLElBQUksQ0FBQyxXQUFXLENBQUMsYUFBYSxDQUFDO2dCQUMvRCxNQUFNLEVBQUMsS0FBSyxFQUFFLE1BQU0sRUFBRSxRQUFRLEVBQUUsU0FBUyxFQUFDLEdBQUcsSUFBSSxDQUFDLFFBQVEsQ0FBQyxNQUFNLENBQUM7Z0JBQ2xFLE1BQU0sS0FBSyxHQUFHLHdCQUF3QixDQUFDLEtBQUssQ0FBQyxDQUFDO2dCQUM5QyxNQUFNLE1BQU0sR0FBRyxLQUFLLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxDQUFDLENBQUM7Z0JBQ25ELE1BQU0sTUFBTSxHQUFHLEtBQUssQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLGtCQUFrQixDQUFDLENBQUMsQ0FBQztnQkFDbkQsTUFBTSxhQUFhLEdBQUcsSUFBSSxDQUFDLGNBQWMsQ0FBQztnQkFDMUMsTUFBTSxZQUFZLEdBQUcsSUFBSSxDQUFDLGFBQWEsQ0FBQztnQkFDeEMsTUFBTSxPQUFPLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQztnQkFDM0IsTUFBTSxlQUFlLEdBQUcsSUFBSSxDQUFDLFFBQVEsQ0FBQyxNQUFNLENBQUMsZUFBZSxJQUFJLEtBQUssQ0FBQyxRQUFRLENBQUM7Z0JBQy9FLElBQUksUUFBUSxHQUFHLENBQUMsQ0FBQztnQkFDakIsSUFBSSxTQUFTLEdBQUcsQ0FBQyxDQUFDO2dCQUNsQixNQUFNLFFBQVEsR0FBRyxJQUFJLENBQUMsUUFBUSxDQUFDLFNBQVMsRUFBRSxDQUFDO2dCQUUzQyxJQUFJLE9BQU8sRUFBRTtvQkFDVCxrRUFBa0U7b0JBQ2xFLE1BQU0sT0FBTyxHQUFHLENBQUMsQ0FBQyxLQUFLLEdBQUcsQ0FBQyxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxNQUFNLENBQUMsQ0FBQztvQkFDdEQsTUFBTSxPQUFPLEdBQUcsQ0FBQyxDQUFDLE1BQU0sR0FBRyxDQUFDLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLE1BQU0sQ0FBQyxDQUFDO29CQUV2RCxNQUFNO29CQUNOLE1BQU0sSUFBSSxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsT0FBTyxJQUFJLENBQUMsR0FBRyxPQUFPLElBQUksQ0FBQyxDQUFDLENBQUM7b0JBQ3BELFFBQVEsR0FBRyxTQUFTLEdBQUcsSUFBSSxHQUFHLENBQUMsQ0FBQztpQkFFbkM7cUJBQU0sSUFBSSxlQUFlLEVBQUU7b0JBQ3hCLFFBQVEsR0FBRyxLQUFLLEdBQUcsTUFBTSxHQUFHLENBQUMsQ0FBQztvQkFDOUIsU0FBUyxHQUFHLE1BQU0sR0FBRyxNQUFNLEdBQUcsQ0FBQyxDQUFDO29CQUNoQyxJQUFJLEtBQUssS0FBSyxNQUFNLEVBQUU7d0JBQ2xCLElBQUksS0FBSyxHQUFHLE1BQU0sRUFBRTs0QkFDaEIsU0FBUyxHQUFHLE1BQU0sR0FBRyxDQUFDLEtBQUssR0FBRyxRQUFRLENBQUMsQ0FBQzt5QkFDM0M7NkJBQU0sSUFBSSxNQUFNLEdBQUcsS0FBSyxFQUFFOzRCQUN2QixRQUFRLEdBQUcsS0FBSyxHQUFHLENBQUMsTUFBTSxHQUFHLFNBQVMsQ0FBQyxDQUFDO3lCQUMzQztxQkFDSjt5QkFBTTt3QkFDSCxRQUFRLEdBQUcsU0FBUyxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsUUFBUSxFQUFFLFNBQVMsQ0FBQyxDQUFDO3FCQUN4RDtpQkFDSjtxQkFBTTtvQkFDSCxRQUFRLEdBQUcsS0FBSyxHQUFHLE1BQU0sR0FBRyxDQUFDLENBQUM7b0JBQzlCLFNBQVMsR0FBRyxNQUFNLEdBQUcsTUFBTSxHQUFHLENBQUMsQ0FBQztpQkFDbkM7Z0JBRUQsZUFBZTtnQkFDZixJQUFJLFFBQVEsR0FBRyxRQUFRLEVBQUU7b0JBQ3JCLFFBQVEsR0FBRyxRQUFRLENBQUM7aUJBQ3ZCO2dCQUNELGdCQUFnQjtnQkFDaEIsSUFBSSxTQUFTLEdBQUcsU0FBUyxFQUFFO29CQUN2QixTQUFTLEdBQUcsU0FBUyxDQUFDO2lCQUN6QjtnQkFFRCxtQ0FBbUM7Z0JBQ25DLE1BQU0sT0FBTyxHQUFHLGFBQWEsQ0FBQyxDQUFDLEdBQUcsYUFBYSxDQUFDLEtBQUssR0FBRyxDQUFDLENBQUM7Z0JBQzFELE1BQU0sT0FBTyxHQUFHLGFBQWEsQ0FBQyxDQUFDLEdBQUcsYUFBYSxDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUM7Z0JBQzNELE1BQU0sV0FBVyxHQUFHLFlBQVksQ0FBQyxDQUFDLEdBQUcsT0FBTyxHQUFHLENBQUMsU0FBUyxHQUFHLENBQUMsQ0FBQyxDQUFDO2dCQUMvRCxNQUFNLGNBQWMsR0FBRyxPQUFPLEdBQUcsQ0FBQyxTQUFTLEdBQUcsQ0FBQyxDQUFDLEdBQUcsWUFBWSxDQUFDLE1BQU0sQ0FBQztnQkFDdkUsTUFBTSxtQkFBbUIsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsT0FBTyxHQUFHLFlBQVksQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxZQUFZLENBQUMsTUFBTSxHQUFHLE9BQU8sQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDO2dCQUMxRyxNQUFNLFlBQVksR0FBRyxZQUFZLENBQUMsQ0FBQyxHQUFHLE9BQU8sR0FBRyxDQUFDLFFBQVEsR0FBRyxDQUFDLENBQUMsQ0FBQztnQkFDL0QsTUFBTSxhQUFhLEdBQUcsT0FBTyxHQUFHLENBQUMsUUFBUSxHQUFHLENBQUMsQ0FBQyxHQUFHLFlBQVksQ0FBQyxLQUFLLENBQUM7Z0JBQ3BFLE1BQU0sa0JBQWtCLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLE9BQU8sR0FBRyxZQUFZLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsWUFBWSxDQUFDLEtBQUssR0FBRyxPQUFPLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQztnQkFDeEcsTUFBTSxhQUFhLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxrQkFBa0IsRUFBRSxtQkFBbUIsQ0FBQyxDQUFDO2dCQUN4RSxJQUFJLEtBQUssRUFBRTtvQkFDUCxJQUFJLFdBQVcsSUFBSSxjQUFjLElBQUksWUFBWSxJQUFJLGFBQWEsRUFBRTt3QkFDaEUsU0FBUyxHQUFHLFFBQVEsR0FBRyxhQUFhLENBQUM7cUJBQ3hDO2lCQUNKO3FCQUFNLElBQUksZUFBZSxFQUFFO29CQUN4QixNQUFNLFdBQVcsR0FBYSxFQUFFLENBQUM7b0JBQ2pDLE1BQU0sWUFBWSxHQUFhLEVBQUUsQ0FBQztvQkFDbEMsSUFBSSxDQUFDLFdBQVcsSUFBSSxjQUFjLENBQUMsSUFBSSxJQUFJLENBQUMsR0FBRyxFQUFFLEVBQUU7d0JBQy9DLFNBQVMsR0FBRyxtQkFBbUIsQ0FBQzt3QkFDaEMsWUFBWSxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQzt3QkFDN0IsUUFBUSxHQUFHLEtBQUssR0FBRyxDQUFDLE1BQU0sR0FBRyxtQkFBbUIsQ0FBQyxDQUFDO3dCQUNsRCxXQUFXLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDO3FCQUM5QjtvQkFDRCxJQUFJLENBQUMsWUFBWSxJQUFJLGFBQWEsQ0FBQyxFQUFFO3dCQUNqQyxRQUFRLEdBQUcsa0JBQWtCLENBQUM7d0JBQzlCLFdBQVcsQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUM7d0JBQzNCLFNBQVMsR0FBRyxNQUFNLEdBQUcsQ0FBQyxLQUFLLEdBQUcsa0JBQWtCLENBQUMsQ0FBQzt3QkFDbEQsWUFBWSxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQztxQkFDaEM7b0JBQ0QsSUFBSSxXQUFXLENBQUMsTUFBTSxLQUFLLENBQUMsRUFBRTt3QkFDMUIsUUFBUSxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsR0FBRyxXQUFXLENBQUMsQ0FBQztxQkFDdkM7b0JBQ0QsSUFBSSxZQUFZLENBQUMsTUFBTSxLQUFLLENBQUMsRUFBRTt3QkFDM0IsU0FBUyxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsR0FBRyxZQUFZLENBQUMsQ0FBQztxQkFDekM7aUJBQ0o7cUJBQU07b0JBQ0gsSUFBSSxXQUFXLElBQUksY0FBYyxFQUFFO3dCQUMvQixTQUFTLEdBQUcsbUJBQW1CLENBQUM7cUJBQ25DO29CQUNELElBQUksWUFBWSxJQUFJLGFBQWEsRUFBRTt3QkFDL0IsUUFBUSxHQUFHLGtCQUFrQixDQUFDO3FCQUNqQztpQkFDSjtnQkFFRCxnQ0FBZ0M7Z0JBQ2hDLElBQUksS0FBSyxFQUFFO29CQUNQLE1BQU0sR0FBRyxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsUUFBUSxDQUFDLEtBQUssRUFBRSxRQUFRLENBQUMsTUFBTSxDQUFDLENBQUM7b0JBQ3RELElBQUksUUFBUSxHQUFHLEdBQUcsRUFBRTt3QkFDaEIsUUFBUSxHQUFHLFNBQVMsR0FBRyxHQUFHLENBQUM7cUJBQzlCO3lCQUFNLElBQUksU0FBUyxHQUFHLEdBQUcsRUFBRTt3QkFDeEIsUUFBUSxHQUFHLFNBQVMsR0FBRyxHQUFHLENBQUM7cUJBQzlCO2lCQUNKO3FCQUFNLElBQUksZUFBZSxFQUFFO29CQUN4QixJQUFJLFFBQVEsR0FBRyxRQUFRLENBQUMsS0FBSyxFQUFFO3dCQUMzQixRQUFRLEdBQUcsUUFBUSxDQUFDLEtBQUssQ0FBQzt3QkFDMUIsU0FBUyxHQUFHLE1BQU0sR0FBRyxDQUFDLEtBQUssR0FBRyxRQUFRLENBQUMsS0FBSyxDQUFDLENBQUM7cUJBQ2pEO3lCQUFNLElBQUksU0FBUyxHQUFHLFFBQVEsQ0FBQyxNQUFNLEVBQUU7d0JBQ3BDLFFBQVEsR0FBRyxLQUFLLEdBQUcsQ0FBQyxNQUFNLEdBQUcsUUFBUSxDQUFDLE1BQU0sQ0FBQyxDQUFDO3dCQUM5QyxTQUFTLEdBQUcsUUFBUSxDQUFDLE1BQU0sQ0FBQztxQkFDL0I7aUJBQ0o7cUJBQU07b0JBQ0gsSUFBSSxRQUFRLEdBQUcsUUFBUSxDQUFDLEtBQUssRUFBRTt3QkFDM0IsUUFBUSxHQUFHLFFBQVEsQ0FBQyxLQUFLLENBQUM7cUJBQzdCO3lCQUFNLElBQUksU0FBUyxHQUFHLFFBQVEsQ0FBQyxNQUFNLEVBQUU7d0JBQ3BDLFNBQVMsR0FBRyxRQUFRLENBQUMsTUFBTSxDQUFDO3FCQUMvQjtpQkFDSjtnQkFHRCxlQUFlO2dCQUNmLFFBQVEsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLFFBQVEsQ0FBQyxDQUFDO2dCQUNoQyxTQUFTLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxTQUFTLENBQUMsQ0FBQztnQkFFbEMsT0FBTyxDQUFDLEtBQUssQ0FBQyxLQUFLLEdBQUcsR0FBRyxRQUFRLElBQUksQ0FBQztnQkFDdEMsT0FBTyxDQUFDLEtBQUssQ0FBQyxNQUFNLEdBQUcsR0FBRyxTQUFTLElBQUksQ0FBQztnQkFDeEMsSUFBSSxDQUFDLGFBQWEsR0FBRyxRQUFRLENBQUM7Z0JBQzlCLElBQUksQ0FBQyxjQUFjLEdBQUcsU0FBUyxDQUFDO2FBQ25DO1FBQ0wsQ0FBQyxDQUFBO1FBRUQscURBQXFEO1FBQzdDLGVBQVUsR0FBRyxDQUFDLEtBQThCLEVBQUUsRUFBRTtZQUNwRCxJQUFJLElBQUksQ0FBQyxVQUFVLEVBQUU7Z0JBQ2pCLEtBQUssQ0FBQyxjQUFjLEVBQUUsQ0FBQztnQkFDdkIsSUFBSSxDQUFDLG1CQUFtQixFQUFFLENBQUM7Z0JBQzNCLElBQUksQ0FBQyxRQUFRLENBQUMsaUJBQWlCLEdBQUcsSUFBSSxDQUFDLFFBQVEsQ0FBQyxNQUFNLENBQUMsS0FBSyxHQUFHLElBQUksQ0FBQyxhQUFhLENBQUM7Z0JBQ2xGLElBQUksQ0FBQyxRQUFRLENBQUMsa0JBQWtCLEdBQUcsSUFBSSxDQUFDLFFBQVEsQ0FBQyxNQUFNLENBQUMsTUFBTSxHQUFHLElBQUksQ0FBQyxjQUFjLENBQUM7Z0JBQ3JGLElBQUksQ0FBQyxRQUFRLENBQUMsTUFBTSxHQUFHLElBQUksQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFDO2dCQUM1QyxJQUFJLENBQUMsUUFBUSxDQUFDLGVBQWUsRUFBRSxDQUFDO2dCQUNoQyxJQUFJLENBQUMsVUFBVSxHQUFHLEtBQUssQ0FBQztnQkFDeEIsSUFBSSxDQUFDLGtCQUFrQixHQUFHLElBQUksQ0FBQzthQUNsQztRQUNMLENBQUMsQ0FBQTtRQUVELDZDQUE2QztRQUNyQyxnQkFBVyxHQUFHLEdBQUcsRUFBRTtZQUN2QiwrRUFBK0U7WUFDL0Usc0VBQXNFO1lBQ3RFLElBQUksSUFBSSxDQUFDLGlCQUFpQixFQUFFO2dCQUN4QixJQUFJLENBQUMsVUFBVSxDQUFDLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxDQUFDO2FBQzNDO1FBQ0wsQ0FBQyxDQUFBO1FBMU5HLElBQUksQ0FBQyxTQUFTLEdBQUcsU0FBUyxDQUFDO0lBQy9CLENBQUM7SUFJRCxJQUNXLGFBQWEsQ0FBQyxHQUFZO1FBQ2pDLElBQUksR0FBRyxLQUFLLElBQUksQ0FBQyxjQUFjLEVBQUU7WUFDN0IsSUFBSSxDQUFDLGNBQWMsR0FBRyxHQUFHLENBQUM7WUFDMUIsT0FBTyxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FBQyxJQUFJLENBQUMsR0FBRyxFQUFFO2dCQUM1QixJQUFJLEdBQUcsRUFBRTtvQkFDTCxJQUFJLENBQUMsb0JBQW9CLEVBQUUsQ0FBQztvQkFDNUIsSUFBSSxDQUFDLGlCQUFpQixFQUFFLENBQUM7aUJBQzVCO3FCQUFNO29CQUNILElBQUksQ0FBQyxvQkFBb0IsRUFBRSxDQUFDO2lCQUMvQjtZQUNMLENBQUMsQ0FBQyxDQUFDO1NBQ047SUFDTCxDQUFDO0lBQ0QsSUFBVyxhQUFhO1FBQ3BCLE9BQU8sSUFBSSxDQUFDLGNBQWMsQ0FBQztJQUMvQixDQUFDO0lBRU0sV0FBVztRQUNkLElBQUksQ0FBQyxvQkFBb0IsRUFBRSxDQUFDO0lBQ2hDLENBQUM7SUFFTyxpQkFBaUI7UUFDckIsSUFBSSxDQUFDLE9BQU8sQ0FBQyxpQkFBaUIsQ0FBQyxHQUFHLEVBQUU7WUFDaEMsTUFBTSxPQUFPLEdBQUcsSUFBSSxDQUFDLFFBQVEsQ0FBQyxhQUFhLENBQUM7WUFDNUMsT0FBTyxDQUFDLGdCQUFnQixDQUFDLFdBQVcsRUFBRSxJQUFJLENBQUMsWUFBWSxFQUFFLGtCQUFrQixDQUFDLENBQUM7WUFDN0UsT0FBTyxDQUFDLGdCQUFnQixDQUFDLFlBQVksRUFBRSxJQUFJLENBQUMsWUFBWSxFQUFFLGtCQUFrQixDQUFDLENBQUM7UUFDbEYsQ0FBQyxDQUFDLENBQUM7SUFDUCxDQUFDO0lBRU8sb0JBQW9CO1FBQ3hCLE1BQU0sT0FBTyxHQUFHLElBQUksQ0FBQyxRQUFRLEVBQUUsYUFBYSxDQUFDO1FBQzdDLElBQUksT0FBTyxFQUFFO1lBQ1QsSUFBSSxDQUFDLGlCQUFpQixHQUFHLElBQUksQ0FBQztZQUM5QixJQUFJLENBQUMsbUJBQW1CLEVBQUUsQ0FBQztZQUMzQixPQUFPLENBQUMsbUJBQW1CLENBQUMsV0FBVyxFQUFFLElBQUksQ0FBQyxZQUFZLEVBQUUsa0JBQWtCLENBQUMsQ0FBQztZQUNoRixPQUFPLENBQUMsbUJBQW1CLENBQUMsWUFBWSxFQUFFLElBQUksQ0FBQyxZQUFZLEVBQUUsa0JBQWtCLENBQUMsQ0FBQztTQUNwRjtJQUNMLENBQUM7SUFpTE8saUJBQWlCLENBQUMsWUFBcUM7UUFDM0QsTUFBTSxPQUFPLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQztRQUMvQixNQUFNLE9BQU8sR0FBRyxZQUFZLENBQUMsWUFBWSxDQUFDLENBQUM7UUFDM0MsTUFBTSxhQUFhLEdBQUcsT0FBTyxDQUFDLENBQUMsQ0FBQyxXQUFXLENBQUMsQ0FBQyxDQUFDLFdBQVcsQ0FBQztRQUMxRCxNQUFNLFlBQVksR0FBRyxPQUFPLENBQUMsQ0FBQyxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDO1FBQ3RELE9BQU8sQ0FBQyxnQkFBZ0IsQ0FBQyxhQUFhLEVBQUUsSUFBSSxDQUFDLFlBQVksRUFBRSxrQkFBa0IsQ0FBQyxDQUFDO1FBQy9FLE9BQU8sQ0FBQyxnQkFBZ0IsQ0FBQyxZQUFZLEVBQUUsSUFBSSxDQUFDLFVBQVUsRUFBRSxrQkFBa0IsQ0FBQyxDQUFDO1FBRTVFLElBQUksT0FBTyxFQUFFO1lBQ1QsT0FBTyxDQUFDLGdCQUFnQixDQUFDLGFBQWEsRUFBRSxJQUFJLENBQUMsVUFBVSxFQUFFLGtCQUFrQixDQUFDLENBQUM7U0FDaEY7UUFFRCxNQUFNLE1BQU0sR0FBRyxJQUFJLENBQUMsVUFBVSxFQUFFLENBQUM7UUFFakMsSUFBSSxPQUFPLE1BQU0sS0FBSyxXQUFXLElBQUksTUFBTSxFQUFFO1lBQ3pDLE1BQU0sQ0FBQyxnQkFBZ0IsQ0FBQyxNQUFNLEVBQUUsSUFBSSxDQUFDLFdBQVcsQ0FBQyxDQUFDO1NBQ3JEO0lBQ0wsQ0FBQztJQUVELGlFQUFpRTtJQUN6RCxtQkFBbUI7UUFDdkIsTUFBTSxPQUFPLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQztRQUMvQixPQUFPLENBQUMsbUJBQW1CLENBQUMsV0FBVyxFQUFFLElBQUksQ0FBQyxZQUFZLEVBQUUsa0JBQWtCLENBQUMsQ0FBQztRQUNoRixPQUFPLENBQUMsbUJBQW1CLENBQUMsU0FBUyxFQUFFLElBQUksQ0FBQyxVQUFVLEVBQUUsa0JBQWtCLENBQUMsQ0FBQztRQUM1RSxPQUFPLENBQUMsbUJBQW1CLENBQUMsV0FBVyxFQUFFLElBQUksQ0FBQyxZQUFZLEVBQUUsa0JBQWtCLENBQUMsQ0FBQztRQUNoRixPQUFPLENBQUMsbUJBQW1CLENBQUMsVUFBVSxFQUFFLElBQUksQ0FBQyxVQUFVLEVBQUUsa0JBQWtCLENBQUMsQ0FBQztRQUM3RSxPQUFPLENBQUMsbUJBQW1CLENBQUMsYUFBYSxFQUFFLElBQUksQ0FBQyxVQUFVLEVBQUUsa0JBQWtCLENBQUMsQ0FBQztRQUVoRixNQUFNLE1BQU0sR0FBRyxJQUFJLENBQUMsVUFBVSxFQUFFLENBQUM7UUFFakMsSUFBSSxPQUFPLE1BQU0sS0FBSyxXQUFXLElBQUksTUFBTSxFQUFFO1lBQ3pDLE1BQU0sQ0FBQyxtQkFBbUIsQ0FBQyxNQUFNLEVBQUUsSUFBSSxDQUFDLFdBQVcsQ0FBQyxDQUFDO1NBQ3hEO0lBQ0wsQ0FBQztJQUVELCtGQUErRjtJQUN2RixVQUFVO1FBQ2QsT0FBTyxJQUFJLENBQUMsU0FBUyxDQUFDLFdBQVcsSUFBSSxNQUFNLENBQUM7SUFDaEQsQ0FBQzs4R0FsU1Esd0JBQXdCLGtCQTJCckIsUUFBUTtrR0EzQlgsd0JBQXdCLHFURTd6Q3JDLGtFQUNBOzsyRkY0ekNhLHdCQUF3QjtrQkFQcEMsU0FBUzsrQkFDSSxtQkFBbUIsaUJBR2QsaUJBQWlCLENBQUMsSUFBSSxtQkFDcEIsdUJBQXVCLENBQUMsTUFBTTs7MEJBNkIxQyxNQUFNOzJCQUFDLFFBQVE7K0hBekJILFFBQVE7c0JBRHhCLFNBQVM7dUJBQUMsU0FBUztnQkFJYixlQUFlO3NCQURyQixLQUFLO2dCQUtDLEtBQUs7c0JBRlgsS0FBSzs7c0JBQ0wsV0FBVzt1QkFBQyxhQUFhO2dCQThCZixhQUFhO3NCQUR2QixLQUFLIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBBZGFwdGVkIGZyb20gaHR0cHM6Ly9naXRodWIuY29tL0EtbC15LWwtZS9BbHlsZS1VSS90cmVlLzEwLjUuMy9zcmMvbGliL2ltYWdlLWNyb3BwZXJcbiAqL1xuXG5pbXBvcnQgeyBub3JtYWxpemVQYXNzaXZlTGlzdGVuZXJPcHRpb25zIH0gZnJvbSBcIkBhbmd1bGFyL2Nkay9wbGF0Zm9ybVwiO1xuaW1wb3J0IHsgVmlld3BvcnRSdWxlciB9IGZyb20gXCJAYW5ndWxhci9jZGsvc2Nyb2xsaW5nXCI7XG5pbXBvcnQgeyBET0NVTUVOVCB9IGZyb20gXCJAYW5ndWxhci9jb21tb25cIjtcbmltcG9ydCB7XG4gICAgQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3ksXG4gICAgQ2hhbmdlRGV0ZWN0b3JSZWYsXG4gICAgQ29tcG9uZW50LFxuICAgIEVsZW1lbnRSZWYsXG4gICAgRXZlbnRFbWl0dGVyLCBIb3N0QmluZGluZyxcbiAgICBJbmplY3QsXG4gICAgSW5wdXQsXG4gICAgTmdab25lLFxuICAgIE9uRGVzdHJveSxcbiAgICBPbkluaXQsXG4gICAgT3V0cHV0LFxuICAgIFJlbmRlcmVyMixcbiAgICBWaWV3Q2hpbGQsXG4gICAgVmlld0VuY2Fwc3VsYXRpb25cbn0gZnJvbSBcIkBhbmd1bGFyL2NvcmVcIjtcbmltcG9ydCB7IE9ic2VydmFibGUsIFN1YmplY3QgfSBmcm9tIFwicnhqc1wiO1xuaW1wb3J0IHsgdGFrZSwgdGFrZVVudGlsIH0gZnJvbSBcInJ4anMvb3BlcmF0b3JzXCI7XG5pbXBvcnQgeyByZXNpemVDYW52YXMgfSBmcm9tIFwiLi9yZXNpemUtY2FudmFzXCI7XG5cbmNvbnN0IGFjdGl2ZUV2ZW50T3B0aW9ucyA9IG5vcm1hbGl6ZVBhc3NpdmVMaXN0ZW5lck9wdGlvbnMoeyBwYXNzaXZlOiBmYWxzZSB9KTtcblxuLyoqIEltYWdlIENyb3BwZXIgQ29uZmlnICovXG5leHBvcnQgY2xhc3MgSW1nQ3JvcHBlckNvbmZpZyB7XG4gICAgLyoqIENyb3BwZXIgYXJlYSB3aWR0aCAqL1xuICAgIHdpZHRoID0gMjUwO1xuICAgIC8qKiBDcm9wcGVyIGFyZWEgaGVpZ2h0ICovXG4gICAgaGVpZ2h0ID0gMjAwO1xuICAgIG1pbldpZHRoID0gNDA7XG4gICAgbWluSGVpZ2h0ID0gNDA7XG4gICAgLyoqIElmIHRoaXMgaXMgbm90IGRlZmluZWQsIHRoZSBuZXcgaW1hZ2Ugd2lsbCBiZSBhdXRvbWF0aWNhbGx5IGRlZmluZWQuICovXG4gICAgdHlwZT86IHN0cmluZztcbiAgICAvKiogQmFja2dyb3VuZCBjb2xvciggZGVmYXVsdDogbnVsbCksIGlmIGlzIG51bGwgaW4gcG5nIGlzIHRyYW5zcGFyZW50IGJ1dCBub3QgaW4ganBnLiAqL1xuICAgIGZpbGw/OiBzdHJpbmcgfCBudWxsO1xuICAgIC8qKlxuICAgICAqIFNldCBhbnRpLWFsaWFzZWQgKGRlZmF1bHQ6IHRydWUpXG4gICAgICogQGRlcHJlY2F0ZWQgdGhpcyBpcyBub3QgbmVjZXNzYXJ5IGFzIHRoZSBjcm9wcGVyIHdpbGwgYXV0b21hdGljYWxseSByZXNpemUgdGhlIGltYWdlXG4gICAgICogdG8gdGhlIGJlc3QgcXVhbGl0eVxuICAgICAqL1xuICAgIGFudGlBbGlhc2VkID0gdHJ1ZTtcbiAgICBhdXRvQ3JvcD86IGJvb2xlYW47XG4gICAgb3V0cHV0PzogSW1nT3V0cHV0IHwgSW1nUmVzb2x1dGlvbiA9IEltZ1Jlc29sdXRpb24uRGVmYXVsdDtcbiAgICAvKipcbiAgICAgKiBab29tIG91dCB1bnRpbCB0aGUgZW50aXJlIGltYWdlIGZpdHMgaW50byB0aGUgY3JvcHBpbmcgYXJlYS5cbiAgICAgKiBkZWZhdWx0OiBmYWxzZVxuICAgICAqL1xuICAgIGV4dHJhWm9vbU91dD86IGJvb2xlYW47XG4gICAgLyoqXG4gICAgICogRW1pdCBldmVudCBgZXJyb3JgIGlmIHRoZSBmaWxlIHNpemUgaW4gYnl0ZXMgZm9yIHRoZSBsaW1pdC5cbiAgICAgKiBOb3RlOiBJdCBvbmx5IHdvcmtzIHdoZW4gdGhlIGltYWdlIGlzIHJlY2VpdmVkIGZyb20gdGhlIGA8aW5wdXQ+YCBldmVudC5cbiAgICAgKi9cbiAgICBtYXhGaWxlU2l6ZT86IG51bWJlciB8IG51bGw7XG4gICAgLyoqXG4gICAgICogV2hldGhlciB0aGUgY3JvcHBlciBhcmVhIHdpbGwgYmUgcm91bmQuXG4gICAgICogVGhpcyBpbXBsaWVzIHRoYXQgdGhlIGNyb3BwZXIgYXJlYSB3aWxsIG1haW50YWluIGl0cyBhc3BlY3QgcmF0aW8uXG4gICAgICogZGVmYXVsdDogZmFsc2VcbiAgICAgKi9cbiAgICByb3VuZD86IGJvb2xlYW47XG4gICAgLyoqXG4gICAgICogV2hldGhlciB0aGUgY3JvcHBlciBhcmVhIGlzIHJlc2l6YWJsZS5cbiAgICAgKiBkZWZhdWx0OiBmYWxzZVxuICAgICAqL1xuICAgIHJlc2l6YWJsZUFyZWE/OiBib29sZWFuO1xuICAgIC8qKlxuICAgICAqIEtlZXAgdGhlIHdpZHRoIGFuZCBoZWlnaHQgb2YgdGhlIGdyb3dpbmcgYXJlYSB0aGUgc2FtZSBhY2NvcmRpbmdcbiAgICAgKiB0byBgSW1nQ3JvcHBlckNvbmZpZy53aWR0aGAgYW5kIGBJbWdDcm9wcGVyQ29uZmlnLmhlaWdodGBcbiAgICAgKiBkZWZhdWx0OiBmYWxzZVxuICAgICAqL1xuICAgIGtlZXBBc3BlY3RSYXRpbz86IGJvb2xlYW47XG4gICAgLyoqXG4gICAgICogV2hldGhlciB0aGUgY3JvcHBlciBhcmVhIGlzIHJlc3BvbnNpdmUuXG4gICAgICogQnkgZGVmYXVsdCwgdGhlIHdpZHRoIGFuZCBoZWlnaHQgb2YgdGhlIGNyb3BwZXIgYXJlYSBpcyBmaXhlZCxcbiAgICAgKiBzbyBjYW4gdXNlIHdoZW4gdGhlIGNyb3BwZXIgYXJlYSBpcyBsYXJnZXIgdGhhbiBpdHMgY29udGFpbmVyLFxuICAgICAqIG90aGVyd2lzZSB0aGlzIHdpbGwgYnJpbmcgcHJvYmxlbXMgd2hlbiBjcm9wcGluZy5cbiAgICAgKi9cbiAgICByZXNwb25zaXZlQXJlYT86IGJvb2xlYW47XG59XG5cbi8qKlxuICogVGhlIG91dHB1dCBpbWFnZVxuICogV2l0aCB0aGlzIG9wdGlvbiB5b3UgY2FuIHJlc2l6ZSB0aGUgb3V0cHV0IGltYWdlLlxuICogSWYgYHdpZHRoYCBvciBgaGVpZ2h0YCBhcmUgMCwgdGhpcyB3aWxsIGJlIHNldCBhdXRvbWF0aWNhbGx5LlxuICogQm90aCBjYW5ub3QgYmUgMC5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBJbWdPdXRwdXQge1xuICAgIC8qKlxuICAgICAqIFRoZSBjcm9wcGVkIGltYWdlIHdpbGwgYmUgcmVzaXplZCB0byB0aGlzIGB3aWR0aGAuXG4gICAgICovXG4gICAgd2lkdGg6IG51bWJlcjtcbiAgICAvKipcbiAgICAgKiBDcm9wcGVkIGltYWdlIHdpbGwgYmUgcmVzaXplZCB0byB0aGlzIGBoZWlnaHRgLlxuICAgICAqL1xuICAgIGhlaWdodDogbnVtYmVyO1xufVxuXG4vKiogSW1hZ2Ugb3V0cHV0ICovXG5leHBvcnQgZW51bSBJbWdSZXNvbHV0aW9uIHtcbiAgICAvKipcbiAgICAgKiBUaGUgb3V0cHV0IGltYWdlIHdpbGwgYmUgZXF1YWwgdG8gdGhlIGluaXRpYWwgc2l6ZSBvZiB0aGUgY3JvcHBlciBhcmVhLlxuICAgICAqL1xuICAgIERlZmF1bHQsXG4gICAgLyoqIEp1c3QgY3JvcCB0aGUgaW1hZ2Ugd2l0aG91dCByZXNpemluZyAqL1xuICAgIE9yaWdpbmFsSW1hZ2Vcbn1cblxuLyoqIEltYWdlIG91dHB1dCAqL1xuZXhwb3J0IGVudW0gSW1nQ3JvcHBlckVycm9yIHtcbiAgICAvKiogVGhlIGxvYWRlZCBpbWFnZSBleGNlZWRzIHRoZSBzaXplIGxpbWl0IHNldC4gKi9cbiAgICBTaXplLFxuICAgIC8qKiBUaGUgZmlsZSBsb2FkZWQgaXMgbm90IGltYWdlLiAqL1xuICAgIFR5cGUsXG4gICAgLyoqIFdoZW4gdGhlIGltYWdlIGhhcyBub3QgYmVlbiBsb2FkZWQuICovXG4gICAgT3RoZXJcbn1cblxuZXhwb3J0IGludGVyZmFjZSBJbWdDcm9wcGVyRXZlbnQge1xuICAgIC8qKiBDcm9wcGVkIGltYWdlIGRhdGEgVVJMICovXG4gICAgZGF0YVVSTD86IHN0cmluZztcbiAgICBuYW1lOiBzdHJpbmcgfCBudWxsO1xuICAgIC8qKiBGaWxldHlwZSAqL1xuICAgIHR5cGU/OiBzdHJpbmc7XG4gICAgLyoqIENyb3BwZWQgYXJlYSB3aWR0aCAqL1xuICAgIGFyZWFXaWR0aDogbnVtYmVyO1xuICAgIC8qKiBDcm9wcGVkIGFyZWEgaGVpZ2h0ICovXG4gICAgYXJlYUhlaWdodDogbnVtYmVyO1xuICAgIC8qKiBDcm9wcGVkIGltYWdlIHdpZHRoICovXG4gICAgd2lkdGg6IG51bWJlcjtcbiAgICAvKiogQ3JvcHBlZCBpbWFnZSBoZWlnaHQgKi9cbiAgICBoZWlnaHQ6IG51bWJlcjtcbiAgICAvKiogT3JpZ2luYWwgSW1hZ2UgZGF0YSBVUkwgKi9cbiAgICBvcmlnaW5hbERhdGFVUkw/OiBzdHJpbmc7XG4gICAgc2NhbGU6IG51bWJlcjtcbiAgICAvKiogQ3VycmVudCByb3RhdGlvbiBpbiBkZWdyZWVzICovXG4gICAgcm90YXRpb246IG51bWJlcjtcbiAgICAvKiogU2l6ZSBvZiB0aGUgaW1hZ2UgaW4gYnl0ZXMgKi9cbiAgICBzaXplOiBudW1iZXI7XG4gICAgLyoqIFNjYWxlZCBvZmZzZXQgZnJvbSB0aGUgbGVmdCBlZGdlIG9mIHRoZSBpbWFnZSAqL1xuICAgIGxlZnQ6IG51bWJlcjtcbiAgICAvKiogU2NhbGVkIG9mZnNldCBmcm9tIHRoZSB0b3AgZWRnZSBvZiB0aGUgaW1hZ2UgKi9cbiAgICB0b3A6IG51bWJlcjtcbiAgICAvKipcbiAgICAgKiBTY2FsZWQgb2Zmc2V0IGZyb20gdGhlIGxlZnQgZWRnZSBvZiB0aGUgaW1hZ2UgdG8gY2VudGVyIG9mIGFyZWFcbiAgICAgKiBDYW4gYmUgdXNlZCB0byBzZXQgaW1hZ2UgcG9zaXRpb25cbiAgICAgKi9cbiAgICB4T3JpZ2luOiBudW1iZXI7XG4gICAgLyoqXG4gICAgICogU2NhbGVkIG9mZnNldCBmcm9tIHRoZSB0b3AgZWRnZSBvZiB0aGUgaW1hZ2UgdG8gY2VudGVyIG9mIGFyZWFcbiAgICAgKiBDYW4gYmUgdXNlZCB0byBzZXQgaW1hZ2UgcG9zaXRpb25cbiAgICAgKi9cbiAgICB5T3JpZ2luOiBudW1iZXI7XG4gICAgLyoqIEBkZXByZWNhdGVkIFVzZSBgeE9yaWdpbiAmIHlPcmlnaW5gIGluc3RlYWQuICovXG4gICAgcG9zaXRpb24/OiB7XG4gICAgICAgIHg6IG51bWJlclxuICAgICAgICB5OiBudW1iZXJcbiAgICB9O1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIEltZ0Nyb3BwZXJFcnJvckV2ZW50IHtcbiAgICBuYW1lPzogc3RyaW5nO1xuICAgIC8qKiBTaXplIG9mIHRoZSBpbWFnZSBpbiBieXRlcyAqL1xuICAgIHNpemU6IG51bWJlcjtcbiAgICAvKiogRmlsZXR5cGUgKi9cbiAgICB0eXBlOiBzdHJpbmc7XG4gICAgLyoqIFR5cGUgb2YgZXJyb3IgKi9cbiAgICBlcnJvcjogSW1nQ3JvcHBlckVycm9yO1xuICAgIGVycm9yTXNnPzogc3RyaW5nO1xufVxuXG5pbnRlcmZhY2UgSW1nUmVjdCB7XG4gICAgeDogbnVtYmVyO1xuICAgIHk6IG51bWJlcjtcbiAgICB4YzogbnVtYmVyO1xuICAgIHljOiBudW1iZXI7XG4gICAgLyoqIHRyYW5zZm9ybSB3aXRoICovXG4gICAgd3Q6IG51bWJlcjtcbiAgICBodDogbnVtYmVyO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIEltZ0Nyb3BwZXJMb2FkZXJDb25maWcge1xuICAgIG5hbWU/OiBzdHJpbmcgfCBudWxsO1xuICAgIC8qKiBGaWxldHlwZSAqL1xuICAgIHR5cGU/OiBzdHJpbmc7XG4gICAgLyoqIENyb3BwZWQgYXJlYSB3aWR0aCAqL1xuICAgIGFyZWFXaWR0aD86IG51bWJlcjtcbiAgICAvKiogQ3JvcHBlZCBhcmVhIGhlaWdodCAqL1xuICAgIGFyZWFIZWlnaHQ/OiBudW1iZXI7XG4gICAgLyoqIENyb3BwZWQgaW1hZ2Ugd2lkdGggKi9cbiAgICB3aWR0aD86IG51bWJlcjtcbiAgICAvKiogQ3JvcHBlZCBpbWFnZSBoZWlnaHQgKi9cbiAgICBoZWlnaHQ/OiBudW1iZXI7XG4gICAgLyoqIE9yaWdpbmFsIEltYWdlIGRhdGEgVVJMICovXG4gICAgb3JpZ2luYWxEYXRhVVJMOiBzdHJpbmc7XG4gICAgc2NhbGU/OiBudW1iZXI7XG4gICAgLyoqIEN1cnJlbnQgcm90YXRpb24gaW4gZGVncmVlcyAqL1xuICAgIHJvdGF0aW9uPzogbnVtYmVyO1xuICAgIC8qKiBTaXplIG9mIHRoZSBpbWFnZSBpbiBieXRlcyAqL1xuICAgIHNpemU/OiBudW1iZXI7XG4gICAgLyoqIE9mZnNldCBmcm9tIHRoZSBsZWZ0IGVkZ2Ugb2YgdGhlIGltYWdlIHRvIGNlbnRlciBvZiBhcmVhICovXG4gICAgeE9yaWdpbj86IG51bWJlcjtcbiAgICAvKiogT2Zmc2V0IGZyb20gdGhlIHRvcCBlZGdlIG9mIHRoZSBpbWFnZSB0byBjZW50ZXIgb2YgYXJlYSAqL1xuICAgIHlPcmlnaW4/OiBudW1iZXI7XG59XG5cbkBDb21wb25lbnQoe1xuICAgIGNoYW5nZURldGVjdGlvbjogQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3kuT25QdXNoLFxuICAgIHByZXNlcnZlV2hpdGVzcGFjZXM6IGZhbHNlLFxuICAgIHNlbGVjdG9yOiBcIm5pY2UtaW1nLWNyb3BwZXIsIG5pY2UtaW1hZ2UtY3JvcHBlclwiLFxuICAgIHRlbXBsYXRlVXJsOiBcImltYWdlLWNyb3BwZXIudGVtcGxhdGUuaHRtbFwiLFxuICAgIHN0eWxlVXJsczogW1wiaW1hZ2UtY3JvcHBlci5zdHlsZS5zY3NzXCJdLFxuICAgIGVuY2Fwc3VsYXRpb246IFZpZXdFbmNhcHN1bGF0aW9uLk5vbmVcbn0pXG5leHBvcnQgY2xhc3MgTmljZUltYWdlQ3JvcHBlckNvbXBvbmVudCBpbXBsZW1lbnRzIE9uSW5pdCwgT25EZXN0cm95IHtcbiAgICBzdGF0aWMgcmVhZG9ubHkg0LggPSBcIk5pY2VJbWFnZUNyb3BwZXJcIjtcblxuICAgIHByaXZhdGUgX2N1cnJlbnRMb2FkQ29uZmlnPzogSW1nQ3JvcHBlckxvYWRlckNvbmZpZztcblxuICAgIC8qKiBPcmlnaW5hbCBpbWFnZSAqL1xuICAgIHByaXZhdGUgX2ltZzogSFRNTEltYWdlRWxlbWVudDtcbiAgICBwcml2YXRlIG9mZnNldD86IHtcbiAgICAgICAgeDogbnVtYmVyXG4gICAgICAgIHk6IG51bWJlclxuICAgICAgICBsZWZ0OiBudW1iZXJcbiAgICAgICAgdG9wOiBudW1iZXJcbiAgICB9O1xuICAgIHByaXZhdGUgX3NjYWxlPzogbnVtYmVyO1xuICAgIHByaXZhdGUgX3NjYWwzRml4PzogbnVtYmVyO1xuICAgIHByaXZhdGUgX21pblNjYWxlPzogbnVtYmVyO1xuICAgIHByaXZhdGUgX21heFNjYWxlPzogbnVtYmVyO1xuICAgIC8qKiBJbml0aWFsIGNvbmZpZyAqL1xuICAgIHByaXZhdGUgX2NvbmZpZ1ByaW1hcnk6IEltZ0Nyb3BwZXJDb25maWc7XG4gICAgcHJpdmF0ZSBfY29uZmlnOiBJbWdDcm9wcGVyQ29uZmlnO1xuICAgIHByaXZhdGUgX2ltZ1JlY3Q6IEltZ1JlY3QgPSB7fSBhcyBhbnk7XG4gICAgcHJpdmF0ZSBfcm90YXRpb24gPSAwO1xuICAgIC8vIHByaXZhdGUgX3NpemVJbkJ5dGVzOiBudW1iZXIgfCBudWxsO1xuICAgIHByaXZhdGUgX2lzU2xpZGluZzogYm9vbGVhbjtcbiAgICAvKiogS2VlcHMgdHJhY2sgb2YgdGhlIGxhc3QgcG9pbnRlciBldmVudCB0aGF0IHdhcyBjYXB0dXJlZCBieSB0aGUgY3JvcCBhcmVhLiAqL1xuICAgIHByaXZhdGUgX2xhc3RQb2ludGVyRXZlbnQ6IE1vdXNlRXZlbnQgfCBUb3VjaEV2ZW50IHwgbnVsbDtcbiAgICBwcml2YXRlIF9zdGFydFBvaW50ZXJFdmVudDoge1xuICAgICAgICB4OiBudW1iZXJcbiAgICAgICAgeTogbnVtYmVyXG4gICAgfSB8IG51bGw7XG4gICAgcHVibGljIF9wcmltYXJ5QXJlYVdpZHRoOiBudW1iZXI7XG4gICAgcHVibGljIF9wcmltYXJ5QXJlYUhlaWdodDogbnVtYmVyO1xuXG4gICAgcHVibGljIF9hYnNvbHV0ZVNjYWxlOiBudW1iZXI7XG5cbiAgICAvKipcbiAgICAgKiBXaGVuIGlzIGxvYWRlZCBpbWFnZVxuICAgICAqIEBpbnRlcm5hbFxuICAgICAqL1xuICAgIHB1YmxpYyBfaXNMb2FkZWRJbWc6IGJvb2xlYW47XG5cbiAgICAvKiogV2hlbiBpcyBsb2FkZWQgaW1hZ2UgJiByZWFkeSBmb3IgY3JvcCAqL1xuICAgIHB1YmxpYyBpc0xvYWRlZDogYm9vbGVhbjtcbiAgICAvKiogV2hlbiB0aGUgY3JvcHBlciBpcyByZWFkeSB0byBiZSBpbnRlcmFjdGVkICAqL1xuICAgIHB1YmxpYyBpc1JlYWR5OiBib29sZWFuO1xuICAgIHB1YmxpYyBpc0Nyb3BwZWQ6IGJvb2xlYW47XG5cbiAgICBAVmlld0NoaWxkKFwiX2ltZ0NvbnRhaW5lclwiLCB7IHN0YXRpYzogdHJ1ZSB9KVxuICAgIHByaXZhdGUgX2ltZ0NvbnRhaW5lcjogRWxlbWVudFJlZjtcblxuICAgIEBWaWV3Q2hpbGQoXCJfYXJlYVwiLCB7IHJlYWQ6IEVsZW1lbnRSZWYgfSlcbiAgICBwcml2YXRlIF9hcmVhUmVmOiBFbGVtZW50UmVmO1xuICAgIEBWaWV3Q2hpbGQoXCJfaW1nQ2FudmFzXCIsIHsgc3RhdGljOiB0cnVlIH0pXG4gICAgcHJpdmF0ZSBfaW1nQ2FudmFzOiBFbGVtZW50UmVmPEhUTUxDYW52YXNFbGVtZW50PjtcblxuICAgIEBJbnB1dCgpXG4gICAgcHVibGljIHNldCBjb25maWcodmFsOiBJbWdDcm9wcGVyQ29uZmlnKSB7XG4gICAgICAgIHRoaXMuX2NvbmZpZyA9IG1lcmdlRGVlcCh7fSwgbmV3IEltZ0Nyb3BwZXJDb25maWcoKSwgdmFsKTtcbiAgICAgICAgdGhpcy5fY29uZmlnUHJpbWFyeSA9IG1lcmdlRGVlcCh7fSwgdGhpcy5fY29uZmlnKTtcbiAgICAgICAgdGhpcy5fcHJpbWFyeUFyZWFXaWR0aCA9IHRoaXMuY29uZmlnLndpZHRoO1xuICAgICAgICB0aGlzLl9wcmltYXJ5QXJlYUhlaWdodCA9IHRoaXMuY29uZmlnLmhlaWdodDtcbiAgICAgICAgaWYgKFxuICAgICAgICAgICAgdGhpcy5fY29uZmlnLnJvdW5kXG4gICAgICAgICAgICAmJiB0aGlzLmNvbmZpZy53aWR0aCAhPT0gdGhpcy5jb25maWcuaGVpZ2h0XG4gICAgICAgICkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGAke05pY2VJbWFnZUNyb3BwZXJDb21wb25lbnQu0Lh9OiBCb3RoIHdpZHRoIGFuZCBoZWlnaHQgbXVzdCBiZSBlcXVhbCB3aGVuIHVzaW5nIFxcYEltZ0Nyb3BwZXJDb25maWcucm91bmQgPSB0cnVlXFxgYCk7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgbWF4RmlsZVNpemUgPSB0aGlzLl9jb25maWcubWF4RmlsZVNpemU7XG4gICAgICAgIGlmIChtYXhGaWxlU2l6ZSkge1xuICAgICAgICAgICAgdGhpcy5tYXhGaWxlU2l6ZSA9IG1heEZpbGVTaXplO1xuICAgICAgICB9XG4gICAgfVxuICAgIHB1YmxpYyBnZXQgY29uZmlnKCk6IEltZ0Nyb3BwZXJDb25maWcge1xuICAgICAgICByZXR1cm4gdGhpcy5fY29uZmlnO1xuICAgIH1cbiAgICAvKiogU2V0IHNjYWxlICovXG4gICAgQElucHV0KClcbiAgICBwdWJsaWMgc2V0IHNjYWxlKHZhbDogbnVtYmVyIHwgdW5kZWZpbmVkKSB7XG4gICAgICAgIHRoaXMuc2V0U2NhbGUodmFsKTtcbiAgICB9XG4gICAgcHVibGljIGdldCBzY2FsZSgpOiBudW1iZXIgfCB1bmRlZmluZWQge1xuICAgICAgICByZXR1cm4gdGhpcy5fc2NhbGU7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogRW1pdCBldmVudCBgZXJyb3JgIGlmIHRoZSBmaWxlIHNpemUgZm9yIHRoZSBsaW1pdC5cbiAgICAgKiBOb3RlOiBJdCBvbmx5IHdvcmtzIHdoZW4gdGhlIGltYWdlIGlzIHJlY2VpdmVkIGZyb20gdGhlIGA8aW5wdXQ+YCBldmVudC5cbiAgICAgKi9cbiAgICBASW5wdXQoKVxuICAgIHB1YmxpYyBtYXhGaWxlU2l6ZTogbnVtYmVyO1xuXG4gICAgLyoqIEdldCBtaW4gc2NhbGUgKi9cbiAgICBwdWJsaWMgZ2V0IG1pblNjYWxlKCk6IG51bWJlciB8IHVuZGVmaW5lZCB7XG4gICAgICAgIHJldHVybiB0aGlzLl9taW5TY2FsZTtcbiAgICB9XG5cbiAgICBAT3V0cHV0KClcbiAgICBwcml2YXRlIHJlYWRvbmx5IHNjYWxlQ2hhbmdlID0gbmV3IEV2ZW50RW1pdHRlcjxudW1iZXI+KCk7XG5cbiAgICAvKiogRW1pdHMgbWluaW11bSBzdXBwb3J0ZWQgaW1hZ2Ugc2NhbGUgKi9cbiAgICAvLyB0c2xpbnQ6ZGlzYWJsZS1uZXh0LWxpbmU6bm8tb3V0cHV0LXJlbmFtZVxuICAgIEBPdXRwdXQoXCJtaW5TY2FsZVwiKVxuICAgIHByaXZhdGUgcmVhZG9ubHkgbWluU2NhbGVDaGFuZ2UgPSBuZXcgRXZlbnRFbWl0dGVyPG51bWJlcj4oKTtcblxuICAgIC8qKiBFbWl0cyBtYXhpbXVtIHN1cHBvcnRlZCBpbWFnZSBzY2FsZSAqL1xuICAgIC8vIHRzbGludDpkaXNhYmxlLW5leHQtbGluZTpuby1vdXRwdXQtcmVuYW1lXG4gICAgQE91dHB1dChcIm1heFNjYWxlXCIpXG4gICAgcHJpdmF0ZSByZWFkb25seSBtYXhTY2FsZUNoYW5nZSA9IG5ldyBFdmVudEVtaXR0ZXI8bnVtYmVyPigpO1xuXG4gICAgLyoqIEVtaXRzIHdoZW4gdGhlIGltYWdlIGlzIGxvYWRlZCAqL1xuICAgIEBPdXRwdXQoKVxuICAgIHByaXZhdGUgcmVhZG9ubHkgaW1hZ2VMb2FkZWQgPSBuZXcgRXZlbnRFbWl0dGVyPEltZ0Nyb3BwZXJFdmVudD4oKTtcblxuICAgIC8qKiBFbWl0cyB3aGVuIHRoZSBjcm9wcGVyIGlzIHJlYWR5IHRvIGJlIGludGVyYWN0ZWQgKi9cbiAgICBAT3V0cHV0KClcbiAgICBwcml2YXRlIHJlYWRvbmx5IHJlYWR5ID0gbmV3IEV2ZW50RW1pdHRlcjxJbWdDcm9wcGVyRXZlbnQ+KCk7XG5cbiAgICAvKiogT24gY3JvcCBuZXcgaW1hZ2UgKi9cbiAgICBAT3V0cHV0KClcbiAgICBwcml2YXRlIHJlYWRvbmx5IGNyb3BwZWQgPSBuZXcgRXZlbnRFbWl0dGVyPEltZ0Nyb3BwZXJFdmVudD4oKTtcblxuICAgIC8qKiBFbWl0cyB3aGVuIHRoZSBjcm9wcGVyIGlzIGNsZWFuZWQgKi9cbiAgICBAT3V0cHV0KClcbiAgICBwcml2YXRlIHJlYWRvbmx5IGNsZWFuZWQgPSBuZXcgRXZlbnRFbWl0dGVyPHZvaWQ+KCk7XG5cbiAgICAvKiogRW1pdCBhbiBlcnJvciB3aGVuIHRoZSBsb2FkZWQgaW1hZ2UgaXMgbm90IHZhbGlkICovXG4gICAgLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lOiBuby1vdXRwdXQtbmF0aXZlXG4gICAgQE91dHB1dCgpXG4gICAgcHJpdmF0ZSByZWFkb25seSBlcnJvciA9IG5ldyBFdmVudEVtaXR0ZXI8SW1nQ3JvcHBlckVycm9yRXZlbnQ+KCk7XG5cbiAgICBwcml2YXRlIF9jdXJyZW50SW5wdXRFbGVtZW50PzogSFRNTElucHV0RWxlbWVudDtcblxuICAgIC8qKiBFbWl0cyB3aGVuZXZlciB0aGUgY29tcG9uZW50IGlzIGRlc3Ryb3llZC4gKi9cbiAgICBwcml2YXRlIHJlYWRvbmx5IF9kZXN0cm95ID0gbmV3IFN1YmplY3Q8dm9pZD4oKTtcblxuICAgIC8qKiBVc2VkIHRvIHN1YnNjcmliZSB0byBnbG9iYWwgbW92ZSBhbmQgZW5kIGV2ZW50cyAqL1xuICAgIHByb3RlY3RlZCBfZG9jdW1lbnQ6IERvY3VtZW50O1xuXG4gICAgY29uc3RydWN0b3IoXG4gICAgICAgIHByaXZhdGUgX3JlbmRlcmVyOiBSZW5kZXJlcjIsXG4gICAgICAgIHJlYWRvbmx5IF9lbGVtZW50UmVmOiBFbGVtZW50UmVmPEhUTUxFbGVtZW50PixcbiAgICAgICAgcHJpdmF0ZSBjZDogQ2hhbmdlRGV0ZWN0b3JSZWYsXG4gICAgICAgIHByaXZhdGUgX25nWm9uZTogTmdab25lLFxuICAgICAgICBASW5qZWN0KERPQ1VNRU5UKSBfZG9jdW1lbnQ6IGFueSxcbiAgICAgICAgdmlld1BvcnRSdWxlcjogVmlld3BvcnRSdWxlclxuICAgICkge1xuICAgICAgICB0aGlzLl9kb2N1bWVudCA9IF9kb2N1bWVudDtcbiAgICAgICAgdmlld1BvcnRSdWxlci5jaGFuZ2UoKVxuICAgICAgICAgICAgLnBpcGUodGFrZVVudGlsKHRoaXMuX2Rlc3Ryb3kpKVxuICAgICAgICAgICAgLnN1YnNjcmliZSgoKSA9PlxuICAgICAgICAgICAgICAgIHRoaXMuX25nWm9uZS5ydW4oKCkgPT4gdGhpcy51cGRhdGVDcm9wcGVyUG9zaXRpb24oKSlcbiAgICAgICAgICAgICk7XG4gICAgfVxuXG4gICAgcHVibGljIG5nT25Jbml0KCk6IHZvaWQge1xuICAgICAgICB0aGlzLl9uZ1pvbmUucnVuT3V0c2lkZUFuZ3VsYXIoKCkgPT4ge1xuICAgICAgICAgICAgY29uc3QgZWxlbWVudCA9IHRoaXMuX2ltZ0NvbnRhaW5lci5uYXRpdmVFbGVtZW50O1xuICAgICAgICAgICAgZWxlbWVudC5hZGRFdmVudExpc3RlbmVyKFwibW91c2Vkb3duXCIsIHRoaXMuX3BvaW50ZXJEb3duLCBhY3RpdmVFdmVudE9wdGlvbnMpO1xuICAgICAgICAgICAgZWxlbWVudC5hZGRFdmVudExpc3RlbmVyKFwidG91Y2hzdGFydFwiLCB0aGlzLl9wb2ludGVyRG93biwgYWN0aXZlRXZlbnRPcHRpb25zKTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgcHVibGljIG5nT25EZXN0cm95KCk6IHZvaWQge1xuICAgICAgICB0aGlzLl9kZXN0cm95Lm5leHQoKTtcbiAgICAgICAgdGhpcy5fZGVzdHJveS5jb21wbGV0ZSgpO1xuICAgICAgICBjb25zdCBlbGVtZW50ID0gdGhpcy5faW1nQ29udGFpbmVyLm5hdGl2ZUVsZW1lbnQ7XG4gICAgICAgIHRoaXMuX2xhc3RQb2ludGVyRXZlbnQgPSBudWxsO1xuICAgICAgICB0aGlzLl9yZW1vdmVHbG9iYWxFdmVudHMoKTtcbiAgICAgICAgZWxlbWVudC5yZW1vdmVFdmVudExpc3RlbmVyKFwibW91c2Vkb3duXCIsIHRoaXMuX3BvaW50ZXJEb3duLCBhY3RpdmVFdmVudE9wdGlvbnMpO1xuICAgICAgICBlbGVtZW50LnJlbW92ZUV2ZW50TGlzdGVuZXIoXCJ0b3VjaHN0YXJ0XCIsIHRoaXMuX3BvaW50ZXJEb3duLCBhY3RpdmVFdmVudE9wdGlvbnMpO1xuICAgIH1cblxuICAgIC8qKiBMb2FkIGltYWdlIHdpdGggY2FudmFzICovXG4gICAgcHJpdmF0ZSBfaW1nTG9hZGVkKGltZ0VsZW1lbnQ6IEhUTUxJbWFnZUVsZW1lbnQpOiB2b2lkIHtcbiAgICAgICAgaWYgKGltZ0VsZW1lbnQpIHtcbiAgICAgICAgICAgIHRoaXMuX2ltZyA9IGltZ0VsZW1lbnQ7XG4gICAgICAgICAgICBjb25zdCBjYW52YXMgPSB0aGlzLl9pbWdDYW52YXMubmF0aXZlRWxlbWVudDtcbiAgICAgICAgICAgIGNhbnZhcy53aWR0aCA9IGltZ0VsZW1lbnQud2lkdGg7XG4gICAgICAgICAgICBjYW52YXMuaGVpZ2h0ID0gaW1nRWxlbWVudC5oZWlnaHQ7XG4gICAgICAgICAgICBjb25zdCBjdHggPSBjYW52YXMuZ2V0Q29udGV4dChcIjJkXCIpO1xuICAgICAgICAgICAgY3R4LmNsZWFyUmVjdCgwLCAwLCBpbWdFbGVtZW50LndpZHRoLCBpbWdFbGVtZW50LmhlaWdodCk7XG4gICAgICAgICAgICBjdHguZHJhd0ltYWdlKGltZ0VsZW1lbnQsIDAsIDApO1xuXG4gICAgICAgICAgICAvKiogc2V0IG1pbiBzY2FsZSAqL1xuICAgICAgICAgICAgdGhpcy5fdXBkYXRlTWluU2NhbGUoY2FudmFzKTtcbiAgICAgICAgICAgIHRoaXMuX3VwZGF0ZU1heFNjYWxlKCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwcml2YXRlIF9zZXRTdHlsZXNGb3JDb250SW1nKHZhbHVlczogeyB4PzogbnVtYmVyLCB5PzogbnVtYmVyIH0pIHtcbiAgICAgICAgY29uc3QgbmV3U3R5bGVzID0geyB9IGFzIGFueTtcbiAgICAgICAgaWYgKHZhbHVlcy54ICE9IG51bGwgJiYgdmFsdWVzLnkgIT0gbnVsbCkge1xuICAgICAgICAgICAgY29uc3Qgcm9vdFJlY3QgPSB0aGlzLl9yb290UmVjdCgpO1xuICAgICAgICAgICAgY29uc3QgeCA9IHJvb3RSZWN0LndpZHRoIC8gMiAtICh2YWx1ZXMueCk7XG4gICAgICAgICAgICBjb25zdCB5ID0gcm9vdFJlY3QuaGVpZ2h0IC8gMiAtICh2YWx1ZXMueSk7XG5cbiAgICAgICAgICAgIHRoaXMuX2ltZ1JlY3QueCA9ICh2YWx1ZXMueCk7XG4gICAgICAgICAgICB0aGlzLl9pbWdSZWN0LnkgPSAodmFsdWVzLnkpO1xuICAgICAgICAgICAgdGhpcy5faW1nUmVjdC54YyA9ICh4KTtcbiAgICAgICAgICAgIHRoaXMuX2ltZ1JlY3QueWMgPSAoeSk7XG5cbiAgICAgICAgfVxuICAgICAgICBuZXdTdHlsZXMudHJhbnNmb3JtID0gYHRyYW5zbGF0ZTNkKCR7KHRoaXMuX2ltZ1JlY3QueCl9cHgsJHsodGhpcy5faW1nUmVjdC55KX1weCwgMClgO1xuICAgICAgICBuZXdTdHlsZXMudHJhbnNmb3JtICs9IGBzY2FsZSgke3RoaXMuX3NjYWwzRml4fSlgO1xuICAgICAgICBuZXdTdHlsZXMudHJhbnNmb3JtT3JpZ2luID0gYCR7dGhpcy5faW1nUmVjdC54Y31weCAke3RoaXMuX2ltZ1JlY3QueWN9cHggMGA7XG4gICAgICAgIG5ld1N0eWxlc1tcIi13ZWJraXQtdHJhbnNmb3JtXCJdID0gbmV3U3R5bGVzLnRyYW5zZm9ybTtcbiAgICAgICAgbmV3U3R5bGVzW1wiLXdlYmtpdC10cmFuc2Zvcm0tb3JpZ2luXCJdID0gbmV3U3R5bGVzLnRyYW5zZm9ybU9yaWdpbjtcbiAgICAgICAgZm9yIChjb25zdCBrZXkgaW4gbmV3U3R5bGVzKSB7XG4gICAgICAgICAgICBpZiAobmV3U3R5bGVzLmhhc093blByb3BlcnR5KGtleSkpIHtcbiAgICAgICAgICAgICAgICB0aGlzLl9yZW5kZXJlci5zZXRTdHlsZSh0aGlzLl9pbWdDb250YWluZXIubmF0aXZlRWxlbWVudCwga2V5LCBuZXdTdHlsZXNba2V5XSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogVXBkYXRlIGFyZWEgYW5kIGltYWdlIHBvc2l0aW9uIG9ubHkgaWYgbmVlZGVkLFxuICAgICAqIHRoaXMgaXMgdXNlZCB3aGVuIHdpbmRvdyByZXNpemVcbiAgICAgKi9cbiAgICBwdWJsaWMgdXBkYXRlQ3JvcHBlclBvc2l0aW9uKCk6IHZvaWQge1xuICAgICAgICBpZiAodGhpcy5pc0xvYWRlZCkge1xuICAgICAgICAgICAgdGhpcy51cGRhdGVQb3NpdGlvbigpO1xuICAgICAgICAgICAgdGhpcy5fdXBkYXRlQXJlYUlmTmVlZGVkKCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKiogTG9hZCBJbWFnZSBmcm9tIGlucHV0IGV2ZW50ICovXG4gICAgcHVibGljIHNlbGVjdElucHV0RXZlbnQoaW1nOiBFdmVudCkge1xuICAgICAgICB0aGlzLl9jdXJyZW50SW5wdXRFbGVtZW50ID0gaW1nLnRhcmdldCBhcyBIVE1MSW5wdXRFbGVtZW50O1xuICAgICAgICBjb25zdCBfaW1nID0gaW1nLnRhcmdldCBhcyBIVE1MSW5wdXRFbGVtZW50O1xuICAgICAgICBpZiAoX2ltZy5maWxlcyAmJiBfaW1nLmZpbGVzLmxlbmd0aCAhPT0gMSkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGZpbGVTaXplID0gX2ltZy5maWxlc1swXS5zaXplO1xuICAgICAgICBjb25zdCBmaWxlTmFtZSA9IF9pbWcudmFsdWUucmVwbGFjZSgvLiooXFwvfFxcXFwpLywgXCJcIik7XG5cbiAgICAgICAgaWYgKHRoaXMubWF4RmlsZVNpemUgJiYgZmlsZVNpemUgPiB0aGlzLm1heEZpbGVTaXplKSB7XG4gICAgICAgICAgICBjb25zdCBjcm9wRXZlbnQ6IEltZ0Nyb3BwZXJFcnJvckV2ZW50ID0ge1xuICAgICAgICAgICAgICAgIG5hbWU6IGZpbGVOYW1lLFxuICAgICAgICAgICAgICAgIHR5cGU6IF9pbWcuZmlsZXNbMF0udHlwZSxcbiAgICAgICAgICAgICAgICBzaXplOiBmaWxlU2l6ZSxcbiAgICAgICAgICAgICAgICBlcnJvcjogSW1nQ3JvcHBlckVycm9yLlNpemVcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICB0aGlzLmNsZWFuKCk7XG4gICAgICAgICAgICB0aGlzLmVycm9yLmVtaXQoY3JvcEV2ZW50IGFzIEltZ0Nyb3BwZXJFcnJvckV2ZW50KTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIG5ldyBPYnNlcnZhYmxlPFByb2dyZXNzRXZlbnQ+KG9ic2VydmVyID0+IHtcblxuICAgICAgICAgICAgY29uc3QgcmVhZGVyID0gbmV3IEZpbGVSZWFkZXIoKTtcblxuICAgICAgICAgICAgcmVhZGVyLm9uZXJyb3IgPSBlcnIgPT4gb2JzZXJ2ZXIuZXJyb3IoZXJyKTtcbiAgICAgICAgICAgIHJlYWRlci5vbmFib3J0ID0gZXJyID0+IG9ic2VydmVyLmVycm9yKGVycik7XG4gICAgICAgICAgICByZWFkZXIub25sb2FkID0gKGV2KSA9PiBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgICAgICAgICBvYnNlcnZlci5uZXh0KGV2KTtcbiAgICAgICAgICAgICAgICBvYnNlcnZlci5jb21wbGV0ZSgpO1xuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgIHJlYWRlci5yZWFkQXNEYXRhVVJMKF9pbWcuZmlsZXNbMF0pO1xuICAgICAgICB9KVxuICAgICAgICAgICAgLnBpcGUodGFrZSgxKSwgdGFrZVVudGlsKHRoaXMuX2Rlc3Ryb3kpKVxuICAgICAgICAgICAgLnN1YnNjcmliZShcbiAgICAgICAgICAgICAgICAobG9hZEV2ZW50KSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IG9yaWdpbmFsRGF0YVVSTCA9IChsb2FkRXZlbnQudGFyZ2V0IGFzIEZpbGVSZWFkZXIpLnJlc3VsdCBhcyBzdHJpbmc7XG5cbiAgICAgICAgICAgICAgICAgICAgdGhpcy5sb2FkSW1hZ2Uoe1xuICAgICAgICAgICAgICAgICAgICAgICAgbmFtZTogZmlsZU5hbWUsXG4gICAgICAgICAgICAgICAgICAgICAgICBzaXplOiBfaW1nLmZpbGVzWzBdLnNpemUsIC8vIHNpemUgaW4gYnl0ZXNcbiAgICAgICAgICAgICAgICAgICAgICAgIHR5cGU6IHRoaXMuY29uZmlnLnR5cGUgfHwgX2ltZy5maWxlc1swXS50eXBlLFxuICAgICAgICAgICAgICAgICAgICAgICAgb3JpZ2luYWxEYXRhVVJMXG4gICAgICAgICAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuY2QubWFya0ZvckNoZWNrKCk7XG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGNyb3BFdmVudDogSW1nQ3JvcHBlckVycm9yRXZlbnQgPSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBuYW1lOiBmaWxlTmFtZSxcbiAgICAgICAgICAgICAgICAgICAgICAgIHNpemU6IGZpbGVTaXplLFxuICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3I6IEltZ0Nyb3BwZXJFcnJvci5PdGhlcixcbiAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yTXNnOiBcIlRoZSBGaWxlIGNvdWxkIG5vdCBiZSBsb2FkZWQuXCIsXG4gICAgICAgICAgICAgICAgICAgICAgICB0eXBlOiBfaW1nLmZpbGVzWzBdLnR5cGVcbiAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5jbGVhbigpO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmVycm9yLmVtaXQoY3JvcEV2ZW50IGFzIEltZ0Nyb3BwZXJFcnJvckV2ZW50KTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICApO1xuXG4gICAgfVxuXG4gICAgLyoqIFNldCB0aGUgc2l6ZSBvZiB0aGUgaW1hZ2UsIHRoZSB2YWx1ZXMgY2FuIGJlIDAgYmV0d2VlbiAxLCB3aGVyZSAxIGlzIHRoZSBvcmlnaW5hbCBzaXplICovXG4gICAgcHVibGljIHNldFNjYWxlKHNpemU/OiBudW1iZXIsIG5vQXV0b0Nyb3A/OiBib29sZWFuKSB7XG4gICAgICAgIC8vIGZpeCBtaW4gc2NhbGVcbiAgICAgICAgY29uc3QgbmV3U2l6ZSA9IHNpemUgPj0gdGhpcy5taW5TY2FsZSAmJiBzaXplIDw9IDEgPyBzaXplIDogdGhpcy5taW5TY2FsZTtcblxuICAgICAgICAvLyBjaGVja1xuICAgICAgICBjb25zdCBjaGFuZ2VkID0gc2l6ZSAhPSBudWxsICYmIHNpemUgIT09IHRoaXMuc2NhbGUgJiYgbmV3U2l6ZSAhPT0gdGhpcy5zY2FsZTtcbiAgICAgICAgdGhpcy5fc2NhbGUgPSBzaXplO1xuICAgICAgICBpZiAoIWNoYW5nZWQpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLl9zY2FsM0ZpeCA9IG5ld1NpemU7XG4gICAgICAgIHRoaXMuX3VwZGF0ZUFic29sdXRlU2NhbGUoKTtcbiAgICAgICAgaWYgKHRoaXMuaXNMb2FkZWQpIHtcbiAgICAgICAgICAgIGlmIChjaGFuZ2VkKSB7XG4gICAgICAgICAgICAgICAgY29uc3Qgb3JpZ2luUG9zaXRpb24gPSB7Li4udGhpcy5faW1nUmVjdH07XG4gICAgICAgICAgICAgICAgdGhpcy5vZmZzZXQgPSB7XG4gICAgICAgICAgICAgICAgICAgIHg6IG9yaWdpblBvc2l0aW9uLngsXG4gICAgICAgICAgICAgICAgICAgIHk6IG9yaWdpblBvc2l0aW9uLnksXG4gICAgICAgICAgICAgICAgICAgIGxlZnQ6IG9yaWdpblBvc2l0aW9uLnhjLFxuICAgICAgICAgICAgICAgICAgICB0b3A6IG9yaWdpblBvc2l0aW9uLnljXG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICB0aGlzLl9zZXRTdHlsZXNGb3JDb250SW1nKHt9KTtcbiAgICAgICAgICAgICAgICB0aGlzLl9zaW11bGF0ZVBvaW50ZXJNb3ZlKCk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIGlmICh0aGlzLm1pblNjYWxlKSB7XG4gICAgICAgICAgICB0aGlzLl9zZXRTdHlsZXNGb3JDb250SW1nKHtcbiAgICAgICAgICAgICAgICAuLi50aGlzLl9nZXRDZW50ZXJQb2ludHMoKVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLnNjYWxlQ2hhbmdlLmVtaXQoc2l6ZSk7XG4gICAgICAgIGlmICghbm9BdXRvQ3JvcCkge1xuICAgICAgICAgICAgdGhpcy5fY3JvcElmQXV0b0Nyb3AoKTtcbiAgICAgICAgfVxuXG4gICAgfVxuXG4gICAgcHJpdmF0ZSBfZ2V0Q2VudGVyUG9pbnRzKCkge1xuICAgICAgICBjb25zdCByb290ID0gdGhpcy5fZWxlbWVudFJlZi5uYXRpdmVFbGVtZW50IGFzIEhUTUxFbGVtZW50O1xuICAgICAgICBjb25zdCBpbWcgPSB0aGlzLl9pbWdDYW52YXMubmF0aXZlRWxlbWVudDtcbiAgICAgICAgY29uc3QgeCA9IChyb290Lm9mZnNldFdpZHRoIC0gKGltZy53aWR0aCkpIC8gMjtcbiAgICAgICAgY29uc3QgeSA9IChyb290Lm9mZnNldEhlaWdodCAtIChpbWcuaGVpZ2h0KSkgLyAyO1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgeCxcbiAgICAgICAgICAgIHlcbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBGaXQgdG8gc2NyZWVuXG4gICAgICovXG4gICAgcHVibGljIGZpdFRvU2NyZWVuKCkge1xuICAgICAgICBjb25zdCBjb250YWluZXIgPSB0aGlzLl9lbGVtZW50UmVmLm5hdGl2ZUVsZW1lbnQgYXMgSFRNTEVsZW1lbnQ7XG4gICAgICAgIGNvbnN0IG1pbiA9IHtcbiAgICAgICAgICAgIHdpZHRoOiBjb250YWluZXIub2Zmc2V0V2lkdGgsXG4gICAgICAgICAgICBoZWlnaHQ6IGNvbnRhaW5lci5vZmZzZXRIZWlnaHRcbiAgICAgICAgfTtcbiAgICAgICAgY29uc3QgeyB3aWR0aCwgaGVpZ2h0IH0gPSB0aGlzLl9pbWc7XG4gICAgICAgIGNvbnN0IG1pblNjYWxlID0ge1xuICAgICAgICAgICAgd2lkdGg6IG1pbi53aWR0aCAvIHdpZHRoLFxuICAgICAgICAgICAgaGVpZ2h0OiBtaW4uaGVpZ2h0IC8gaGVpZ2h0XG4gICAgICAgIH07XG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IE1hdGgubWF4KG1pblNjYWxlLndpZHRoLCBtaW5TY2FsZS5oZWlnaHQpO1xuICAgICAgICB0aGlzLnNldFNjYWxlKHJlc3VsdCk7XG4gICAgfVxuXG4gICAgcHVibGljIGZpdCgpIHtcbiAgICAgICAgdGhpcy5zZXRTY2FsZSh0aGlzLm1pblNjYWxlKTtcbiAgICB9XG5cbiAgICBwcml2YXRlIF9wb2ludGVyRG93biA9IChldmVudDogVG91Y2hFdmVudCB8IE1vdXNlRXZlbnQpID0+IHtcbiAgICAgICAgLy8gRG9uJ3QgZG8gYW55dGhpbmcgaWYgdGhlXG4gICAgICAgIC8vIHVzZXIgaXMgdXNpbmcgYW55dGhpbmcgb3RoZXIgdGhhbiB0aGUgbWFpbiBtb3VzZSBidXR0b24uXG4gICAgICAgIGlmICh0aGlzLl9pc1NsaWRpbmcgfHwgKCFpc1RvdWNoRXZlbnQoZXZlbnQpICYmIGV2ZW50LmJ1dHRvbiAhPT0gMCkpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuX25nWm9uZS5ydW4oKCkgPT4ge1xuICAgICAgICAgICAgdGhpcy5faXNTbGlkaW5nID0gdHJ1ZTtcbiAgICAgICAgICAgIHRoaXMub2Zmc2V0ID0ge1xuICAgICAgICAgICAgICAgIHg6IHRoaXMuX2ltZ1JlY3QueCxcbiAgICAgICAgICAgICAgICB5OiB0aGlzLl9pbWdSZWN0LnksXG4gICAgICAgICAgICAgICAgbGVmdDogdGhpcy5faW1nUmVjdC54YyxcbiAgICAgICAgICAgICAgICB0b3A6IHRoaXMuX2ltZ1JlY3QueWNcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICB0aGlzLl9sYXN0UG9pbnRlckV2ZW50ID0gZXZlbnQ7XG4gICAgICAgICAgICB0aGlzLl9zdGFydFBvaW50ZXJFdmVudCA9IGdldEdlc3R1cmVQb2ludEZyb21FdmVudChldmVudCk7XG4gICAgICAgICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICAgICAgdGhpcy5fYmluZEdsb2JhbEV2ZW50cyhldmVudCk7XG4gICAgICAgIH0pO1xuXG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogU2ltdWxhdGUgcG9pbnRlck1vdmUgd2l0aCBjbGllbnRYID0gMCBhbmQgY2xpZW50WSA9IDAsXG4gICAgICogdGhpcyBpcyB1c2VkIGJ5IGBzZXRTY2FsZWAgYW5kIGByb3RhdGVgXG4gICAgICovXG4gICAgcHJpdmF0ZSBfc2ltdWxhdGVQb2ludGVyTW92ZSgpIHtcbiAgICAgICAgdGhpcy5faXNTbGlkaW5nID0gdHJ1ZTtcbiAgICAgICAgdGhpcy5fc3RhcnRQb2ludGVyRXZlbnQgPSB7XG4gICAgICAgICAgICB4OiAwLFxuICAgICAgICAgICAgeTogMFxuICAgICAgICB9O1xuICAgICAgICB0aGlzLl9wb2ludGVyTW92ZSh7XG4gICAgICAgICAgICBjbGllbnRYOiAwLFxuICAgICAgICAgICAgY2xpZW50WTogMCxcbiAgICAgICAgICAgIHR5cGU6IFwiblwiLFxuICAgICAgICAgICAgcHJldmVudERlZmF1bHQ6ICgpID0+IHt9XG4gICAgICAgIH0gYXMgTW91c2VFdmVudCk7XG4gICAgICAgIHRoaXMuX2lzU2xpZGluZyA9IGZhbHNlO1xuICAgICAgICB0aGlzLl9zdGFydFBvaW50ZXJFdmVudCA9IG51bGw7XG4gICAgfVxuXG4gICAgcHVibGljIF9tYXJrRm9yQ2hlY2soKSB7XG4gICAgICAgIHRoaXMuY2QubWFya0ZvckNoZWNrKCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ2FsbGVkIHdoZW4gdGhlIHVzZXIgaGFzIG1vdmVkIHRoZWlyIHBvaW50ZXIgYWZ0ZXJcbiAgICAgKiBzdGFydGluZyB0byBkcmFnLlxuICAgICAqL1xuICAgIHByaXZhdGUgX3BvaW50ZXJNb3ZlID0gKGV2ZW50OiBUb3VjaEV2ZW50IHwgTW91c2VFdmVudCkgPT4ge1xuICAgICAgICBpZiAodGhpcy5faXNTbGlkaW5nKSB7XG4gICAgICAgICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICAgICAgdGhpcy5fbGFzdFBvaW50ZXJFdmVudCA9IGV2ZW50O1xuICAgICAgICAgICAgbGV0IHg6IG51bWJlciB8IHVuZGVmaW5lZDtcbiAgICAgICAgICAgIGxldCB5OiBudW1iZXIgfCB1bmRlZmluZWQ7XG4gICAgICAgICAgICBjb25zdCBjYW52YXMgPSB0aGlzLl9pbWdDYW52YXMubmF0aXZlRWxlbWVudDtcbiAgICAgICAgICAgIGNvbnN0IHNjYWxlRml4ID0gdGhpcy5fc2NhbDNGaXg7XG4gICAgICAgICAgICBjb25zdCBjb25maWcgPSB0aGlzLmNvbmZpZztcbiAgICAgICAgICAgIGNvbnN0IHN0YXJ0UCA9IHRoaXMub2Zmc2V0O1xuICAgICAgICAgICAgY29uc3QgcG9pbnQgPSBnZXRHZXN0dXJlUG9pbnRGcm9tRXZlbnQoZXZlbnQpO1xuICAgICAgICAgICAgY29uc3QgZGVsdGFYID0gcG9pbnQueCAtIHRoaXMuX3N0YXJ0UG9pbnRlckV2ZW50Lng7XG4gICAgICAgICAgICBjb25zdCBkZWx0YVkgPSBwb2ludC55IC0gdGhpcy5fc3RhcnRQb2ludGVyRXZlbnQueTtcbiAgICAgICAgICAgIGlmICghc2NhbGVGaXggfHwgIXN0YXJ0UCkge1xuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgY29uc3QgaXNNaW5TY2FsZVkgPSBjYW52YXMuaGVpZ2h0ICogc2NhbGVGaXggPCBjb25maWcuaGVpZ2h0ICYmIGNvbmZpZy5leHRyYVpvb21PdXQ7XG4gICAgICAgICAgICBjb25zdCBpc01pblNjYWxlWCA9IGNhbnZhcy53aWR0aCAqIHNjYWxlRml4IDwgY29uZmlnLndpZHRoICYmIGNvbmZpZy5leHRyYVpvb21PdXQ7XG5cbiAgICAgICAgICAgIGNvbnN0IGxpbWl0TGVmdCA9IChjb25maWcud2lkdGggLyAyIC8gc2NhbGVGaXgpID49IHN0YXJ0UC5sZWZ0IC0gKGRlbHRhWCAvIHNjYWxlRml4KTtcbiAgICAgICAgICAgIGNvbnN0IGxpbWl0UmlnaHQgPSAoY29uZmlnLndpZHRoIC8gMiAvIHNjYWxlRml4KSArXG4gICAgICAgICAgICAgICAgKGNhbnZhcy53aWR0aCkgLSAoc3RhcnRQLmxlZnQgLSAoZGVsdGFYIC8gc2NhbGVGaXgpKSA8PSBjb25maWcud2lkdGggLyBzY2FsZUZpeDtcbiAgICAgICAgICAgIGNvbnN0IGxpbWl0VG9wID0gKChjb25maWcuaGVpZ2h0IC8gMiAvIHNjYWxlRml4KSA+PSAoc3RhcnRQLnRvcCAtIChkZWx0YVkgLyBzY2FsZUZpeCkpKTtcbiAgICAgICAgICAgIGNvbnN0IGxpbWl0Qm90dG9tID0gKFxuICAgICAgICAgICAgICAgICgoY29uZmlnLmhlaWdodCAvIDIgLyBzY2FsZUZpeCkgKyAoY2FudmFzLmhlaWdodCkgLSAoc3RhcnRQLnRvcCAtIChkZWx0YVkgLyBzY2FsZUZpeCkpKSA8PSAoY29uZmlnLmhlaWdodCAvIHNjYWxlRml4KVxuICAgICAgICAgICAgKTtcblxuICAgICAgICAgICAgLy8gTGltaXQgZm9yIGxlZnRcbiAgICAgICAgICAgIGlmICgobGltaXRMZWZ0ICYmICFpc01pblNjYWxlWCkgfHwgKCFsaW1pdExlZnQgJiYgaXNNaW5TY2FsZVgpKSB7XG4gICAgICAgICAgICAgICAgeCA9IHN0YXJ0UC54ICsgKHN0YXJ0UC5sZWZ0KSAtIChjb25maWcud2lkdGggLyAyIC8gc2NhbGVGaXgpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAvLyBMaW1pdCBmb3IgcmlnaHRcbiAgICAgICAgICAgIGlmICgobGltaXRSaWdodCAmJiAhaXNNaW5TY2FsZVgpIHx8ICghbGltaXRSaWdodCAmJiBpc01pblNjYWxlWCkpIHtcbiAgICAgICAgICAgICAgICB4ID0gc3RhcnRQLnggKyAoc3RhcnRQLmxlZnQpICsgKGNvbmZpZy53aWR0aCAvIDIgLyBzY2FsZUZpeCkgLSBjYW52YXMud2lkdGg7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIExpbWl0IGZvciB0b3BcbiAgICAgICAgICAgIGlmICgobGltaXRUb3AgJiYgIWlzTWluU2NhbGVZKSB8fCAoIWxpbWl0VG9wICYmIGlzTWluU2NhbGVZKSkge1xuICAgICAgICAgICAgICAgIHkgPSBzdGFydFAueSArIChzdGFydFAudG9wKSAtIChjb25maWcuaGVpZ2h0IC8gMiAvIHNjYWxlRml4KTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gTGltaXQgZm9yIGJvdHRvbVxuICAgICAgICAgICAgaWYgKChsaW1pdEJvdHRvbSAmJiAhaXNNaW5TY2FsZVkpIHx8ICghbGltaXRCb3R0b20gJiYgaXNNaW5TY2FsZVkpKSB7XG4gICAgICAgICAgICAgICAgeSA9IHN0YXJ0UC55ICsgKHN0YXJ0UC50b3ApICsgKGNvbmZpZy5oZWlnaHQgLyAyIC8gc2NhbGVGaXgpIC0gY2FudmFzLmhlaWdodDtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gV2hlbiBwcmVzcyBzaGlmdEtleSwgZGVwcmVjYXRlZFxuICAgICAgICAgICAgLy8gaWYgKGV2ZW50LnNyY0V2ZW50ICYmIGV2ZW50LnNyY0V2ZW50LnNoaWZ0S2V5KSB7XG4gICAgICAgICAgICAvLyAgIGlmIChNYXRoLmFicyhldmVudC5kZWx0YVgpID09PSBNYXRoLm1heChNYXRoLmFicyhldmVudC5kZWx0YVgpLCBNYXRoLmFicyhldmVudC5kZWx0YVkpKSkge1xuICAgICAgICAgICAgLy8gICAgIHkgPSB0aGlzLm9mZnNldC50b3A7XG4gICAgICAgICAgICAvLyAgIH0gZWxzZSB7XG4gICAgICAgICAgICAvLyAgICAgeCA9IHRoaXMub2Zmc2V0LmxlZnQ7XG4gICAgICAgICAgICAvLyAgIH1cbiAgICAgICAgICAgIC8vIH1cblxuICAgICAgICAgICAgaWYgKHggPT09IHZvaWQgMCkgeyB4ID0gKGRlbHRhWCAvIHNjYWxlRml4KSArIChzdGFydFAueCk7IH1cbiAgICAgICAgICAgIGlmICh5ID09PSB2b2lkIDApIHsgeSA9IChkZWx0YVkgLyBzY2FsZUZpeCkgKyAoc3RhcnRQLnkpOyB9XG4gICAgICAgICAgICB0aGlzLl9zZXRTdHlsZXNGb3JDb250SW1nKHtcbiAgICAgICAgICAgICAgICB4LCB5XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHB1YmxpYyB1cGRhdGVQb3NpdGlvbigpOiB2b2lkO1xuICAgIHB1YmxpYyB1cGRhdGVQb3NpdGlvbih4T3JpZ2luOiBudW1iZXIsIHlPcmlnaW46IG51bWJlcik6IHZvaWQ7XG4gICAgcHVibGljIHVwZGF0ZVBvc2l0aW9uKHhPcmlnaW4/OiBudW1iZXIsIHlPcmlnaW4/OiBudW1iZXIpOiB2b2lkIHtcbiAgICAgICAgY29uc3QgaG9zdFJlY3QgPSB0aGlzLl9yb290UmVjdCgpO1xuICAgICAgICBjb25zdCBhcmVhUmVjdCA9IHRoaXMuX2FyZWFDcm9wcGVyUmVjdCgpO1xuICAgICAgICBjb25zdCBhcmVhV2lkdGggPSBhcmVhUmVjdC53aWR0aCA+IGhvc3RSZWN0LndpZHRoXG4gICAgICAgICAgICA/IGhvc3RSZWN0LndpZHRoXG4gICAgICAgICAgICA6IGFyZWFSZWN0LndpZHRoO1xuICAgICAgICBjb25zdCBhcmVhSGVpZ2h0ID0gYXJlYVJlY3QuaGVpZ2h0ID4gaG9zdFJlY3QuaGVpZ2h0XG4gICAgICAgICAgICA/IGhvc3RSZWN0LmhlaWdodFxuICAgICAgICAgICAgOiBhcmVhUmVjdC5oZWlnaHQ7XG4gICAgICAgIGxldCB4OiBudW1iZXI7XG4gICAgICAgIGxldCB5OiBudW1iZXI7XG4gICAgICAgIGlmICh4T3JpZ2luID09IG51bGwgJiYgeU9yaWdpbiA9PSBudWxsKSB7XG4gICAgICAgICAgICB4T3JpZ2luID0gdGhpcy5faW1nUmVjdC54YztcbiAgICAgICAgICAgIHlPcmlnaW4gPSB0aGlzLl9pbWdSZWN0LnljO1xuICAgICAgICB9XG4gICAgICAgIHggPSAoYXJlYVJlY3QubGVmdCAtIGhvc3RSZWN0LmxlZnQpO1xuICAgICAgICB5ID0gKGFyZWFSZWN0LnRvcCAtIGhvc3RSZWN0LnRvcCk7XG4gICAgICAgIHggLT0gKHhPcmlnaW4gLSAoYXJlYVdpZHRoIC8gMikpO1xuICAgICAgICB5IC09ICh5T3JpZ2luIC0gKGFyZWFIZWlnaHQgLyAyKSk7XG5cbiAgICAgICAgdGhpcy5fc2V0U3R5bGVzRm9yQ29udEltZyh7XG4gICAgICAgICAgICB4LCB5XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIHB1YmxpYyBfc2xpZGVFbmQoKSB7XG4gICAgICAgIHRoaXMuX2Nyb3BJZkF1dG9Dcm9wKCk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBfY3JvcElmQXV0b0Nyb3AoKSB7XG4gICAgICAgIGlmICh0aGlzLmNvbmZpZy5hdXRvQ3JvcCkge1xuICAgICAgICAgICAgdGhpcy5jcm9wKCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKiogKyAqL1xuICAgIHB1YmxpYyB6b29tSW4oKSB7XG4gICAgICAgIGNvbnN0IHNjYWxlID0gdGhpcy5fc2NhbDNGaXggKyAuMDU7XG4gICAgICAgIGlmIChzY2FsZSA+IHRoaXMubWluU2NhbGUgJiYgc2NhbGUgPD0gdGhpcy5fbWF4U2NhbGUpIHtcbiAgICAgICAgICAgIHRoaXMuc2V0U2NhbGUoc2NhbGUpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5zZXRTY2FsZSh0aGlzLl9tYXhTY2FsZSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKiogQ2xlYW4gdGhlIGltZyBjcm9wcGVyICovXG4gICAgcHVibGljIGNsZWFuKCkge1xuICAgICAgICAvLyBmaXggY2hvb3NpbmcgdGhlIHNhbWUgaW1hZ2UgZG9lcyBub3QgbG9hZFxuICAgICAgICBpZiAodGhpcy5fY3VycmVudElucHV0RWxlbWVudCkge1xuICAgICAgICAgICAgdGhpcy5fY3VycmVudElucHV0RWxlbWVudC52YWx1ZSA9IFwiXCI7XG4gICAgICAgICAgICB0aGlzLl9jdXJyZW50SW5wdXRFbGVtZW50ID0gbnVsbDtcbiAgICAgICAgfVxuICAgICAgICBpZiAodGhpcy5pc0xvYWRlZCkge1xuICAgICAgICAgICAgdGhpcy5faW1nUmVjdCA9IHsgfSBhcyBhbnk7XG4gICAgICAgICAgICB0aGlzLm9mZnNldCA9IHVuZGVmaW5lZDtcbiAgICAgICAgICAgIHRoaXMuc2NhbGUgPSB1bmRlZmluZWQgYXMgYW55O1xuICAgICAgICAgICAgdGhpcy5fc2NhbDNGaXggPSB1bmRlZmluZWQ7XG4gICAgICAgICAgICB0aGlzLl9yb3RhdGlvbiA9IDA7XG4gICAgICAgICAgICB0aGlzLl9taW5TY2FsZSA9IHVuZGVmaW5lZDtcbiAgICAgICAgICAgIHRoaXMuX2lzTG9hZGVkSW1nID0gZmFsc2U7XG4gICAgICAgICAgICB0aGlzLmlzTG9hZGVkID0gZmFsc2U7XG4gICAgICAgICAgICB0aGlzLmlzQ3JvcHBlZCA9IGZhbHNlO1xuICAgICAgICAgICAgdGhpcy5fY3VycmVudExvYWRDb25maWcgPSB1bmRlZmluZWQ7XG4gICAgICAgICAgICB0aGlzLmNvbmZpZyA9IHRoaXMuX2NvbmZpZ1ByaW1hcnk7XG4gICAgICAgICAgICBjb25zdCBjYW52YXMgPSB0aGlzLl9pbWdDYW52YXMubmF0aXZlRWxlbWVudDtcbiAgICAgICAgICAgIGNhbnZhcy53aWR0aCA9IDA7XG4gICAgICAgICAgICBjYW52YXMuaGVpZ2h0ID0gMDtcbiAgICAgICAgICAgIHRoaXMuY2xlYW5lZC5lbWl0KG51bGwpO1xuICAgICAgICAgICAgdGhpcy5jZC5tYXJrRm9yQ2hlY2soKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKiAtICovXG4gICAgcHVibGljIHpvb21PdXQoKSB7XG4gICAgICAgIGNvbnN0IHNjYWxlID0gdGhpcy5fc2NhbDNGaXggLSAuMDU7XG4gICAgICAgIGlmIChzY2FsZSA+IHRoaXMubWluU2NhbGUgJiYgc2NhbGUgPD0gdGhpcy5fbWF4U2NhbGUpIHtcbiAgICAgICAgICAgIHRoaXMuc2V0U2NhbGUoc2NhbGUpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5maXQoKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBwdWJsaWMgY2VudGVyKCkge1xuICAgICAgICBjb25zdCBuZXdTdHlsZXMgPSB7XG4gICAgICAgICAgICAuLi50aGlzLl9nZXRDZW50ZXJQb2ludHMoKVxuICAgICAgICB9O1xuICAgICAgICB0aGlzLl9zZXRTdHlsZXNGb3JDb250SW1nKG5ld1N0eWxlcyk7XG4gICAgICAgIHRoaXMuX2Nyb3BJZkF1dG9Dcm9wKCk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIGxvYWQgYW4gaW1hZ2UgZnJvbSBhIGdpdmVuIGNvbmZpZ3VyYXRpb24sXG4gICAgICogb3IgZnJvbSB0aGUgcmVzdWx0IG9mIGEgY3JvcHBlZCBpbWFnZVxuICAgICAqL1xuICAgIHB1YmxpYyBsb2FkSW1hZ2UoY29uZmlnOiBJbWdDcm9wcGVyTG9hZGVyQ29uZmlnIHwgc3RyaW5nLCBmbj86ICgpID0+IHZvaWQpIHtcbiAgICAgICAgdGhpcy5jbGVhbigpO1xuICAgICAgICBjb25zdCBfY29uZmlnID0gdGhpcy5fY3VycmVudExvYWRDb25maWcgPSB0eXBlb2YgY29uZmlnID09PSBcInN0cmluZ1wiXG4gICAgICAgICAgICA/IHsgb3JpZ2luYWxEYXRhVVJMOiBjb25maWcgfVxuICAgICAgICAgICAgOiB7IC4uLmNvbmZpZyB9O1xuICAgICAgICBsZXQgc3JjID0gX2NvbmZpZy5vcmlnaW5hbERhdGFVUkw7XG4gICAgICAgIHRoaXMuX3ByaW1hcnlBcmVhV2lkdGggPSB0aGlzLl9jb25maWdQcmltYXJ5LndpZHRoO1xuICAgICAgICB0aGlzLl9wcmltYXJ5QXJlYUhlaWdodCA9IHRoaXMuX2NvbmZpZ1ByaW1hcnkuaGVpZ2h0O1xuICAgICAgICBpZiAoX2NvbmZpZy5hcmVhV2lkdGggJiYgX2NvbmZpZy5hcmVhSGVpZ2h0KSB7XG4gICAgICAgICAgICB0aGlzLmNvbmZpZy53aWR0aCA9IF9jb25maWcuYXJlYVdpZHRoO1xuICAgICAgICAgICAgdGhpcy5jb25maWcuaGVpZ2h0ID0gX2NvbmZpZy5hcmVhSGVpZ2h0O1xuICAgICAgICB9XG4gICAgICAgIHNyYyA9IG5vcm1hbGl6ZVNWRyhzcmMpO1xuXG4gICAgICAgIGNvbnN0IGltZyA9IGNyZWF0ZUh0bWxJbWcoc3JjKTtcblxuICAgICAgICBjb25zdCBjcm9wRXZlbnQgPSB7IC4uLl9jb25maWcgfSBhcyBJbWdDcm9wcGVyRXZlbnQ7XG5cbiAgICAgICAgbmV3IE9ic2VydmFibGU8dm9pZD4ob2JzZXJ2ZXIgPT4ge1xuXG4gICAgICAgICAgICBpbWcub25lcnJvciA9IGVyciA9PiBvYnNlcnZlci5lcnJvcihlcnIpO1xuICAgICAgICAgICAgaW1nLm9uYWJvcnQgPSBlcnIgPT4gb2JzZXJ2ZXIuZXJyb3IoZXJyKTtcbiAgICAgICAgICAgIGltZy5vbmxvYWQgPSAoKSA9PiBvYnNlcnZlci5uZXh0KG51bGwpO1xuICAgICAgICB9KVxuICAgICAgICAgICAgLnBpcGUodGFrZSgxKSwgdGFrZVVudGlsKHRoaXMuX2Rlc3Ryb3kpKVxuICAgICAgICAgICAgLnN1YnNjcmliZShcbiAgICAgICAgICAgICAgICAoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX2ltZ0xvYWRlZChpbWcpO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLl9pc0xvYWRlZEltZyA9IHRydWU7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuaW1hZ2VMb2FkZWQuZW1pdChjcm9wRXZlbnQpO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmNkLm1hcmtGb3JDaGVjaygpO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLl9uZ1pvbmUucnVuT3V0c2lkZUFuZ3VsYXIoKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fbmdab25lXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLm9uU3RhYmxlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLmFzT2JzZXJ2YWJsZSgpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLnBpcGUodGFrZSgxKSwgdGFrZVVudGlsKHRoaXMuX2Rlc3Ryb3kpKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5zdWJzY3JpYmUoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICgpID0+IHNldFRpbWVvdXQoKCkgPT4gdGhpcy5fbmdab25lLnJ1bigoKSA9PiB0aGlzLl9wb3NpdGlvbkltZyhjcm9wRXZlbnQsIGZuKSkpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGVycm9yOiBJbWdDcm9wcGVyRXJyb3JFdmVudCA9IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIG5hbWU6IF9jb25maWcubmFtZSxcbiAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yOiBJbWdDcm9wcGVyRXJyb3IuVHlwZSxcbiAgICAgICAgICAgICAgICAgICAgICAgIHR5cGU6IF9jb25maWcudHlwZSxcbiAgICAgICAgICAgICAgICAgICAgICAgIHNpemU6IF9jb25maWcuc2l6ZVxuICAgICAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmVycm9yLmVtaXQoZXJyb3IpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBfdXBkYXRlQXJlYUlmTmVlZGVkKCkge1xuICAgICAgICBpZiAoIXRoaXMuX2NvbmZpZy5yZXNwb25zaXZlQXJlYSkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3Qgcm9vdFJlY3QgPSB0aGlzLl9yb290UmVjdCgpO1xuICAgICAgICBjb25zdCBhcmVhUmVjdCA9IHRoaXMuX2FyZWFDcm9wcGVyUmVjdCgpO1xuICAgICAgICBjb25zdCBtaW5XaWR0aCA9IHRoaXMuY29uZmlnLm1pbldpZHRoIHx8IDE7XG4gICAgICAgIGNvbnN0IG1pbkhlaWdodCA9IHRoaXMuY29uZmlnLm1pbkhlaWdodCB8fCAxO1xuICAgICAgICBpZiAoIShcbiAgICAgICAgICAgIGFyZWFSZWN0LndpZHRoID4gcm9vdFJlY3Qud2lkdGhcbiAgICAgICAgICAgIHx8IGFyZWFSZWN0LmhlaWdodCA+IHJvb3RSZWN0LmhlaWdodFxuICAgICAgICAgICAgfHwgYXJlYVJlY3Qud2lkdGggPCB0aGlzLl9wcmltYXJ5QXJlYVdpZHRoXG4gICAgICAgICAgICB8fCBhcmVhUmVjdC5oZWlnaHQgPCB0aGlzLl9wcmltYXJ5QXJlYUhlaWdodFxuICAgICAgICApKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgYXJlYVdpZHRoQ29uZiA9IE1hdGgubWF4KHRoaXMuY29uZmlnLndpZHRoLCBtaW5XaWR0aCk7XG4gICAgICAgIGNvbnN0IGFyZWFXaWR0aE1heCA9IE1hdGgubWF4KHJvb3RSZWN0LndpZHRoLCBtaW5XaWR0aCk7XG4gICAgICAgIGNvbnN0IG1pbkhvc3QgPSBNYXRoLm1pbihcbiAgICAgICAgICAgIE1hdGgubWF4KHJvb3RSZWN0LndpZHRoLCBtaW5XaWR0aCksIE1hdGgubWF4KHJvb3RSZWN0LmhlaWdodCwgbWluSGVpZ2h0KVxuICAgICAgICApO1xuICAgICAgICBjb25zdCBjdXJyZW50U2NhbGUgPSB0aGlzLl9zY2FsM0ZpeDtcbiAgICAgICAgbGV0IG5ld1NjYWxlID0gMDtcbiAgICAgICAgY29uc3Qgcm91bmRDb25mID0gdGhpcy5jb25maWcucm91bmQ7XG5cbiAgICAgICAgaWYgKHJvdW5kQ29uZikge1xuICAgICAgICAgICAgdGhpcy5jb25maWcud2lkdGggPSB0aGlzLmNvbmZpZy5oZWlnaHQgPSBtaW5Ib3N0O1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgaWYgKGFyZWFXaWR0aENvbmYgPT09IGFyZWFSZWN0LndpZHRoKSB7XG4gICAgICAgICAgICAgICAgaWYgKGFyZWFXaWR0aE1heCA+IHRoaXMuX3ByaW1hcnlBcmVhV2lkdGgpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5jb25maWcud2lkdGggPSB0aGlzLl9wcmltYXJ5QXJlYVdpZHRoO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmNvbmZpZy5oZWlnaHQgPSAodGhpcy5fcHJpbWFyeUFyZWFXaWR0aCAqIGFyZWFSZWN0LmhlaWdodCkgLyBhcmVhUmVjdC53aWR0aDtcbiAgICAgICAgICAgICAgICAgICAgbmV3U2NhbGUgPSAoY3VycmVudFNjYWxlICogdGhpcy5fcHJpbWFyeUFyZWFXaWR0aCkgLyBhcmVhUmVjdC53aWR0aDtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmNvbmZpZy53aWR0aCA9IGFyZWFXaWR0aE1heDtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5jb25maWcuaGVpZ2h0ID0gKGFyZWFXaWR0aE1heCAqIGFyZWFSZWN0LmhlaWdodCkgLyBhcmVhUmVjdC53aWR0aDtcbiAgICAgICAgICAgICAgICAgICAgbmV3U2NhbGUgPSAoY3VycmVudFNjYWxlICogYXJlYVdpZHRoTWF4KSAvIGFyZWFSZWN0LndpZHRoO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB0aGlzLl91cGRhdGVNaW5TY2FsZSgpO1xuICAgICAgICAgICAgICAgIHRoaXMuX3VwZGF0ZU1heFNjYWxlKCk7XG4gICAgICAgICAgICAgICAgdGhpcy5zZXRTY2FsZShuZXdTY2FsZSwgdHJ1ZSk7XG4gICAgICAgICAgICAgICAgdGhpcy5fbWFya0ZvckNoZWNrKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwcml2YXRlIF91cGRhdGVBYnNvbHV0ZVNjYWxlKCkge1xuICAgICAgICBjb25zdCBzY2FsZSA9IHRoaXMuX3NjYWwzRml4IC8gKHRoaXMuY29uZmlnLndpZHRoIC8gdGhpcy5fcHJpbWFyeUFyZWFXaWR0aCk7XG4gICAgICAgIHRoaXMuX2Fic29sdXRlU2NhbGUgPSBzY2FsZTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBMb2FkIEltYWdlIGZyb20gVVJMXG4gICAgICogQGRlcHJlY2F0ZWQgVXNlIGBsb2FkSW1hZ2VgIGluc3RlYWQgb2YgYHNldEltYWdlVXJsYFxuICAgICAqIEBwYXJhbSBzcmMgVVJMXG4gICAgICogQHBhcmFtIGZuIGZ1bmN0aW9uIHRoYXQgd2lsbCBiZSBjYWxsZWQgYmVmb3JlIGVtaXQgdGhlIGV2ZW50IGxvYWRlZFxuICAgICAqL1xuICAgIHB1YmxpYyBzZXRJbWFnZVVybChzcmM6IHN0cmluZywgZm4/OiAoKSA9PiB2b2lkKSB7XG4gICAgICAgIHRoaXMubG9hZEltYWdlKHNyYywgZm4pO1xuICAgIH1cblxuICAgIHByaXZhdGUgX3Bvc2l0aW9uSW1nKGNyb3BFdmVudDogSW1nQ3JvcHBlckV2ZW50LCBmbj86ICgpID0+IHZvaWQpIHtcbiAgICAgICAgY29uc3QgbG9hZENvbmZpZyA9IHRoaXMuX2N1cnJlbnRMb2FkQ29uZmlnO1xuICAgICAgICB0aGlzLl91cGRhdGVNaW5TY2FsZSh0aGlzLl9pbWdDYW52YXMubmF0aXZlRWxlbWVudCk7XG4gICAgICAgIHRoaXMuX3VwZGF0ZU1heFNjYWxlKCk7XG4gICAgICAgIHRoaXMuaXNMb2FkZWQgPSBmYWxzZTtcbiAgICAgICAgaWYgKGZuKSB7XG4gICAgICAgICAgICBmbigpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgaWYgKGxvYWRDb25maWcuc2NhbGUpIHtcbiAgICAgICAgICAgICAgICB0aGlzLnNldFNjYWxlKGxvYWRDb25maWcuc2NhbGUsIHRydWUpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aGlzLnNldFNjYWxlKHRoaXMubWluU2NhbGUsIHRydWUpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy5yb3RhdGUobG9hZENvbmZpZy5yb3RhdGlvbiB8fCAwKTtcbiAgICAgICAgICAgIHRoaXMuX3VwZGF0ZUFyZWFJZk5lZWRlZCgpO1xuICAgICAgICAgICAgdGhpcy5fbWFya0ZvckNoZWNrKCk7XG4gICAgICAgICAgICB0aGlzLl9uZ1pvbmUucnVuT3V0c2lkZUFuZ3VsYXIoKCkgPT4ge1xuICAgICAgICAgICAgICAgIHRoaXMuX25nWm9uZVxuICAgICAgICAgICAgICAgICAgICAub25TdGFibGVcbiAgICAgICAgICAgICAgICAgICAgLmFzT2JzZXJ2YWJsZSgpXG4gICAgICAgICAgICAgICAgICAgIC5waXBlKHRha2UoMSksIHRha2VVbnRpbCh0aGlzLl9kZXN0cm95KSlcbiAgICAgICAgICAgICAgICAgICAgLnN1YnNjcmliZSgoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAobG9hZENvbmZpZy54T3JpZ2luICE9IG51bGwgJiYgbG9hZENvbmZpZy55T3JpZ2luICE9IG51bGwpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnVwZGF0ZVBvc2l0aW9uKGxvYWRDb25maWcueE9yaWdpbiwgbG9hZENvbmZpZy55T3JpZ2luKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX3VwZGF0ZUFyZWFJZk5lZWRlZCgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5pc0xvYWRlZCA9IHRydWU7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl9jcm9wSWZBdXRvQ3JvcCgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fbmdab25lLnJ1bigoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fbWFya0ZvckNoZWNrKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5yZWFkeS5lbWl0KGNyb3BFdmVudCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHB1YmxpYyByb3RhdGUoZGVncmVlczogbnVtYmVyKSB7XG4gICAgICAgIGxldCB2YWxpZERlZ3JlZXMgPSBfbm9ybWFsaXplRGVncmVlcyhkZWdyZWVzKTtcbiAgICAgICAgLy8gSWYgbmVnYXRpdmUgY29udmVydCB0byBwb3NpdGl2ZVxuICAgICAgICBpZiAodmFsaWREZWdyZWVzIDwgMCkge1xuICAgICAgICAgICAgdmFsaWREZWdyZWVzICs9IDM2MDtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBuZXdSb3RhdGlvbiA9IF9ub3JtYWxpemVEZWdyZWVzKCh0aGlzLl9yb3RhdGlvbiB8fCAwKSArIHZhbGlkRGVncmVlcyk7XG4gICAgICAgIGlmIChuZXdSb3RhdGlvbiA9PT0gdGhpcy5fcm90YXRpb24pIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBkZWdyZWVzUmFkID0gdmFsaWREZWdyZWVzICogTWF0aC5QSSAvIDE4MDtcbiAgICAgICAgY29uc3QgY2FudmFzID0gdGhpcy5faW1nQ2FudmFzLm5hdGl2ZUVsZW1lbnQ7XG4gICAgICAgIGNvbnN0IGNhbnZhc0Nsb24gPSBjcmVhdGVDYW52YXNJbWcoY2FudmFzKTtcbiAgICAgICAgY29uc3QgY3R4ID0gY2FudmFzLmdldENvbnRleHQoXCIyZFwiKTtcbiAgICAgICAgdGhpcy5fcm90YXRpb24gPSBuZXdSb3RhdGlvbjtcblxuICAgICAgICAvLyBjbGVhclxuICAgICAgICBjdHguY2xlYXJSZWN0KDAsIDAsIGNhbnZhc0Nsb24ud2lkdGgsIGNhbnZhc0Nsb24uaGVpZ2h0KTtcblxuICAgICAgICAvLyByb3RhdGUgY2FudmFzIGltYWdlXG4gICAgICAgIGNvbnN0IHRyYW5zZm9ybSA9IGByb3RhdGUoJHt2YWxpZERlZ3JlZXN9ZGVnKSBzY2FsZSgkezEgLyB0aGlzLl9zY2FsM0ZpeH0pYDtcbiAgICAgICAgY29uc3QgdHJhbnNmb3JtT3JpZ2luID0gYCR7dGhpcy5faW1nUmVjdC54Y31weCAke3RoaXMuX2ltZ1JlY3QueWN9cHggMGA7XG4gICAgICAgIGNhbnZhcy5zdHlsZS50cmFuc2Zvcm0gPSB0cmFuc2Zvcm07XG4gICAgICAgIC8vIHRzbGludDpkaXNhYmxlLW5leHQtbGluZTogZGVwcmVjYXRpb25cbiAgICAgICAgY2FudmFzLnN0eWxlLndlYmtpdFRyYW5zZm9ybSA9IHRyYW5zZm9ybTtcbiAgICAgICAgY2FudmFzLnN0eWxlLnRyYW5zZm9ybU9yaWdpbiA9IHRyYW5zZm9ybU9yaWdpbjtcbiAgICAgICAgLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lOiBkZXByZWNhdGlvblxuICAgICAgICBjYW52YXMuc3R5bGUud2Via2l0VHJhbnNmb3JtT3JpZ2luID0gdHJhbnNmb3JtT3JpZ2luO1xuXG4gICAgICAgIGNvbnN0IHsgbGVmdCwgdG9wIH0gPSBjYW52YXMuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCkgYXMgRE9NUmVjdDtcblxuICAgICAgICAvLyBzYXZlIHJlY3RcbiAgICAgICAgY29uc3QgY2FudmFzUmVjdCA9IGNhbnZhcy5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcblxuICAgICAgICAvLyByZW1vdmUgcm90YXRlIHN0eWxlc1xuICAgICAgICBjYW52YXMucmVtb3ZlQXR0cmlidXRlKFwic3R5bGVcIik7XG5cbiAgICAgICAgLy8gc2V0IHcgJiBoXG4gICAgICAgIGNvbnN0IHcgPSBjYW52YXNSZWN0LndpZHRoO1xuICAgICAgICBjb25zdCBoID0gY2FudmFzUmVjdC5oZWlnaHQ7XG4gICAgICAgIGN0eC5jYW52YXMud2lkdGggPSB3O1xuICAgICAgICBjdHguY2FudmFzLmhlaWdodCA9IGg7XG5cbiAgICAgICAgLy8gY2xlYXJcbiAgICAgICAgY3R4LmNsZWFyUmVjdCgwLCAwLCB3LCBoKTtcblxuICAgICAgICAvLyB0cmFuc2xhdGUgYW5kIHJvdGF0ZVxuICAgICAgICBjdHgudHJhbnNsYXRlKHcgLyAyLCBoIC8gMik7XG4gICAgICAgIGN0eC5yb3RhdGUoZGVncmVlc1JhZCk7XG4gICAgICAgIGN0eC5kcmF3SW1hZ2UoY2FudmFzQ2xvbiwgLWNhbnZhc0Nsb24ud2lkdGggLyAyLCAtY2FudmFzQ2xvbi5oZWlnaHQgLyAyKTtcblxuICAgICAgICAvLyBVcGRhdGUgbWluIHNjYWxlXG4gICAgICAgIHRoaXMuX3VwZGF0ZU1pblNjYWxlKGNhbnZhcyk7XG4gICAgICAgIHRoaXMuX3VwZGF0ZU1heFNjYWxlKCk7XG5cbiAgICAgICAgLy8gc2V0IHRoZSBtaW5pbXVtIHNjYWxlLCBvbmx5IGlmIG5lY2Vzc2FyeVxuICAgICAgICBpZiAodGhpcy5zY2FsZSA8IHRoaXMubWluU2NhbGUpIHtcbiAgICAgICAgICAgIHRoaXMuc2V0U2NhbGUoMCwgdHJ1ZSk7XG4gICAgICAgIH0gLy8gICAgICAgICAgICAgICAg4oaRIG5vIEF1dG9Dcm9wXG5cbiAgICAgICAgY29uc3Qgcm9vdFJlY3QgPSB0aGlzLl9yb290UmVjdCgpO1xuXG4gICAgICAgIHRoaXMuX3NldFN0eWxlc0ZvckNvbnRJbWcoe1xuICAgICAgICAgICAgeDogKGxlZnQgLSByb290UmVjdC5sZWZ0KSxcbiAgICAgICAgICAgIHk6ICh0b3AgLSByb290UmVjdC50b3ApXG4gICAgICAgIH0pO1xuXG4gICAgICAgIC8vIGtlZXAgaW1hZ2UgaW5zaWRlIHRoZSBmcmFtZVxuICAgICAgICBjb25zdCBvcmlnaW5Qb3NpdGlvbiA9IHsuLi50aGlzLl9pbWdSZWN0fTtcbiAgICAgICAgdGhpcy5vZmZzZXQgPSB7XG4gICAgICAgICAgICB4OiBvcmlnaW5Qb3NpdGlvbi54LFxuICAgICAgICAgICAgeTogb3JpZ2luUG9zaXRpb24ueSxcbiAgICAgICAgICAgIGxlZnQ6IG9yaWdpblBvc2l0aW9uLnhjLFxuICAgICAgICAgICAgdG9wOiBvcmlnaW5Qb3NpdGlvbi55Y1xuICAgICAgICB9O1xuICAgICAgICB0aGlzLl9zZXRTdHlsZXNGb3JDb250SW1nKHt9KTtcbiAgICAgICAgdGhpcy5fc2ltdWxhdGVQb2ludGVyTW92ZSgpO1xuXG4gICAgICAgIHRoaXMuX2Nyb3BJZkF1dG9Dcm9wKCk7XG4gICAgfVxuXG4gICAgcHVibGljIF91cGRhdGVNaW5TY2FsZShjYW52YXM/OiBIVE1MQ2FudmFzRWxlbWVudCkge1xuICAgICAgICBpZiAoIWNhbnZhcykge1xuICAgICAgICAgICAgY2FudmFzID0gdGhpcy5faW1nQ2FudmFzLm5hdGl2ZUVsZW1lbnQ7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgY29uZmlnID0gdGhpcy5jb25maWc7XG4gICAgICAgIGNvbnN0IG1pblNjYWxlID0gKGNvbmZpZy5leHRyYVpvb21PdXQgPyBNYXRoLm1pbiA6IE1hdGgubWF4KShcbiAgICAgICAgICAgIGNvbmZpZy53aWR0aCAvIGNhbnZhcy53aWR0aCxcbiAgICAgICAgICAgIGNvbmZpZy5oZWlnaHQgLyBjYW52YXMuaGVpZ2h0KTtcbiAgICAgICAgdGhpcy5fbWluU2NhbGUgPSBtaW5TY2FsZTtcbiAgICAgICAgdGhpcy5taW5TY2FsZUNoYW5nZS5lbWl0KG1pblNjYWxlKTtcbiAgICB9XG5cbiAgICBwcml2YXRlIF91cGRhdGVNYXhTY2FsZSgpIHtcbiAgICAgICAgY29uc3QgbWF4U2NhbGUgPSAodGhpcy5jb25maWcud2lkdGggLyB0aGlzLl9wcmltYXJ5QXJlYVdpZHRoKTtcbiAgICAgICAgdGhpcy5fbWF4U2NhbGUgPSBtYXhTY2FsZTtcbiAgICAgICAgdGhpcy5tYXhTY2FsZUNoYW5nZS5lbWl0KG1heFNjYWxlKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBSZXNpemUgJiBjcm9wIGltYWdlXG4gICAgICovXG4gICAgcHVibGljIGNyb3AoY29uZmlnPzogSW1nQ3JvcHBlckNvbmZpZyk6IEltZ0Nyb3BwZXJFdmVudCB7XG4gICAgICAgIGNvbnN0IG5ld0NvbmZpZyA9IGNvbmZpZ1xuICAgICAgICAgICAgPyBtZXJnZURlZXAoeyB9LCB0aGlzLmNvbmZpZyB8fCBuZXcgSW1nQ3JvcHBlckNvbmZpZygpLCBjb25maWcpIDogdGhpcy5jb25maWc7XG4gICAgICAgIGNvbnN0IGNyb3BFdmVudCA9IHRoaXMuX2ltZ0Nyb3AobmV3Q29uZmlnKTtcbiAgICAgICAgdGhpcy5jZC5tYXJrRm9yQ2hlY2soKTtcbiAgICAgICAgcmV0dXJuIGNyb3BFdmVudDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAZG9jcy1wcml2YXRlXG4gICAgICovXG4gICAgcHJpdmF0ZSBfaW1nQ3JvcChteUNvbmZpZzogSW1nQ3JvcHBlckNvbmZpZykge1xuICAgICAgICBjb25zdCBjYW52YXNFbGVtZW50OiBIVE1MQ2FudmFzRWxlbWVudCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJjYW52YXNcIik7XG4gICAgICAgIGNvbnN0IGFyZWFSZWN0ID0gdGhpcy5fYXJlYUNyb3BwZXJSZWN0KCk7XG4gICAgICAgIGNvbnN0IGNhbnZhc1JlY3QgPSB0aGlzLl9jYW52YXNSZWN0KCk7XG4gICAgICAgIGNvbnN0IHNjYWxlRml4ID0gdGhpcy5fc2NhbDNGaXg7XG4gICAgICAgIGNvbnN0IGxlZnQgPSAoYXJlYVJlY3QubGVmdCAtIGNhbnZhc1JlY3QubGVmdCkgLyBzY2FsZUZpeDtcbiAgICAgICAgY29uc3QgdG9wID0gKGFyZWFSZWN0LnRvcCAtIGNhbnZhc1JlY3QudG9wKSAvIHNjYWxlRml4O1xuICAgICAgICBjb25zdCB7IG91dHB1dCB9ID0gbXlDb25maWc7XG4gICAgICAgIGNvbnN0IGN1cnJlbnRJbWFnZUxvYWRDb25maWcgPSB0aGlzLl9jdXJyZW50TG9hZENvbmZpZztcbiAgICAgICAgY29uc3QgYXJlYSA9IHtcbiAgICAgICAgICAgIHdpZHRoOiBteUNvbmZpZy53aWR0aCxcbiAgICAgICAgICAgIGhlaWdodDogbXlDb25maWcuaGVpZ2h0XG4gICAgICAgIH07XG4gICAgICAgIGNhbnZhc0VsZW1lbnQud2lkdGggPSBhcmVhLndpZHRoIC8gc2NhbGVGaXg7XG4gICAgICAgIGNhbnZhc0VsZW1lbnQuaGVpZ2h0ID0gYXJlYS5oZWlnaHQgLyBzY2FsZUZpeDtcbiAgICAgICAgY29uc3QgY3R4ID0gY2FudmFzRWxlbWVudC5nZXRDb250ZXh0KFwiMmRcIik7XG4gICAgICAgIGlmIChteUNvbmZpZy5maWxsKSB7XG4gICAgICAgICAgICBjdHguZmlsbFN0eWxlID0gbXlDb25maWcuZmlsbDtcbiAgICAgICAgICAgIGN0eC5maWxsUmVjdCgwLCAwLCBjYW52YXNFbGVtZW50LndpZHRoLCBjYW52YXNFbGVtZW50LmhlaWdodCk7XG4gICAgICAgIH1cbiAgICAgICAgY3R4LmRyYXdJbWFnZSh0aGlzLl9pbWdDYW52YXMubmF0aXZlRWxlbWVudCxcbiAgICAgICAgICAgIC0obGVmdCksIC0odG9wKSxcbiAgICAgICAgKTtcbiAgICAgICAgY29uc3QgcmVzdWx0ID0gY2FudmFzRWxlbWVudDtcbiAgICAgICAgaWYgKG15Q29uZmlnLm91dHB1dCA9PT0gSW1nUmVzb2x1dGlvbi5EZWZhdWx0KSB7XG4gICAgICAgICAgICByZXNpemVDYW52YXMoXG4gICAgICAgICAgICAgICAgcmVzdWx0LFxuICAgICAgICAgICAgICAgIHRoaXMuX2NvbmZpZ1ByaW1hcnkud2lkdGgsXG4gICAgICAgICAgICAgICAgdGhpcy5fY29uZmlnUHJpbWFyeS5oZWlnaHQpO1xuICAgICAgICB9IGVsc2UgaWYgKHR5cGVvZiBvdXRwdXQgPT09IFwib2JqZWN0XCIpIHtcbiAgICAgICAgICAgIGlmIChvdXRwdXQud2lkdGggJiYgb3V0cHV0LmhlaWdodCkge1xuICAgICAgICAgICAgICAgIHJlc2l6ZUNhbnZhcyhyZXN1bHQsIG91dHB1dC53aWR0aCwgb3V0cHV0LmhlaWdodCk7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKG91dHB1dC53aWR0aCkge1xuICAgICAgICAgICAgICAgIGNvbnN0IG5ld0hlaWdodCA9IGFyZWEuaGVpZ2h0ICogb3V0cHV0LndpZHRoIC8gYXJlYS53aWR0aDtcbiAgICAgICAgICAgICAgICByZXNpemVDYW52YXMocmVzdWx0LCBvdXRwdXQud2lkdGgsIG5ld0hlaWdodCk7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKG91dHB1dC5oZWlnaHQpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBuZXdXaWR0aCA9IGFyZWEud2lkdGggKiBvdXRwdXQuaGVpZ2h0IC8gYXJlYS5oZWlnaHQ7XG4gICAgICAgICAgICAgICAgcmVzaXplQ2FudmFzKHJlc3VsdCwgbmV3V2lkdGgsIG91dHB1dC5oZWlnaHQpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHR5cGUgPSBjdXJyZW50SW1hZ2VMb2FkQ29uZmlnLm9yaWdpbmFsRGF0YVVSTC5zdGFydHNXaXRoKFwiaHR0cFwiKVxuICAgICAgICAgICAgPyBjdXJyZW50SW1hZ2VMb2FkQ29uZmlnLnR5cGUgfHwgbXlDb25maWcudHlwZVxuICAgICAgICAgICAgOiBteUNvbmZpZy50eXBlIHx8IGN1cnJlbnRJbWFnZUxvYWRDb25maWcudHlwZTtcbiAgICAgICAgY29uc3QgZGF0YVVSTCA9IHJlc3VsdC50b0RhdGFVUkwodHlwZSk7XG4gICAgICAgIGNvbnN0IGNyb3BFdmVudDogSW1nQ3JvcHBlckV2ZW50ID0ge1xuICAgICAgICAgICAgZGF0YVVSTCxcbiAgICAgICAgICAgIHR5cGUsXG4gICAgICAgICAgICBuYW1lOiBjdXJyZW50SW1hZ2VMb2FkQ29uZmlnLm5hbWUsXG4gICAgICAgICAgICBhcmVhV2lkdGg6IHRoaXMuX3ByaW1hcnlBcmVhV2lkdGgsXG4gICAgICAgICAgICBhcmVhSGVpZ2h0OiB0aGlzLl9wcmltYXJ5QXJlYUhlaWdodCxcbiAgICAgICAgICAgIHdpZHRoOiByZXN1bHQud2lkdGgsXG4gICAgICAgICAgICBoZWlnaHQ6IHJlc3VsdC5oZWlnaHQsXG4gICAgICAgICAgICBvcmlnaW5hbERhdGFVUkw6IGN1cnJlbnRJbWFnZUxvYWRDb25maWcub3JpZ2luYWxEYXRhVVJMLFxuICAgICAgICAgICAgc2NhbGU6IHRoaXMuX2Fic29sdXRlU2NhbGUsXG4gICAgICAgICAgICByb3RhdGlvbjogdGhpcy5fcm90YXRpb24sXG4gICAgICAgICAgICBsZWZ0OiAoYXJlYVJlY3QubGVmdCAtIGNhbnZhc1JlY3QubGVmdCkgLyB0aGlzLl9zY2FsM0ZpeCxcbiAgICAgICAgICAgIHRvcDogKGFyZWFSZWN0LnRvcCAtIGNhbnZhc1JlY3QudG9wKSAvIHRoaXMuX3NjYWwzRml4LFxuICAgICAgICAgICAgc2l6ZTogY3VycmVudEltYWdlTG9hZENvbmZpZy5zaXplLFxuICAgICAgICAgICAgeE9yaWdpbjogdGhpcy5faW1nUmVjdC54YyxcbiAgICAgICAgICAgIHlPcmlnaW46IHRoaXMuX2ltZ1JlY3QueWMsXG4gICAgICAgICAgICBwb3NpdGlvbjoge1xuICAgICAgICAgICAgICAgIHg6IHRoaXMuX2ltZ1JlY3QueGMsXG4gICAgICAgICAgICAgICAgeTogdGhpcy5faW1nUmVjdC55Y1xuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuXG4gICAgICAgIHRoaXMuaXNDcm9wcGVkID0gdHJ1ZTtcbiAgICAgICAgdGhpcy5jcm9wcGVkLmVtaXQoY3JvcEV2ZW50KTtcbiAgICAgICAgcmV0dXJuIGNyb3BFdmVudDtcbiAgICB9XG5cbiAgICBwdWJsaWMgX3Jvb3RSZWN0KCk6IERPTVJlY3Qge1xuICAgICAgICByZXR1cm4gdGhpcy5fZWxlbWVudFJlZi5uYXRpdmVFbGVtZW50LmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpIGFzIERPTVJlY3Q7XG4gICAgfVxuXG4gICAgcHVibGljIF9hcmVhQ3JvcHBlclJlY3QoKTogRE9NUmVjdCB7XG4gICAgICAgIHJldHVybiB0aGlzLl9hcmVhUmVmLm5hdGl2ZUVsZW1lbnQuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCkgYXMgRE9NUmVjdDtcbiAgICB9XG5cbiAgICBwdWJsaWMgX2NhbnZhc1JlY3QoKTogRE9NUmVjdCB7XG4gICAgICAgIHJldHVybiB0aGlzLl9pbWdDYW52YXMubmF0aXZlRWxlbWVudC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcbiAgICB9XG5cblxuICAgIC8qKiBDYWxsZWQgd2hlbiB0aGUgdXNlciBoYXMgbGlmdGVkIHRoZWlyIHBvaW50ZXIuICovXG4gICAgcHJpdmF0ZSBfcG9pbnRlclVwID0gKGV2ZW50OiBUb3VjaEV2ZW50IHwgTW91c2VFdmVudCkgPT4ge1xuICAgICAgICBpZiAodGhpcy5faXNTbGlkaW5nKSB7XG4gICAgICAgICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICAgICAgdGhpcy5fcmVtb3ZlR2xvYmFsRXZlbnRzKCk7XG4gICAgICAgICAgICB0aGlzLl9pc1NsaWRpbmcgPSBmYWxzZTtcbiAgICAgICAgICAgIHRoaXMuX3N0YXJ0UG9pbnRlckV2ZW50ID0gbnVsbDtcbiAgICAgICAgICAgIHRoaXMuX2Nyb3BJZkF1dG9Dcm9wKCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKiogQ2FsbGVkIHdoZW4gdGhlIHdpbmRvdyBoYXMgbG9zdCBmb2N1cy4gKi9cbiAgICBwcml2YXRlIF93aW5kb3dCbHVyID0gKCkgPT4ge1xuICAgICAgICAvLyBJZiB0aGUgd2luZG93IGlzIGJsdXJyZWQgd2hpbGUgZHJhZ2dpbmcgd2UgbmVlZCB0byBzdG9wIGRyYWdnaW5nIGJlY2F1c2UgdGhlXG4gICAgICAgIC8vIGJyb3dzZXIgd29uJ3QgZGlzcGF0Y2ggdGhlIGBtb3VzZXVwYCBhbmQgYHRvdWNoZW5kYCBldmVudHMgYW55bW9yZS5cbiAgICAgICAgaWYgKHRoaXMuX2xhc3RQb2ludGVyRXZlbnQpIHtcbiAgICAgICAgICAgIHRoaXMuX3BvaW50ZXJVcCh0aGlzLl9sYXN0UG9pbnRlckV2ZW50KTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHByaXZhdGUgX2JpbmRHbG9iYWxFdmVudHModHJpZ2dlckV2ZW50OiBUb3VjaEV2ZW50IHwgTW91c2VFdmVudCkge1xuICAgICAgICBjb25zdCBlbGVtZW50ID0gdGhpcy5fZG9jdW1lbnQ7XG4gICAgICAgIGNvbnN0IGlzVG91Y2ggPSBpc1RvdWNoRXZlbnQodHJpZ2dlckV2ZW50KTtcbiAgICAgICAgY29uc3QgbW92ZUV2ZW50TmFtZSA9IGlzVG91Y2ggPyBcInRvdWNobW92ZVwiIDogXCJtb3VzZW1vdmVcIjtcbiAgICAgICAgY29uc3QgZW5kRXZlbnROYW1lID0gaXNUb3VjaCA/IFwidG91Y2hlbmRcIiA6IFwibW91c2V1cFwiO1xuICAgICAgICBlbGVtZW50LmFkZEV2ZW50TGlzdGVuZXIobW92ZUV2ZW50TmFtZSwgdGhpcy5fcG9pbnRlck1vdmUsIGFjdGl2ZUV2ZW50T3B0aW9ucyk7XG4gICAgICAgIGVsZW1lbnQuYWRkRXZlbnRMaXN0ZW5lcihlbmRFdmVudE5hbWUsIHRoaXMuX3BvaW50ZXJVcCwgYWN0aXZlRXZlbnRPcHRpb25zKTtcblxuICAgICAgICBpZiAoaXNUb3VjaCkge1xuICAgICAgICAgICAgZWxlbWVudC5hZGRFdmVudExpc3RlbmVyKFwidG91Y2hjYW5jZWxcIiwgdGhpcy5fcG9pbnRlclVwLCBhY3RpdmVFdmVudE9wdGlvbnMpO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3Qgd2luZG93ID0gdGhpcy5fZ2V0V2luZG93KCk7XG5cbiAgICAgICAgaWYgKHR5cGVvZiB3aW5kb3cgIT09IFwidW5kZWZpbmVkXCIgJiYgd2luZG93KSB7XG4gICAgICAgICAgICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcihcImJsdXJcIiwgdGhpcy5fd2luZG93Qmx1cik7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKiogUmVtb3ZlcyBhbnkgZ2xvYmFsIGV2ZW50IGxpc3RlbmVycyB0aGF0IHdlIG1heSBoYXZlIGFkZGVkLiAqL1xuICAgIHByaXZhdGUgX3JlbW92ZUdsb2JhbEV2ZW50cygpIHtcbiAgICAgICAgY29uc3QgZWxlbWVudCA9IHRoaXMuX2RvY3VtZW50O1xuICAgICAgICBlbGVtZW50LnJlbW92ZUV2ZW50TGlzdGVuZXIoXCJtb3VzZW1vdmVcIiwgdGhpcy5fcG9pbnRlck1vdmUsIGFjdGl2ZUV2ZW50T3B0aW9ucyk7XG4gICAgICAgIGVsZW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcihcIm1vdXNldXBcIiwgdGhpcy5fcG9pbnRlclVwLCBhY3RpdmVFdmVudE9wdGlvbnMpO1xuICAgICAgICBlbGVtZW50LnJlbW92ZUV2ZW50TGlzdGVuZXIoXCJ0b3VjaG1vdmVcIiwgdGhpcy5fcG9pbnRlck1vdmUsIGFjdGl2ZUV2ZW50T3B0aW9ucyk7XG4gICAgICAgIGVsZW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcihcInRvdWNoZW5kXCIsIHRoaXMuX3BvaW50ZXJVcCwgYWN0aXZlRXZlbnRPcHRpb25zKTtcbiAgICAgICAgZWxlbWVudC5yZW1vdmVFdmVudExpc3RlbmVyKFwidG91Y2hjYW5jZWxcIiwgdGhpcy5fcG9pbnRlclVwLCBhY3RpdmVFdmVudE9wdGlvbnMpO1xuXG4gICAgICAgIGNvbnN0IHdpbmRvdyA9IHRoaXMuX2dldFdpbmRvdygpO1xuXG4gICAgICAgIGlmICh0eXBlb2Ygd2luZG93ICE9PSBcInVuZGVmaW5lZFwiICYmIHdpbmRvdykge1xuICAgICAgICAgICAgd2luZG93LnJlbW92ZUV2ZW50TGlzdGVuZXIoXCJibHVyXCIsIHRoaXMuX3dpbmRvd0JsdXIpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqIFVzZSBkZWZhdWx0VmlldyBvZiBpbmplY3RlZCBkb2N1bWVudCBpZiBhdmFpbGFibGUgb3IgZmFsbGJhY2sgdG8gZ2xvYmFsIHdpbmRvdyByZWZlcmVuY2UgKi9cbiAgICBwcml2YXRlIF9nZXRXaW5kb3coKTogV2luZG93IHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2RvY3VtZW50LmRlZmF1bHRWaWV3IHx8IHdpbmRvdztcbiAgICB9XG5cbn1cblxuLyoqXG4gKiBOb3JtYWxpemUgZGVncmVlcyBmb3IgY3JvcHBlciByb3RhdGlvblxuICogQGRvY3MtcHJpdmF0ZVxuICovXG5leHBvcnQgZnVuY3Rpb24gX25vcm1hbGl6ZURlZ3JlZXMobjogbnVtYmVyKSB7XG4gICAgY29uc3QgZGUgPSBuICUgMzYwO1xuICAgIGlmIChkZSAlIDkwKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgTHlDcm9wcGVyOiBJbnZhbGlkIFxcYCR7bn1cXGAgZGVncmVlLCBvbmx5IGFjY2VwdGVkIHZhbHVlczogMCwgOTAsIDE4MCwgMjcwICYgMzYwLmApO1xuICAgIH1cbiAgICByZXR1cm4gZGU7XG59XG5cbi8qKlxuICogQGRvY3MtcHJpdmF0ZVxuICovXG5mdW5jdGlvbiBjcmVhdGVDYW52YXNJbWcoaW1nOiBIVE1MQ2FudmFzRWxlbWVudCB8IEhUTUxJbWFnZUVsZW1lbnQpIHtcblxuICAgIC8vIGNyZWF0ZSBhIG5ldyBjYW52YXNcbiAgICBjb25zdCBuZXdDYW52YXMgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KFwiY2FudmFzXCIpO1xuICAgIGNvbnN0IGNvbnRleHQgPSBuZXdDYW52YXMuZ2V0Q29udGV4dChcIjJkXCIpO1xuXG4gICAgLy8gc2V0IGRpbWVuc2lvbnNcbiAgICBuZXdDYW52YXMud2lkdGggPSBpbWcud2lkdGg7XG4gICAgbmV3Q2FudmFzLmhlaWdodCA9IGltZy5oZWlnaHQ7XG5cbiAgICAvLyBhcHBseSB0aGUgb2xkIGNhbnZhcyB0byB0aGUgbmV3IG9uZVxuICAgIGNvbnRleHQuZHJhd0ltYWdlKGltZywgMCwgMCk7XG5cbiAgICAvLyByZXR1cm4gdGhlIG5ldyBjYW52YXNcbiAgICByZXR1cm4gbmV3Q2FudmFzO1xufVxuXG5cbmNvbnN0IERBVEFfSU1BR0VfU1ZHX1BSRUZJWCA9IFwiZGF0YTppbWFnZS9zdmcreG1sO2Jhc2U2NCxcIjtcblxuZnVuY3Rpb24gbm9ybWFsaXplU1ZHKGRhdGFVUkw6IHN0cmluZykge1xuICAgIGlmICh3aW5kb3cuYXRvYiAmJiBpc1N2Z0ltYWdlKGRhdGFVUkwpKSB7XG4gICAgICAgIGNvbnN0IGxlbiA9IGRhdGFVUkwubGVuZ3RoIC8gNTtcbiAgICAgICAgY29uc3QgdGV4dCA9IHdpbmRvdy5hdG9iKGRhdGFVUkwucmVwbGFjZShEQVRBX0lNQUdFX1NWR19QUkVGSVgsIFwiXCIpKTtcbiAgICAgICAgY29uc3Qgc3BhbiA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJzcGFuXCIpO1xuICAgICAgICBzcGFuLmlubmVySFRNTCA9IHRleHQ7XG4gICAgICAgIGNvbnN0IHN2ZyA9IHNwYW4ucXVlcnlTZWxlY3RvcihcInN2Z1wiKTtcbiAgICAgICAgc3Bhbi5zZXRBdHRyaWJ1dGUoXCJzdHlsZVwiLCBcImRpc3BsYXk6bm9uZVwiKTtcbiAgICAgICAgZG9jdW1lbnQuYm9keS5hcHBlbmRDaGlsZChzcGFuKTtcbiAgICAgICAgY29uc3Qgd2lkdGggPSBwYXJzZUZsb2F0KGdldENvbXB1dGVkU3R5bGUoc3ZnKS53aWR0aCkgfHwgMTtcbiAgICAgICAgY29uc3QgaGVpZ2h0ID0gcGFyc2VGbG9hdChnZXRDb21wdXRlZFN0eWxlKHN2ZykuaGVpZ2h0KSB8fCAxO1xuICAgICAgICBjb25zdCBtYXggPSBNYXRoLm1heCh3aWR0aCwgaGVpZ2h0KTtcblxuICAgICAgICBzdmcuc2V0QXR0cmlidXRlKFwid2lkdGhcIiwgYCR7bGVuIC8gKHdpZHRoIC8gbWF4KX1weGApO1xuICAgICAgICBzdmcuc2V0QXR0cmlidXRlKFwiaGVpZ2h0XCIsIGAke2xlbiAvIChoZWlnaHQgLyBtYXgpfXB4YCk7XG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IERBVEFfSU1BR0VfU1ZHX1BSRUZJWCArIHdpbmRvdy5idG9hKHNwYW4uaW5uZXJIVE1MKTtcbiAgICAgICAgZG9jdW1lbnQuYm9keS5yZW1vdmVDaGlsZChzcGFuKTtcbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9XG4gICAgcmV0dXJuIGRhdGFVUkw7XG59XG5cbmZ1bmN0aW9uIGlzU3ZnSW1hZ2UoZGF0YVVybDogc3RyaW5nKSB7XG4gICAgcmV0dXJuIGRhdGFVcmwuc3RhcnRzV2l0aChEQVRBX0lNQUdFX1NWR19QUkVGSVgpO1xufVxuXG5mdW5jdGlvbiBjcmVhdGVIdG1sSW1nKHNyYzogc3RyaW5nKSB7XG4gICAgY29uc3QgaW1nID0gbmV3IEltYWdlKCk7XG4gICAgaW1nLmNyb3NzT3JpZ2luID0gXCJhbm9ueW1vdXNcIjtcbiAgICBpbWcuc3JjID0gc3JjO1xuICAgIHJldHVybiBpbWc7XG59XG5cblxuZnVuY3Rpb24gZ2V0R2VzdHVyZVBvaW50RnJvbUV2ZW50KGV2ZW50OiBUb3VjaEV2ZW50IHwgTW91c2VFdmVudCkge1xuXG4gICAgLy8gYHRvdWNoZXNgIHdpbGwgYmUgZW1wdHkgZm9yIHN0YXJ0L2VuZCBldmVudHMgc28gd2UgaGF2ZSB0byBmYWxsIGJhY2sgdG8gYGNoYW5nZWRUb3VjaGVzYC5cbiAgICBjb25zdCBwb2ludCA9IGlzVG91Y2hFdmVudChldmVudClcbiAgICAgICAgPyAoZXZlbnQudG91Y2hlc1swXSB8fCBldmVudC5jaGFuZ2VkVG91Y2hlc1swXSlcbiAgICAgICAgOiBldmVudDtcblxuICAgIHJldHVybiB7XG4gICAgICAgIHg6IHBvaW50LmNsaWVudFgsXG4gICAgICAgIHk6IHBvaW50LmNsaWVudFlcbiAgICB9O1xufVxuXG4vKiogUmV0dXJucyB3aGV0aGVyIGFuIGV2ZW50IGlzIGEgdG91Y2ggZXZlbnQuICovXG5mdW5jdGlvbiBpc1RvdWNoRXZlbnQoZXZlbnQ6IE1vdXNlRXZlbnQgfCBUb3VjaEV2ZW50KTogZXZlbnQgaXMgVG91Y2hFdmVudCB7XG4gICAgcmV0dXJuIGV2ZW50LnR5cGVbMF0gPT09IFwidFwiO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gcm91bmQobjogbnVtYmVyKSB7XG4gICAgcmV0dXJuIE1hdGgucm91bmQobik7XG59XG5cbi8qKlxuICogU2ltcGxlIG9iamVjdCBjaGVjay5cbiAqIEBwYXJhbSBpdGVtXG4gKi9cbmZ1bmN0aW9uIGlzT2JqZWN0KGl0ZW0pIHtcbiAgICByZXR1cm4gKGl0ZW0gJiYgdHlwZW9mIGl0ZW0gPT09IFwib2JqZWN0XCIgJiYgIUFycmF5LmlzQXJyYXkoaXRlbSkpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gbWVyZ2VEZWVwPFQsIFU+KHRhcmdldDogVCwgc291cmNlOiBVKTogVCAmIFU7XG5leHBvcnQgZnVuY3Rpb24gbWVyZ2VEZWVwPFQsIFUsIFY+KHRhcmdldDogVCwgc291cmNlMTogVSwgc291cmNlMjogVik6IFQgJiBVICYgVjtcbmV4cG9ydCBmdW5jdGlvbiBtZXJnZURlZXA8VCwgVSwgViwgVz4odGFyZ2V0OiBULCBzb3VyY2UxOiBVLCBzb3VyY2UyOiBWLCBzb3VyY2UzOiBXKTogVCAmIFUgJiBWICYgVztcbmV4cG9ydCBmdW5jdGlvbiBtZXJnZURlZXAodGFyZ2V0OiBvYmplY3QsIC4uLnNvdXJjZXM6IGFueVtdKTogYW55O1xuXG4vKipcbiAqIERlZXAgbWVyZ2UgdHdvIG9iamVjdHMuXG4gKiBAcGFyYW0gdGFyZ2V0XG4gKiBAcGFyYW0gLi4uc291cmNlc1xuICovXG5leHBvcnQgZnVuY3Rpb24gbWVyZ2VEZWVwKHRhcmdldDogYW55LCAuLi5zb3VyY2VzOiBhbnlbXSkge1xuICAgIGlmICghc291cmNlcy5sZW5ndGgpIHsgcmV0dXJuIHRhcmdldDsgfVxuICAgIGNvbnN0IHNvdXJjZSA9IHNvdXJjZXMuc2hpZnQoKTtcblxuICAgIGlmIChpc09iamVjdCh0YXJnZXQpICYmIGlzT2JqZWN0KHNvdXJjZSkpIHtcbiAgICAgICAgZm9yIChjb25zdCBrZXkgaW4gc291cmNlKSB7XG4gICAgICAgICAgICBpZiAoaXNPYmplY3Qoc291cmNlW2tleV0pKSB7XG4gICAgICAgICAgICAgICAgaWYgKCF0YXJnZXRba2V5XSkgeyBPYmplY3QuYXNzaWduKHRhcmdldCwgeyBba2V5XToge30gfSk7IH1cbiAgICAgICAgICAgICAgICBtZXJnZURlZXAodGFyZ2V0W2tleV0sIHNvdXJjZVtrZXldKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgT2JqZWN0LmFzc2lnbih0YXJnZXQsIHsgW2tleV06IHNvdXJjZVtrZXldIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIG1lcmdlRGVlcCh0YXJnZXQsIC4uLnNvdXJjZXMpO1xufVxuXG5cbi8qKlxuICogV2UgaGF2ZSB0aGUgY3JvcHBlciBhcmVhIGluIHRoZSBzYW1lIGZpbGUgdG8gZml4IHRoZSBidWlsZFxuICovXG5cbkBDb21wb25lbnQoe1xuICAgIHNlbGVjdG9yOiBcIm5pY2UtY3JvcHBlci1hcmVhXCIsXG4gICAgdGVtcGxhdGVVcmw6IFwiLi9pbWFnZS1jcm9wcGVyLWFyZWEudGVtcGxhdGUuaHRtbFwiLFxuICAgIHN0eWxlVXJsczogW1wiLi9pbWFnZS1jcm9wcGVyLWFyZWEuc3R5bGUuc2Nzc1wiXSxcbiAgICBlbmNhcHN1bGF0aW9uOiBWaWV3RW5jYXBzdWxhdGlvbi5Ob25lLFxuICAgIGNoYW5nZURldGVjdGlvbjogQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3kuT25QdXNoXG59KVxuZXhwb3J0IGNsYXNzIE5pY2VDcm9wcGVyQXJlYUNvbXBvbmVudCBpbXBsZW1lbnRzIE9uRGVzdHJveSB7XG4gICAgQFZpZXdDaGlsZChcInJlc2l6ZXJcIilcbiAgICBwcml2YXRlIHJlYWRvbmx5IF9yZXNpemVyPzogRWxlbWVudFJlZjtcblxuICAgIEBJbnB1dCgpXG4gICAgcHVibGljIGtlZXBBc3BlY3RSYXRpbzogYm9vbGVhbjtcblxuICAgIEBJbnB1dCgpXG4gICAgQEhvc3RCaW5kaW5nKFwiY2xhc3Mucm91bmRcIilcbiAgICBwdWJsaWMgcm91bmQ6IGJvb2xlYW47XG5cbiAgICAvKiogVXNlZCB0byBzdWJzY3JpYmUgdG8gZ2xvYmFsIG1vdmUgYW5kIGVuZCBldmVudHMgKi9cbiAgICBwcm90ZWN0ZWQgX2RvY3VtZW50OiBEb2N1bWVudDtcbiAgICBwcml2YXRlIF9pc1NsaWRpbmc6IGJvb2xlYW47XG5cbiAgICAvKiogS2VlcHMgdHJhY2sgb2YgdGhlIGxhc3QgcG9pbnRlciBldmVudCB0aGF0IHdhcyBjYXB0dXJlZCBieSB0aGUgY3JvcCBhcmVhLiAqL1xuICAgIHByaXZhdGUgX2xhc3RQb2ludGVyRXZlbnQ6IE1vdXNlRXZlbnQgfCBUb3VjaEV2ZW50IHwgbnVsbDtcbiAgICBwcml2YXRlIF9zdGFydFBvaW50ZXJFdmVudDoge1xuICAgICAgICB4OiBudW1iZXJcbiAgICAgICAgeTogbnVtYmVyXG4gICAgfSB8IG51bGw7XG4gICAgcHJpdmF0ZSBfY3VycmVudFdpZHRoOiBudW1iZXI7XG4gICAgcHJpdmF0ZSBfY3VycmVudEhlaWdodDogbnVtYmVyO1xuICAgIHByaXZhdGUgX3N0YXJ0QXJlYVJlY3Q6IERPTVJlY3Q7XG4gICAgcHJpdmF0ZSBfc3RhcnRJbWdSZWN0OiBET01SZWN0O1xuXG4gICAgY29uc3RydWN0b3IoXG4gICAgICAgIEBJbmplY3QoRE9DVU1FTlQpIF9kb2N1bWVudDogYW55LFxuICAgICAgICBwcml2YXRlIHJlYWRvbmx5IF9lbGVtZW50UmVmOiBFbGVtZW50UmVmLFxuICAgICAgICBwcml2YXRlIHJlYWRvbmx5IF9jcm9wcGVyOiBOaWNlSW1hZ2VDcm9wcGVyQ29tcG9uZW50LFxuICAgICAgICBwcml2YXRlIHJlYWRvbmx5IF9uZ1pvbmU6IE5nWm9uZSxcbiAgICApIHtcbiAgICAgICAgdGhpcy5fZG9jdW1lbnQgPSBfZG9jdW1lbnQ7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBfcmVzaXphYmxlQXJlYTogYm9vbGVhbjtcblxuICAgIEBJbnB1dCgpXG4gICAgcHVibGljIHNldCByZXNpemFibGVBcmVhKHZhbDogYm9vbGVhbikge1xuICAgICAgICBpZiAodmFsICE9PSB0aGlzLl9yZXNpemFibGVBcmVhKSB7XG4gICAgICAgICAgICB0aGlzLl9yZXNpemFibGVBcmVhID0gdmFsO1xuICAgICAgICAgICAgUHJvbWlzZS5yZXNvbHZlKG51bGwpLnRoZW4oKCkgPT4ge1xuICAgICAgICAgICAgICAgIGlmICh2YWwpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fcmVtb3ZlUmVzaXphYmxlQXJlYSgpO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLl9hZGRSZXNpemFibGVBcmVhKCk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fcmVtb3ZlUmVzaXphYmxlQXJlYSgpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgfVxuICAgIHB1YmxpYyBnZXQgcmVzaXphYmxlQXJlYSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3Jlc2l6YWJsZUFyZWE7XG4gICAgfVxuXG4gICAgcHVibGljIG5nT25EZXN0cm95KCkge1xuICAgICAgICB0aGlzLl9yZW1vdmVSZXNpemFibGVBcmVhKCk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBfYWRkUmVzaXphYmxlQXJlYSgpIHtcbiAgICAgICAgdGhpcy5fbmdab25lLnJ1bk91dHNpZGVBbmd1bGFyKCgpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IGVsZW1lbnQgPSB0aGlzLl9yZXNpemVyLm5hdGl2ZUVsZW1lbnQ7XG4gICAgICAgICAgICBlbGVtZW50LmFkZEV2ZW50TGlzdGVuZXIoXCJtb3VzZWRvd25cIiwgdGhpcy5fcG9pbnRlckRvd24sIGFjdGl2ZUV2ZW50T3B0aW9ucyk7XG4gICAgICAgICAgICBlbGVtZW50LmFkZEV2ZW50TGlzdGVuZXIoXCJ0b3VjaHN0YXJ0XCIsIHRoaXMuX3BvaW50ZXJEb3duLCBhY3RpdmVFdmVudE9wdGlvbnMpO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBwcml2YXRlIF9yZW1vdmVSZXNpemFibGVBcmVhKCkge1xuICAgICAgICBjb25zdCBlbGVtZW50ID0gdGhpcy5fcmVzaXplcj8ubmF0aXZlRWxlbWVudDtcbiAgICAgICAgaWYgKGVsZW1lbnQpIHtcbiAgICAgICAgICAgIHRoaXMuX2xhc3RQb2ludGVyRXZlbnQgPSBudWxsO1xuICAgICAgICAgICAgdGhpcy5fcmVtb3ZlR2xvYmFsRXZlbnRzKCk7XG4gICAgICAgICAgICBlbGVtZW50LnJlbW92ZUV2ZW50TGlzdGVuZXIoXCJtb3VzZWRvd25cIiwgdGhpcy5fcG9pbnRlckRvd24sIGFjdGl2ZUV2ZW50T3B0aW9ucyk7XG4gICAgICAgICAgICBlbGVtZW50LnJlbW92ZUV2ZW50TGlzdGVuZXIoXCJ0b3VjaHN0YXJ0XCIsIHRoaXMuX3BvaW50ZXJEb3duLCBhY3RpdmVFdmVudE9wdGlvbnMpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBfcG9pbnRlckRvd24gPSAoZXZlbnQ6IE1vdXNlRXZlbnQgfCBUb3VjaEV2ZW50KSA9PiB7XG4gICAgICAgIC8vIERvbid0IGRvIGFueXRoaW5nIGlmIHRoZVxuICAgICAgICAvLyB1c2VyIGlzIHVzaW5nIGFueXRoaW5nIG90aGVyIHRoYW4gdGhlIG1haW4gbW91c2UgYnV0dG9uLlxuICAgICAgICBpZiAodGhpcy5faXNTbGlkaW5nIHx8ICghaXNUb3VjaEV2ZW50KGV2ZW50KSAmJiBldmVudC5idXR0b24gIT09IDApKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuXG4gICAgICAgIHRoaXMuX25nWm9uZS5ydW4oKCkgPT4ge1xuICAgICAgICAgICAgdGhpcy5faXNTbGlkaW5nID0gdHJ1ZTtcbiAgICAgICAgICAgIHRoaXMuX2xhc3RQb2ludGVyRXZlbnQgPSBldmVudDtcbiAgICAgICAgICAgIHRoaXMuX3N0YXJ0UG9pbnRlckV2ZW50ID0gZ2V0R2VzdHVyZVBvaW50RnJvbUV2ZW50KGV2ZW50KTtcbiAgICAgICAgICAgIHRoaXMuX3N0YXJ0QXJlYVJlY3QgPSB0aGlzLl9jcm9wcGVyLl9hcmVhQ3JvcHBlclJlY3QoKTtcbiAgICAgICAgICAgIHRoaXMuX3N0YXJ0SW1nUmVjdCA9IHRoaXMuX2Nyb3BwZXIuX2NhbnZhc1JlY3QoKTtcbiAgICAgICAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgICAgICB0aGlzLl9iaW5kR2xvYmFsRXZlbnRzKGV2ZW50KTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBfcG9pbnRlck1vdmUgPSAoZXZlbnQ6IE1vdXNlRXZlbnQgfCBUb3VjaEV2ZW50KSA9PiB7XG4gICAgICAgIGlmICh0aGlzLl9pc1NsaWRpbmcpIHtcbiAgICAgICAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgICAgICB0aGlzLl9sYXN0UG9pbnRlckV2ZW50ID0gZXZlbnQ7XG4gICAgICAgICAgICBjb25zdCBlbGVtZW50OiBIVE1MRGl2RWxlbWVudCA9IHRoaXMuX2VsZW1lbnRSZWYubmF0aXZlRWxlbWVudDtcbiAgICAgICAgICAgIGNvbnN0IHt3aWR0aCwgaGVpZ2h0LCBtaW5XaWR0aCwgbWluSGVpZ2h0fSA9IHRoaXMuX2Nyb3BwZXIuY29uZmlnO1xuICAgICAgICAgICAgY29uc3QgcG9pbnQgPSBnZXRHZXN0dXJlUG9pbnRGcm9tRXZlbnQoZXZlbnQpO1xuICAgICAgICAgICAgY29uc3QgZGVsdGFYID0gcG9pbnQueCAtIHRoaXMuX3N0YXJ0UG9pbnRlckV2ZW50Lng7XG4gICAgICAgICAgICBjb25zdCBkZWx0YVkgPSBwb2ludC55IC0gdGhpcy5fc3RhcnRQb2ludGVyRXZlbnQueTtcbiAgICAgICAgICAgIGNvbnN0IHN0YXJ0QXJlYVJlY3QgPSB0aGlzLl9zdGFydEFyZWFSZWN0O1xuICAgICAgICAgICAgY29uc3Qgc3RhcnRJbWdSZWN0ID0gdGhpcy5fc3RhcnRJbWdSZWN0O1xuICAgICAgICAgICAgY29uc3QgaXNSb3VuZCA9IHRoaXMucm91bmQ7XG4gICAgICAgICAgICBjb25zdCBrZWVwQXNwZWN0UmF0aW8gPSB0aGlzLl9jcm9wcGVyLmNvbmZpZy5rZWVwQXNwZWN0UmF0aW8gfHwgZXZlbnQuc2hpZnRLZXk7XG4gICAgICAgICAgICBsZXQgbmV3V2lkdGggPSAwO1xuICAgICAgICAgICAgbGV0IG5ld0hlaWdodCA9IDA7XG4gICAgICAgICAgICBjb25zdCByb290UmVjdCA9IHRoaXMuX2Nyb3BwZXIuX3Jvb3RSZWN0KCk7XG5cbiAgICAgICAgICAgIGlmIChpc1JvdW5kKSB7XG4gICAgICAgICAgICAgICAgLy8gVGhlIGRpc3RhbmNlIGZyb20gdGhlIGNlbnRlciBvZiB0aGUgY3JvcHBlciBhcmVhIHRvIHRoZSBwb2ludGVyXG4gICAgICAgICAgICAgICAgY29uc3Qgb3JpZ2luWCA9ICgod2lkdGggLyAyIC8gTWF0aC5zcXJ0KDIpKSArIGRlbHRhWCk7XG4gICAgICAgICAgICAgICAgY29uc3Qgb3JpZ2luWSA9ICgoaGVpZ2h0IC8gMiAvIE1hdGguc3FydCgyKSkgKyBkZWx0YVkpO1xuXG4gICAgICAgICAgICAgICAgLy8gTGVnXG4gICAgICAgICAgICAgICAgY29uc3Qgc2lkZSA9IE1hdGguc3FydChvcmlnaW5YICoqIDIgKyBvcmlnaW5ZICoqIDIpO1xuICAgICAgICAgICAgICAgIG5ld1dpZHRoID0gbmV3SGVpZ2h0ID0gc2lkZSAqIDI7XG5cbiAgICAgICAgICAgIH0gZWxzZSBpZiAoa2VlcEFzcGVjdFJhdGlvKSB7XG4gICAgICAgICAgICAgICAgbmV3V2lkdGggPSB3aWR0aCArIGRlbHRhWCAqIDI7XG4gICAgICAgICAgICAgICAgbmV3SGVpZ2h0ID0gaGVpZ2h0ICsgZGVsdGFZICogMjtcbiAgICAgICAgICAgICAgICBpZiAod2lkdGggIT09IGhlaWdodCkge1xuICAgICAgICAgICAgICAgICAgICBpZiAod2lkdGggPiBoZWlnaHQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIG5ld0hlaWdodCA9IGhlaWdodCAvICh3aWR0aCAvIG5ld1dpZHRoKTtcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChoZWlnaHQgPiB3aWR0aCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgbmV3V2lkdGggPSB3aWR0aCAvIChoZWlnaHQgLyBuZXdIZWlnaHQpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgbmV3V2lkdGggPSBuZXdIZWlnaHQgPSBNYXRoLm1heChuZXdXaWR0aCwgbmV3SGVpZ2h0KTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIG5ld1dpZHRoID0gd2lkdGggKyBkZWx0YVggKiAyO1xuICAgICAgICAgICAgICAgIG5ld0hlaWdodCA9IGhlaWdodCArIGRlbHRhWSAqIDI7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIFRvIG1pbiB3aWR0aFxuICAgICAgICAgICAgaWYgKG5ld1dpZHRoIDwgbWluV2lkdGgpIHtcbiAgICAgICAgICAgICAgICBuZXdXaWR0aCA9IG1pbldpZHRoO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLy8gVG8gbWluIGhlaWdodFxuICAgICAgICAgICAgaWYgKG5ld0hlaWdodCA8IG1pbkhlaWdodCkge1xuICAgICAgICAgICAgICAgIG5ld0hlaWdodCA9IG1pbkhlaWdodDtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gRG8gbm90IG92ZXJmbG93IHRoZSBjcm9wcGVyIGFyZWFcbiAgICAgICAgICAgIGNvbnN0IGNlbnRlclggPSBzdGFydEFyZWFSZWN0LnggKyBzdGFydEFyZWFSZWN0LndpZHRoIC8gMjtcbiAgICAgICAgICAgIGNvbnN0IGNlbnRlclkgPSBzdGFydEFyZWFSZWN0LnkgKyBzdGFydEFyZWFSZWN0LmhlaWdodCAvIDI7XG4gICAgICAgICAgICBjb25zdCB0b3BPdmVyZmxvdyA9IHN0YXJ0SW1nUmVjdC55ID4gY2VudGVyWSAtIChuZXdIZWlnaHQgLyAyKTtcbiAgICAgICAgICAgIGNvbnN0IGJvdHRvbU92ZXJmbG93ID0gY2VudGVyWSArIChuZXdIZWlnaHQgLyAyKSA+IHN0YXJ0SW1nUmVjdC5ib3R0b207XG4gICAgICAgICAgICBjb25zdCBtaW5IZWlnaHRPbk92ZXJmbG93ID0gTWF0aC5taW4oKGNlbnRlclkgLSBzdGFydEltZ1JlY3QueSkgKiAyLCAoc3RhcnRJbWdSZWN0LmJvdHRvbSAtIGNlbnRlclkpICogMik7XG4gICAgICAgICAgICBjb25zdCBsZWZ0T3ZlcmZsb3cgPSBzdGFydEltZ1JlY3QueCA+IGNlbnRlclggLSAobmV3V2lkdGggLyAyKTtcbiAgICAgICAgICAgIGNvbnN0IHJpZ2h0T3ZlcmZsb3cgPSBjZW50ZXJYICsgKG5ld1dpZHRoIC8gMikgPiBzdGFydEltZ1JlY3QucmlnaHQ7XG4gICAgICAgICAgICBjb25zdCBtaW5XaWR0aE9uT3ZlcmZsb3cgPSBNYXRoLm1pbigoY2VudGVyWCAtIHN0YXJ0SW1nUmVjdC54KSAqIDIsIChzdGFydEltZ1JlY3QucmlnaHQgLSBjZW50ZXJYKSAqIDIpO1xuICAgICAgICAgICAgY29uc3QgbWluT25PdmVyZmxvdyA9IE1hdGgubWluKG1pbldpZHRoT25PdmVyZmxvdywgbWluSGVpZ2h0T25PdmVyZmxvdyk7XG4gICAgICAgICAgICBpZiAocm91bmQpIHtcbiAgICAgICAgICAgICAgICBpZiAodG9wT3ZlcmZsb3cgfHwgYm90dG9tT3ZlcmZsb3cgfHwgbGVmdE92ZXJmbG93IHx8IHJpZ2h0T3ZlcmZsb3cpIHtcbiAgICAgICAgICAgICAgICAgICAgbmV3SGVpZ2h0ID0gbmV3V2lkdGggPSBtaW5Pbk92ZXJmbG93O1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0gZWxzZSBpZiAoa2VlcEFzcGVjdFJhdGlvKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgbmV3TmV3V2lkdGg6IG51bWJlcltdID0gW107XG4gICAgICAgICAgICAgICAgY29uc3QgbmV3TmV3SGVpZ2h0OiBudW1iZXJbXSA9IFtdO1xuICAgICAgICAgICAgICAgIGlmICgodG9wT3ZlcmZsb3cgfHwgYm90dG9tT3ZlcmZsb3cpICYmIE1hdGgubWluKCkpIHtcbiAgICAgICAgICAgICAgICAgICAgbmV3SGVpZ2h0ID0gbWluSGVpZ2h0T25PdmVyZmxvdztcbiAgICAgICAgICAgICAgICAgICAgbmV3TmV3SGVpZ2h0LnB1c2gobmV3SGVpZ2h0KTtcbiAgICAgICAgICAgICAgICAgICAgbmV3V2lkdGggPSB3aWR0aCAvIChoZWlnaHQgLyBtaW5IZWlnaHRPbk92ZXJmbG93KTtcbiAgICAgICAgICAgICAgICAgICAgbmV3TmV3V2lkdGgucHVzaChuZXdXaWR0aCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlmICgobGVmdE92ZXJmbG93IHx8IHJpZ2h0T3ZlcmZsb3cpKSB7XG4gICAgICAgICAgICAgICAgICAgIG5ld1dpZHRoID0gbWluV2lkdGhPbk92ZXJmbG93O1xuICAgICAgICAgICAgICAgICAgICBuZXdOZXdXaWR0aC5wdXNoKG5ld1dpZHRoKTtcbiAgICAgICAgICAgICAgICAgICAgbmV3SGVpZ2h0ID0gaGVpZ2h0IC8gKHdpZHRoIC8gbWluV2lkdGhPbk92ZXJmbG93KTtcbiAgICAgICAgICAgICAgICAgICAgbmV3TmV3SGVpZ2h0LnB1c2gobmV3SGVpZ2h0KTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYgKG5ld05ld1dpZHRoLmxlbmd0aCA9PT0gMikge1xuICAgICAgICAgICAgICAgICAgICBuZXdXaWR0aCA9IE1hdGgubWluKC4uLm5ld05ld1dpZHRoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYgKG5ld05ld0hlaWdodC5sZW5ndGggPT09IDIpIHtcbiAgICAgICAgICAgICAgICAgICAgbmV3SGVpZ2h0ID0gTWF0aC5taW4oLi4ubmV3TmV3SGVpZ2h0KTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGlmICh0b3BPdmVyZmxvdyB8fCBib3R0b21PdmVyZmxvdykge1xuICAgICAgICAgICAgICAgICAgICBuZXdIZWlnaHQgPSBtaW5IZWlnaHRPbk92ZXJmbG93O1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpZiAobGVmdE92ZXJmbG93IHx8IHJpZ2h0T3ZlcmZsb3cpIHtcbiAgICAgICAgICAgICAgICAgICAgbmV3V2lkdGggPSBtaW5XaWR0aE9uT3ZlcmZsb3c7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAvLyBEbyBub3Qgb3ZlcmZsb3cgdGhlIGNvbnRhaW5lclxuICAgICAgICAgICAgaWYgKHJvdW5kKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgbWluID0gTWF0aC5taW4ocm9vdFJlY3Qud2lkdGgsIHJvb3RSZWN0LmhlaWdodCk7XG4gICAgICAgICAgICAgICAgaWYgKG5ld1dpZHRoID4gbWluKSB7XG4gICAgICAgICAgICAgICAgICAgIG5ld1dpZHRoID0gbmV3SGVpZ2h0ID0gbWluO1xuICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAobmV3SGVpZ2h0ID4gbWluKSB7XG4gICAgICAgICAgICAgICAgICAgIG5ld1dpZHRoID0gbmV3SGVpZ2h0ID0gbWluO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0gZWxzZSBpZiAoa2VlcEFzcGVjdFJhdGlvKSB7XG4gICAgICAgICAgICAgICAgaWYgKG5ld1dpZHRoID4gcm9vdFJlY3Qud2lkdGgpIHtcbiAgICAgICAgICAgICAgICAgICAgbmV3V2lkdGggPSByb290UmVjdC53aWR0aDtcbiAgICAgICAgICAgICAgICAgICAgbmV3SGVpZ2h0ID0gaGVpZ2h0IC8gKHdpZHRoIC8gcm9vdFJlY3Qud2lkdGgpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAobmV3SGVpZ2h0ID4gcm9vdFJlY3QuaGVpZ2h0KSB7XG4gICAgICAgICAgICAgICAgICAgIG5ld1dpZHRoID0gd2lkdGggLyAoaGVpZ2h0IC8gcm9vdFJlY3QuaGVpZ2h0KTtcbiAgICAgICAgICAgICAgICAgICAgbmV3SGVpZ2h0ID0gcm9vdFJlY3QuaGVpZ2h0O1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgaWYgKG5ld1dpZHRoID4gcm9vdFJlY3Qud2lkdGgpIHtcbiAgICAgICAgICAgICAgICAgICAgbmV3V2lkdGggPSByb290UmVjdC53aWR0aDtcbiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKG5ld0hlaWdodCA+IHJvb3RSZWN0LmhlaWdodCkge1xuICAgICAgICAgICAgICAgICAgICBuZXdIZWlnaHQgPSByb290UmVjdC5oZWlnaHQ7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG5cbiAgICAgICAgICAgIC8vIHJvdW5kIHZhbHVlc1xuICAgICAgICAgICAgbmV3V2lkdGggPSBNYXRoLnJvdW5kKG5ld1dpZHRoKTtcbiAgICAgICAgICAgIG5ld0hlaWdodCA9IE1hdGgucm91bmQobmV3SGVpZ2h0KTtcblxuICAgICAgICAgICAgZWxlbWVudC5zdHlsZS53aWR0aCA9IGAke25ld1dpZHRofXB4YDtcbiAgICAgICAgICAgIGVsZW1lbnQuc3R5bGUuaGVpZ2h0ID0gYCR7bmV3SGVpZ2h0fXB4YDtcbiAgICAgICAgICAgIHRoaXMuX2N1cnJlbnRXaWR0aCA9IG5ld1dpZHRoO1xuICAgICAgICAgICAgdGhpcy5fY3VycmVudEhlaWdodCA9IG5ld0hlaWdodDtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKiBDYWxsZWQgd2hlbiB0aGUgdXNlciBoYXMgbGlmdGVkIHRoZWlyIHBvaW50ZXIuICovXG4gICAgcHJpdmF0ZSBfcG9pbnRlclVwID0gKGV2ZW50OiBUb3VjaEV2ZW50IHwgTW91c2VFdmVudCkgPT4ge1xuICAgICAgICBpZiAodGhpcy5faXNTbGlkaW5nKSB7XG4gICAgICAgICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICAgICAgdGhpcy5fcmVtb3ZlR2xvYmFsRXZlbnRzKCk7XG4gICAgICAgICAgICB0aGlzLl9jcm9wcGVyLl9wcmltYXJ5QXJlYVdpZHRoID0gdGhpcy5fY3JvcHBlci5jb25maWcud2lkdGggPSB0aGlzLl9jdXJyZW50V2lkdGg7XG4gICAgICAgICAgICB0aGlzLl9jcm9wcGVyLl9wcmltYXJ5QXJlYUhlaWdodCA9IHRoaXMuX2Nyb3BwZXIuY29uZmlnLmhlaWdodCA9IHRoaXMuX2N1cnJlbnRIZWlnaHQ7XG4gICAgICAgICAgICB0aGlzLl9jcm9wcGVyLmNvbmZpZyA9IHRoaXMuX2Nyb3BwZXIuY29uZmlnO1xuICAgICAgICAgICAgdGhpcy5fY3JvcHBlci5fdXBkYXRlTWluU2NhbGUoKTtcbiAgICAgICAgICAgIHRoaXMuX2lzU2xpZGluZyA9IGZhbHNlO1xuICAgICAgICAgICAgdGhpcy5fc3RhcnRQb2ludGVyRXZlbnQgPSBudWxsO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqIENhbGxlZCB3aGVuIHRoZSB3aW5kb3cgaGFzIGxvc3QgZm9jdXMuICovXG4gICAgcHJpdmF0ZSBfd2luZG93Qmx1ciA9ICgpID0+IHtcbiAgICAgICAgLy8gSWYgdGhlIHdpbmRvdyBpcyBibHVycmVkIHdoaWxlIGRyYWdnaW5nIHdlIG5lZWQgdG8gc3RvcCBkcmFnZ2luZyBiZWNhdXNlIHRoZVxuICAgICAgICAvLyBicm93c2VyIHdvbid0IGRpc3BhdGNoIHRoZSBgbW91c2V1cGAgYW5kIGB0b3VjaGVuZGAgZXZlbnRzIGFueW1vcmUuXG4gICAgICAgIGlmICh0aGlzLl9sYXN0UG9pbnRlckV2ZW50KSB7XG4gICAgICAgICAgICB0aGlzLl9wb2ludGVyVXAodGhpcy5fbGFzdFBvaW50ZXJFdmVudCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwcml2YXRlIF9iaW5kR2xvYmFsRXZlbnRzKHRyaWdnZXJFdmVudDogVG91Y2hFdmVudCB8IE1vdXNlRXZlbnQpIHtcbiAgICAgICAgY29uc3QgZWxlbWVudCA9IHRoaXMuX2RvY3VtZW50O1xuICAgICAgICBjb25zdCBpc1RvdWNoID0gaXNUb3VjaEV2ZW50KHRyaWdnZXJFdmVudCk7XG4gICAgICAgIGNvbnN0IG1vdmVFdmVudE5hbWUgPSBpc1RvdWNoID8gXCJ0b3VjaG1vdmVcIiA6IFwibW91c2Vtb3ZlXCI7XG4gICAgICAgIGNvbnN0IGVuZEV2ZW50TmFtZSA9IGlzVG91Y2ggPyBcInRvdWNoZW5kXCIgOiBcIm1vdXNldXBcIjtcbiAgICAgICAgZWxlbWVudC5hZGRFdmVudExpc3RlbmVyKG1vdmVFdmVudE5hbWUsIHRoaXMuX3BvaW50ZXJNb3ZlLCBhY3RpdmVFdmVudE9wdGlvbnMpO1xuICAgICAgICBlbGVtZW50LmFkZEV2ZW50TGlzdGVuZXIoZW5kRXZlbnROYW1lLCB0aGlzLl9wb2ludGVyVXAsIGFjdGl2ZUV2ZW50T3B0aW9ucyk7XG5cbiAgICAgICAgaWYgKGlzVG91Y2gpIHtcbiAgICAgICAgICAgIGVsZW1lbnQuYWRkRXZlbnRMaXN0ZW5lcihcInRvdWNoY2FuY2VsXCIsIHRoaXMuX3BvaW50ZXJVcCwgYWN0aXZlRXZlbnRPcHRpb25zKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IHdpbmRvdyA9IHRoaXMuX2dldFdpbmRvdygpO1xuXG4gICAgICAgIGlmICh0eXBlb2Ygd2luZG93ICE9PSBcInVuZGVmaW5lZFwiICYmIHdpbmRvdykge1xuICAgICAgICAgICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoXCJibHVyXCIsIHRoaXMuX3dpbmRvd0JsdXIpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqIFJlbW92ZXMgYW55IGdsb2JhbCBldmVudCBsaXN0ZW5lcnMgdGhhdCB3ZSBtYXkgaGF2ZSBhZGRlZC4gKi9cbiAgICBwcml2YXRlIF9yZW1vdmVHbG9iYWxFdmVudHMoKSB7XG4gICAgICAgIGNvbnN0IGVsZW1lbnQgPSB0aGlzLl9kb2N1bWVudDtcbiAgICAgICAgZWxlbWVudC5yZW1vdmVFdmVudExpc3RlbmVyKFwibW91c2Vtb3ZlXCIsIHRoaXMuX3BvaW50ZXJNb3ZlLCBhY3RpdmVFdmVudE9wdGlvbnMpO1xuICAgICAgICBlbGVtZW50LnJlbW92ZUV2ZW50TGlzdGVuZXIoXCJtb3VzZXVwXCIsIHRoaXMuX3BvaW50ZXJVcCwgYWN0aXZlRXZlbnRPcHRpb25zKTtcbiAgICAgICAgZWxlbWVudC5yZW1vdmVFdmVudExpc3RlbmVyKFwidG91Y2htb3ZlXCIsIHRoaXMuX3BvaW50ZXJNb3ZlLCBhY3RpdmVFdmVudE9wdGlvbnMpO1xuICAgICAgICBlbGVtZW50LnJlbW92ZUV2ZW50TGlzdGVuZXIoXCJ0b3VjaGVuZFwiLCB0aGlzLl9wb2ludGVyVXAsIGFjdGl2ZUV2ZW50T3B0aW9ucyk7XG4gICAgICAgIGVsZW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcihcInRvdWNoY2FuY2VsXCIsIHRoaXMuX3BvaW50ZXJVcCwgYWN0aXZlRXZlbnRPcHRpb25zKTtcblxuICAgICAgICBjb25zdCB3aW5kb3cgPSB0aGlzLl9nZXRXaW5kb3coKTtcblxuICAgICAgICBpZiAodHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiAmJiB3aW5kb3cpIHtcbiAgICAgICAgICAgIHdpbmRvdy5yZW1vdmVFdmVudExpc3RlbmVyKFwiYmx1clwiLCB0aGlzLl93aW5kb3dCbHVyKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKiBVc2UgZGVmYXVsdFZpZXcgb2YgaW5qZWN0ZWQgZG9jdW1lbnQgaWYgYXZhaWxhYmxlIG9yIGZhbGxiYWNrIHRvIGdsb2JhbCB3aW5kb3cgcmVmZXJlbmNlICovXG4gICAgcHJpdmF0ZSBfZ2V0V2luZG93KCk6IFdpbmRvdyB7XG4gICAgICAgIHJldHVybiB0aGlzLl9kb2N1bWVudC5kZWZhdWx0VmlldyB8fCB3aW5kb3c7XG4gICAgfVxufVxuIiwiPCEtLSAoc2VsZWN0c3RhcnQpOiBPbiBTYWZhcmkgc3RhcnRpbmcgdG8gc2xpZGUgdGVtcG9yYXJpbHkgdHJpZ2dlcnMgdGV4dCBzZWxlY3Rpb24gbW9kZSB3aGljaFxuc2hvdyB0aGUgd3JvbmcgY3Vyc29yLiBXZSBwcmV2ZW50IGl0IGJ5IHN0b3BwaW5nIHRoZSBgc2VsZWN0c3RhcnRgIGV2ZW50LiAtLT5cbjxkaXYgY2xhc3M9XCJpbWFnZS1jb250YWluZXJcIiAjX2ltZ0NvbnRhaW5lclxuICAgICAoc2VsZWN0c3RhcnQpPVwiJGV2ZW50LnByZXZlbnREZWZhdWx0KClcIlxuPlxuICAgIDxjYW52YXMgI19pbWdDYW52YXM+PC9jYW52YXM+XG48L2Rpdj5cbjxuaWNlLWNyb3BwZXItYXJlYVxuICAgICNfYXJlYVxuICAgICpuZ0lmPVwiX2lzTG9hZGVkSW1nXCJcbiAgICBbcm91bmRdPVwiISFjb25maWcucm91bmRcIlxuICAgIFtyZXNpemFibGVBcmVhXT1cIiEhY29uZmlnLnJlc2l6YWJsZUFyZWFcIlxuICAgIFtrZWVwQXNwZWN0UmF0aW9dPVwiISFjb25maWcua2VlcEFzcGVjdFJhdGlvXCJcbiAgICBbbmdTdHlsZV09XCJ7XG4gICAgICAgIHdpZHRoOiBjb25maWcud2lkdGggKyAncHgnLFxuICAgICAgICBoZWlnaHQ6IGNvbmZpZy5oZWlnaHQgKyAncHgnXG4gICAgfVwiXG4+PC9uaWNlLWNyb3BwZXItYXJlYT5cbjxidXR0b24gY2xhc3M9XCJjbG9zZS1idXR0b25cIiBtYXQtaWNvbi1idXR0b24gKm5nSWY9XCJfaXNMb2FkZWRJbWdcIiAoY2xpY2spPVwiY2xlYW4oKVwiPlxuICAgIDxtYXQtaWNvbj5hcnJvd19iYWNrPC9tYXQtaWNvbj5cbjwvYnV0dG9uPlxuIiwiPGRpdiBjbGFzcz1cInJlc2l6ZXJcIiAjcmVzaXplciAqbmdJZj1cInJlc2l6YWJsZUFyZWFcIj48L2Rpdj5cbiJdfQ==